aboutsummaryrefslogtreecommitdiffstats
path: root/src/libfreeswan
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2006-05-10 07:32:34 +0000
committerMartin Willi <martin@strongswan.org>2006-05-10 07:32:34 +0000
commitbc4a07a0adc9e31af75576477fbed488c31edaa4 (patch)
tree82a8ba5612c448b8db585b437fbbe38ef243a0ba /src/libfreeswan
parent37a2b616e28649b6db7c87e96b375ba1176b52cc (diff)
downloadstrongswan-bc4a07a0adc9e31af75576477fbed488c31edaa4.tar.bz2
strongswan-bc4a07a0adc9e31af75576477fbed488c31edaa4.tar.xz
- started to rebuild source layout
Diffstat (limited to 'src/libfreeswan')
-rw-r--r--src/libfreeswan/.cvsignore2
-rw-r--r--src/libfreeswan/COPYING.LIB481
-rw-r--r--src/libfreeswan/Makefile41
-rw-r--r--src/libfreeswan/Makefile.kernel65
-rw-r--r--src/libfreeswan/README3
-rw-r--r--src/libfreeswan/libcrypto/include/cbc_generic.h110
-rw-r--r--src/libfreeswan/libcrypto/include/hmac_generic.h60
-rw-r--r--src/libfreeswan/libcrypto/include/md32_common.h607
-rw-r--r--src/libfreeswan/libcrypto/libaes/Makefile40
-rw-r--r--src/libfreeswan/libcrypto/libaes/aes.c1415
-rw-r--r--src/libfreeswan/libcrypto/libaes/aes.h97
-rw-r--r--src/libfreeswan/libcrypto/libaes/aes_cbc.c13
-rw-r--r--src/libfreeswan/libcrypto/libaes/aes_cbc.h4
-rw-r--r--src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.c67
-rw-r--r--src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.h12
-rw-r--r--src/libfreeswan/libcrypto/libaes/asm/aes-i586.S892
-rw-r--r--src/libfreeswan/libcrypto/libaes/test_main.c41
-rw-r--r--src/libfreeswan/libcrypto/libaes/test_main_mac.c30
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/COPYRIGHT46
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/INSTALL14
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/Makefile121
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/Makefile.ssl118
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/README8
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/VERSION6
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/asm/bf-586.pl136
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/asm/bf-686.pl127
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/asm/readme10
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/bf_enc.c306
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/bf_locl.h218
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/bf_pi.h325
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/bf_skey.c122
-rw-r--r--src/libfreeswan/libcrypto/libblowfish/blowfish.h133
-rw-r--r--src/libfreeswan/libcrypto/libserpent/Makefile20
-rw-r--r--src/libfreeswan/libcrypto/libserpent/serpent.c995
-rw-r--r--src/libfreeswan/libcrypto/libserpent/serpent.h17
-rw-r--r--src/libfreeswan/libcrypto/libserpent/serpent_cbc.c8
-rw-r--r--src/libfreeswan/libcrypto/libserpent/serpent_cbc.h3
-rw-r--r--src/libfreeswan/libcrypto/libserpent/test_main.c34
-rw-r--r--src/libfreeswan/libcrypto/libsha2/Makefile21
-rw-r--r--src/libfreeswan/libcrypto/libsha2/hmac_sha2.c32
-rw-r--r--src/libfreeswan/libcrypto/libsha2/hmac_sha2.h17
-rw-r--r--src/libfreeswan/libcrypto/libsha2/sha2.c437
-rw-r--r--src/libfreeswan/libcrypto/libsha2/sha2.h52
-rw-r--r--src/libfreeswan/libcrypto/libtwofish/Makefile21
-rw-r--r--src/libfreeswan/libcrypto/libtwofish/test_main.c34
-rw-r--r--src/libfreeswan/libcrypto/libtwofish/twofish.c861
-rw-r--r--src/libfreeswan/libcrypto/libtwofish/twofish.h20
-rw-r--r--src/libfreeswan/libcrypto/libtwofish/twofish_cbc.c8
-rw-r--r--src/libfreeswan/libcrypto/libtwofish/twofish_cbc.h3
-rw-r--r--src/libfreeswan/libcrypto/perlasm/LICENSE127
-rw-r--r--src/libfreeswan/libcrypto/perlasm/alpha.pl434
-rw-r--r--src/libfreeswan/libcrypto/perlasm/cbc.pl342
-rw-r--r--src/libfreeswan/libcrypto/perlasm/readme124
-rw-r--r--src/libfreeswan/libcrypto/perlasm/version5
-rw-r--r--src/libfreeswan/libcrypto/perlasm/x86asm.pl118
-rw-r--r--src/libfreeswan/libcrypto/perlasm/x86ms.pl365
-rw-r--r--src/libfreeswan/libcrypto/perlasm/x86nasm.pl366
-rw-r--r--src/libfreeswan/libcrypto/perlasm/x86unix.pl472
-rw-r--r--src/libfreeswan/libdes/.cvsignore3
-rw-r--r--src/libfreeswan/libdes/Makefile245
-rw-r--r--src/libfreeswan/libdes/des.h308
-rw-r--r--src/libfreeswan/libdes/des/COPYRIGHT50
-rw-r--r--src/libfreeswan/libdes/des/INSTALL69
-rw-r--r--src/libfreeswan/libdes/des/Makefile.objs20
-rw-r--r--src/libfreeswan/libdes/des/README54
-rw-r--r--src/libfreeswan/libdes/des/README.freeswan33
-rw-r--r--src/libfreeswan/libdes/des/VERSION406
-rw-r--r--src/libfreeswan/libdes/des/asm/crypt586.pl204
-rw-r--r--src/libfreeswan/libdes/des/asm/des-586.pl251
-rw-r--r--src/libfreeswan/libdes/des/asm/des686.pl230
-rw-r--r--src/libfreeswan/libdes/des/asm/desboth.pl79
-rw-r--r--src/libfreeswan/libdes/des/asm/perlasm/cbc.pl342
-rw-r--r--src/libfreeswan/libdes/des/asm/perlasm/readme124
-rw-r--r--src/libfreeswan/libdes/des/asm/perlasm/x86asm.pl111
-rw-r--r--src/libfreeswan/libdes/des/asm/perlasm/x86ms.pl345
-rw-r--r--src/libfreeswan/libdes/des/asm/perlasm/x86unix.pl403
-rw-r--r--src/libfreeswan/libdes/des/asm/readme131
-rw-r--r--src/libfreeswan/libdes/des/cbc_enc.c135
-rw-r--r--src/libfreeswan/libdes/des/des.doc505
-rw-r--r--src/libfreeswan/libdes/des/des_crypt.man508
-rw-r--r--src/libfreeswan/libdes/des/des_enc.c502
-rw-r--r--src/libfreeswan/libdes/des/des_locl.h515
-rw-r--r--src/libfreeswan/libdes/des/des_opts.c620
-rw-r--r--src/libfreeswan/libdes/des/des_ver.h60
-rw-r--r--src/libfreeswan/libdes/des/destest.c871
-rw-r--r--src/libfreeswan/libdes/des/dx86unix.S3160
-rw-r--r--src/libfreeswan/libdes/des/ecb_enc.c128
-rw-r--r--src/libfreeswan/libdes/des/fcrypt.c152
-rw-r--r--src/libfreeswan/libdes/des/fcrypt_b.c148
-rw-r--r--src/libfreeswan/libdes/des/options.txt39
-rw-r--r--src/libfreeswan/libdes/des/podd.h75
-rw-r--r--src/libfreeswan/libdes/des/set_key.c246
-rw-r--r--src/libfreeswan/libdes/des/sk.h204
-rw-r--r--src/libfreeswan/libdes/des/speed.c329
-rw-r--r--src/libfreeswan/libdes/des/spr.h204
-rw-r--r--src/libfreeswan/libfreeswan/.cvsignore9
-rw-r--r--src/libfreeswan/libfreeswan/Makefile174
-rw-r--r--src/libfreeswan/libfreeswan/Makefile.objs18
-rw-r--r--src/libfreeswan/libfreeswan/addrtoa.c68
-rw-r--r--src/libfreeswan/libfreeswan/addrtot.c302
-rw-r--r--src/libfreeswan/libfreeswan/addrtypeof.c94
-rw-r--r--src/libfreeswan/libfreeswan/anyaddr.387
-rw-r--r--src/libfreeswan/libfreeswan/anyaddr.c146
-rw-r--r--src/libfreeswan/libfreeswan/atoaddr.3294
-rw-r--r--src/libfreeswan/libfreeswan/atoaddr.c238
-rw-r--r--src/libfreeswan/libfreeswan/atoasr.3186
-rw-r--r--src/libfreeswan/libfreeswan/atoasr.c212
-rw-r--r--src/libfreeswan/libfreeswan/atosa.3218
-rw-r--r--src/libfreeswan/libfreeswan/atosa.c200
-rw-r--r--src/libfreeswan/libfreeswan/atosubnet.c216
-rw-r--r--src/libfreeswan/libfreeswan/atoul.3161
-rw-r--r--src/libfreeswan/libfreeswan/atoul.c90
-rw-r--r--src/libfreeswan/libfreeswan/copyright.c56
-rw-r--r--src/libfreeswan/libfreeswan/datatot.c233
-rw-r--r--src/libfreeswan/libfreeswan/goodmask.357
-rw-r--r--src/libfreeswan/libfreeswan/goodmask.c97
-rw-r--r--src/libfreeswan/libfreeswan/initaddr.3129
-rw-r--r--src/libfreeswan/libfreeswan/initaddr.c51
-rw-r--r--src/libfreeswan/libfreeswan/initsaid.c33
-rw-r--r--src/libfreeswan/libfreeswan/initsubnet.3137
-rw-r--r--src/libfreeswan/libfreeswan/initsubnet.c95
-rw-r--r--src/libfreeswan/libfreeswan/internal.h81
-rw-r--r--src/libfreeswan/libfreeswan/keyblobtoid.3103
-rw-r--r--src/libfreeswan/libfreeswan/keyblobtoid.c148
-rw-r--r--src/libfreeswan/libfreeswan/optionsfrom.3182
-rw-r--r--src/libfreeswan/libfreeswan/optionsfrom.c301
-rw-r--r--src/libfreeswan/libfreeswan/pfkey_v2_build.c1438
-rw-r--r--src/libfreeswan/libfreeswan/pfkey_v2_debug.c179
-rw-r--r--src/libfreeswan/libfreeswan/pfkey_v2_ext_bits.c803
-rw-r--r--src/libfreeswan/libfreeswan/pfkey_v2_parse.c1832
-rw-r--r--src/libfreeswan/libfreeswan/portof.370
-rw-r--r--src/libfreeswan/libfreeswan/portof.c96
-rw-r--r--src/libfreeswan/libfreeswan/prng.3121
-rw-r--r--src/libfreeswan/libfreeswan/prng.c202
-rw-r--r--src/libfreeswan/libfreeswan/rangetoa.c61
-rw-r--r--src/libfreeswan/libfreeswan/rangetosubnet.359
-rw-r--r--src/libfreeswan/libfreeswan/rangetosubnet.c226
-rw-r--r--src/libfreeswan/libfreeswan/sameaddr.3165
-rw-r--r--src/libfreeswan/libfreeswan/sameaddr.c190
-rw-r--r--src/libfreeswan/libfreeswan/satoa.c102
-rw-r--r--src/libfreeswan/libfreeswan/satot.c132
-rw-r--r--src/libfreeswan/libfreeswan/subnetof.347
-rw-r--r--src/libfreeswan/libfreeswan/subnetof.c60
-rw-r--r--src/libfreeswan/libfreeswan/subnettoa.c62
-rw-r--r--src/libfreeswan/libfreeswan/subnettot.c56
-rw-r--r--src/libfreeswan/libfreeswan/subnettypeof.c109
-rw-r--r--src/libfreeswan/libfreeswan/ttoaddr.3377
-rw-r--r--src/libfreeswan/libfreeswan/ttoaddr.c426
-rw-r--r--src/libfreeswan/libfreeswan/ttodata.3281
-rw-r--r--src/libfreeswan/libfreeswan/ttodata.c722
-rw-r--r--src/libfreeswan/libfreeswan/ttoprotoport.c103
-rw-r--r--src/libfreeswan/libfreeswan/ttosa.3288
-rw-r--r--src/libfreeswan/libfreeswan/ttosa.c280
-rw-r--r--src/libfreeswan/libfreeswan/ttosubnet.c296
-rw-r--r--src/libfreeswan/libfreeswan/ttoul.3192
-rw-r--r--src/libfreeswan/libfreeswan/ttoul.c91
-rw-r--r--src/libfreeswan/libfreeswan/ultoa.c67
-rw-r--r--src/libfreeswan/libfreeswan/ultot.c83
-rw-r--r--src/libfreeswan/libfreeswan/version.344
-rw-r--r--src/libfreeswan/libfreeswan/version.in.c44
-rw-r--r--src/libfreeswan/libipsecpolicy/.cvsignore1
-rw-r--r--src/libfreeswan/libipsecpolicy/Makefile96
-rw-r--r--src/libfreeswan/libipsecpolicy/cgipolicy.c77
-rw-r--r--src/libfreeswan/libipsecpolicy/libipsecpolicy.h4
-rw-r--r--src/libfreeswan/libipsecpolicy/policyquery.c167
-rw-r--r--src/libfreeswan/libipsecpolicy/version.in.c38
-rw-r--r--src/libfreeswan/liblwres/Makefile73
-rw-r--r--src/libfreeswan/liblwres/api3
-rw-r--r--src/libfreeswan/liblwres/assert_p.h33
-rw-r--r--src/libfreeswan/liblwres/async.c361
-rw-r--r--src/libfreeswan/liblwres/config.h0
-rw-r--r--src/libfreeswan/liblwres/context.c380
-rw-r--r--src/libfreeswan/liblwres/context_p.h68
-rw-r--r--src/libfreeswan/liblwres/gai_strerror.c52
-rw-r--r--src/libfreeswan/liblwres/getaddrinfo.c692
-rw-r--r--src/libfreeswan/liblwres/gethost.c219
-rw-r--r--src/libfreeswan/liblwres/getipnode.c839
-rw-r--r--src/libfreeswan/liblwres/getnameinfo.c289
-rw-r--r--src/libfreeswan/liblwres/getrrset.c211
-rw-r--r--src/libfreeswan/liblwres/getrrset2.c97
-rw-r--r--src/libfreeswan/liblwres/herror.c101
-rw-r--r--src/libfreeswan/liblwres/include/lwres/async.h78
-rw-r--r--src/libfreeswan/liblwres/include/lwres/context.h133
-rw-r--r--src/libfreeswan/liblwres/include/lwres/int.h32
-rw-r--r--src/libfreeswan/liblwres/include/lwres/ipv6.h118
-rw-r--r--src/libfreeswan/liblwres/include/lwres/lang.h31
-rw-r--r--src/libfreeswan/liblwres/include/lwres/list.h119
-rw-r--r--src/libfreeswan/liblwres/include/lwres/lwbuffer.h402
-rw-r--r--src/libfreeswan/liblwres/include/lwres/lwpacket.h124
-rw-r--r--src/libfreeswan/liblwres/include/lwres/lwres.h584
-rw-r--r--src/libfreeswan/liblwres/include/lwres/netdb.h522
-rw-r--r--src/libfreeswan/liblwres/include/lwres/netdb.h.in518
-rw-r--r--src/libfreeswan/liblwres/include/lwres/platform.h91
-rw-r--r--src/libfreeswan/liblwres/include/lwres/platform.h.in91
-rw-r--r--src/libfreeswan/liblwres/include/lwres/result.h40
-rw-r--r--src/libfreeswan/liblwres/lwbuffer.c287
-rw-r--r--src/libfreeswan/liblwres/lwconfig.c703
-rw-r--r--src/libfreeswan/liblwres/lwinetaton.c203
-rw-r--r--src/libfreeswan/liblwres/lwinetntop.c191
-rw-r--r--src/libfreeswan/liblwres/lwinetpton.c206
-rw-r--r--src/libfreeswan/liblwres/lwpacket.c85
-rw-r--r--src/libfreeswan/liblwres/lwres_gabn.c415
-rw-r--r--src/libfreeswan/liblwres/lwres_gnba.c328
-rw-r--r--src/libfreeswan/liblwres/lwres_grbn.c416
-rw-r--r--src/libfreeswan/liblwres/lwres_noop.c255
-rw-r--r--src/libfreeswan/liblwres/lwresutil.c491
-rw-r--r--src/libfreeswan/liblwres/man/Makefile.in232
-rw-r--r--src/libfreeswan/liblwres/man/lwres.3158
-rw-r--r--src/libfreeswan/liblwres/man/lwres.docbook244
-rw-r--r--src/libfreeswan/liblwres/man/lwres.html444
-rw-r--r--src/libfreeswan/liblwres/man/lwres_buffer.3277
-rw-r--r--src/libfreeswan/liblwres/man/lwres_buffer.docbook378
-rw-r--r--src/libfreeswan/liblwres/man/lwres_buffer.html608
-rw-r--r--src/libfreeswan/liblwres/man/lwres_config.3105
-rw-r--r--src/libfreeswan/liblwres/man/lwres_config.docbook159
-rw-r--r--src/libfreeswan/liblwres/man/lwres_config.html295
-rw-r--r--src/libfreeswan/liblwres/man/lwres_context.3194
-rw-r--r--src/libfreeswan/liblwres/man/lwres_context.docbook283
-rw-r--r--src/libfreeswan/liblwres/man/lwres_context.html519
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gabn.3193
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gabn.docbook255
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gabn.html442
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gai_strerror.386
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gai_strerror.docbook161
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gai_strerror.html294
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getaddrinfo.3247
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getaddrinfo.docbook372
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getaddrinfo.html722
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gethostent.3270
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gethostent.docbook407
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gethostent.html827
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getipnode.3187
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getipnode.docbook307
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getipnode.html529
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getnameinfo.384
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getnameinfo.docbook154
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getnameinfo.html303
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getrrsetbyname.3142
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getrrsetbyname.docbook208
-rw-r--r--src/libfreeswan/liblwres/man/lwres_getrrsetbyname.html371
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gnba.3186
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gnba.docbook259
-rw-r--r--src/libfreeswan/liblwres/man/lwres_gnba.html408
-rw-r--r--src/libfreeswan/liblwres/man/lwres_hstrerror.367
-rw-r--r--src/libfreeswan/liblwres/man/lwres_hstrerror.docbook124
-rw-r--r--src/libfreeswan/liblwres/man/lwres_hstrerror.html242
-rw-r--r--src/libfreeswan/liblwres/man/lwres_inetntop.352
-rw-r--r--src/libfreeswan/liblwres/man/lwres_inetntop.docbook99
-rw-r--r--src/libfreeswan/liblwres/man/lwres_inetntop.html186
-rw-r--r--src/libfreeswan/liblwres/man/lwres_noop.3160
-rw-r--r--src/libfreeswan/liblwres/man/lwres_noop.docbook229
-rw-r--r--src/libfreeswan/liblwres/man/lwres_noop.html409
-rw-r--r--src/libfreeswan/liblwres/man/lwres_packet.3149
-rw-r--r--src/libfreeswan/liblwres/man/lwres_packet.docbook218
-rw-r--r--src/libfreeswan/liblwres/man/lwres_packet.html373
-rw-r--r--src/libfreeswan/liblwres/man/lwres_resutil.3151
-rw-r--r--src/libfreeswan/liblwres/man/lwres_resutil.docbook221
-rw-r--r--src/libfreeswan/liblwres/man/lwres_resutil.html412
-rw-r--r--src/libfreeswan/liblwres/unix/include/lwres/net.h127
-rw-r--r--src/libfreeswan/liblwres/version.c24
260 files changed, 60952 insertions, 0 deletions
diff --git a/src/libfreeswan/.cvsignore b/src/libfreeswan/.cvsignore
new file mode 100644
index 000000000..aa84dc001
--- /dev/null
+++ b/src/libfreeswan/.cvsignore
@@ -0,0 +1,2 @@
+ktmp
+version.c
diff --git a/src/libfreeswan/COPYING.LIB b/src/libfreeswan/COPYING.LIB
new file mode 100644
index 000000000..92b8903ff
--- /dev/null
+++ b/src/libfreeswan/COPYING.LIB
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/src/libfreeswan/Makefile b/src/libfreeswan/Makefile
new file mode 100644
index 000000000..fa2b27bef
--- /dev/null
+++ b/src/libfreeswan/Makefile
@@ -0,0 +1,41 @@
+# Makefile for the KLIPS interface utilities
+# Copyright (C) 1998, 1999 Henry Spencer.
+# Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:24 as Exp $
+
+FREESWANSRCDIR=..
+include ${FREESWANSRCDIR}/Makefile.inc
+
+SUBDIRS=libfreeswan libdes
+
+ifeq ($(USE_LWRES),true)
+SUBDIRS+=liblwres
+endif
+
+ifeq ($(USE_IPSECPOLICY),true)
+SUBDIRS+=libipsecpolicy
+endif
+
+def:
+ @echo "Please read doc/intro.html or INSTALL before running make"
+ @false
+
+# programs
+
+cleanall distclean mostlyclean realclean install programs checkprograms check clean spotless install_file_list:
+ @for d in $(SUBDIRS) ; \
+ do \
+ (cd $$d && $(MAKE) FREESWANSRCDIR=$(FREESWANSRCDIR)/.. $@ ) || exit 1; \
+ done; \
+
diff --git a/src/libfreeswan/Makefile.kernel b/src/libfreeswan/Makefile.kernel
new file mode 100644
index 000000000..f32a4f0b7
--- /dev/null
+++ b/src/libfreeswan/Makefile.kernel
@@ -0,0 +1,65 @@
+# FreeS/WAN library
+# Copyright (C) 1998-2002 Henry Spencer.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: Makefile.kernel,v 1.1 2004/03/15 20:35:24 as Exp $
+
+
+
+include ../Makefile.inc
+include ../Makefile.ver
+
+
+
+ifndef TOPDIR
+TOPDIR := /usr/src/linux
+endif
+
+L_TARGET := libkernel.a
+
+obj-y := addrtoa.o datatot.o goodmask.o \
+ pfkey_v2_build.o pfkey_v2_debug.o pfkey_v2_ext_bits.o pfkey_v2_parse.o \
+ prng.o rangetoa.o satoa.o \
+ subnetof.o subnettoa.o ultoa.o version.o
+
+HDRS=freeswan.h internal.h
+
+EXTRA_CFLAGS += -I. $(KLIPSCOMPILE)
+
+EXTRA_CFLAGS += -Wall
+#EXTRA_CFLAGS += -Wconversion
+#EXTRA_CFLAGS += -Wmissing-prototypes
+EXTRA_CFLAGS += -Wpointer-arith
+#EXTRA_CFLAGS += -Wcast-qual
+#EXTRA_CFLAGS += -Wmissing-declarations
+EXTRA_CFLAGS += -Wstrict-prototypes
+#EXTRA_CFLAGS += -pedantic
+#EXTRA_CFLAGS += -W
+#EXTRA_CFLAGS += -Wwrite-strings
+#EXTRA_CFLAGS += -Wbad-function-cast
+
+active-objs := $(sort $(obj-y) $(obj-m))
+L_OBJS := $(obj-y)
+M_OBJS := $(obj-m)
+MIX_OBJS := $(filter $(export-objs), $(active-objs))
+
+include $(TOPDIR)/Rules.make
+
+$(obj-y): $(HDRS)
+
+# build version.c using version number from Makefile.ver
+version.c: version.in.c
+ sed '/"/s/xxx/$(IPSECVERSION)/' version.in.c >$@
+
+clean:
+ rm -f $(L_TARGET) *.o try* core *.core version.c
+ ( cd des && $(MAKE) clean )
diff --git a/src/libfreeswan/README b/src/libfreeswan/README
new file mode 100644
index 000000000..1834a8792
--- /dev/null
+++ b/src/libfreeswan/README
@@ -0,0 +1,3 @@
+These are general library functions used in many places in FreeS/WAN.
+
+They are under the GNU library license; see COPYING.LIB.
diff --git a/src/libfreeswan/libcrypto/include/cbc_generic.h b/src/libfreeswan/libcrypto/include/cbc_generic.h
new file mode 100644
index 000000000..0dd3a77d6
--- /dev/null
+++ b/src/libfreeswan/libcrypto/include/cbc_generic.h
@@ -0,0 +1,110 @@
+#ifndef _CBC_GENERIC_H
+#define _CBC_GENERIC_H
+/*
+ * CBC macro helpers
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ */
+
+/*
+ * Heavily inspired in loop_AES
+ */
+#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
+int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
+ int ret=ilen, pos; \
+ const u_int32_t *iv_i; \
+ if ((ilen) % 16) return 0; \
+ if (encrypt) { \
+ pos=0; \
+ while(pos<ilen) { \
+ if (pos==0) \
+ iv_i=(const u_int32_t*) iv; \
+ else \
+ iv_i=(const u_int32_t*) (out-16); \
+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
+ enc_func(ctx, (addr_type) out, (addr_type) out); \
+ in+=16; \
+ out+=16; \
+ pos+=16; \
+ } \
+ } else { \
+ pos=ilen-16; \
+ in+=pos; \
+ out+=pos; \
+ while(pos>=0) { \
+ dec_func(ctx, (const addr_type) in, (addr_type) out); \
+ if (pos==0) \
+ iv_i=(const u_int32_t*) (iv); \
+ else \
+ iv_i=(const u_int32_t*) (in-16); \
+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
+ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
+ in-=16; \
+ out-=16; \
+ pos-=16; \
+ } \
+ } \
+ return ret; \
+}
+#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
+ int ret=ilen, pos; \
+ const u_int32_t *iv_i; \
+ if ((ilen) % 8) return 0; \
+ if (encrypt) { \
+ pos=0; \
+ while(pos<ilen) { \
+ if (pos==0) \
+ iv_i=(const u_int32_t*) iv; \
+ else \
+ iv_i=(const u_int32_t*) (out-8); \
+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
+ enc_func(ctx, (addr_type)out, (addr_type)out); \
+ in+=8; \
+ out+=8; \
+ pos+=8; \
+ } \
+ } else { \
+ pos=ilen-8; \
+ in+=pos; \
+ out+=pos; \
+ while(pos>=0) { \
+ dec_func(ctx, (const addr_type)in, (addr_type)out); \
+ if (pos==0) \
+ iv_i=(const u_int32_t*) (iv); \
+ else \
+ iv_i=(const u_int32_t*) (in-8); \
+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
+ in-=8; \
+ out-=8; \
+ pos-=8; \
+ } \
+ } \
+ return ret; \
+}
+#define CBC_DECL(name, ctx_type) \
+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
+/*
+Eg.:
+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
+CBC_DECL(AES_cbc_encrypt, aes_context);
+*/
+#endif /* _CBC_GENERIC_H */
diff --git a/src/libfreeswan/libcrypto/include/hmac_generic.h b/src/libfreeswan/libcrypto/include/hmac_generic.h
new file mode 100644
index 000000000..a749228e3
--- /dev/null
+++ b/src/libfreeswan/libcrypto/include/hmac_generic.h
@@ -0,0 +1,60 @@
+#ifndef _HMAC_GENERIC_H
+#define _HMAC_GENERIC_H
+/*
+ * HMAC macro helpers
+ *
+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ */
+
+#ifndef DIVUP
+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
+#endif
+#ifndef HMAC_IPAD
+#define HMAC_IPAD 0x36
+#define HMAC_OPAD 0x5C
+#endif
+#define HMAC_SET_KEY_IMPL(func_name, hctx_t, blocksize, func_init, func_update) \
+void func_name(hctx_t *hctx, const u_int8_t * key, int keylen) { \
+ int i;\
+ u_int8_t kb[blocksize]; \
+ for (i = 0; i < DIVUP(keylen*8, 8); i++) { \
+ kb[i] = key[i] ^ HMAC_IPAD; \
+ } \
+ for (; i < blocksize; i++) { \
+ kb[i] = HMAC_IPAD; \
+ } \
+ func_init(&hctx->ictx); \
+ func_update(&hctx->ictx, kb, blocksize); \
+ for (i = 0; i < blocksize; i++) { \
+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); \
+ } \
+ func_init(&hctx->octx); \
+ func_update(&hctx->octx, kb, blocksize); \
+}
+#define HMAC_HASH_IMPL(func_name, hctx_t, ctx_t, ahlen, func_update, func_result ) \
+void func_name(hctx_t *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen) { \
+ ctx_t ctx; \
+ ctx=hctx->ictx; \
+ if (dat) func_update(&ctx, dat, len); \
+ if (hash) { \
+ u_int8_t hash_buf[ahlen]; \
+ func_result(&ctx, hash_buf, ahlen); \
+ ctx=hctx->octx; \
+ func_update(&ctx, hash_buf, ahlen); \
+ func_result(&ctx, hash, hashlen); \
+ memset(&ctx, 0, sizeof (ctx)); \
+ memset(&hash_buf, 0, sizeof (hash_buf));\
+ } \
+}
+#endif /* _HMAC_GENERIC_H */
diff --git a/src/libfreeswan/libcrypto/include/md32_common.h b/src/libfreeswan/libcrypto/include/md32_common.h
new file mode 100644
index 000000000..1a404a458
--- /dev/null
+++ b/src/libfreeswan/libcrypto/include/md32_common.h
@@ -0,0 +1,607 @@
+/* crypto/md32_common.h */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * This is a generic 32 bit "collector" for message digest algorithms.
+ * Whenever needed it collects input character stream into chunks of
+ * 32 bit values and invokes a block function that performs actual hash
+ * calculations.
+ *
+ * Porting guide.
+ *
+ * Obligatory macros:
+ *
+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
+ * this macro defines byte order of input stream.
+ * HASH_CBLOCK
+ * size of a unit chunk HASH_BLOCK operates on.
+ * HASH_LONG
+ * has to be at lest 32 bit wide, if it's wider, then
+ * HASH_LONG_LOG2 *has to* be defined along
+ * HASH_CTX
+ * context structure that at least contains following
+ * members:
+ * typedef struct {
+ * ...
+ * HASH_LONG Nl,Nh;
+ * HASH_LONG data[HASH_LBLOCK];
+ * int num;
+ * ...
+ * } HASH_CTX;
+ * HASH_UPDATE
+ * name of "Update" function, implemented here.
+ * HASH_TRANSFORM
+ * name of "Transform" function, implemented here.
+ * HASH_FINAL
+ * name of "Final" function, implemented here.
+ * HASH_BLOCK_HOST_ORDER
+ * name of "block" function treating *aligned* input message
+ * in host byte order, implemented externally.
+ * HASH_BLOCK_DATA_ORDER
+ * name of "block" function treating *unaligned* input message
+ * in original (data) byte order, implemented externally (it
+ * actually is optional if data and host are of the same
+ * "endianess").
+ * HASH_MAKE_STRING
+ * macro convering context variables to an ASCII hash string.
+ *
+ * Optional macros:
+ *
+ * B_ENDIAN or L_ENDIAN
+ * defines host byte-order.
+ * HASH_LONG_LOG2
+ * defaults to 2 if not states otherwise.
+ * HASH_LBLOCK
+ * assumed to be HASH_CBLOCK/4 if not stated otherwise.
+ * HASH_BLOCK_DATA_ORDER_ALIGNED
+ * alternative "block" function capable of treating
+ * aligned input message in original (data) order,
+ * implemented externally.
+ *
+ * MD5 example:
+ *
+ * #define DATA_ORDER_IS_LITTLE_ENDIAN
+ *
+ * #define HASH_LONG MD5_LONG
+ * #define HASH_LONG_LOG2 MD5_LONG_LOG2
+ * #define HASH_CTX MD5_CTX
+ * #define HASH_CBLOCK MD5_CBLOCK
+ * #define HASH_LBLOCK MD5_LBLOCK
+ * #define HASH_UPDATE MD5_Update
+ * #define HASH_TRANSFORM MD5_Transform
+ * #define HASH_FINAL MD5_Final
+ * #define HASH_BLOCK_HOST_ORDER md5_block_host_order
+ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
+ *
+ * <appro@fy.chalmers.se>
+ */
+
+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+#error "DATA_ORDER must be defined!"
+#endif
+
+#ifndef HASH_CBLOCK
+#error "HASH_CBLOCK must be defined!"
+#endif
+#ifndef HASH_LONG
+#error "HASH_LONG must be defined!"
+#endif
+#ifndef HASH_CTX
+#error "HASH_CTX must be defined!"
+#endif
+
+#ifndef HASH_UPDATE
+#error "HASH_UPDATE must be defined!"
+#endif
+#ifndef HASH_TRANSFORM
+#error "HASH_TRANSFORM must be defined!"
+#endif
+#ifndef HASH_FINAL
+#error "HASH_FINAL must be defined!"
+#endif
+
+#ifndef HASH_BLOCK_HOST_ORDER
+#error "HASH_BLOCK_HOST_ORDER must be defined!"
+#endif
+
+#if 0
+/*
+ * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
+ * isn't defined.
+ */
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+#endif
+
+#ifndef HASH_LBLOCK
+#define HASH_LBLOCK (HASH_CBLOCK/4)
+#endif
+
+#ifndef HASH_LONG_LOG2
+#define HASH_LONG_LOG2 2
+#endif
+
+/*
+ * Engage compiler specific rotate intrinsic function if available.
+ */
+#undef ROTATE
+#ifndef PEDANTIC
+# if defined(_MSC_VER)
+# define ROTATE(a,n) _lrotl(a,n)
+# elif defined(__MWERKS__)
+# if defined(__POWERPC__)
+# define ROTATE(a,n) __rlwinm(a,n,0,31)
+# elif defined(__MC68K__)
+ /* Motorola specific tweak. <appro@fy.chalmers.se> */
+# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
+# else
+# define ROTATE(a,n) __rol(a,n)
+# endif
+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
+ /*
+ * Some GNU C inline assembler templates. Note that these are
+ * rotates by *constant* number of bits! But that's exactly
+ * what we need here...
+ *
+ * <appro@fy.chalmers.se>
+ */
+# if defined(__i386)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "roll %1,%0" \
+ : "=r"(ret) \
+ : "I"(n), "0"(a) \
+ : "cc"); \
+ ret; \
+ })
+# elif defined(__powerpc) || defined(__ppc)
+# define ROTATE(a,n) ({ register unsigned int ret; \
+ asm ( \
+ "rlwinm %0,%1,%2,0,31" \
+ : "=r"(ret) \
+ : "r"(a), "I"(n)); \
+ ret; \
+ })
+# endif
+# endif
+
+/*
+ * Engage compiler specific "fetch in reverse byte order"
+ * intrinsic function if available.
+ */
+# if defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
+ /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
+# if defined(__i386) && !defined(I386_ONLY)
+# define BE_FETCH32(a) ({ register unsigned int l=(a);\
+ asm ( \
+ "bswapl %0" \
+ : "=r"(l) : "0"(l)); \
+ l; \
+ })
+# elif defined(__powerpc)
+# define LE_FETCH32(a) ({ register unsigned int l; \
+ asm ( \
+ "lwbrx %0,0,%1" \
+ : "=r"(l) \
+ : "r"(a)); \
+ l; \
+ })
+
+# elif defined(__sparc) && defined(ULTRASPARC)
+# define LE_FETCH32(a) ({ register unsigned int l; \
+ asm ( \
+ "lda [%1]#ASI_PRIMARY_LITTLE,%0"\
+ : "=r"(l) \
+ : "r"(a)); \
+ l; \
+ })
+# endif
+# endif
+#endif /* PEDANTIC */
+
+#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
+#ifdef ROTATE
+/* 5 instructions with rotate instruction, else 9 */
+#define REVERSE_FETCH32(a,l) ( \
+ l=*(const HASH_LONG *)(a), \
+ ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \
+ )
+#else
+/* 6 instructions with rotate instruction, else 8 */
+#define REVERSE_FETCH32(a,l) ( \
+ l=*(const HASH_LONG *)(a), \
+ l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \
+ ROTATE(l,16) \
+ )
+/*
+ * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
+ * It's rewritten as above for two reasons:
+ * - RISCs aren't good at long constants and have to explicitely
+ * compose 'em with several (well, usually 2) instructions in a
+ * register before performing the actual operation and (as you
+ * already realized:-) having same constant should inspire the
+ * compiler to permanently allocate the only register for it;
+ * - most modern CPUs have two ALUs, but usually only one has
+ * circuitry for shifts:-( this minor tweak inspires compiler
+ * to schedule shift instructions in a better way...
+ *
+ * <appro@fy.chalmers.se>
+ */
+#endif
+#endif
+
+#ifndef ROTATE
+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
+#endif
+
+/*
+ * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
+ * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
+ * and host are of the same "endianess". It's possible to mask
+ * this with blank #define HASH_BLOCK_DATA_ORDER though...
+ *
+ * <appro@fy.chalmers.se>
+ */
+#if defined(B_ENDIAN)
+# if defined(DATA_ORDER_IS_BIG_ENDIAN)
+# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
+# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
+# endif
+# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# ifndef HOST_FETCH32
+# ifdef LE_FETCH32
+# define HOST_FETCH32(p,l) LE_FETCH32(p)
+# elif defined(REVERSE_FETCH32)
+# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
+# endif
+# endif
+# endif
+#elif defined(L_ENDIAN)
+# if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
+# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
+# endif
+# elif defined(DATA_ORDER_IS_BIG_ENDIAN)
+# ifndef HOST_FETCH32
+# ifdef BE_FETCH32
+# define HOST_FETCH32(p,l) BE_FETCH32(p)
+# elif defined(REVERSE_FETCH32)
+# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
+# endif
+# endif
+# endif
+#endif
+
+#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+#ifndef HASH_BLOCK_DATA_ORDER
+#error "HASH_BLOCK_DATA_ORDER must be defined!"
+#endif
+#endif
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+
+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++))) ), \
+ l)
+#define HOST_p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 3: l|=((unsigned long)(*((c)++))); \
+ } }
+#define HOST_p_c2l_p(c,l,sc,len) { \
+ switch (sc) { \
+ case 0: l =((unsigned long)(*((c)++)))<<24; \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
+ } }
+/* NOTE the pointer is not incremented at the end of this */
+#define HOST_c2l_p(c,l,n) { \
+ l=0; (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<< 8; \
+ case 2: l|=((unsigned long)(*(--(c))))<<16; \
+ case 1: l|=((unsigned long)(*(--(c))))<<24; \
+ } }
+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff), \
+ l)
+
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+
+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
+ l|=(((unsigned long)(*((c)++)))<< 8), \
+ l|=(((unsigned long)(*((c)++)))<<16), \
+ l|=(((unsigned long)(*((c)++)))<<24), \
+ l)
+#define HOST_p_c2l(c,l,n) { \
+ switch (n) { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ case 3: l|=((unsigned long)(*((c)++)))<<24; \
+ } }
+#define HOST_p_c2l_p(c,l,sc,len) { \
+ switch (sc) { \
+ case 0: l =((unsigned long)(*((c)++))); \
+ if (--len == 0) break; \
+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
+ if (--len == 0) break; \
+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
+ } }
+/* NOTE the pointer is not incremented at the end of this */
+#define HOST_c2l_p(c,l,n) { \
+ l=0; (c)+=n; \
+ switch (n) { \
+ case 3: l =((unsigned long)(*(--(c))))<<16; \
+ case 2: l|=((unsigned long)(*(--(c))))<< 8; \
+ case 1: l|=((unsigned long)(*(--(c)))); \
+ } }
+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
+ l)
+
+#endif
+
+/*
+ * Time for some action:-)
+ */
+
+void HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
+ {
+ const unsigned char *data=data_;
+ register HASH_LONG * p;
+ register unsigned long l;
+ int sw,sc,ew,ec;
+
+ if (len==0) return;
+
+ l=(c->Nl+(len<<3))&0xffffffffL;
+ /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
+ * Wei Dai <weidai@eskimo.com> for pointing it out. */
+ if (l < c->Nl) /* overflow */
+ c->Nh++;
+ c->Nh+=(len>>29);
+ c->Nl=l;
+
+ if (c->num != 0)
+ {
+ p=c->data;
+ sw=c->num>>2;
+ sc=c->num&0x03;
+
+ if ((c->num+len) >= HASH_CBLOCK)
+ {
+ l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
+ for (; sw<HASH_LBLOCK; sw++)
+ {
+ HOST_c2l(data,l); p[sw]=l;
+ }
+ HASH_BLOCK_HOST_ORDER (c,p,1);
+ len-=(HASH_CBLOCK-c->num);
+ c->num=0;
+ /* drop through and do the rest */
+ }
+ else
+ {
+ c->num+=len;
+ if ((sc+len) < 4) /* ugly, add char's to a word */
+ {
+ l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
+ }
+ else
+ {
+ ew=(c->num>>2);
+ ec=(c->num&0x03);
+ l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
+ for (; sw < ew; sw++)
+ {
+ HOST_c2l(data,l); p[sw]=l;
+ }
+ if (ec)
+ {
+ HOST_c2l_p(data,l,ec); p[sw]=l;
+ }
+ }
+ return;
+ }
+ }
+
+ sw=len/HASH_CBLOCK;
+ if (sw > 0)
+ {
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+ /*
+ * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
+ * only if sizeof(HASH_LONG)==4.
+ */
+ if ((((unsigned long)data)%4) == 0)
+ {
+ /* data is properly aligned so that we can cast it: */
+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
+ sw*=HASH_CBLOCK;
+ data+=sw;
+ len-=sw;
+ }
+ else
+#if !defined(HASH_BLOCK_DATA_ORDER)
+ while (sw--)
+ {
+ memcpy (p=c->data,data,HASH_CBLOCK);
+ HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
+ data+=HASH_CBLOCK;
+ len-=HASH_CBLOCK;
+ }
+#endif
+#endif
+#if defined(HASH_BLOCK_DATA_ORDER)
+ {
+ HASH_BLOCK_DATA_ORDER(c,data,sw);
+ sw*=HASH_CBLOCK;
+ data+=sw;
+ len-=sw;
+ }
+#endif
+ }
+
+ if (len!=0)
+ {
+ p = c->data;
+ c->num = len;
+ ew=len>>2; /* words to copy */
+ ec=len&0x03;
+ for (; ew; ew--,p++)
+ {
+ HOST_c2l(data,l); *p=l;
+ }
+ HOST_c2l_p(data,l,ec);
+ *p=l;
+ }
+ }
+
+
+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
+ {
+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
+ if ((((unsigned long)data)%4) == 0)
+ /* data is properly aligned so that we can cast it: */
+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
+ else
+#if !defined(HASH_BLOCK_DATA_ORDER)
+ {
+ memcpy (c->data,data,HASH_CBLOCK);
+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
+ }
+#endif
+#endif
+#if defined(HASH_BLOCK_DATA_ORDER)
+ HASH_BLOCK_DATA_ORDER (c,data,1);
+#endif
+ }
+
+
+void HASH_FINAL (unsigned char *md, HASH_CTX *c)
+ {
+ register HASH_LONG *p;
+ register unsigned long l;
+ register int i,j;
+ static const unsigned char end[4]={0x80,0x00,0x00,0x00};
+ const unsigned char *cp=end;
+
+ /* c->num should definitly have room for at least one more byte. */
+ p=c->data;
+ i=c->num>>2;
+ j=c->num&0x03;
+
+#if 0
+ /* purify often complains about the following line as an
+ * Uninitialized Memory Read. While this can be true, the
+ * following p_c2l macro will reset l when that case is true.
+ * This is because j&0x03 contains the number of 'valid' bytes
+ * already in p[i]. If and only if j&0x03 == 0, the UMR will
+ * occur but this is also the only time p_c2l will do
+ * l= *(cp++) instead of l|= *(cp++)
+ * Many thanks to Alex Tang <altitude@cic.net> for pickup this
+ * 'potential bug' */
+#ifdef PURIFY
+ if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
+#endif
+ l=p[i];
+#else
+ l = (j==0) ? 0 : p[i];
+#endif
+ HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
+
+ if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
+ {
+ if (i<HASH_LBLOCK) p[i]=0;
+ HASH_BLOCK_HOST_ORDER (c,p,1);
+ i=0;
+ }
+ for (; i<(HASH_LBLOCK-2); i++)
+ p[i]=0;
+
+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
+ p[HASH_LBLOCK-2]=c->Nh;
+ p[HASH_LBLOCK-1]=c->Nl;
+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
+ p[HASH_LBLOCK-2]=c->Nl;
+ p[HASH_LBLOCK-1]=c->Nh;
+#endif
+ HASH_BLOCK_HOST_ORDER (c,p,1);
+
+#ifndef HASH_MAKE_STRING
+#error "HASH_MAKE_STRING must be defined!"
+#else
+ HASH_MAKE_STRING(c,md);
+#endif
+
+ c->num=0;
+ /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
+ * but I'm not worried :-)
+ memset((void *)c,0,sizeof(HASH_CTX));
+ */
+ }
diff --git a/src/libfreeswan/libcrypto/libaes/Makefile b/src/libfreeswan/libcrypto/libaes/Makefile
new file mode 100644
index 000000000..7e4cff6e8
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/Makefile
@@ -0,0 +1,40 @@
+CFLAGS=-O3 -fomit-frame-pointer -D__KERNEL__ -Wall -Wcast-qual $(EXTRA_CFLAGS)
+INC=-I../include
+
+AES_CORE_OBJ:=aes.o
+
+ASM-$(ARCH_ASM):=1
+ASM_X86:=$(ASM-i586)$(ASM-i686)
+ifneq ($(strip $(ASM_X86)),)
+AES_CORE_OBJ:= asm/aes-i586.o
+endif
+
+LIBOBJ := aes_xcbc_mac.o aes_cbc.o $(AES_CORE_OBJ)
+LDLIBS := -laes
+LDFLAGS := -L.
+
+BLIB := libaes.a
+
+L_TARGET := $(BLIB)
+
+.c.o:
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@
+
+.S.o:
+ $(CC) $(AFLAGS) -c $< -o $@
+
+$(BLIB): $(LIBOBJ)
+ /bin/rm -f $(BLIB)
+ ar cr $(BLIB) $(LIBOBJ)
+ -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \
+ else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \
+ else exit 0; fi; fi
+
+testx: test_main_mac.o $(BLIB)
+ $(CC) -o $@ $^
+
+test: test_main.o $(BLIB)
+ $(CC) -o $@ $^
+
+clean:
+ rm -f *.[oa] asm/*.o core $(TARGET) test testx
diff --git a/src/libfreeswan/libcrypto/libaes/aes.c b/src/libfreeswan/libcrypto/libaes/aes.c
new file mode 100644
index 000000000..1748119ac
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/aes.c
@@ -0,0 +1,1415 @@
+// I retain copyright in this code but I encourage its free use provided
+// that I don't carry any responsibility for the results. I am especially
+// happy to see it used in free and open source software. If you do use
+// it I would appreciate an acknowledgement of its origin in the code or
+// the product that results and I would also appreciate knowing a little
+// about the use to which it is being put. I am grateful to Frank Yellin
+// for some ideas that are used in this implementation.
+//
+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
+//
+// This is an implementation of the AES encryption algorithm (Rijndael)
+// designed by Joan Daemen and Vincent Rijmen. This version is designed
+// to provide both fixed and dynamic block and key lengths and can also
+// run with either big or little endian internal byte order (see aes.h).
+// It inputs block and key lengths in bytes with the legal values being
+// 16, 24 and 32.
+
+/*
+ * Modified by Jari Ruusu, May 1 2001
+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
+ * - Major name space cleanup: Names visible to outside now begin
+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
+ * - Removed C++ and DLL support as part of name space cleanup.
+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
+ * - Merged precomputed constant tables to aes.c file.
+ * - Removed data alignment restrictions for portability reasons.
+ * - Made block and key lengths accept bit count (128/192/256)
+ * as well byte count (16/24/32).
+ * - Removed all error checks. This change also eliminated the need
+ * to preinitialize the context struct to zero.
+ * - Removed some totally unused constants.
+ */
+
+#include "aes.h"
+
+// CONFIGURATION OPTIONS (see also aes.h)
+//
+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
+// Do not enable this without understanding stack space requirements.
+// 5. Define ARRAYS to use arrays to hold the local state block. If this
+// is not defined, individually declared 32-bit words are used.
+// 6. Define FAST_VARIABLE if a high speed variable block implementation
+// is needed (essentially three separate fixed block size code sequences)
+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
+// version using 1 table (2 kbytes of table space) or 4 tables (8
+// kbytes of table space) for higher speed.
+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
+// increase by using tables for the last rounds but with more table
+// space (2 or 8 kbytes extra).
+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
+// slower version is provided.
+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
+
+#define UNROLL
+//#define PARTIAL_UNROLL
+
+#define FIXED_TABLES
+//#define FF_TABLES
+//#define ARRAYS
+#define FAST_VARIABLE
+
+//#define ONE_TABLE
+#define FOUR_TABLES
+
+//#define ONE_LR_TABLE
+#define FOUR_LR_TABLES
+
+//#define ONE_IM_TABLE
+#define FOUR_IM_TABLES
+
+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
+#error both UNROLL and PARTIAL_UNROLL are defined
+#endif
+
+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
+#error both ONE_TABLE and FOUR_TABLES are defined
+#endif
+
+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
+#endif
+
+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
+#endif
+
+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
+#error an illegal block size has been specified
+#endif
+
+// upr(x,n): rotates bytes within words by n positions, moving bytes
+// to higher index positions with wrap around into low positions
+// ups(x,n): moves bytes by n positions to higher index positions in
+// words but without wrap around
+// bval(x,n): extracts a byte from a word
+
+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
+#define ups(x,n) ((x) << 8 * (n))
+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
+#define bytes2word(b0, b1, b2, b3) \
+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
+
+
+/* little endian processor without data alignment restrictions: AES_LE_OK */
+/* original code: i386 */
+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
+#define AES_LE_OK 1
+/* added (tested): alpha --jjo */
+#elif defined(__alpha__)|| defined (__alpha)
+#define AES_LE_OK 1
+/* added (tested): ia64 --jjo */
+#elif defined(__ia64__)|| defined (__ia64)
+#define AES_LE_OK 1
+#endif
+
+#ifdef AES_LE_OK
+/* little endian processor without data alignment restrictions */
+#define word_in(x) *(u_int32_t*)(x)
+#define const_word_in(x) *(const u_int32_t*)(x)
+#define word_out(x,v) *(u_int32_t*)(x) = (v)
+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
+#else
+/* slower but generic big endian or with data alignment restrictions */
+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
+#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
+#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
+#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
+#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
+#endif
+
+// Disable at least some poor combinations of options
+
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
+#define FIXED_TABLES
+#undef UNROLL
+#undef ONE_LR_TABLE
+#undef FOUR_LR_TABLES
+#undef ONE_IM_TABLE
+#undef FOUR_IM_TABLES
+#elif !defined(FOUR_TABLES)
+#ifdef FOUR_LR_TABLES
+#undef FOUR_LR_TABLES
+#define ONE_LR_TABLE
+#endif
+#ifdef FOUR_IM_TABLES
+#undef FOUR_IM_TABLES
+#define ONE_IM_TABLE
+#endif
+#elif !defined(AES_BLOCK_SIZE)
+#if defined(UNROLL)
+#define PARTIAL_UNROLL
+#undef UNROLL
+#endif
+#endif
+
+// the finite field modular polynomial and elements
+
+#define ff_poly 0x011b
+#define ff_hi 0x80
+
+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
+
+#define m1 0x80808080
+#define m2 0x7f7f7f7f
+#define m3 0x0000001b
+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
+
+// The following defines provide alternative definitions of FFmulX that might
+// give improved performance if a fast 32-bit multiply is not available. Note
+// that a temporary variable u needs to be defined where FFmulX is used.
+
+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
+// #define m4 0x1b1b1b1b
+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
+
+// perform column mix operation on four bytes in parallel
+
+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
+
+#if defined(FIXED_TABLES)
+
+// the S-Box table
+
+static const unsigned char s_box[256] =
+{
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+// the inverse S-Box table
+
+static const unsigned char inv_s_box[256] =
+{
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
+};
+
+#define w0(p) 0x000000##p
+
+// Number of elements required in this table for different
+// block and key lengths is:
+//
+// Nk = 4 6 8
+// ----------
+// Nb = 4 | 10 8 7
+// 6 | 19 12 11
+// 8 | 29 19 14
+//
+// this table can be a table of bytes if the key schedule
+// code is adjusted accordingly
+
+static const u_int32_t rcon_tab[29] =
+{
+ w0(01), w0(02), w0(04), w0(08),
+ w0(10), w0(20), w0(40), w0(80),
+ w0(1b), w0(36), w0(6c), w0(d8),
+ w0(ab), w0(4d), w0(9a), w0(2f),
+ w0(5e), w0(bc), w0(63), w0(c6),
+ w0(97), w0(35), w0(6a), w0(d4),
+ w0(b3), w0(7d), w0(fa), w0(ef),
+ w0(c5)
+};
+
+#undef w0
+
+#define r0(p,q,r,s) 0x##p##q##r##s
+#define r1(p,q,r,s) 0x##q##r##s##p
+#define r2(p,q,r,s) 0x##r##s##p##q
+#define r3(p,q,r,s) 0x##s##p##q##r
+#define w0(p) 0x000000##p
+#define w1(p) 0x0000##p##00
+#define w2(p) 0x00##p##0000
+#define w3(p) 0x##p##000000
+
+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
+
+// data for forward tables (other than last round)
+
+#define f_table \
+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
+
+// data for inverse tables (other than last round)
+
+#define i_table \
+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
+
+// generate the required tables in the desired endian format
+
+#undef r
+#define r r0
+
+#if defined(ONE_TABLE)
+static const u_int32_t ft_tab[256] =
+ { f_table };
+#elif defined(FOUR_TABLES)
+static const u_int32_t ft_tab[4][256] =
+{ { f_table },
+#undef r
+#define r r1
+ { f_table },
+#undef r
+#define r r2
+ { f_table },
+#undef r
+#define r r3
+ { f_table }
+};
+#endif
+
+#undef r
+#define r r0
+#if defined(ONE_TABLE)
+static const u_int32_t it_tab[256] =
+ { i_table };
+#elif defined(FOUR_TABLES)
+static const u_int32_t it_tab[4][256] =
+{ { i_table },
+#undef r
+#define r r1
+ { i_table },
+#undef r
+#define r r2
+ { i_table },
+#undef r
+#define r r3
+ { i_table }
+};
+#endif
+
+#endif
+
+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
+
+// data for inverse tables (last round)
+
+#define li_table \
+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
+
+// generate the required tables in the desired endian format
+
+#undef r
+#define r(p,q,r,s) w0(q)
+#if defined(ONE_LR_TABLE)
+static const u_int32_t fl_tab[256] =
+ { f_table };
+#elif defined(FOUR_LR_TABLES)
+static const u_int32_t fl_tab[4][256] =
+{ { f_table },
+#undef r
+#define r(p,q,r,s) w1(q)
+ { f_table },
+#undef r
+#define r(p,q,r,s) w2(q)
+ { f_table },
+#undef r
+#define r(p,q,r,s) w3(q)
+ { f_table }
+};
+#endif
+
+#undef w
+#define w w0
+#if defined(ONE_LR_TABLE)
+static const u_int32_t il_tab[256] =
+ { li_table };
+#elif defined(FOUR_LR_TABLES)
+static const u_int32_t il_tab[4][256] =
+{ { li_table },
+#undef w
+#define w w1
+ { li_table },
+#undef w
+#define w w2
+ { li_table },
+#undef w
+#define w w3
+ { li_table }
+};
+#endif
+
+#endif
+
+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
+
+#define m_table \
+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
+
+#undef r
+#define r r0
+
+#if defined(ONE_IM_TABLE)
+static const u_int32_t im_tab[256] =
+ { m_table };
+#elif defined(FOUR_IM_TABLES)
+static const u_int32_t im_tab[4][256] =
+{ { m_table },
+#undef r
+#define r r1
+ { m_table },
+#undef r
+#define r r2
+ { m_table },
+#undef r
+#define r r3
+ { m_table }
+};
+#endif
+
+#endif
+
+#else
+
+static int tab_gen = 0;
+
+static unsigned char s_box[256]; // the S box
+static unsigned char inv_s_box[256]; // the inverse S box
+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
+
+#if defined(ONE_TABLE)
+static u_int32_t ft_tab[256];
+static u_int32_t it_tab[256];
+#elif defined(FOUR_TABLES)
+static u_int32_t ft_tab[4][256];
+static u_int32_t it_tab[4][256];
+#endif
+
+#if defined(ONE_LR_TABLE)
+static u_int32_t fl_tab[256];
+static u_int32_t il_tab[256];
+#elif defined(FOUR_LR_TABLES)
+static u_int32_t fl_tab[4][256];
+static u_int32_t il_tab[4][256];
+#endif
+
+#if defined(ONE_IM_TABLE)
+static u_int32_t im_tab[256];
+#elif defined(FOUR_IM_TABLES)
+static u_int32_t im_tab[4][256];
+#endif
+
+// Generate the tables for the dynamic table option
+
+#if !defined(FF_TABLES)
+
+// It will generally be sensible to use tables to compute finite
+// field multiplies and inverses but where memory is scarse this
+// code might sometimes be better.
+
+// return 2 ^ (n - 1) where n is the bit number of the highest bit
+// set in x with x in the range 1 < x < 0x00000200. This form is
+// used so that locals within FFinv can be bytes rather than words
+
+static unsigned char hibit(const u_int32_t x)
+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
+
+ r |= (r >> 2);
+ r |= (r >> 4);
+ return (r + 1) >> 1;
+}
+
+// return the inverse of the finite field element x
+
+static unsigned char FFinv(const unsigned char x)
+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
+
+ if(x < 2) return x;
+
+ for(;;)
+ {
+ if(!n1) return v1;
+
+ while(n2 >= n1)
+ {
+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
+ }
+
+ if(!n2) return v2;
+
+ while(n1 >= n2)
+ {
+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
+ }
+ }
+}
+
+// define the finite field multiplies required for Rijndael
+
+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
+#define FFmul03(x) ((x) ^ FFmul02(x))
+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
+
+#else
+
+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
+
+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
+
+#endif
+
+// The forward and inverse affine transformations used in the S-box
+
+#define fwd_affine(x) \
+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
+
+#define inv_affine(x) \
+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
+
+static void gen_tabs(void)
+{ u_int32_t i, w;
+
+#if defined(FF_TABLES)
+
+ unsigned char pow[512], log[256];
+
+ // log and power tables for GF(2^8) finite field with
+ // 0x011b as modular polynomial - the simplest primitive
+ // root is 0x03, used here to generate the tables
+
+ i = 0; w = 1;
+ do
+ {
+ pow[i] = (unsigned char)w;
+ pow[i + 255] = (unsigned char)w;
+ log[w] = (unsigned char)i++;
+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
+ }
+ while (w != 1);
+
+#endif
+
+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
+ {
+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
+ }
+
+ for(i = 0; i < 256; ++i)
+ { unsigned char b;
+
+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
+
+ w = bytes2word(b, 0, 0, 0);
+#if defined(ONE_LR_TABLE)
+ fl_tab[i] = w;
+#elif defined(FOUR_LR_TABLES)
+ fl_tab[0][i] = w;
+ fl_tab[1][i] = upr(w,1);
+ fl_tab[2][i] = upr(w,2);
+ fl_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
+#if defined(ONE_TABLE)
+ ft_tab[i] = w;
+#elif defined(FOUR_TABLES)
+ ft_tab[0][i] = w;
+ ft_tab[1][i] = upr(w,1);
+ ft_tab[2][i] = upr(w,2);
+ ft_tab[3][i] = upr(w,3);
+#endif
+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
+
+ w = bytes2word(b, 0, 0, 0);
+#if defined(ONE_LR_TABLE)
+ il_tab[i] = w;
+#elif defined(FOUR_LR_TABLES)
+ il_tab[0][i] = w;
+ il_tab[1][i] = upr(w,1);
+ il_tab[2][i] = upr(w,2);
+ il_tab[3][i] = upr(w,3);
+#endif
+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
+#if defined(ONE_TABLE)
+ it_tab[i] = w;
+#elif defined(FOUR_TABLES)
+ it_tab[0][i] = w;
+ it_tab[1][i] = upr(w,1);
+ it_tab[2][i] = upr(w,2);
+ it_tab[3][i] = upr(w,3);
+#endif
+#if defined(ONE_IM_TABLE)
+ im_tab[b] = w;
+#elif defined(FOUR_IM_TABLES)
+ im_tab[0][b] = w;
+ im_tab[1][b] = upr(w,1);
+ im_tab[2][b] = upr(w,2);
+ im_tab[3][b] = upr(w,3);
+#endif
+
+ }
+}
+
+#endif
+
+#define no_table(x,box,vf,rf,c) bytes2word( \
+ box[bval(vf(x,0,c),rf(0,c))], \
+ box[bval(vf(x,1,c),rf(1,c))], \
+ box[bval(vf(x,2,c),rf(2,c))], \
+ box[bval(vf(x,3,c),rf(3,c))])
+
+#define one_table(x,op,tab,vf,rf,c) \
+ ( tab[bval(vf(x,0,c),rf(0,c))] \
+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
+
+#define four_tables(x,tab,vf,rf,c) \
+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
+
+#define vf1(x,r,c) (x)
+#define rf1(r,c) (r)
+#define rf2(r,c) ((r-c)&3)
+
+#if defined(FOUR_LR_TABLES)
+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
+#elif defined(ONE_LR_TABLE)
+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
+#else
+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
+#endif
+
+#if defined(FOUR_IM_TABLES)
+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
+#elif defined(ONE_IM_TABLE)
+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
+#else
+#define inv_mcol(x) \
+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
+#endif
+
+// Subroutine to set the block size (if variable) in bytes, legal
+// values being 16, 24 and 32.
+
+#if defined(AES_BLOCK_SIZE)
+#define nc (AES_BLOCK_SIZE / 4)
+#else
+#define nc (cx->aes_Ncol)
+
+void aes_set_blk(aes_context *cx, int n_bytes)
+{
+#if !defined(FIXED_TABLES)
+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
+#endif
+
+ switch(n_bytes) {
+ case 32: /* bytes */
+ case 256: /* bits */
+ nc = 8;
+ break;
+ case 24: /* bytes */
+ case 192: /* bits */
+ nc = 6;
+ break;
+ case 16: /* bytes */
+ case 128: /* bits */
+ default:
+ nc = 4;
+ break;
+ }
+}
+
+#endif
+
+// Initialise the key schedule from the user supplied key. The key
+// length is now specified in bytes - 16, 24 or 32 as appropriate.
+// This corresponds to bit lengths of 128, 192 and 256 bits, and
+// to Nk values of 4, 6 and 8 respectively.
+
+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
+#define cp(t,f) *t++ = *f++
+
+#if AES_BLOCK_SIZE == 16
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
+#elif AES_BLOCK_SIZE == 24
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s)
+#elif AES_BLOCK_SIZE == 32
+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
+#else
+
+#define cpy(d,s) \
+switch(nc) \
+{ case 8: cp(d,s); cp(d,s); \
+ case 6: cp(d,s); cp(d,s); \
+ case 4: cp(d,s); cp(d,s); \
+ cp(d,s); cp(d,s); \
+}
+
+#define mix(d,s) \
+switch(nc) \
+{ case 8: mx(d,s); mx(d,s); \
+ case 6: mx(d,s); mx(d,s); \
+ case 4: mx(d,s); mx(d,s); \
+ mx(d,s); mx(d,s); \
+}
+
+#endif
+
+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
+{ u_int32_t *kf, *kt, rci;
+
+#if !defined(FIXED_TABLES)
+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
+#endif
+
+ switch(n_bytes) {
+ case 32: /* bytes */
+ case 256: /* bits */
+ cx->aes_Nkey = 8;
+ break;
+ case 24: /* bytes */
+ case 192: /* bits */
+ cx->aes_Nkey = 6;
+ break;
+ case 16: /* bytes */
+ case 128: /* bits */
+ default:
+ cx->aes_Nkey = 4;
+ break;
+ }
+
+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
+
+ cx->aes_e_key[0] = const_word_in(in_key );
+ cx->aes_e_key[1] = const_word_in(in_key + 4);
+ cx->aes_e_key[2] = const_word_in(in_key + 8);
+ cx->aes_e_key[3] = const_word_in(in_key + 12);
+
+ kf = cx->aes_e_key;
+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
+ rci = 0;
+
+ switch(cx->aes_Nkey)
+ {
+ case 4: do
+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
+ kf[5] = kf[1] ^ kf[4];
+ kf[6] = kf[2] ^ kf[5];
+ kf[7] = kf[3] ^ kf[6];
+ kf += 4;
+ }
+ while(kf < kt);
+ break;
+
+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
+ cx->aes_e_key[5] = const_word_in(in_key + 20);
+ do
+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
+ kf[ 7] = kf[1] ^ kf[ 6];
+ kf[ 8] = kf[2] ^ kf[ 7];
+ kf[ 9] = kf[3] ^ kf[ 8];
+ kf[10] = kf[4] ^ kf[ 9];
+ kf[11] = kf[5] ^ kf[10];
+ kf += 6;
+ }
+ while(kf < kt);
+ break;
+
+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
+ cx->aes_e_key[5] = const_word_in(in_key + 20);
+ cx->aes_e_key[6] = const_word_in(in_key + 24);
+ cx->aes_e_key[7] = const_word_in(in_key + 28);
+ do
+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
+ kf[ 9] = kf[1] ^ kf[ 8];
+ kf[10] = kf[2] ^ kf[ 9];
+ kf[11] = kf[3] ^ kf[10];
+ kf[12] = kf[4] ^ ls_box(kf[11],0);
+ kf[13] = kf[5] ^ kf[12];
+ kf[14] = kf[6] ^ kf[13];
+ kf[15] = kf[7] ^ kf[14];
+ kf += 8;
+ }
+ while (kf < kt);
+ break;
+ }
+
+ if(!f)
+ { u_int32_t i;
+
+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
+ kf = cx->aes_e_key;
+
+ cpy(kt, kf); kt -= 2 * nc;
+
+ for(i = 1; i < cx->aes_Nrnd; ++i)
+ {
+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
+ u_int32_t f2, f4, f8, f9;
+#endif
+ mix(kt, kf);
+#else
+ cpy(kt, kf);
+#endif
+ kt -= 2 * nc;
+ }
+
+ cpy(kt, kf);
+ }
+}
+
+// y = output word, x = input word, r = row, c = column
+// for r = 0, 1, 2 and 3 = column accessed for row r
+
+#if defined(ARRAYS)
+#define s(x,c) x[c]
+#else
+#define s(x,c) x##c
+#endif
+
+// I am grateful to Frank Yellin for the following constructions
+// which, given the column (c) of the output state variable that
+// is being computed, return the input state variables which are
+// needed for each row (r) of the state
+
+// For the fixed block size options, compilers reduce these two
+// expressions to fixed variable references. For variable block
+// size code conditional clauses will sometimes be returned
+
+#define unused 77 // Sunset Strip
+
+#define fwd_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? s(x,1) \
+ : c==1 ? s(x,2) \
+ : c==2 ? s(x,3) \
+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
+ : c==4 ? s(x,5) \
+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
+ : c==6 ? s(x,7) \
+ : s(x,0)) \
+ : r==2 ? \
+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==6 ? s(x,1) \
+ : s(x,2)) \
+ : \
+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#define inv_var(x,r,c) \
+ ( r==0 ? \
+ ( c==0 ? s(x,0) \
+ : c==1 ? s(x,1) \
+ : c==2 ? s(x,2) \
+ : c==3 ? s(x,3) \
+ : c==4 ? s(x,4) \
+ : c==5 ? s(x,5) \
+ : c==6 ? s(x,6) \
+ : s(x,7)) \
+ : r==1 ? \
+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
+ : c==1 ? s(x,0) \
+ : c==2 ? s(x,1) \
+ : c==3 ? s(x,2) \
+ : c==4 ? s(x,3) \
+ : c==5 ? s(x,4) \
+ : c==6 ? s(x,5) \
+ : s(x,6)) \
+ : r==2 ? \
+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
+ : c==6 ? s(x,3) \
+ : s(x,4)) \
+ : \
+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
+ : c==6 ? s(x,2) \
+ : s(x,3)))
+
+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
+
+#if defined(FOUR_TABLES)
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#elif defined(ONE_TABLE)
+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#else
+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#endif
+
+#if defined(FOUR_LR_TABLES)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#elif defined(ONE_LR_TABLE)
+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#else
+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#endif
+
+#if AES_BLOCK_SIZE == 16
+
+#if defined(ARRAYS)
+#define locals(y,x) x[4],y[4]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
+// the following defines prevent the compiler requiring the declaration
+// of generated but unused variables in the fwd_var and inv_var macros
+#define b04 unused
+#define b05 unused
+#define b06 unused
+#define b07 unused
+#define b14 unused
+#define b15 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
+
+#elif AES_BLOCK_SIZE == 24
+
+#if defined(ARRAYS)
+#define locals(y,x) x[6],y[6]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
+ y##0,y##1,y##2,y##3,y##4,y##5
+#define b06 unused
+#define b07 unused
+#define b16 unused
+#define b17 unused
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5);
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
+ so(y,x,3); so(y,x,4); so(y,x,5)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
+#else
+
+#if defined(ARRAYS)
+#define locals(y,x) x[8],y[8]
+#else
+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
+#endif
+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
+ s(y,6) = s(x,6); s(y,7) = s(x,7);
+
+#if AES_BLOCK_SIZE == 32
+
+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
+#else
+
+#define state_in(y,x,k) \
+switch(nc) \
+{ case 8: si(y,x,k,7); si(y,x,k,6); \
+ case 6: si(y,x,k,5); si(y,x,k,4); \
+ case 4: si(y,x,k,3); si(y,x,k,2); \
+ si(y,x,k,1); si(y,x,k,0); \
+}
+
+#define state_out(y,x) \
+switch(nc) \
+{ case 8: so(y,x,7); so(y,x,6); \
+ case 6: so(y,x,5); so(y,x,4); \
+ case 4: so(y,x,3); so(y,x,2); \
+ so(y,x,1); so(y,x,0); \
+}
+
+#if defined(FAST_VARIABLE)
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+ break; \
+}
+#else
+
+#define round(rm,y,x,k) \
+switch(nc) \
+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
+ rm(y,x,k,1); rm(y,x,k,0); \
+}
+
+#endif
+
+#endif
+#endif
+
+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
+{ u_int32_t locals(b0, b1);
+ const u_int32_t *kp = cx->aes_e_key;
+
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
+ u_int32_t f2;
+#endif
+
+ state_in(b0, in_blk, kp); kp += nc;
+
+#if defined(UNROLL)
+
+ switch(cx->aes_Nrnd)
+ {
+ case 14: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 12: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 10: round(fwd_rnd, b1, b0, kp );
+ round(fwd_rnd, b0, b1, kp + nc);
+ round(fwd_rnd, b1, b0, kp + 2 * nc);
+ round(fwd_rnd, b0, b1, kp + 3 * nc);
+ round(fwd_rnd, b1, b0, kp + 4 * nc);
+ round(fwd_rnd, b0, b1, kp + 5 * nc);
+ round(fwd_rnd, b1, b0, kp + 6 * nc);
+ round(fwd_rnd, b0, b1, kp + 7 * nc);
+ round(fwd_rnd, b1, b0, kp + 8 * nc);
+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
+ }
+
+#elif defined(PARTIAL_UNROLL)
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
+ {
+ round(fwd_rnd, b1, b0, kp);
+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
+ }
+
+ round(fwd_rnd, b1, b0, kp);
+ round(fwd_lrnd, b0, b1, kp + nc);
+ }
+#else
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
+ {
+ round(fwd_rnd, b1, b0, kp);
+ l_copy(b0, b1); kp += nc;
+ }
+
+ round(fwd_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+}
+
+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
+{ u_int32_t locals(b0, b1);
+ const u_int32_t *kp = cx->aes_d_key;
+
+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
+ u_int32_t f2, f4, f8, f9;
+#endif
+
+ state_in(b0, in_blk, kp); kp += nc;
+
+#if defined(UNROLL)
+
+ switch(cx->aes_Nrnd)
+ {
+ case 14: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 12: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
+ case 10: round(inv_rnd, b1, b0, kp );
+ round(inv_rnd, b0, b1, kp + nc);
+ round(inv_rnd, b1, b0, kp + 2 * nc);
+ round(inv_rnd, b0, b1, kp + 3 * nc);
+ round(inv_rnd, b1, b0, kp + 4 * nc);
+ round(inv_rnd, b0, b1, kp + 5 * nc);
+ round(inv_rnd, b1, b0, kp + 6 * nc);
+ round(inv_rnd, b0, b1, kp + 7 * nc);
+ round(inv_rnd, b1, b0, kp + 8 * nc);
+ round(inv_lrnd, b0, b1, kp + 9 * nc);
+ }
+
+#elif defined(PARTIAL_UNROLL)
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
+ {
+ round(inv_rnd, b1, b0, kp);
+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
+ }
+
+ round(inv_rnd, b1, b0, kp);
+ round(inv_lrnd, b0, b1, kp + nc);
+ }
+#else
+ { u_int32_t rnd;
+
+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
+ {
+ round(inv_rnd, b1, b0, kp);
+ l_copy(b0, b1); kp += nc;
+ }
+
+ round(inv_lrnd, b0, b1, kp);
+ }
+#endif
+
+ state_out(out_blk, b0);
+}
diff --git a/src/libfreeswan/libcrypto/libaes/aes.h b/src/libfreeswan/libcrypto/libaes/aes.h
new file mode 100644
index 000000000..4f1e3b335
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/aes.h
@@ -0,0 +1,97 @@
+// I retain copyright in this code but I encourage its free use provided
+// that I don't carry any responsibility for the results. I am especially
+// happy to see it used in free and open source software. If you do use
+// it I would appreciate an acknowledgement of its origin in the code or
+// the product that results and I would also appreciate knowing a little
+// about the use to which it is being put. I am grateful to Frank Yellin
+// for some ideas that are used in this implementation.
+//
+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
+//
+// This is an implementation of the AES encryption algorithm (Rijndael)
+// designed by Joan Daemen and Vincent Rijmen. This version is designed
+// to provide both fixed and dynamic block and key lengths and can also
+// run with either big or little endian internal byte order (see aes.h).
+// It inputs block and key lengths in bytes with the legal values being
+// 16, 24 and 32.
+
+/*
+ * Modified by Jari Ruusu, May 1 2001
+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
+ * - Major name space cleanup: Names visible to outside now begin
+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
+ * - Removed C++ and DLL support as part of name space cleanup.
+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
+ * - Merged precomputed constant tables to aes.c file.
+ * - Removed data alignment restrictions for portability reasons.
+ * - Made block and key lengths accept bit count (128/192/256)
+ * as well byte count (16/24/32).
+ * - Removed all error checks. This change also eliminated the need
+ * to preinitialize the context struct to zero.
+ * - Removed some totally unused constants.
+ */
+
+#ifndef _AES_H
+#define _AES_H
+
+#if defined(__linux__) && defined(__KERNEL__)
+# include <linux/types.h>
+#else
+# include <sys/types.h>
+#endif
+
+// CONFIGURATION OPTIONS (see also aes.c)
+//
+// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
+// leave this undefined for dynamically variable block size (this will
+// result in much slower code).
+// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
+// left undefined a slower version providing variable block length is compiled
+
+#define AES_BLOCK_SIZE 16
+
+// The number of key schedule words for different block and key lengths
+// allowing for method of computation which requires the length to be a
+// multiple of the key length
+//
+// Nk = 4 6 8
+// -------------
+// Nb = 4 | 60 60 64
+// 6 | 96 90 96
+// 8 | 120 120 120
+
+#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
+#define AES_KS_LENGTH 120
+#define AES_RC_LENGTH 29
+#else
+#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
+#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
+#endif
+
+typedef struct
+{
+ u_int32_t aes_Nkey; // the number of words in the key input block
+ u_int32_t aes_Nrnd; // the number of cipher rounds
+ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
+ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
+#if !defined(AES_BLOCK_SIZE)
+ u_int32_t aes_Ncol; // the number of columns in the cipher state
+#endif
+} aes_context;
+
+// THE CIPHER INTERFACE
+
+#if !defined(AES_BLOCK_SIZE)
+extern void aes_set_blk(aes_context *, const int);
+#endif
+extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
+extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
+extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
+
+// The block length inputs to aes_set_block and aes_set_key are in numbers
+// of bytes or bits. The calls to subroutines must be made in the above
+// order but multiple calls can be made without repeating earlier calls
+// if their parameters have not changed.
+
+#endif // _AES_H
diff --git a/src/libfreeswan/libcrypto/libaes/aes_cbc.c b/src/libfreeswan/libcrypto/libaes/aes_cbc.c
new file mode 100644
index 000000000..962dd1a35
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/aes_cbc.c
@@ -0,0 +1,13 @@
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#include "aes_cbc.h"
+#include "cbc_generic.h"
+/* returns bool success */
+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
+ aes_set_key(aes_ctx, key, keysize, 0);
+ return 1;
+}
+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
diff --git a/src/libfreeswan/libcrypto/libaes/aes_cbc.h b/src/libfreeswan/libcrypto/libaes/aes_cbc.h
new file mode 100644
index 000000000..92f5d77f5
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/aes_cbc.h
@@ -0,0 +1,4 @@
+/* Glue header */
+#include "aes.h"
+int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
+int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
diff --git a/src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.c b/src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.c
new file mode 100644
index 000000000..89d7bc067
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.c
@@ -0,0 +1,67 @@
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/kernel.h>
+#define DEBUG(x)
+#else
+#include <stdio.h>
+#include <sys/types.h>
+#define DEBUG(x) x
+#endif
+
+#include "aes.h"
+#include "aes_xcbc_mac.h"
+
+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
+{
+ int ret=1;
+ aes_block kn[3] = {
+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
+ };
+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
+ return ret;
+}
+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
+ int pos=0;
+ for (pos=1; pos <= 16; pos++, in++, out++) {
+ if (pos <= len)
+ *out ^= *in;
+ if (pos > len) {
+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
+ *out ^= 0x80;
+ break;
+ }
+ }
+}
+static void xor_block(aes_block res, const aes_block op) {
+ res[0] ^= op[0];
+ res[1] ^= op[1];
+ res[2] ^= op[2];
+ res[3] ^= op[3];
+}
+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
+ int ret=ilen;
+ u_int32_t out[4] = { 0, 0, 0, 0 };
+ for (; ilen > 16 ; ilen-=16) {
+ xor_block(out, (const u_int32_t*) &in[0]);
+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
+ in+=16;
+ }
+ do_pad_xor((u_int8_t *)&out, in, ilen);
+ if (ilen==16) {
+ DEBUG(printf("using k3\n"));
+ xor_block(out, ctxm->k3);
+ }
+ else
+ {
+ DEBUG(printf("using k2\n"));
+ xor_block(out, ctxm->k2);
+ }
+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
+ return ret;
+}
diff --git a/src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.h b/src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.h
new file mode 100644
index 000000000..baf438cd4
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/aes_xcbc_mac.h
@@ -0,0 +1,12 @@
+#ifndef _AES_XCBC_MAC_H
+#define _AES_XCBC_MAC_H
+
+typedef u_int32_t aes_block[4];
+typedef struct {
+ aes_context ctx_k1;
+ aes_block k2;
+ aes_block k3;
+} aes_context_mac;
+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
+#endif /* _AES_XCBC_MAC_H */
diff --git a/src/libfreeswan/libcrypto/libaes/asm/aes-i586.S b/src/libfreeswan/libcrypto/libaes/asm/aes-i586.S
new file mode 100644
index 000000000..df19d0d62
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/asm/aes-i586.S
@@ -0,0 +1,892 @@
+//
+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
+// All rights reserved.
+//
+// TERMS
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted subject to the following conditions:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The copyright holder's name must not be used to endorse or promote
+// any products derived from this software without his specific prior
+// written permission.
+//
+// This software is provided 'as is' with no express or implied warranties
+// of correctness or fitness for purpose.
+
+// Modified by Jari Ruusu, December 24 2001
+// - Converted syntax to GNU CPP/assembler syntax
+// - C programming interface converted back to "old" API
+// - Minor portability cleanups and speed optimizations
+
+// An AES (Rijndael) implementation for the Pentium. This version only
+// implements the standard AES block length (128 bits, 16 bytes). This code
+// does not preserve the eax, ecx or edx registers or the artihmetic status
+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
+// calls.
+
+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
+
+#if defined(USE_UNDERLINE)
+# define aes_set_key _aes_set_key
+# define aes_encrypt _aes_encrypt
+# define aes_decrypt _aes_decrypt
+#endif
+#if !defined(ALIGN32BYTES)
+# define ALIGN32BYTES 32
+#endif
+
+ .file "aes-i586.S"
+ .globl aes_set_key
+ .globl aes_encrypt
+ .globl aes_decrypt
+
+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
+
+// offsets to parameters with one register pushed onto stack
+
+#define ctx 8 // AES context structure
+#define in_blk 12 // input byte array address parameter
+#define out_blk 16 // output byte array address parameter
+
+// offsets in context structure
+
+#define nkey 0 // key length, size 4
+#define nrnd 4 // number of rounds, size 4
+#define ekey 8 // encryption key schedule base address, size 256
+#define dkey 264 // decryption key schedule base address, size 256
+
+// This macro performs a forward encryption cycle. It is entered with
+// the first previous round column values in %eax, %ebx, %esi and %edi and
+// exits with the final values in the same registers.
+
+#define fwd_rnd(p1,p2) \
+ mov %ebx,(%esp) ;\
+ movzbl %al,%edx ;\
+ mov %eax,%ecx ;\
+ mov p2(%ebp),%eax ;\
+ mov %edi,4(%esp) ;\
+ mov p2+12(%ebp),%edi ;\
+ xor p1(,%edx,4),%eax ;\
+ movzbl %ch,%edx ;\
+ shr $16,%ecx ;\
+ mov p2+4(%ebp),%ebx ;\
+ xor p1+tlen(,%edx,4),%edi ;\
+ movzbl %cl,%edx ;\
+ movzbl %ch,%ecx ;\
+ xor p1+3*tlen(,%ecx,4),%ebx ;\
+ mov %esi,%ecx ;\
+ mov p1+2*tlen(,%edx,4),%esi ;\
+ movzbl %cl,%edx ;\
+ xor p1(,%edx,4),%esi ;\
+ movzbl %ch,%edx ;\
+ shr $16,%ecx ;\
+ xor p1+tlen(,%edx,4),%ebx ;\
+ movzbl %cl,%edx ;\
+ movzbl %ch,%ecx ;\
+ xor p1+2*tlen(,%edx,4),%eax ;\
+ mov (%esp),%edx ;\
+ xor p1+3*tlen(,%ecx,4),%edi ;\
+ movzbl %dl,%ecx ;\
+ xor p2+8(%ebp),%esi ;\
+ xor p1(,%ecx,4),%ebx ;\
+ movzbl %dh,%ecx ;\
+ shr $16,%edx ;\
+ xor p1+tlen(,%ecx,4),%eax ;\
+ movzbl %dl,%ecx ;\
+ movzbl %dh,%edx ;\
+ xor p1+2*tlen(,%ecx,4),%edi ;\
+ mov 4(%esp),%ecx ;\
+ xor p1+3*tlen(,%edx,4),%esi ;\
+ movzbl %cl,%edx ;\
+ xor p1(,%edx,4),%edi ;\
+ movzbl %ch,%edx ;\
+ shr $16,%ecx ;\
+ xor p1+tlen(,%edx,4),%esi ;\
+ movzbl %cl,%edx ;\
+ movzbl %ch,%ecx ;\
+ xor p1+2*tlen(,%edx,4),%ebx ;\
+ xor p1+3*tlen(,%ecx,4),%eax
+
+// This macro performs an inverse encryption cycle. It is entered with
+// the first previous round column values in %eax, %ebx, %esi and %edi and
+// exits with the final values in the same registers.
+
+#define inv_rnd(p1,p2) \
+ movzbl %al,%edx ;\
+ mov %ebx,(%esp) ;\
+ mov %eax,%ecx ;\
+ mov p2(%ebp),%eax ;\
+ mov %edi,4(%esp) ;\
+ mov p2+4(%ebp),%ebx ;\
+ xor p1(,%edx,4),%eax ;\
+ movzbl %ch,%edx ;\
+ shr $16,%ecx ;\
+ mov p2+12(%ebp),%edi ;\
+ xor p1+tlen(,%edx,4),%ebx ;\
+ movzbl %cl,%edx ;\
+ movzbl %ch,%ecx ;\
+ xor p1+3*tlen(,%ecx,4),%edi ;\
+ mov %esi,%ecx ;\
+ mov p1+2*tlen(,%edx,4),%esi ;\
+ movzbl %cl,%edx ;\
+ xor p1(,%edx,4),%esi ;\
+ movzbl %ch,%edx ;\
+ shr $16,%ecx ;\
+ xor p1+tlen(,%edx,4),%edi ;\
+ movzbl %cl,%edx ;\
+ movzbl %ch,%ecx ;\
+ xor p1+2*tlen(,%edx,4),%eax ;\
+ mov (%esp),%edx ;\
+ xor p1+3*tlen(,%ecx,4),%ebx ;\
+ movzbl %dl,%ecx ;\
+ xor p2+8(%ebp),%esi ;\
+ xor p1(,%ecx,4),%ebx ;\
+ movzbl %dh,%ecx ;\
+ shr $16,%edx ;\
+ xor p1+tlen(,%ecx,4),%esi ;\
+ movzbl %dl,%ecx ;\
+ movzbl %dh,%edx ;\
+ xor p1+2*tlen(,%ecx,4),%edi ;\
+ mov 4(%esp),%ecx ;\
+ xor p1+3*tlen(,%edx,4),%eax ;\
+ movzbl %cl,%edx ;\
+ xor p1(,%edx,4),%edi ;\
+ movzbl %ch,%edx ;\
+ shr $16,%ecx ;\
+ xor p1+tlen(,%edx,4),%eax ;\
+ movzbl %cl,%edx ;\
+ movzbl %ch,%ecx ;\
+ xor p1+2*tlen(,%edx,4),%ebx ;\
+ xor p1+3*tlen(,%ecx,4),%esi
+
+// AES (Rijndael) Encryption Subroutine
+
+ .text
+ .align ALIGN32BYTES
+aes_encrypt:
+ push %ebp
+ mov ctx(%esp),%ebp // pointer to context
+ mov in_blk(%esp),%ecx
+ push %ebx
+ push %esi
+ push %edi
+ mov nrnd(%ebp),%edx // number of rounds
+ lea ekey+16(%ebp),%ebp // key pointer
+
+// input four columns and xor in first round key
+
+ mov (%ecx),%eax
+ mov 4(%ecx),%ebx
+ mov 8(%ecx),%esi
+ mov 12(%ecx),%edi
+ xor -16(%ebp),%eax
+ xor -12(%ebp),%ebx
+ xor -8(%ebp),%esi
+ xor -4(%ebp),%edi
+
+ sub $8,%esp // space for register saves on stack
+
+ sub $10,%edx
+ je aes_15
+ add $32,%ebp
+ sub $2,%edx
+ je aes_13
+ add $32,%ebp
+
+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
+ fwd_rnd(aes_ft_tab,-48)
+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
+ fwd_rnd(aes_ft_tab,-16)
+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
+ fwd_rnd(aes_ft_tab,16)
+ fwd_rnd(aes_ft_tab,32)
+ fwd_rnd(aes_ft_tab,48)
+ fwd_rnd(aes_ft_tab,64)
+ fwd_rnd(aes_ft_tab,80)
+ fwd_rnd(aes_ft_tab,96)
+ fwd_rnd(aes_ft_tab,112)
+ fwd_rnd(aes_ft_tab,128)
+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
+
+// move final values to the output array.
+
+ mov out_blk+20(%esp),%ebp
+ add $8,%esp
+ mov %eax,(%ebp)
+ mov %ebx,4(%ebp)
+ mov %esi,8(%ebp)
+ mov %edi,12(%ebp)
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %ebp
+ ret
+
+
+// AES (Rijndael) Decryption Subroutine
+
+ .align ALIGN32BYTES
+aes_decrypt:
+ push %ebp
+ mov ctx(%esp),%ebp // pointer to context
+ mov in_blk(%esp),%ecx
+ push %ebx
+ push %esi
+ push %edi
+ mov nrnd(%ebp),%edx // number of rounds
+ lea dkey+16(%ebp),%ebp // key pointer
+
+// input four columns and xor in first round key
+
+ mov (%ecx),%eax
+ mov 4(%ecx),%ebx
+ mov 8(%ecx),%esi
+ mov 12(%ecx),%edi
+ xor -16(%ebp),%eax
+ xor -12(%ebp),%ebx
+ xor -8(%ebp),%esi
+ xor -4(%ebp),%edi
+
+ sub $8,%esp // space for register saves on stack
+
+ sub $10,%edx
+ je aes_25
+ add $32,%ebp
+ sub $2,%edx
+ je aes_23
+ add $32,%ebp
+
+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
+ inv_rnd(aes_it_tab,-48)
+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
+ inv_rnd(aes_it_tab,-16)
+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
+ inv_rnd(aes_it_tab,16)
+ inv_rnd(aes_it_tab,32)
+ inv_rnd(aes_it_tab,48)
+ inv_rnd(aes_it_tab,64)
+ inv_rnd(aes_it_tab,80)
+ inv_rnd(aes_it_tab,96)
+ inv_rnd(aes_it_tab,112)
+ inv_rnd(aes_it_tab,128)
+ inv_rnd(aes_il_tab,144) // last round uses a different table
+
+// move final values to the output array.
+
+ mov out_blk+20(%esp),%ebp
+ add $8,%esp
+ mov %eax,(%ebp)
+ mov %ebx,4(%ebp)
+ mov %esi,8(%ebp)
+ mov %edi,12(%ebp)
+ pop %edi
+ pop %esi
+ pop %ebx
+ pop %ebp
+ ret
+
+// AES (Rijndael) Key Schedule Subroutine
+
+// input/output parameters
+
+#define aes_cx 12 // AES context
+#define in_key 16 // key input array address
+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
+
+// offsets for locals
+
+#define cnt -4
+#define kpf -8
+#define slen 8
+
+// This macro performs a column mixing operation on an input 32-bit
+// word to give a 32-bit result. It uses each of the 4 bytes in the
+// the input column to index 4 different tables of 256 32-bit words
+// that are xored together to form the output value.
+
+#define mix_col(p1) \
+ movzbl %bl,%ecx ;\
+ mov p1(,%ecx,4),%eax ;\
+ movzbl %bh,%ecx ;\
+ ror $16,%ebx ;\
+ xor p1+tlen(,%ecx,4),%eax ;\
+ movzbl %bl,%ecx ;\
+ xor p1+2*tlen(,%ecx,4),%eax ;\
+ movzbl %bh,%ecx ;\
+ xor p1+3*tlen(,%ecx,4),%eax
+
+// Key Schedule Macros
+
+#define ksc4(p1) \
+ rol $24,%ebx ;\
+ mix_col(aes_fl_tab) ;\
+ ror $8,%ebx ;\
+ xor 4*p1+aes_rcon_tab,%eax ;\
+ xor %eax,%esi ;\
+ xor %esi,%ebp ;\
+ mov %esi,16*p1(%edi) ;\
+ mov %ebp,16*p1+4(%edi) ;\
+ xor %ebp,%edx ;\
+ xor %edx,%ebx ;\
+ mov %edx,16*p1+8(%edi) ;\
+ mov %ebx,16*p1+12(%edi)
+
+#define ksc6(p1) \
+ rol $24,%ebx ;\
+ mix_col(aes_fl_tab) ;\
+ ror $8,%ebx ;\
+ xor 4*p1+aes_rcon_tab,%eax ;\
+ xor 24*p1-24(%edi),%eax ;\
+ mov %eax,24*p1(%edi) ;\
+ xor 24*p1-20(%edi),%eax ;\
+ mov %eax,24*p1+4(%edi) ;\
+ xor %eax,%esi ;\
+ xor %esi,%ebp ;\
+ mov %esi,24*p1+8(%edi) ;\
+ mov %ebp,24*p1+12(%edi) ;\
+ xor %ebp,%edx ;\
+ xor %edx,%ebx ;\
+ mov %edx,24*p1+16(%edi) ;\
+ mov %ebx,24*p1+20(%edi)
+
+#define ksc8(p1) \
+ rol $24,%ebx ;\
+ mix_col(aes_fl_tab) ;\
+ ror $8,%ebx ;\
+ xor 4*p1+aes_rcon_tab,%eax ;\
+ xor 32*p1-32(%edi),%eax ;\
+ mov %eax,32*p1(%edi) ;\
+ xor 32*p1-28(%edi),%eax ;\
+ mov %eax,32*p1+4(%edi) ;\
+ xor 32*p1-24(%edi),%eax ;\
+ mov %eax,32*p1+8(%edi) ;\
+ xor 32*p1-20(%edi),%eax ;\
+ mov %eax,32*p1+12(%edi) ;\
+ push %ebx ;\
+ mov %eax,%ebx ;\
+ mix_col(aes_fl_tab) ;\
+ pop %ebx ;\
+ xor %eax,%esi ;\
+ xor %esi,%ebp ;\
+ mov %esi,32*p1+16(%edi) ;\
+ mov %ebp,32*p1+20(%edi) ;\
+ xor %ebp,%edx ;\
+ xor %edx,%ebx ;\
+ mov %edx,32*p1+24(%edi) ;\
+ mov %ebx,32*p1+28(%edi)
+
+ .align ALIGN32BYTES
+aes_set_key:
+ pushfl
+ push %ebp
+ mov %esp,%ebp
+ sub $slen,%esp
+ push %ebx
+ push %esi
+ push %edi
+
+ mov aes_cx(%ebp),%edx // edx -> AES context
+
+ mov key_ln(%ebp),%ecx // key length
+ cmpl $128,%ecx
+ jb aes_30
+ shr $3,%ecx
+aes_30: cmpl $32,%ecx
+ je aes_32
+ cmpl $24,%ecx
+ je aes_32
+ mov $16,%ecx
+aes_32: shr $2,%ecx
+ mov %ecx,nkey(%edx)
+
+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
+ mov %eax,nrnd(%edx)
+
+ mov in_key(%ebp),%esi // key input array
+ lea ekey(%edx),%edi // key position in AES context
+ cld
+ push %ebp
+ mov %ecx,%eax // save key length in eax
+ rep ; movsl // words in the key schedule
+ mov -4(%esi),%ebx // put some values in registers
+ mov -8(%esi),%edx // to allow faster code
+ mov -12(%esi),%ebp
+ mov -16(%esi),%esi
+
+ cmpl $4,%eax // jump on key size
+ je aes_36
+ cmpl $6,%eax
+ je aes_35
+
+ ksc8(0)
+ ksc8(1)
+ ksc8(2)
+ ksc8(3)
+ ksc8(4)
+ ksc8(5)
+ ksc8(6)
+ jmp aes_37
+aes_35: ksc6(0)
+ ksc6(1)
+ ksc6(2)
+ ksc6(3)
+ ksc6(4)
+ ksc6(5)
+ ksc6(6)
+ ksc6(7)
+ jmp aes_37
+aes_36: ksc4(0)
+ ksc4(1)
+ ksc4(2)
+ ksc4(3)
+ ksc4(4)
+ ksc4(5)
+ ksc4(6)
+ ksc4(7)
+ ksc4(8)
+ ksc4(9)
+aes_37: pop %ebp
+ mov aes_cx(%ebp),%edx // edx -> AES context
+ cmpl $0,ed_flg(%ebp)
+ jne aes_39
+
+// compile decryption key schedule from encryption schedule - reverse
+// order and do mix_column operation on round keys except first and last
+
+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
+ shl $2,%eax
+ lea dkey(%edx,%eax,4),%edi
+ lea ekey(%edx),%esi // kf = cx->e_key
+
+ movsl // copy first round key (unmodified)
+ movsl
+ movsl
+ movsl
+ sub $32,%edi
+ movl $1,cnt(%ebp)
+aes_38: // do mix column on each column of
+ lodsl // each round key
+ mov %eax,%ebx
+ mix_col(aes_im_tab)
+ stosl
+ lodsl
+ mov %eax,%ebx
+ mix_col(aes_im_tab)
+ stosl
+ lodsl
+ mov %eax,%ebx
+ mix_col(aes_im_tab)
+ stosl
+ lodsl
+ mov %eax,%ebx
+ mix_col(aes_im_tab)
+ stosl
+ sub $32,%edi
+
+ incl cnt(%ebp)
+ mov cnt(%ebp),%eax
+ cmp nrnd(%edx),%eax
+ jb aes_38
+
+ movsl // copy last round key (unmodified)
+ movsl
+ movsl
+ movsl
+aes_39: pop %edi
+ pop %esi
+ pop %ebx
+ mov %ebp,%esp
+ pop %ebp
+ popfl
+ ret
+
+
+// finite field multiplies by {02}, {04} and {08}
+
+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
+
+// finite field multiplies required in table generation
+
+#define f3(x) (f2(x) ^ x)
+#define f9(x) (f8(x) ^ x)
+#define fb(x) (f8(x) ^ f2(x) ^ x)
+#define fd(x) (f8(x) ^ f4(x) ^ x)
+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
+
+// These defines generate the forward table entries
+
+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
+
+// These defines generate the inverse table entries
+
+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
+
+// These defines generate entries for the last round tables
+
+#define w0(x) (x)
+#define w1(x) (x << 8)
+#define w2(x) (x << 16)
+#define w3(x) (x << 24)
+
+// macro to generate inverse mix column tables (needed for the key schedule)
+
+#define im_data0(p1) \
+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
+#define im_data1(p1) \
+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
+#define im_data2(p1) \
+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
+#define im_data3(p1) \
+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
+#define im_data4(p1) \
+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
+#define im_data5(p1) \
+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
+#define im_data6(p1) \
+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
+#define im_data7(p1) \
+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
+
+// S-box data - 256 entries
+
+#define sb_data0(p1) \
+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
+#define sb_data1(p1) \
+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
+#define sb_data2(p1) \
+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
+#define sb_data3(p1) \
+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
+#define sb_data4(p1) \
+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
+#define sb_data5(p1) \
+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
+#define sb_data6(p1) \
+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
+#define sb_data7(p1) \
+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
+
+// Inverse S-box data - 256 entries
+
+#define ib_data0(p1) \
+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
+#define ib_data1(p1) \
+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
+#define ib_data2(p1) \
+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
+#define ib_data3(p1) \
+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
+#define ib_data4(p1) \
+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
+#define ib_data5(p1) \
+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
+#define ib_data6(p1) \
+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
+#define ib_data7(p1) \
+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
+
+// The rcon_table (needed for the key schedule)
+//
+// Here is original Dr Brian Gladman's source code:
+// _rcon_tab:
+// %assign x 1
+// %rep 29
+// dd x
+// %assign x f2(x)
+// %endrep
+//
+// Here is precomputed output (it's more portable this way):
+
+ .align ALIGN32BYTES
+aes_rcon_tab:
+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
+ .long 0xb3,0x7d,0xfa,0xef,0xc5
+
+// The forward xor tables
+
+ .align ALIGN32BYTES
+aes_ft_tab:
+ sb_data0(u0)
+ sb_data1(u0)
+ sb_data2(u0)
+ sb_data3(u0)
+ sb_data4(u0)
+ sb_data5(u0)
+ sb_data6(u0)
+ sb_data7(u0)
+
+ sb_data0(u1)
+ sb_data1(u1)
+ sb_data2(u1)
+ sb_data3(u1)
+ sb_data4(u1)
+ sb_data5(u1)
+ sb_data6(u1)
+ sb_data7(u1)
+
+ sb_data0(u2)
+ sb_data1(u2)
+ sb_data2(u2)
+ sb_data3(u2)
+ sb_data4(u2)
+ sb_data5(u2)
+ sb_data6(u2)
+ sb_data7(u2)
+
+ sb_data0(u3)
+ sb_data1(u3)
+ sb_data2(u3)
+ sb_data3(u3)
+ sb_data4(u3)
+ sb_data5(u3)
+ sb_data6(u3)
+ sb_data7(u3)
+
+ .align ALIGN32BYTES
+aes_fl_tab:
+ sb_data0(w0)
+ sb_data1(w0)
+ sb_data2(w0)
+ sb_data3(w0)
+ sb_data4(w0)
+ sb_data5(w0)
+ sb_data6(w0)
+ sb_data7(w0)
+
+ sb_data0(w1)
+ sb_data1(w1)
+ sb_data2(w1)
+ sb_data3(w1)
+ sb_data4(w1)
+ sb_data5(w1)
+ sb_data6(w1)
+ sb_data7(w1)
+
+ sb_data0(w2)
+ sb_data1(w2)
+ sb_data2(w2)
+ sb_data3(w2)
+ sb_data4(w2)
+ sb_data5(w2)
+ sb_data6(w2)
+ sb_data7(w2)
+
+ sb_data0(w3)
+ sb_data1(w3)
+ sb_data2(w3)
+ sb_data3(w3)
+ sb_data4(w3)
+ sb_data5(w3)
+ sb_data6(w3)
+ sb_data7(w3)
+
+// The inverse xor tables
+
+ .align ALIGN32BYTES
+aes_it_tab:
+ ib_data0(v0)
+ ib_data1(v0)
+ ib_data2(v0)
+ ib_data3(v0)
+ ib_data4(v0)
+ ib_data5(v0)
+ ib_data6(v0)
+ ib_data7(v0)
+
+ ib_data0(v1)
+ ib_data1(v1)
+ ib_data2(v1)
+ ib_data3(v1)
+ ib_data4(v1)
+ ib_data5(v1)
+ ib_data6(v1)
+ ib_data7(v1)
+
+ ib_data0(v2)
+ ib_data1(v2)
+ ib_data2(v2)
+ ib_data3(v2)
+ ib_data4(v2)
+ ib_data5(v2)
+ ib_data6(v2)
+ ib_data7(v2)
+
+ ib_data0(v3)
+ ib_data1(v3)
+ ib_data2(v3)
+ ib_data3(v3)
+ ib_data4(v3)
+ ib_data5(v3)
+ ib_data6(v3)
+ ib_data7(v3)
+
+ .align ALIGN32BYTES
+aes_il_tab:
+ ib_data0(w0)
+ ib_data1(w0)
+ ib_data2(w0)
+ ib_data3(w0)
+ ib_data4(w0)
+ ib_data5(w0)
+ ib_data6(w0)
+ ib_data7(w0)
+
+ ib_data0(w1)
+ ib_data1(w1)
+ ib_data2(w1)
+ ib_data3(w1)
+ ib_data4(w1)
+ ib_data5(w1)
+ ib_data6(w1)
+ ib_data7(w1)
+
+ ib_data0(w2)
+ ib_data1(w2)
+ ib_data2(w2)
+ ib_data3(w2)
+ ib_data4(w2)
+ ib_data5(w2)
+ ib_data6(w2)
+ ib_data7(w2)
+
+ ib_data0(w3)
+ ib_data1(w3)
+ ib_data2(w3)
+ ib_data3(w3)
+ ib_data4(w3)
+ ib_data5(w3)
+ ib_data6(w3)
+ ib_data7(w3)
+
+// The inverse mix column tables
+
+ .align ALIGN32BYTES
+aes_im_tab:
+ im_data0(v0)
+ im_data1(v0)
+ im_data2(v0)
+ im_data3(v0)
+ im_data4(v0)
+ im_data5(v0)
+ im_data6(v0)
+ im_data7(v0)
+
+ im_data0(v1)
+ im_data1(v1)
+ im_data2(v1)
+ im_data3(v1)
+ im_data4(v1)
+ im_data5(v1)
+ im_data6(v1)
+ im_data7(v1)
+
+ im_data0(v2)
+ im_data1(v2)
+ im_data2(v2)
+ im_data3(v2)
+ im_data4(v2)
+ im_data5(v2)
+ im_data6(v2)
+ im_data7(v2)
+
+ im_data0(v3)
+ im_data1(v3)
+ im_data2(v3)
+ im_data3(v3)
+ im_data4(v3)
+ im_data5(v3)
+ im_data6(v3)
+ im_data7(v3)
diff --git a/src/libfreeswan/libcrypto/libaes/test_main.c b/src/libfreeswan/libcrypto/libaes/test_main.c
new file mode 100644
index 000000000..5fd4599be
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/test_main.c
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include "aes_cbc.h"
+#define AES_BLOCK_SIZE 16
+#define KEY_SIZE 128 /* bits */
+#define KEY "1234567890123456"
+#define STR "hola guaso como estaisss ... 012"
+#define STRSZ (sizeof(STR)-1)
+
+#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE
+#define AES_CONTEXT_T aes_context
+#define EMT_ESPAES_KEY_SZ 16
+int pretty_print(const unsigned char *buf, int count) {
+ int i=0;
+ for (;i<count;i++) {
+ if (i%8==0) putchar(' ');
+ if (i%16==0) putchar('\n');
+ printf ("%02hhx ", buf[i]);
+ }
+ putchar('\n');
+ return i;
+}
+//#define SIZE STRSZ/2
+#define SIZE STRSZ
+int main() {
+ int ret;
+ char buf0[SIZE+1], buf1[SIZE+1];
+ char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0";
+ aes_context ac;
+ AES_set_key(&ac, KEY, KEY_SIZE);
+ //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key));
+ memset(buf0, 0, sizeof (buf0));
+ memset(buf1, 0, sizeof (buf1));
+ ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
+ pretty_print(buf0, SIZE);
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
+ ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
+ return 0;
+}
diff --git a/src/libfreeswan/libcrypto/libaes/test_main_mac.c b/src/libfreeswan/libcrypto/libaes/test_main_mac.c
new file mode 100644
index 000000000..eea47dc9c
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libaes/test_main_mac.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include "aes.h"
+#include "aes_xcbc_mac.h"
+#define STR "Hola guasssso c|mo estais ...012"
+void print_hash(const __u8 *hash) {
+ printf("%08x %08x %08x %08x\n",
+ *(__u32*)(&hash[0]),
+ *(__u32*)(&hash[4]),
+ *(__u32*)(&hash[8]),
+ *(__u32*)(&hash[12]));
+}
+int main(int argc, char *argv[]) {
+ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 };
+ __u8 hash[16];
+ char *str = argv[1];
+ aes_context_mac ctx;
+ if (str==NULL) {
+ fprintf(stderr, "pasame el str\n");
+ return 255;
+ }
+ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key));
+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
+ print_hash(hash);
+ str[2]='x';
+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
+ print_hash(hash);
+ return 0;
+}
diff --git a/src/libfreeswan/libcrypto/libblowfish/COPYRIGHT b/src/libfreeswan/libcrypto/libblowfish/COPYRIGHT
new file mode 100644
index 000000000..685722350
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/COPYRIGHT
@@ -0,0 +1,46 @@
+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an Blowfish implementation written
+by Eric Young (eay@cryptsoft.com).
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution.
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Eric Young (eay@cryptsoft.com)
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The license and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distrubution license
+[including the GNU Public License.]
+
+The reason behind this being stated in this direct manner is past
+experience in code simply being copied and the attribution removed
+from it and then being distributed as part of other packages. This
+implementation was a non-trivial and unpaid effort.
diff --git a/src/libfreeswan/libcrypto/libblowfish/INSTALL b/src/libfreeswan/libcrypto/libblowfish/INSTALL
new file mode 100644
index 000000000..3b2592353
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/INSTALL
@@ -0,0 +1,14 @@
+This Eric Young's blowfish implementation, taken from his SSLeay library
+and made available as a separate library.
+
+The version number (0.7.2m) is the SSLeay version that this library was
+taken from.
+
+To build, just unpack and type make.
+If you are not using gcc, edit the Makefile.
+If you are compiling for an x86 box, try the assembler (it needs improving).
+There are also some compile time options that can improve performance,
+these are documented in the Makefile.
+
+eric 15-Apr-1997
+
diff --git a/src/libfreeswan/libcrypto/libblowfish/Makefile b/src/libfreeswan/libcrypto/libblowfish/Makefile
new file mode 100644
index 000000000..62724042b
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/Makefile
@@ -0,0 +1,121 @@
+#
+# SSLeay/crypto/blowfish/Makefile
+#
+
+DIR= bf
+TOP= ../..
+CC= cc
+CPP= $(CC) -E
+INC=-I ../include
+CFLAG=-g -D__KERNEL__ -I/usr/src/linux/include
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKE= make -f Makefile.ssl
+MAKEDEPEND= $(TOP)/util/domd $(TOP)
+MAKEFILE= Makefile.ssl
+AR= ar r
+RANLIB= ranlib
+PERL= perl
+
+CFLAGS= $(INC) $(CFLAG)
+
+.c.o:
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@
+
+BF_ASM-i586 := bf-586.pl
+BF_ASM-i686 := bf-686.pl
+BF_ENC := bf_enc.o
+
+ASM-$(ARCH_ASM):=1
+ASM_X86:=$(ASM-i586)$(ASM-i686)
+ifneq ($(strip $(ASM_X86)),)
+ BF_ENC= asm/bx86-elf.o
+ BF_ASM= $(BF_ASM-$(ARCH_ASM))
+endif
+
+
+GENERAL=Makefile
+TEST=bftest.c
+APPS=
+
+LIB=libblowfish.a
+LIBSRC=bf_skey.c bf_enc.c
+LIBOBJ=bf_skey.o $(BF_ENC)
+
+SRC= $(LIBSRC)
+
+EXHEADER= blowfish.h
+HEADER= bf_pi.h bf_locl.h $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+#top:
+# (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIB)
+
+$(LIB): $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ $(RANLIB) $(LIB)
+
+# elf
+asm/bx86-elf.o: asm/bx86unix.cpp
+ $(CPP) -DELF -x c asm/bx86unix.cpp | as -o asm/bx86-elf.o
+
+# solaris
+asm/bx86-sol.o: asm/bx86unix.cpp
+ $(CC) -E -DSOL asm/bx86unix.cpp | sed 's/^#.*//' > asm/bx86-sol.s
+ as -o asm/bx86-sol.o asm/bx86-sol.s
+ rm -f asm/bx86-sol.s
+
+# a.out
+asm/bx86-out.o: asm/bx86unix.cpp
+ $(CPP) -DOUT asm/bx86unix.cpp | as -o asm/bx86-out.o
+
+# bsdi
+asm/bx86bsdi.o: asm/bx86unix.cpp
+ $(CPP) -DBSDI asm/bx86unix.cpp | sed 's/ :/:/' | as -o asm/bx86bsdi.o
+
+asm/bx86unix.cpp: asm/$(BF_ASM) ../perlasm/x86asm.pl ../perlasm/cbc.pl
+ (cd asm; $(PERL) $(BF_ASM) cpp $(PROCESSOR) >bx86unix.cpp)
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
+
+links:
+ @$(TOP)/util/point.sh Makefile.ssl Makefile
+ @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install: installs
+
+installs:
+ @for i in $(EXHEADER) ; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done;
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f asm/bx86unix.cpp *.o asm/*.o *.obj $(LIB) tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/src/libfreeswan/libcrypto/libblowfish/Makefile.ssl b/src/libfreeswan/libcrypto/libblowfish/Makefile.ssl
new file mode 100644
index 000000000..adc9eec3c
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/Makefile.ssl
@@ -0,0 +1,118 @@
+#
+# SSLeay/crypto/blowfish/Makefile
+#
+
+DIR= bf
+TOP= ../..
+CC= cc
+CPP= $(CC) -E
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKE= make -f Makefile.ssl
+MAKEDEPEND= $(TOP)/util/domd $(TOP)
+MAKEFILE= Makefile.ssl
+AR= ar r
+
+BF_ENC= bf_enc.o
+# or use
+#DES_ENC= bx86-elf.o
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST=bftest.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=bf_skey.c bf_ecb.c bf_enc.c bf_cfb64.c bf_ofb64.c
+LIBOBJ=bf_skey.o bf_ecb.o $(BF_ENC) bf_cfb64.o bf_ofb64.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= blowfish.h
+HEADER= bf_pi.h bf_locl.h $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ $(AR) $(LIB) $(LIBOBJ)
+ $(RANLIB) $(LIB)
+ @touch lib
+
+# elf
+asm/bx86-elf.o: asm/bx86unix.cpp
+ $(CPP) -DELF -x c asm/bx86unix.cpp | as -o asm/bx86-elf.o
+
+# solaris
+asm/bx86-sol.o: asm/bx86unix.cpp
+ $(CC) -E -DSOL asm/bx86unix.cpp | sed 's/^#.*//' > asm/bx86-sol.s
+ as -o asm/bx86-sol.o asm/bx86-sol.s
+ rm -f asm/bx86-sol.s
+
+# a.out
+asm/bx86-out.o: asm/bx86unix.cpp
+ $(CPP) -DOUT asm/bx86unix.cpp | as -o asm/bx86-out.o
+
+# bsdi
+asm/bx86bsdi.o: asm/bx86unix.cpp
+ $(CPP) -DBSDI asm/bx86unix.cpp | sed 's/ :/:/' | as -o asm/bx86bsdi.o
+
+asm/bx86unix.cpp: asm/bf-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
+ (cd asm; $(PERL) bf-586.pl cpp $(PROCESSOR) >bx86unix.cpp)
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO
+
+links:
+ @$(TOP)/util/point.sh Makefile.ssl Makefile
+ @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
+
+install: installs
+
+installs:
+ @for i in $(EXHEADER) ; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done;
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f asm/bx86unix.cpp *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+bf_cfb64.o: ../../include/openssl/blowfish.h
+bf_cfb64.o: ../../include/openssl/opensslconf.h bf_locl.h
+bf_ecb.o: ../../include/openssl/blowfish.h ../../include/openssl/opensslconf.h
+bf_ecb.o: ../../include/openssl/opensslv.h bf_locl.h
+bf_enc.o: ../../include/openssl/blowfish.h ../../include/openssl/opensslconf.h
+bf_enc.o: bf_locl.h
+bf_ofb64.o: ../../include/openssl/blowfish.h
+bf_ofb64.o: ../../include/openssl/opensslconf.h bf_locl.h
+bf_skey.o: ../../include/openssl/blowfish.h ../../include/openssl/opensslconf.h
+bf_skey.o: bf_locl.h bf_pi.h
diff --git a/src/libfreeswan/libcrypto/libblowfish/README b/src/libfreeswan/libcrypto/libblowfish/README
new file mode 100644
index 000000000..f2712fd0e
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/README
@@ -0,0 +1,8 @@
+This is a quick packaging up of my blowfish code into a library.
+It has been lifted from SSLeay.
+The copyright notices seem a little harsh because I have not spent the
+time to rewrite the conditions from the normal SSLeay ones.
+
+Basically if you just want to play with the library, not a problem.
+
+eric 15-Apr-1997
diff --git a/src/libfreeswan/libcrypto/libblowfish/VERSION b/src/libfreeswan/libcrypto/libblowfish/VERSION
new file mode 100644
index 000000000..be995855e
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/VERSION
@@ -0,0 +1,6 @@
+The version numbers will follow my SSL implementation
+
+0.7.2r - Some reasonable default compiler options from
+ Peter Gutman <pgut001@cs.auckland.ac.nz>
+
+0.7.2m - the first release
diff --git a/src/libfreeswan/libcrypto/libblowfish/asm/bf-586.pl b/src/libfreeswan/libcrypto/libblowfish/asm/bf-586.pl
new file mode 100644
index 000000000..f00f3f4bf
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/asm/bf-586.pl
@@ -0,0 +1,136 @@
+#!/usr/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+
+&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386");
+
+$BF_ROUNDS=16;
+$BF_OFF=($BF_ROUNDS+2)*4;
+$L="edi";
+$R="esi";
+$P="ebp";
+$tmp1="eax";
+$tmp2="ebx";
+$tmp3="ecx";
+$tmp4="edx";
+
+&BF_encrypt("BF_encrypt",1);
+&BF_encrypt("BF_decrypt",0);
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
+&asm_finish();
+
+sub BF_encrypt
+ {
+ local($name,$enc)=@_;
+
+ &function_begin_B($name,"");
+
+ &comment("");
+
+ &push("ebp");
+ &push("ebx");
+ &mov($tmp2,&wparam(0));
+ &mov($P,&wparam(1));
+ &push("esi");
+ &push("edi");
+
+ &comment("Load the 2 words");
+ &mov($L,&DWP(0,$tmp2,"",0));
+ &mov($R,&DWP(4,$tmp2,"",0));
+
+ &xor( $tmp1, $tmp1);
+
+ # encrypting part
+
+ if ($enc)
+ {
+ &mov($tmp2,&DWP(0,$P,"",0));
+ &xor( $tmp3, $tmp3);
+
+ &xor($L,$tmp2);
+ for ($i=0; $i<$BF_ROUNDS; $i+=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
+
+ &comment("");
+ &comment("Round ".sprintf("%d",$i+1));
+ &BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1);
+ }
+ # &mov($tmp1,&wparam(0)); In last loop
+ &mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+ }
+ else
+ {
+ &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+ &xor( $tmp3, $tmp3);
+
+ &xor($L,$tmp2);
+ for ($i=$BF_ROUNDS; $i>0; $i-=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
+ &comment("");
+ &comment("Round ".sprintf("%d",$i-1));
+ &BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0);
+ }
+ # &mov($tmp1,&wparam(0)); In last loop
+ &mov($tmp4,&DWP(0,$P,"",0));
+ }
+
+ &xor($R,$tmp4);
+ &mov(&DWP(4,$tmp1,"",0),$L);
+
+ &mov(&DWP(0,$tmp1,"",0),$R);
+ &function_end($name);
+ }
+
+sub BF_ENCRYPT
+ {
+ local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_;
+
+ &mov( $tmp4, &DWP(&n2a($i*4),$P,"",0)); # for next round
+
+ &mov( $tmp2, $R);
+ &xor( $L, $tmp4);
+
+ &shr( $tmp2, 16);
+ &mov( $tmp4, $R);
+
+ &movb( &LB($tmp1), &HB($tmp2)); # A
+ &and( $tmp2, 0xff); # B
+
+ &movb( &LB($tmp3), &HB($tmp4)); # C
+ &and( $tmp4, 0xff); # D
+
+ &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
+ &mov( $tmp2, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
+
+ &add( $tmp2, $tmp1);
+ &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4));
+
+ &xor( $tmp2, $tmp1);
+ &mov( $tmp4, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4));
+
+ &add( $tmp2, $tmp4);
+ if (($enc && ($i != 16)) || ((!$enc) && ($i != 1)))
+ { &xor( $tmp1, $tmp1); }
+ else
+ {
+ &comment("Load parameter 0 ($i) enc=$enc");
+ &mov($tmp1,&wparam(0));
+ } # In last loop
+
+ &xor( $L, $tmp2);
+ # delay
+ }
+
+sub n2a
+ {
+ sprintf("%d",$_[0]);
+ }
+
diff --git a/src/libfreeswan/libcrypto/libblowfish/asm/bf-686.pl b/src/libfreeswan/libcrypto/libblowfish/asm/bf-686.pl
new file mode 100644
index 000000000..9222f5e7a
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/asm/bf-686.pl
@@ -0,0 +1,127 @@
+#!/usr/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+
+&asm_init($ARGV[0],"bf-686.pl");
+
+$BF_ROUNDS=16;
+$BF_OFF=($BF_ROUNDS+2)*4;
+$L="ecx";
+$R="edx";
+$P="edi";
+$tot="esi";
+$tmp1="eax";
+$tmp2="ebx";
+$tmp3="ebp";
+
+&des_encrypt("BF_encrypt",1);
+&des_encrypt("BF_decrypt",0);
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1);
+
+&asm_finish();
+
+&file_end();
+
+sub des_encrypt
+ {
+ local($name,$enc)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ &comment("Load the 2 words");
+ &mov("eax",&wparam(0));
+ &mov($L,&DWP(0,"eax","",0));
+ &mov($R,&DWP(4,"eax","",0));
+
+ &comment("");
+ &comment("P pointer, s and enc flag");
+ &mov($P,&wparam(1));
+
+ &xor( $tmp1, $tmp1);
+ &xor( $tmp2, $tmp2);
+
+ # encrypting part
+
+ if ($enc)
+ {
+ &xor($L,&DWP(0,$P,"",0));
+ for ($i=0; $i<$BF_ROUNDS; $i+=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3);
+
+ &comment("");
+ &comment("Round ".sprintf("%d",$i+1));
+ &BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3);
+ }
+ &xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+
+ &mov("eax",&wparam(0));
+ &mov(&DWP(0,"eax","",0),$R);
+ &mov(&DWP(4,"eax","",0),$L);
+ &function_end_A($name);
+ }
+ else
+ {
+ &xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0));
+ for ($i=$BF_ROUNDS; $i>0; $i-=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3);
+ &comment("");
+ &comment("Round ".sprintf("%d",$i-1));
+ &BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3);
+ }
+ &xor($R,&DWP(0,$P,"",0));
+
+ &mov("eax",&wparam(0));
+ &mov(&DWP(0,"eax","",0),$R);
+ &mov(&DWP(4,"eax","",0),$L);
+ &function_end_A($name);
+ }
+
+ &function_end_B($name);
+ }
+
+sub BF_ENCRYPT
+ {
+ local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_;
+
+ &rotr( $R, 16);
+ &mov( $tot, &DWP(&n2a($i*4),$P,"",0));
+
+ &movb( &LB($tmp1), &HB($R));
+ &movb( &LB($tmp2), &LB($R));
+
+ &rotr( $R, 16);
+ &xor( $L, $tot);
+
+ &mov( $tot, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4));
+ &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4));
+
+ &movb( &LB($tmp1), &HB($R));
+ &movb( &LB($tmp2), &LB($R));
+
+ &add( $tot, $tmp3);
+ &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay
+
+ &xor( $tot, $tmp1);
+ &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4));
+
+ &add( $tot, $tmp3);
+ &xor( $tmp1, $tmp1);
+
+ &xor( $L, $tot);
+ # delay
+ }
+
+sub n2a
+ {
+ sprintf("%d",$_[0]);
+ }
+
diff --git a/src/libfreeswan/libcrypto/libblowfish/asm/readme b/src/libfreeswan/libcrypto/libblowfish/asm/readme
new file mode 100644
index 000000000..2385fa381
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/asm/readme
@@ -0,0 +1,10 @@
+There are blowfish assembler generation scripts.
+bf-586.pl version is for the pentium and
+bf-686.pl is my original version, which is faster on the pentium pro.
+
+When using a bf-586.pl, the pentium pro/II is %8 slower than using
+bf-686.pl. When using a bf-686.pl, the pentium is %16 slower
+than bf-586.pl
+
+So the default is bf-586.pl
+
diff --git a/src/libfreeswan/libcrypto/libblowfish/bf_enc.c b/src/libfreeswan/libcrypto/libblowfish/bf_enc.c
new file mode 100644
index 000000000..aa6c79812
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/bf_enc.c
@@ -0,0 +1,306 @@
+/* crypto/bf/bf_enc.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "blowfish.h"
+#include "bf_locl.h"
+
+/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper'
+ * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION,
+ * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993)
+ */
+
+#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20)
+#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \
+to modify the code.
+#endif
+
+void BF_encrypt(BF_LONG *data, const BF_KEY *key)
+ {
+#ifndef BF_PTR2
+ const BF_LONG *p,*s;
+ BF_LONG l,r;
+
+ p=key->P;
+ s= &(key->S[0]);
+ l=data[0];
+ r=data[1];
+
+ l^=p[0];
+ BF_ENC(r,l,s,p[ 1]);
+ BF_ENC(l,r,s,p[ 2]);
+ BF_ENC(r,l,s,p[ 3]);
+ BF_ENC(l,r,s,p[ 4]);
+ BF_ENC(r,l,s,p[ 5]);
+ BF_ENC(l,r,s,p[ 6]);
+ BF_ENC(r,l,s,p[ 7]);
+ BF_ENC(l,r,s,p[ 8]);
+ BF_ENC(r,l,s,p[ 9]);
+ BF_ENC(l,r,s,p[10]);
+ BF_ENC(r,l,s,p[11]);
+ BF_ENC(l,r,s,p[12]);
+ BF_ENC(r,l,s,p[13]);
+ BF_ENC(l,r,s,p[14]);
+ BF_ENC(r,l,s,p[15]);
+ BF_ENC(l,r,s,p[16]);
+#if BF_ROUNDS == 20
+ BF_ENC(r,l,s,p[17]);
+ BF_ENC(l,r,s,p[18]);
+ BF_ENC(r,l,s,p[19]);
+ BF_ENC(l,r,s,p[20]);
+#endif
+ r^=p[BF_ROUNDS+1];
+
+ data[1]=l&0xffffffffL;
+ data[0]=r&0xffffffffL;
+#else
+ BF_LONG l,r,t,*k;
+
+ l=data[0];
+ r=data[1];
+ k=(BF_LONG*)key;
+
+ l^=k[0];
+ BF_ENC(r,l,k, 1);
+ BF_ENC(l,r,k, 2);
+ BF_ENC(r,l,k, 3);
+ BF_ENC(l,r,k, 4);
+ BF_ENC(r,l,k, 5);
+ BF_ENC(l,r,k, 6);
+ BF_ENC(r,l,k, 7);
+ BF_ENC(l,r,k, 8);
+ BF_ENC(r,l,k, 9);
+ BF_ENC(l,r,k,10);
+ BF_ENC(r,l,k,11);
+ BF_ENC(l,r,k,12);
+ BF_ENC(r,l,k,13);
+ BF_ENC(l,r,k,14);
+ BF_ENC(r,l,k,15);
+ BF_ENC(l,r,k,16);
+#if BF_ROUNDS == 20
+ BF_ENC(r,l,k,17);
+ BF_ENC(l,r,k,18);
+ BF_ENC(r,l,k,19);
+ BF_ENC(l,r,k,20);
+#endif
+ r^=k[BF_ROUNDS+1];
+
+ data[1]=l&0xffffffffL;
+ data[0]=r&0xffffffffL;
+#endif
+ }
+
+#ifndef BF_DEFAULT_OPTIONS
+
+void BF_decrypt(BF_LONG *data, const BF_KEY *key)
+ {
+#ifndef BF_PTR2
+ const BF_LONG *p,*s;
+ BF_LONG l,r;
+
+ p=key->P;
+ s= &(key->S[0]);
+ l=data[0];
+ r=data[1];
+
+ l^=p[BF_ROUNDS+1];
+#if BF_ROUNDS == 20
+ BF_ENC(r,l,s,p[20]);
+ BF_ENC(l,r,s,p[19]);
+ BF_ENC(r,l,s,p[18]);
+ BF_ENC(l,r,s,p[17]);
+#endif
+ BF_ENC(r,l,s,p[16]);
+ BF_ENC(l,r,s,p[15]);
+ BF_ENC(r,l,s,p[14]);
+ BF_ENC(l,r,s,p[13]);
+ BF_ENC(r,l,s,p[12]);
+ BF_ENC(l,r,s,p[11]);
+ BF_ENC(r,l,s,p[10]);
+ BF_ENC(l,r,s,p[ 9]);
+ BF_ENC(r,l,s,p[ 8]);
+ BF_ENC(l,r,s,p[ 7]);
+ BF_ENC(r,l,s,p[ 6]);
+ BF_ENC(l,r,s,p[ 5]);
+ BF_ENC(r,l,s,p[ 4]);
+ BF_ENC(l,r,s,p[ 3]);
+ BF_ENC(r,l,s,p[ 2]);
+ BF_ENC(l,r,s,p[ 1]);
+ r^=p[0];
+
+ data[1]=l&0xffffffffL;
+ data[0]=r&0xffffffffL;
+#else
+ BF_LONG l,r,t,*k;
+
+ l=data[0];
+ r=data[1];
+ k=(BF_LONG *)key;
+
+ l^=k[BF_ROUNDS+1];
+#if BF_ROUNDS == 20
+ BF_ENC(r,l,k,20);
+ BF_ENC(l,r,k,19);
+ BF_ENC(r,l,k,18);
+ BF_ENC(l,r,k,17);
+#endif
+ BF_ENC(r,l,k,16);
+ BF_ENC(l,r,k,15);
+ BF_ENC(r,l,k,14);
+ BF_ENC(l,r,k,13);
+ BF_ENC(r,l,k,12);
+ BF_ENC(l,r,k,11);
+ BF_ENC(r,l,k,10);
+ BF_ENC(l,r,k, 9);
+ BF_ENC(r,l,k, 8);
+ BF_ENC(l,r,k, 7);
+ BF_ENC(r,l,k, 6);
+ BF_ENC(l,r,k, 5);
+ BF_ENC(r,l,k, 4);
+ BF_ENC(l,r,k, 3);
+ BF_ENC(r,l,k, 2);
+ BF_ENC(l,r,k, 1);
+ r^=k[0];
+
+ data[1]=l&0xffffffffL;
+ data[0]=r&0xffffffffL;
+#endif
+ }
+
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+ const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+ {
+ BF_LONG tin0,tin1;
+ BF_LONG tout0,tout1,xor0,xor1;
+ long l=length;
+ BF_LONG tin[2];
+
+ if (encrypt)
+ {
+ n2l(ivec,tout0);
+ n2l(ivec,tout1);
+ ivec-=8;
+ for (l-=8; l>=0; l-=8)
+ {
+ n2l(in,tin0);
+ n2l(in,tin1);
+ tin0^=tout0;
+ tin1^=tout1;
+ tin[0]=tin0;
+ tin[1]=tin1;
+ BF_encrypt(tin,schedule);
+ tout0=tin[0];
+ tout1=tin[1];
+ l2n(tout0,out);
+ l2n(tout1,out);
+ }
+ if (l != -8)
+ {
+ n2ln(in,tin0,tin1,l+8);
+ tin0^=tout0;
+ tin1^=tout1;
+ tin[0]=tin0;
+ tin[1]=tin1;
+ BF_encrypt(tin,schedule);
+ tout0=tin[0];
+ tout1=tin[1];
+ l2n(tout0,out);
+ l2n(tout1,out);
+ }
+ l2n(tout0,ivec);
+ l2n(tout1,ivec);
+ }
+ else
+ {
+ n2l(ivec,xor0);
+ n2l(ivec,xor1);
+ ivec-=8;
+ for (l-=8; l>=0; l-=8)
+ {
+ n2l(in,tin0);
+ n2l(in,tin1);
+ tin[0]=tin0;
+ tin[1]=tin1;
+ BF_decrypt(tin,schedule);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2n(tout0,out);
+ l2n(tout1,out);
+ xor0=tin0;
+ xor1=tin1;
+ }
+ if (l != -8)
+ {
+ n2l(in,tin0);
+ n2l(in,tin1);
+ tin[0]=tin0;
+ tin[1]=tin1;
+ BF_decrypt(tin,schedule);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2nn(tout0,tout1,out,l+8);
+ xor0=tin0;
+ xor1=tin1;
+ }
+ l2n(xor0,ivec);
+ l2n(xor1,ivec);
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=0;
+ }
+
+#endif
diff --git a/src/libfreeswan/libcrypto/libblowfish/bf_locl.h b/src/libfreeswan/libcrypto/libblowfish/bf_locl.h
new file mode 100644
index 000000000..283bf4c43
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/bf_locl.h
@@ -0,0 +1,218 @@
+/* crypto/bf/bf_locl.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BF_LOCL_H
+#define HEADER_BF_LOCL_H
+
+#undef c2l
+#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \
+ l|=((unsigned long)(*((c)++)))<< 8L, \
+ l|=((unsigned long)(*((c)++)))<<16L, \
+ l|=((unsigned long)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#undef c2ln
+#define c2ln(c,l1,l2,n) { \
+ c+=n; \
+ l1=l2=0; \
+ switch (n) { \
+ case 8: l2 =((unsigned long)(*(--(c))))<<24L; \
+ case 7: l2|=((unsigned long)(*(--(c))))<<16L; \
+ case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \
+ case 5: l2|=((unsigned long)(*(--(c)))); \
+ case 4: l1 =((unsigned long)(*(--(c))))<<24L; \
+ case 3: l1|=((unsigned long)(*(--(c))))<<16L; \
+ case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \
+ case 1: l1|=((unsigned long)(*(--(c)))); \
+ } \
+ }
+
+#undef l2c
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#undef l2cn
+#define l2cn(l1,l2,c,n) { \
+ c+=n; \
+ switch (n) { \
+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
+ } \
+ }
+
+/* NOTE - c is not incremented as per n2l */
+#define n2ln(c,l1,l2,n) { \
+ c+=n; \
+ l1=l2=0; \
+ switch (n) { \
+ case 8: l2 =((unsigned long)(*(--(c)))) ; \
+ case 7: l2|=((unsigned long)(*(--(c))))<< 8; \
+ case 6: l2|=((unsigned long)(*(--(c))))<<16; \
+ case 5: l2|=((unsigned long)(*(--(c))))<<24; \
+ case 4: l1 =((unsigned long)(*(--(c)))) ; \
+ case 3: l1|=((unsigned long)(*(--(c))))<< 8; \
+ case 2: l1|=((unsigned long)(*(--(c))))<<16; \
+ case 1: l1|=((unsigned long)(*(--(c))))<<24; \
+ } \
+ }
+
+/* NOTE - c is not incremented as per l2n */
+#define l2nn(l1,l2,c,n) { \
+ c+=n; \
+ switch (n) { \
+ case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \
+ case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
+ case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
+ case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
+ case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \
+ case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
+ case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
+ case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
+ } \
+ }
+
+#undef n2l
+#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \
+ l|=((unsigned long)(*((c)++)))<<16L, \
+ l|=((unsigned long)(*((c)++)))<< 8L, \
+ l|=((unsigned long)(*((c)++))))
+
+#undef l2n
+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+/* This is actually a big endian algorithm, the most significant byte
+ * is used to lookup array 0 */
+
+#if defined(BF_PTR2)
+
+/*
+ * This is basically a special Intel version. Point is that Intel
+ * doesn't have many registers, but offers a reach choice of addressing
+ * modes. So we spare some registers by directly traversing BF_KEY
+ * structure and hiring the most decorated addressing mode. The code
+ * generated by EGCS is *perfectly* competitive with assembler
+ * implementation!
+ */
+#define BF_ENC(LL,R,KEY,Pi) (\
+ LL^=KEY[Pi], \
+ t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \
+ t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \
+ t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \
+ t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \
+ LL^=t \
+ )
+
+#elif defined(BF_PTR)
+
+#ifndef BF_LONG_LOG2
+#define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */
+#endif
+#define BF_M (0xFF<<BF_LONG_LOG2)
+#define BF_0 (24-BF_LONG_LOG2)
+#define BF_1 (16-BF_LONG_LOG2)
+#define BF_2 ( 8-BF_LONG_LOG2)
+#define BF_3 BF_LONG_LOG2 /* left shift */
+
+/*
+ * This is normally very good on RISC platforms where normally you
+ * have to explicitly "multiply" array index by sizeof(BF_LONG)
+ * in order to calculate the effective address. This implementation
+ * excuses CPU from this extra work. Power[PC] uses should have most
+ * fun as (R>>BF_i)&BF_M gets folded into a single instruction, namely
+ * rlwinm. So let'em double-check if their compiler does it.
+ */
+
+#define BF_ENC(LL,R,S,P) ( \
+ LL^=P, \
+ LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \
+ *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \
+ *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \
+ *(BF_LONG *)((unsigned char *)&(S[768])+((R<<BF_3)&BF_M))) \
+ )
+#else
+
+/*
+ * This is a *generic* version. Seem to perform best on platforms that
+ * offer explicit support for extraction of 8-bit nibbles preferably
+ * complemented with "multiplying" of array index by sizeof(BF_LONG).
+ * For the moment of this writing the list comprises Alpha CPU featuring
+ * extbl and s[48]addq instructions.
+ */
+
+#define BF_ENC(LL,R,S,P) ( \
+ LL^=P, \
+ LL^=((( S[ ((int)(R>>24)&0xff)] + \
+ S[0x0100+((int)(R>>16)&0xff)])^ \
+ S[0x0200+((int)(R>> 8)&0xff)])+ \
+ S[0x0300+((int)(R )&0xff)])&0xffffffffL \
+ )
+#endif
+
+#endif
diff --git a/src/libfreeswan/libcrypto/libblowfish/bf_pi.h b/src/libfreeswan/libcrypto/libblowfish/bf_pi.h
new file mode 100644
index 000000000..9949513c6
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/bf_pi.h
@@ -0,0 +1,325 @@
+/* crypto/bf/bf_pi.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static const BF_KEY bf_init= {
+ {
+ 0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L,
+ 0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L,
+ 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL,
+ 0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L,
+ 0x9216d5d9L, 0x8979fb1b
+ },{
+ 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L,
+ 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L,
+ 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L,
+ 0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL,
+ 0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL,
+ 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L,
+ 0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL,
+ 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL,
+ 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L,
+ 0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L,
+ 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL,
+ 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL,
+ 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL,
+ 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L,
+ 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L,
+ 0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L,
+ 0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L,
+ 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L,
+ 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL,
+ 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L,
+ 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L,
+ 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L,
+ 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L,
+ 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL,
+ 0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L,
+ 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL,
+ 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL,
+ 0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L,
+ 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL,
+ 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L,
+ 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL,
+ 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L,
+ 0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L,
+ 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL,
+ 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L,
+ 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L,
+ 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL,
+ 0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L,
+ 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL,
+ 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L,
+ 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L,
+ 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL,
+ 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L,
+ 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L,
+ 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L,
+ 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L,
+ 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L,
+ 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL,
+ 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL,
+ 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L,
+ 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L,
+ 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L,
+ 0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L,
+ 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL,
+ 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L,
+ 0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL,
+ 0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL,
+ 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L,
+ 0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L,
+ 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L,
+ 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L,
+ 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L,
+ 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L,
+ 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL,
+ 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L,
+ 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L,
+ 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L,
+ 0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL,
+ 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L,
+ 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L,
+ 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL,
+ 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L,
+ 0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L,
+ 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L,
+ 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL,
+ 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL,
+ 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L,
+ 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L,
+ 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L,
+ 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L,
+ 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL,
+ 0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL,
+ 0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL,
+ 0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L,
+ 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL,
+ 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L,
+ 0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L,
+ 0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL,
+ 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL,
+ 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L,
+ 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL,
+ 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L,
+ 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL,
+ 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL,
+ 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L,
+ 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L,
+ 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L,
+ 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L,
+ 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L,
+ 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L,
+ 0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L,
+ 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL,
+ 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L,
+ 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL,
+ 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L,
+ 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L,
+ 0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L,
+ 0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L,
+ 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L,
+ 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L,
+ 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L,
+ 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L,
+ 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L,
+ 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L,
+ 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L,
+ 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L,
+ 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L,
+ 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L,
+ 0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L,
+ 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L,
+ 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL,
+ 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL,
+ 0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L,
+ 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL,
+ 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L,
+ 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L,
+ 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L,
+ 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L,
+ 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L,
+ 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L,
+ 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL,
+ 0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L,
+ 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L,
+ 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L,
+ 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL,
+ 0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL,
+ 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL,
+ 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L,
+ 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L,
+ 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL,
+ 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L,
+ 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL,
+ 0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L,
+ 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL,
+ 0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L,
+ 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL,
+ 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L,
+ 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL,
+ 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L,
+ 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L,
+ 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL,
+ 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L,
+ 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L,
+ 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L,
+ 0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L,
+ 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL,
+ 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L,
+ 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL,
+ 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L,
+ 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL,
+ 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L,
+ 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL,
+ 0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL,
+ 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL,
+ 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L,
+ 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L,
+ 0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL,
+ 0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL,
+ 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL,
+ 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL,
+ 0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL,
+ 0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L,
+ 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L,
+ 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L,
+ 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L,
+ 0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL,
+ 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL,
+ 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L,
+ 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L,
+ 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L,
+ 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L,
+ 0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L,
+ 0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L,
+ 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L,
+ 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L,
+ 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L,
+ 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L,
+ 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL,
+ 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L,
+ 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL,
+ 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L,
+ 0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L,
+ 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL,
+ 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL,
+ 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL,
+ 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L,
+ 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L,
+ 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L,
+ 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L,
+ 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L,
+ 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L,
+ 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L,
+ 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L,
+ 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L,
+ 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L,
+ 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L,
+ 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L,
+ 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL,
+ 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL,
+ 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L,
+ 0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL,
+ 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL,
+ 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL,
+ 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L,
+ 0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL,
+ 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL,
+ 0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L,
+ 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L,
+ 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L,
+ 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L,
+ 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL,
+ 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL,
+ 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L,
+ 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L,
+ 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L,
+ 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL,
+ 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L,
+ 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L,
+ 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L,
+ 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL,
+ 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L,
+ 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L,
+ 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L,
+ 0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL,
+ 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL,
+ 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L,
+ 0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L,
+ 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L,
+ 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L,
+ 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL,
+ 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L,
+ 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL,
+ 0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL,
+ 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L,
+ 0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L,
+ 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL,
+ 0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L,
+ 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL,
+ 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L,
+ 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL,
+ 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L,
+ 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L,
+ 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL,
+ 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L,
+ 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL,
+ 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L,
+ }
+ };
+
diff --git a/src/libfreeswan/libcrypto/libblowfish/bf_skey.c b/src/libfreeswan/libcrypto/libblowfish/bf_skey.c
new file mode 100644
index 000000000..8cdbbd283
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/bf_skey.c
@@ -0,0 +1,122 @@
+/* crypto/bf/bf_skey.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <stdio.h>
+#include <string.h>
+#endif
+
+#include "blowfish.h"
+#include "bf_locl.h"
+#include "bf_pi.h"
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data)
+ {
+ int i;
+ BF_LONG *p,ri,in[2];
+ const unsigned char *d,*end;
+
+
+ memcpy((char *)key,(const char *)&bf_init,sizeof(BF_KEY));
+ p=key->P;
+
+ if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4;
+
+ d=data;
+ end= &(data[len]);
+ for (i=0; i<(BF_ROUNDS+2); i++)
+ {
+ ri= *(d++);
+ if (d >= end) d=data;
+
+ ri<<=8;
+ ri|= *(d++);
+ if (d >= end) d=data;
+
+ ri<<=8;
+ ri|= *(d++);
+ if (d >= end) d=data;
+
+ ri<<=8;
+ ri|= *(d++);
+ if (d >= end) d=data;
+
+ p[i]^=ri;
+ }
+
+ in[0]=0L;
+ in[1]=0L;
+ for (i=0; i<(BF_ROUNDS+2); i+=2)
+ {
+ BF_encrypt(in,key);
+ p[i ]=in[0];
+ p[i+1]=in[1];
+ }
+
+ p=key->S;
+ for (i=0; i<4*256; i+=2)
+ {
+ BF_encrypt(in,key);
+ p[i ]=in[0];
+ p[i+1]=in[1];
+ }
+ }
+
diff --git a/src/libfreeswan/libcrypto/libblowfish/blowfish.h b/src/libfreeswan/libcrypto/libblowfish/blowfish.h
new file mode 100644
index 000000000..ccb97e272
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libblowfish/blowfish.h
@@ -0,0 +1,133 @@
+/* crypto/bf/blowfish.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BLOWFISH_H
+#define HEADER_BLOWFISH_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NO_BF
+#error BF is disabled.
+#endif
+
+#define BF_ENCRYPT 1
+#define BF_DECRYPT 0
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! BF_LONG_LOG2 has to be defined along. !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(WIN16) || defined(__LP32__)
+#define BF_LONG unsigned long
+#elif defined(_CRAY) || defined(__ILP64__)
+#define BF_LONG unsigned long
+#define BF_LONG_LOG2 3
+#endif
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ * <appro@fy.chalmers.se>
+ */
+
+/* des.h-like hack <jjo-ipsec@mendoza.gov.ar> */
+#ifndef BF_LONG
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#define BF_LONG u_int32_t
+#endif
+
+#define BF_ROUNDS 16
+#define BF_BLOCK 8
+
+typedef struct bf_key_st
+ {
+ BF_LONG P[BF_ROUNDS+2];
+ BF_LONG S[4*256];
+ } BF_KEY;
+
+
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data,const BF_KEY *key);
+void BF_decrypt(BF_LONG *data,const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+ const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+ const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+ const BF_KEY *schedule, unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+ const BF_KEY *schedule, unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/libfreeswan/libcrypto/libserpent/Makefile b/src/libfreeswan/libcrypto/libserpent/Makefile
new file mode 100644
index 000000000..51a1e0582
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libserpent/Makefile
@@ -0,0 +1,20 @@
+CFLAGS=-O3 -fomit-frame-pointer -D__KERNEL__ -Wall $(EXTRA_CFLAGS)
+INC=-I../include
+LIBOBJ=serpent.o serpent_cbc.o
+BLIB=libserpent.a
+
+.c.o:
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@
+
+$(BLIB): $(LIBOBJ)
+ /bin/rm -f $(BLIB)
+ ar cr $(BLIB) $(LIBOBJ)
+ -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \
+ else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \
+ else exit 0; fi; fi
+
+test: test_main.o $(BLIB)
+ $(CC) -o $@ $^
+
+clean:
+ rm -f *.[oa] core $(TARGET) test
diff --git a/src/libfreeswan/libcrypto/libserpent/serpent.c b/src/libfreeswan/libcrypto/libserpent/serpent.c
new file mode 100644
index 000000000..f2cea250e
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libserpent/serpent.c
@@ -0,0 +1,995 @@
+
+/* Optimized implementation of the Serpent AES candidate algorithm
+ * Designed by Anderson, Biham and Knudsen and Implemented by
+ * Gisle Sælensminde 2000.
+ *
+ * The implementation is based on the pentium optimised sboxes of
+ * Dag Arne Osvik. Even these sboxes are designed to be optimal for x86
+ * processors they are efficient on other processors as well, but the speedup
+ * isn't so impressive compared to other implementations.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * as published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifdef __KERNEL__
+#include <linux/init.h>
+#include <linux/types.h>
+
+#include <asm/byteorder.h>
+#else
+#include <sys/types.h>
+#include <asm/byteorder.h>
+#endif
+
+#include "serpent.h"
+
+#define rotl(reg, val) ((reg << val) | (reg >> (32 - val)))
+#define rotr(reg, val) ((reg >> val) | (reg << (32 - val)))
+
+#ifdef __cpu_to_be32
+#define BLOCK_SWAP
+#define io_swap(x) __cpu_to_be32(x)
+#else
+#undef BLOCK_SWAP
+#endif
+
+/* The sbox functions. The first four parameters is the input bits, and
+ * the last is a tempoary. These parameters are also used for output, but
+ * the bit order is permuted. The output bit order from S0 is
+ * (1 4 2 0 3), where 3 is the (now useless) tempoary.
+ */
+
+#define S0(r0,r1,r2,r3,r4) \
+ r3 = r3 ^ r0; \
+ r4 = r1; \
+ r1 = r1 & r3; \
+ r4 = r4 ^ r2; \
+ r1 = r1 ^ r0; \
+ r0 = r0 | r3; \
+ r0 = r0 ^ r4; \
+ r4 = r4 ^ r3; \
+ r3 = r3 ^ r2; \
+ r2 = r2 | r1; \
+ r2 = r2 ^ r4; \
+ r4 = -1 ^ r4; \
+ r4 = r4 | r1; \
+ r1 = r1 ^ r3; \
+ r1 = r1 ^ r4; \
+ r3 = r3 | r0; \
+ r1 = r1 ^ r3; \
+ r4 = r4 ^ r3;
+
+#define S1(r0,r1,r2,r3,r4) \
+ r1 = -1 ^ r1; \
+ r4 = r0; \
+ r0 = r0 ^ r1; \
+ r4 = r4 | r1; \
+ r4 = r4 ^ r3; \
+ r3 = r3 & r0; \
+ r2 = r2 ^ r4; \
+ r3 = r3 ^ r1; \
+ r3 = r3 | r2; \
+ r0 = r0 ^ r4; \
+ r3 = r3 ^ r0; \
+ r1 = r1 & r2; \
+ r0 = r0 | r1; \
+ r1 = r1 ^ r4; \
+ r0 = r0 ^ r2; \
+ r4 = r4 | r3; \
+ r0 = r0 ^ r4; \
+ r4 = -1 ^ r4; \
+ r1 = r1 ^ r3; \
+ r4 = r4 & r2; \
+ r1 = -1 ^ r1; \
+ r4 = r4 ^ r0; \
+ r1 = r1 ^ r4;
+
+#define S2(r0,r1,r2,r3,r4) \
+ r4 = r0; \
+ r0 = r0 & r2; \
+ r0 = r0 ^ r3; \
+ r2 = r2 ^ r1; \
+ r2 = r2 ^ r0; \
+ r3 = r3 | r4; \
+ r3 = r3 ^ r1; \
+ r4 = r4 ^ r2; \
+ r1 = r3; \
+ r3 = r3 | r4; \
+ r3 = r3 ^ r0; \
+ r0 = r0 & r1; \
+ r4 = r4 ^ r0; \
+ r1 = r1 ^ r3; \
+ r1 = r1 ^ r4; \
+ r4 = -1 ^ r4;
+
+#define S3(r0,r1,r2,r3,r4) \
+ r4 = r0 ; \
+ r0 = r0 | r3; \
+ r3 = r3 ^ r1; \
+ r1 = r1 & r4; \
+ r4 = r4 ^ r2; \
+ r2 = r2 ^ r3; \
+ r3 = r3 & r0; \
+ r4 = r4 | r1; \
+ r3 = r3 ^ r4; \
+ r0 = r0 ^ r1; \
+ r4 = r4 & r0; \
+ r1 = r1 ^ r3; \
+ r4 = r4 ^ r2; \
+ r1 = r1 | r0; \
+ r1 = r1 ^ r2; \
+ r0 = r0 ^ r3; \
+ r2 = r1; \
+ r1 = r1 | r3; \
+ r1 = r1 ^ r0;
+
+#define S4(r0,r1,r2,r3,r4) \
+ r1 = r1 ^ r3; \
+ r3 = -1 ^ r3; \
+ r2 = r2 ^ r3; \
+ r3 = r3 ^ r0; \
+ r4 = r1; \
+ r1 = r1 & r3; \
+ r1 = r1 ^ r2; \
+ r4 = r4 ^ r3; \
+ r0 = r0 ^ r4; \
+ r2 = r2 & r4; \
+ r2 = r2 ^ r0; \
+ r0 = r0 & r1; \
+ r3 = r3 ^ r0; \
+ r4 = r4 | r1; \
+ r4 = r4 ^ r0; \
+ r0 = r0 | r3; \
+ r0 = r0 ^ r2; \
+ r2 = r2 & r3; \
+ r0 = -1 ^ r0; \
+ r4 = r4 ^ r2;
+
+#define S5(r0,r1,r2,r3,r4) \
+ r0 = r0 ^ r1; \
+ r1 = r1 ^ r3; \
+ r3 = -1 ^ r3; \
+ r4 = r1; \
+ r1 = r1 & r0; \
+ r2 = r2 ^ r3; \
+ r1 = r1 ^ r2; \
+ r2 = r2 | r4; \
+ r4 = r4 ^ r3; \
+ r3 = r3 & r1; \
+ r3 = r3 ^ r0; \
+ r4 = r4 ^ r1; \
+ r4 = r4 ^ r2; \
+ r2 = r2 ^ r0; \
+ r0 = r0 & r3; \
+ r2 = -1 ^ r2; \
+ r0 = r0 ^ r4; \
+ r4 = r4 | r3; \
+ r2 = r2 ^ r4;
+
+#define S6(r0,r1,r2,r3,r4) \
+ r2 = -1 ^ r2; \
+ r4 = r3; \
+ r3 = r3 & r0; \
+ r0 = r0 ^ r4; \
+ r3 = r3 ^ r2; \
+ r2 = r2 | r4; \
+ r1 = r1 ^ r3; \
+ r2 = r2 ^ r0; \
+ r0 = r0 | r1; \
+ r2 = r2 ^ r1; \
+ r4 = r4 ^ r0; \
+ r0 = r0 | r3; \
+ r0 = r0 ^ r2; \
+ r4 = r4 ^ r3; \
+ r4 = r4 ^ r0; \
+ r3 = -1 ^ r3; \
+ r2 = r2 & r4; \
+ r2 = r2 ^ r3;
+
+#define S7(r0,r1,r2,r3,r4) \
+ r4 = r2; \
+ r2 = r2 & r1; \
+ r2 = r2 ^ r3; \
+ r3 = r3 & r1; \
+ r4 = r4 ^ r2; \
+ r2 = r2 ^ r1; \
+ r1 = r1 ^ r0; \
+ r0 = r0 | r4; \
+ r0 = r0 ^ r2; \
+ r3 = r3 ^ r1; \
+ r2 = r2 ^ r3; \
+ r3 = r3 & r0; \
+ r3 = r3 ^ r4; \
+ r4 = r4 ^ r2; \
+ r2 = r2 & r0; \
+ r4 = -1 ^ r4; \
+ r2 = r2 ^ r4; \
+ r4 = r4 & r0; \
+ r1 = r1 ^ r3; \
+ r4 = r4 ^ r1;
+
+/* The inverse sboxes */
+
+#define I0(r0,r1,r2,r3,r4) \
+ r2 = r2 ^ -1; \
+ r4 = r1; \
+ r1 = r1 | r0; \
+ r4 = r4 ^ -1; \
+ r1 = r1 ^ r2; \
+ r2 = r2 | r4; \
+ r1 = r1 ^ r3; \
+ r0 = r0 ^ r4; \
+ r2 = r2 ^ r0; \
+ r0 = r0 & r3; \
+ r4 = r4 ^ r0; \
+ r0 = r0 | r1; \
+ r0 = r0 ^ r2; \
+ r3 = r3 ^ r4; \
+ r2 = r2 ^ r1; \
+ r3 = r3 ^ r0; \
+ r3 = r3 ^ r1; \
+ r2 = r2 & r3; \
+ r4 = r4 ^ r2;
+
+#define I1(r0,r1,r2,r3,r4) \
+ r4 = r1; \
+ r1 = r1 ^ r3; \
+ r3 = r3 & r1; \
+ r4 = r4 ^ r2; \
+ r3 = r3 ^ r0; \
+ r0 = r0 | r1; \
+ r2 = r2 ^ r3; \
+ r0 = r0 ^ r4; \
+ r0 = r0 | r2; \
+ r1 = r1 ^ r3; \
+ r0 = r0 ^ r1; \
+ r1 = r1 | r3; \
+ r1 = r1 ^ r0; \
+ r4 = r4 ^ -1; \
+ r4 = r4 ^ r1; \
+ r1 = r1 | r0; \
+ r1 = r1 ^ r0; \
+ r1 = r1 | r4; \
+ r3 = r3 ^ r1;
+
+#define I2(r0,r1,r2,r3,r4) \
+ r2 = r2 ^ r3; \
+ r3 = r3 ^ r0; \
+ r4 = r3; \
+ r3 = r3 & r2; \
+ r3 = r3 ^ r1; \
+ r1 = r1 | r2; \
+ r1 = r1 ^ r4; \
+ r4 = r4 & r3; \
+ r2 = r2 ^ r3; \
+ r4 = r4 & r0; \
+ r4 = r4 ^ r2; \
+ r2 = r2 & r1; \
+ r2 = r2 | r0; \
+ r3 = r3 ^ -1; \
+ r2 = r2 ^ r3; \
+ r0 = r0 ^ r3; \
+ r0 = r0 & r1; \
+ r3 = r3 ^ r4; \
+ r3 = r3 ^ r0;
+
+#define I3(r0,r1,r2,r3,r4) \
+ r4 = r2; \
+ r2 = r2 ^ r1; \
+ r0 = r0 ^ r2; \
+ r4 = r4 & r2; \
+ r4 = r4 ^ r0; \
+ r0 = r0 & r1; \
+ r1 = r1 ^ r3; \
+ r3 = r3 | r4; \
+ r2 = r2 ^ r3; \
+ r0 = r0 ^ r3; \
+ r1 = r1 ^ r4; \
+ r3 = r3 & r2; \
+ r3 = r3 ^ r1; \
+ r1 = r1 ^ r0; \
+ r1 = r1 | r2; \
+ r0 = r0 ^ r3; \
+ r1 = r1 ^ r4; \
+ r0 = r0 ^ r1;
+
+#define I4(r0,r1,r2,r3,r4) \
+ r4 = r2; \
+ r2 = r2 & r3; \
+ r2 = r2 ^ r1; \
+ r1 = r1 | r3; \
+ r1 = r1 & r0; \
+ r4 = r4 ^ r2; \
+ r4 = r4 ^ r1; \
+ r1 = r1 & r2; \
+ r0 = r0 ^ -1; \
+ r3 = r3 ^ r4; \
+ r1 = r1 ^ r3; \
+ r3 = r3 & r0; \
+ r3 = r3 ^ r2; \
+ r0 = r0 ^ r1; \
+ r2 = r2 & r0; \
+ r3 = r3 ^ r0; \
+ r2 = r2 ^ r4; \
+ r2 = r2 | r3; \
+ r3 = r3 ^ r0; \
+ r2 = r2 ^ r1;
+
+#define I5(r0,r1,r2,r3,r4) \
+ r1 = r1 ^ -1; \
+ r4 = r3; \
+ r2 = r2 ^ r1; \
+ r3 = r3 | r0; \
+ r3 = r3 ^ r2; \
+ r2 = r2 | r1; \
+ r2 = r2 & r0; \
+ r4 = r4 ^ r3; \
+ r2 = r2 ^ r4; \
+ r4 = r4 | r0; \
+ r4 = r4 ^ r1; \
+ r1 = r1 & r2; \
+ r1 = r1 ^ r3; \
+ r4 = r4 ^ r2; \
+ r3 = r3 & r4; \
+ r4 = r4 ^ r1; \
+ r3 = r3 ^ r0; \
+ r3 = r3 ^ r4; \
+ r4 = r4 ^ -1;
+
+
+#define I6(r0,r1,r2,r3,r4) \
+ r0 = r0 ^ r2; \
+ r4 = r2; \
+ r2 = r2 & r0; \
+ r4 = r4 ^ r3; \
+ r2 = r2 ^ -1; \
+ r3 = r3 ^ r1; \
+ r2 = r2 ^ r3; \
+ r4 = r4 | r0; \
+ r0 = r0 ^ r2; \
+ r3 = r3 ^ r4; \
+ r4 = r4 ^ r1; \
+ r1 = r1 & r3; \
+ r1 = r1 ^ r0; \
+ r0 = r0 ^ r3; \
+ r0 = r0 | r2; \
+ r3 = r3 ^ r1; \
+ r4 = r4 ^ r0;
+
+#define I7(r0,r1,r2,r3,r4) \
+ r4 = r2; \
+ r2 = r2 ^ r0; \
+ r0 = r0 & r3; \
+ r4 = r4 | r3; \
+ r2 = r2 ^ -1; \
+ r3 = r3 ^ r1; \
+ r1 = r1 | r0; \
+ r0 = r0 ^ r2; \
+ r2 = r2 & r4; \
+ r3 = r3 & r4; \
+ r1 = r1 ^ r2; \
+ r2 = r2 ^ r0; \
+ r0 = r0 | r2; \
+ r4 = r4 ^ r1; \
+ r0 = r0 ^ r3; \
+ r3 = r3 ^ r4; \
+ r4 = r4 | r0; \
+ r3 = r3 ^ r2; \
+ r4 = r4 ^ r2;
+
+/* forward and inverse linear transformations */
+
+#define LINTRANS(r0,r1,r2,r3,r4) \
+ r0 = rotl(r0, 13); \
+ r2 = rotl(r2, 3); \
+ r3 = r3 ^ r2; \
+ r4 = r0 << 3; \
+ r1 = r1 ^ r0; \
+ r3 = r3 ^ r4; \
+ r1 = r1 ^ r2; \
+ r3 = rotl(r3, 7); \
+ r1 = rotl(r1, 1); \
+ r2 = r2 ^ r3; \
+ r4 = r1 << 7; \
+ r0 = r0 ^ r1; \
+ r2 = r2 ^ r4; \
+ r0 = r0 ^ r3; \
+ r2 = rotl(r2, 22); \
+ r0 = rotl(r0, 5);
+
+#define ILINTRANS(r0,r1,r2,r3,r4) \
+ r2 = rotr(r2, 22); \
+ r0 = rotr(r0, 5); \
+ r2 = r2 ^ r3; \
+ r4 = r1 << 7; \
+ r0 = r0 ^ r1; \
+ r2 = r2 ^ r4; \
+ r0 = r0 ^ r3; \
+ r3 = rotr(r3, 7); \
+ r1 = rotr(r1, 1); \
+ r3 = r3 ^ r2; \
+ r4 = r0 << 3; \
+ r1 = r1 ^ r0; \
+ r3 = r3 ^ r4; \
+ r1 = r1 ^ r2; \
+ r2 = rotr(r2, 3); \
+ r0 = rotr(r0, 13);
+
+
+#define KEYMIX(r0,r1,r2,r3,r4,IN) \
+ r0 = r0 ^ l_key[IN+8]; \
+ r1 = r1 ^ l_key[IN+9]; \
+ r2 = r2 ^ l_key[IN+10]; \
+ r3 = r3 ^ l_key[IN+11];
+
+#define GETKEY(r0, r1, r2, r3, IN) \
+ r0 = l_key[IN+8]; \
+ r1 = l_key[IN+9]; \
+ r2 = l_key[IN+10]; \
+ r3 = l_key[IN+11];
+
+#define SETKEY(r0, r1, r2, r3, IN) \
+ l_key[IN+8] = r0; \
+ l_key[IN+9] = r1; \
+ l_key[IN+10] = r2; \
+ l_key[IN+11] = r3;
+
+/* initialise the key schedule from the user supplied key */
+
+int serpent_set_key(serpent_context *cx, const unsigned char *key, int key_len)
+{ const u32 *in_key = (const u32 *)key;
+ /* l_key - storage for the key schedule */
+ u32 *l_key = cx->keyinfo;
+ u32 i,lk,r0,r1,r2,r3,r4;
+
+ if (key_len != 16 && key_len != 24 && key_len != 32)
+ return -1; /* unsupported key length */
+
+ key_len *= 8;
+
+ i = 0; lk = (key_len + 31) / 32;
+
+ while(i < lk)
+ {
+#ifdef BLOCK_SWAP
+ l_key[i] = io_swap(in_key[lk - i - 1]);
+#else
+ l_key[i] = in_key[i];
+#endif
+ i++;
+ }
+
+ if (key_len < 256)
+ {
+ while(i < 8)
+
+ l_key[i++] = 0;
+
+ i = key_len / 32; lk = 1 << key_len % 32;
+
+ l_key[i] &= lk - 1;
+ l_key[i] |= lk;
+ }
+
+ for(i = 0; i < 132; ++i)
+ {
+ lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5]
+ ^ l_key[i + 7] ^ 0x9e3779b9 ^ i;
+
+ l_key[i + 8] = (lk << 11) | (lk >> 21);
+ }
+
+ GETKEY(r0, r1, r2, r3, 0);
+ S3(r0,r1,r2,r3,r4);
+ SETKEY(r1, r2, r3, r4, 0)
+
+ GETKEY(r0, r1, r2, r3, 4);
+ S2(r0,r1,r2,r3,r4);
+ SETKEY(r2, r3, r1, r4, 4)
+
+ GETKEY(r0, r1, r2, r3, 8);
+ S1(r0,r1,r2,r3,r4);
+ SETKEY(r3, r1, r2, r0, 8)
+
+ GETKEY(r0, r1, r2, r3, 12);
+ S0(r0,r1,r2,r3,r4);
+ SETKEY(r1, r4, r2, r0, 12)
+
+ GETKEY(r0, r1, r2, r3, 16);
+ S7(r0,r1,r2,r3,r4);
+ SETKEY(r2, r4, r3, r0, 16)
+
+ GETKEY(r0, r1, r2, r3, 20);
+ S6(r0,r1,r2,r3,r4)
+ SETKEY(r0, r1, r4, r2, 20)
+
+ GETKEY(r0, r1, r2, r3, 24);
+ S5(r0,r1,r2,r3,r4);
+ SETKEY(r1, r3, r0, r2, 24)
+
+ GETKEY(r0, r1, r2, r3, 28);
+ S4(r0,r1,r2,r3,r4)
+ SETKEY(r1, r4, r0, r3, 28)
+
+ GETKEY(r0, r1, r2, r3, 32);
+ S3(r0,r1,r2,r3,r4);
+ SETKEY(r1, r2, r3, r4, 32)
+
+ GETKEY(r0, r1, r2, r3, 36);
+ S2(r0,r1,r2,r3,r4);
+ SETKEY(r2, r3, r1, r4, 36)
+
+ GETKEY(r0, r1, r2, r3, 40);
+ S1(r0,r1,r2,r3,r4);
+ SETKEY(r3, r1, r2, r0, 40)
+
+ GETKEY(r0, r1, r2, r3, 44);
+ S0(r0,r1,r2,r3,r4);
+ SETKEY(r1, r4, r2, r0, 44)
+
+ GETKEY(r0, r1, r2, r3, 48);
+ S7(r0,r1,r2,r3,r4);
+ SETKEY(r2, r4, r3, r0, 48)
+
+ GETKEY(r0, r1, r2, r3, 52);
+ S6(r0,r1,r2,r3,r4)
+ SETKEY(r0, r1, r4, r2, 52)
+
+ GETKEY(r0, r1, r2, r3, 56);
+ S5(r0,r1,r2,r3,r4);
+ SETKEY(r1, r3, r0, r2, 56)
+
+ GETKEY(r0, r1, r2, r3, 60);
+ S4(r0,r1,r2,r3,r4)
+ SETKEY(r1, r4, r0, r3, 60)
+
+ GETKEY(r0, r1, r2, r3, 64);
+ S3(r0,r1,r2,r3,r4);
+ SETKEY(r1, r2, r3, r4, 64)
+
+ GETKEY(r0, r1, r2, r3, 68);
+ S2(r0,r1,r2,r3,r4);
+ SETKEY(r2, r3, r1, r4, 68)
+
+ GETKEY(r0, r1, r2, r3, 72);
+ S1(r0,r1,r2,r3,r4);
+ SETKEY(r3, r1, r2, r0, 72)
+
+ GETKEY(r0, r1, r2, r3, 76);
+ S0(r0,r1,r2,r3,r4);
+ SETKEY(r1, r4, r2, r0, 76)
+
+ GETKEY(r0, r1, r2, r3, 80);
+ S7(r0,r1,r2,r3,r4);
+ SETKEY(r2, r4, r3, r0, 80)
+
+ GETKEY(r0, r1, r2, r3, 84);
+ S6(r0,r1,r2,r3,r4)
+ SETKEY(r0, r1, r4, r2, 84)
+
+ GETKEY(r0, r1, r2, r3, 88);
+ S5(r0,r1,r2,r3,r4);
+ SETKEY(r1, r3, r0, r2, 88)
+
+ GETKEY(r0, r1, r2, r3, 92);
+ S4(r0,r1,r2,r3,r4)
+ SETKEY(r1, r4, r0, r3, 92)
+
+ GETKEY(r0, r1, r2, r3, 96);
+ S3(r0,r1,r2,r3,r4);
+ SETKEY(r1, r2, r3, r4, 96)
+
+ GETKEY(r0, r1, r2, r3, 100);
+ S2(r0,r1,r2,r3,r4);
+ SETKEY(r2, r3, r1, r4, 100)
+
+ GETKEY(r0, r1, r2, r3, 104);
+ S1(r0,r1,r2,r3,r4);
+ SETKEY(r3, r1, r2, r0, 104)
+
+ GETKEY(r0, r1, r2, r3, 108);
+ S0(r0,r1,r2,r3,r4);
+ SETKEY(r1, r4, r2, r0, 108)
+
+ GETKEY(r0, r1, r2, r3, 112);
+ S7(r0,r1,r2,r3,r4);
+ SETKEY(r2, r4, r3, r0, 112)
+
+ GETKEY(r0, r1, r2, r3, 116);
+ S6(r0,r1,r2,r3,r4)
+ SETKEY(r0, r1, r4, r2, 116)
+
+ GETKEY(r0, r1, r2, r3, 120);
+ S5(r0,r1,r2,r3,r4);
+ SETKEY(r1, r3, r0, r2, 120)
+
+ GETKEY(r0, r1, r2, r3, 124);
+ S4(r0,r1,r2,r3,r4)
+ SETKEY(r1, r4, r0, r3, 124)
+
+ GETKEY(r0, r1, r2, r3, 128);
+ S3(r0,r1,r2,r3,r4);
+ SETKEY(r1, r2, r3, r4, 128)
+
+ return 0;
+};
+
+/* Encryption and decryption functions. The rounds are fully inlined.
+ * The sboxes alters the bit order of the output, and the altered
+ * bit ordrer is used progressivly. */
+
+/* encrypt a block of text */
+
+int serpent_encrypt(serpent_context *cx, const u8 *in,
+ u8 *out)
+{ u32 *l_key = cx->keyinfo;
+ const u32 *in_blk = (const u32 *) in;
+ u32 *out_blk = (u32 *) out;
+ u32 r0,r1,r2,r3,r4;
+
+#ifdef BLOCK_SWAP
+ r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]);
+ r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
+#else
+ r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
+#endif
+
+ /* round 1 */
+ KEYMIX(r0,r1,r2,r3,r4,0);
+ S0(r0,r1,r2,r3,r4);
+ LINTRANS(r1,r4,r2,r0,r3);
+
+ /* round 2 */
+ KEYMIX(r1,r4,r2,r0,r3,4);
+ S1(r1,r4,r2,r0,r3);
+ LINTRANS(r0,r4,r2,r1,r3);
+
+ /* round 3 */
+ KEYMIX(r0,r4,r2,r1,r3,8);
+ S2(r0,r4,r2,r1,r3);
+ LINTRANS(r2,r1,r4,r3,r0);
+
+ /* round 4 */
+ KEYMIX(r2,r1,r4,r3,r0,12);
+ S3(r2,r1,r4,r3,r0);
+ LINTRANS(r1,r4,r3,r0,r2);
+
+ /* round 5 */
+ KEYMIX(r1,r4,r3,r0,r2,16);
+ S4(r1,r4,r3,r0,r2)
+ LINTRANS(r4,r2,r1,r0,r3);
+
+ /* round 6 */
+ KEYMIX(r4,r2,r1,r0,r3,20);
+ S5(r4,r2,r1,r0,r3);
+ LINTRANS(r2,r0,r4,r1,r3);
+
+ /* round 7 */
+ KEYMIX(r2,r0,r4,r1,r3,24);
+ S6(r2,r0,r4,r1,r3)
+ LINTRANS(r2,r0,r3,r4,r1);
+
+ /* round 8 */
+ KEYMIX(r2,r0,r3,r4,r1,28);
+ S7(r2,r0,r3,r4,r1);
+ LINTRANS(r3,r1,r4,r2,r0);
+
+ /* round 9 */
+ KEYMIX(r3,r1,r4,r2,r0,32);
+ S0(r3,r1,r4,r2,r0);
+ LINTRANS(r1,r0,r4,r3,r2);
+
+ /* round 10 */
+ KEYMIX(r1,r0,r4,r3,r2,36);
+ S1(r1,r0,r4,r3,r2);
+ LINTRANS(r3,r0,r4,r1,r2);
+
+ /* round 11 */
+ KEYMIX(r3,r0,r4,r1,r2,40);
+ S2(r3,r0,r4,r1,r2);
+ LINTRANS(r4,r1,r0,r2,r3);
+
+ /* round 12 */
+ KEYMIX(r4,r1,r0,r2,r3,44);
+ S3(r4,r1,r0,r2,r3);
+ LINTRANS(r1,r0,r2,r3,r4);
+
+ /* round 13 */
+ KEYMIX(r1,r0,r2,r3,r4,48);
+ S4(r1,r0,r2,r3,r4)
+ LINTRANS(r0,r4,r1,r3,r2);
+
+ /* round 14 */
+ KEYMIX(r0,r4,r1,r3,r2,52);
+ S5(r0,r4,r1,r3,r2);
+ LINTRANS(r4,r3,r0,r1,r2);
+
+ /* round 15 */
+ KEYMIX(r4,r3,r0,r1,r2,56);
+ S6(r4,r3,r0,r1,r2)
+ LINTRANS(r4,r3,r2,r0,r1);
+
+ /* round 16 */
+ KEYMIX(r4,r3,r2,r0,r1,60);
+ S7(r4,r3,r2,r0,r1);
+ LINTRANS(r2,r1,r0,r4,r3);
+
+ /* round 17 */
+ KEYMIX(r2,r1,r0,r4,r3,64);
+ S0(r2,r1,r0,r4,r3);
+ LINTRANS(r1,r3,r0,r2,r4);
+
+ /* round 18 */
+ KEYMIX(r1,r3,r0,r2,r4,68);
+ S1(r1,r3,r0,r2,r4);
+ LINTRANS(r2,r3,r0,r1,r4);
+
+ /* round 19 */
+ KEYMIX(r2,r3,r0,r1,r4,72);
+ S2(r2,r3,r0,r1,r4);
+ LINTRANS(r0,r1,r3,r4,r2);
+
+ /* round 20 */
+ KEYMIX(r0,r1,r3,r4,r2,76);
+ S3(r0,r1,r3,r4,r2);
+ LINTRANS(r1,r3,r4,r2,r0);
+
+ /* round 21 */
+ KEYMIX(r1,r3,r4,r2,r0,80);
+ S4(r1,r3,r4,r2,r0)
+ LINTRANS(r3,r0,r1,r2,r4);
+
+ /* round 22 */
+ KEYMIX(r3,r0,r1,r2,r4,84);
+ S5(r3,r0,r1,r2,r4);
+ LINTRANS(r0,r2,r3,r1,r4);
+
+ /* round 23 */
+ KEYMIX(r0,r2,r3,r1,r4,88);
+ S6(r0,r2,r3,r1,r4)
+ LINTRANS(r0,r2,r4,r3,r1);
+
+ /* round 24 */
+ KEYMIX(r0,r2,r4,r3,r1,92);
+ S7(r0,r2,r4,r3,r1);
+ LINTRANS(r4,r1,r3,r0,r2);
+
+ /* round 25 */
+ KEYMIX(r4,r1,r3,r0,r2,96);
+ S0(r4,r1,r3,r0,r2);
+ LINTRANS(r1,r2,r3,r4,r0);
+
+ /* round 26 */
+ KEYMIX(r1,r2,r3,r4,r0,100);
+ S1(r1,r2,r3,r4,r0);
+ LINTRANS(r4,r2,r3,r1,r0);
+
+ /* round 27 */
+ KEYMIX(r4,r2,r3,r1,r0,104);
+ S2(r4,r2,r3,r1,r0);
+ LINTRANS(r3,r1,r2,r0,r4);
+
+ /* round 28 */
+ KEYMIX(r3,r1,r2,r0,r4,108);
+ S3(r3,r1,r2,r0,r4);
+ LINTRANS(r1,r2,r0,r4,r3);
+
+ /* round 29 */
+ KEYMIX(r1,r2,r0,r4,r3,112);
+ S4(r1,r2,r0,r4,r3)
+ LINTRANS(r2,r3,r1,r4,r0);
+
+ /* round 30 */
+ KEYMIX(r2,r3,r1,r4,r0,116);
+ S5(r2,r3,r1,r4,r0);
+ LINTRANS(r3,r4,r2,r1,r0);
+
+ /* round 31 */
+ KEYMIX(r3,r4,r2,r1,r0,120);
+ S6(r3,r4,r2,r1,r0)
+ LINTRANS(r3,r4,r0,r2,r1);
+
+ /* round 32 */
+ KEYMIX(r3,r4,r0,r2,r1,124);
+ S7(r3,r4,r0,r2,r1);
+ KEYMIX(r0,r1,r2,r3,r4,128);
+
+
+#ifdef BLOCK_SWAP
+ out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1);
+ out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
+#else
+ out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
+#endif
+ return 0;
+};
+
+/* decrypt a block of text */
+
+int serpent_decrypt(serpent_context *cx, const u8 *in,
+ u8 *out)
+{ u32 *l_key = cx->keyinfo;
+ const u32 *in_blk = (const u32 *)in;
+ u32 *out_blk = (u32 *)out;
+ u32 r0,r1,r2,r3,r4;
+
+#ifdef BLOCK_SWAP
+ r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]);
+ r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]);
+#else
+ r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3];
+#endif
+
+ /* round 1 */
+ KEYMIX(r0,r1,r2,r3,r4,128);
+ I7(r0,r1,r2,r3,r4);
+ KEYMIX(r3,r0,r1,r4,r2,124);
+
+ /* round 2 */
+ ILINTRANS(r3,r0,r1,r4,r2);
+ I6(r3,r0,r1,r4,r2);
+ KEYMIX(r0,r1,r2,r4,r3,120);
+
+ /* round 3 */
+ ILINTRANS(r0,r1,r2,r4,r3);
+ I5(r0,r1,r2,r4,r3);
+ KEYMIX(r1,r3,r4,r2,r0,116);
+
+ /* round 4 */
+ ILINTRANS(r1,r3,r4,r2,r0);
+ I4(r1,r3,r4,r2,r0);
+ KEYMIX(r1,r2,r4,r0,r3,112);
+
+ /* round 5 */
+ ILINTRANS(r1,r2,r4,r0,r3);
+ I3(r1,r2,r4,r0,r3);
+ KEYMIX(r4,r2,r0,r1,r3,108);
+
+ /* round 6 */
+ ILINTRANS(r4,r2,r0,r1,r3);
+ I2(r4,r2,r0,r1,r3);
+ KEYMIX(r2,r3,r0,r1,r4,104);
+
+ /* round 7 */
+ ILINTRANS(r2,r3,r0,r1,r4);
+ I1(r2,r3,r0,r1,r4);
+ KEYMIX(r4,r2,r1,r0,r3,100);
+
+ /* round 8 */
+ ILINTRANS(r4,r2,r1,r0,r3);
+ I0(r4,r2,r1,r0,r3);
+ KEYMIX(r4,r3,r2,r0,r1,96);
+
+ /* round 9 */
+ ILINTRANS(r4,r3,r2,r0,r1);
+ I7(r4,r3,r2,r0,r1);
+ KEYMIX(r0,r4,r3,r1,r2,92);
+
+ /* round 10 */
+ ILINTRANS(r0,r4,r3,r1,r2);
+ I6(r0,r4,r3,r1,r2);
+ KEYMIX(r4,r3,r2,r1,r0,88);
+
+ /* round 11 */
+ ILINTRANS(r4,r3,r2,r1,r0);
+ I5(r4,r3,r2,r1,r0);
+ KEYMIX(r3,r0,r1,r2,r4,84);
+
+ /* round 12 */
+ ILINTRANS(r3,r0,r1,r2,r4);
+ I4(r3,r0,r1,r2,r4);
+ KEYMIX(r3,r2,r1,r4,r0,80);
+
+ /* round 13 */
+ ILINTRANS(r3,r2,r1,r4,r0);
+ I3(r3,r2,r1,r4,r0);
+ KEYMIX(r1,r2,r4,r3,r0,76);
+
+ /* round 14 */
+ ILINTRANS(r1,r2,r4,r3,r0);
+ I2(r1,r2,r4,r3,r0);
+ KEYMIX(r2,r0,r4,r3,r1,72);
+
+ /* round 15 */
+ ILINTRANS(r2,r0,r4,r3,r1);
+ I1(r2,r0,r4,r3,r1);
+ KEYMIX(r1,r2,r3,r4,r0,68);
+
+ /* round 16 */
+ ILINTRANS(r1,r2,r3,r4,r0);
+ I0(r1,r2,r3,r4,r0);
+ KEYMIX(r1,r0,r2,r4,r3,64);
+
+ /* round 17 */
+ ILINTRANS(r1,r0,r2,r4,r3);
+ I7(r1,r0,r2,r4,r3);
+ KEYMIX(r4,r1,r0,r3,r2,60);
+
+ /* round 18 */
+ ILINTRANS(r4,r1,r0,r3,r2);
+ I6(r4,r1,r0,r3,r2);
+ KEYMIX(r1,r0,r2,r3,r4,56);
+
+ /* round 19 */
+ ILINTRANS(r1,r0,r2,r3,r4);
+ I5(r1,r0,r2,r3,r4);
+ KEYMIX(r0,r4,r3,r2,r1,52);
+
+ /* round 20 */
+ ILINTRANS(r0,r4,r3,r2,r1);
+ I4(r0,r4,r3,r2,r1);
+ KEYMIX(r0,r2,r3,r1,r4,48);
+
+ /* round 21 */
+ ILINTRANS(r0,r2,r3,r1,r4);
+ I3(r0,r2,r3,r1,r4);
+ KEYMIX(r3,r2,r1,r0,r4,44);
+
+ /* round 22 */
+ ILINTRANS(r3,r2,r1,r0,r4);
+ I2(r3,r2,r1,r0,r4);
+ KEYMIX(r2,r4,r1,r0,r3,40);
+
+ /* round 23 */
+ ILINTRANS(r2,r4,r1,r0,r3);
+ I1(r2,r4,r1,r0,r3);
+ KEYMIX(r3,r2,r0,r1,r4,36);
+
+ /* round 24 */
+ ILINTRANS(r3,r2,r0,r1,r4);
+ I0(r3,r2,r0,r1,r4);
+ KEYMIX(r3,r4,r2,r1,r0,32);
+
+ /* round 25 */
+ ILINTRANS(r3,r4,r2,r1,r0);
+ I7(r3,r4,r2,r1,r0);
+ KEYMIX(r1,r3,r4,r0,r2,28);
+
+ /* round 26 */
+ ILINTRANS(r1,r3,r4,r0,r2);
+ I6(r1,r3,r4,r0,r2);
+ KEYMIX(r3,r4,r2,r0,r1,24);
+
+ /* round 27 */
+ ILINTRANS(r3,r4,r2,r0,r1);
+ I5(r3,r4,r2,r0,r1);
+ KEYMIX(r4,r1,r0,r2,r3,20);
+
+ /* round 28 */
+ ILINTRANS(r4,r1,r0,r2,r3);
+ I4(r4,r1,r0,r2,r3);
+ KEYMIX(r4,r2,r0,r3,r1,16);
+
+ /* round 29 */
+ ILINTRANS(r4,r2,r0,r3,r1);
+ I3(r4,r2,r0,r3,r1);
+ KEYMIX(r0,r2,r3,r4,r1,12);
+
+ /* round 30 */
+ ILINTRANS(r0,r2,r3,r4,r1);
+ I2(r0,r2,r3,r4,r1);
+ KEYMIX(r2,r1,r3,r4,r0,8);
+
+ /* round 31 */
+ ILINTRANS(r2,r1,r3,r4,r0);
+ I1(r2,r1,r3,r4,r0);
+ KEYMIX(r0,r2,r4,r3,r1,4);
+
+ /* round 32 */
+ ILINTRANS(r0,r2,r4,r3,r1);
+ I0(r0,r2,r4,r3,r1);
+ KEYMIX(r0,r1,r2,r3,r4,0);
+
+#ifdef BLOCK_SWAP
+ out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1);
+ out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3);
+#else
+ out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3;
+#endif
+ return 0;
+};
+
+
diff --git a/src/libfreeswan/libcrypto/libserpent/serpent.h b/src/libfreeswan/libcrypto/libserpent/serpent.h
new file mode 100644
index 000000000..6357f5bfa
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libserpent/serpent.h
@@ -0,0 +1,17 @@
+#ifndef SERPENT_H
+#define SERPENT_H
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#define u32 u_int32_t
+#define u8 u_int8_t
+#endif
+struct serpent_context {
+ u32 keyinfo[140]; /* storage for the key schedule */
+};
+typedef struct serpent_context serpent_context;
+int serpent_set_key(serpent_context *ctx, const u8 * in_key, int key_len);
+int serpent_decrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk);
+int serpent_encrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk);
+#endif /* SERPENT_H */
diff --git a/src/libfreeswan/libcrypto/libserpent/serpent_cbc.c b/src/libfreeswan/libcrypto/libserpent/serpent_cbc.c
new file mode 100644
index 000000000..3b546278a
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libserpent/serpent_cbc.c
@@ -0,0 +1,8 @@
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#include "serpent_cbc.h"
+#include "cbc_generic.h"
+CBC_IMPL_BLK16(serpent_cbc_encrypt, serpent_context, u_int8_t *, serpent_encrypt, serpent_decrypt);
diff --git a/src/libfreeswan/libcrypto/libserpent/serpent_cbc.h b/src/libfreeswan/libcrypto/libserpent/serpent_cbc.h
new file mode 100644
index 000000000..3064fa3bc
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libserpent/serpent_cbc.h
@@ -0,0 +1,3 @@
+/* Glue header */
+#include "serpent.h"
+int serpent_cbc_encrypt(serpent_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
diff --git a/src/libfreeswan/libcrypto/libserpent/test_main.c b/src/libfreeswan/libcrypto/libserpent/test_main.c
new file mode 100644
index 000000000..350068e60
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libserpent/test_main.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+#include "serpent_cbc.h"
+#define BLOCK_SIZE 16
+#define KEY_SIZE 128 /* bits */
+#define KEY "1234567890123456"
+#define STR "hola guaso como estaisss ... 012"
+#define STRSZ (sizeof(STR)-1)
+
+#define BLKLEN BLOCK_SIZE
+#define CONTEXT_T serpent_context
+static int pretty_print(const unsigned char *buf, int count) {
+ int i=0;
+ for (;i<count;i++) printf ("%02hhx ", buf[i]);
+ putchar('\n');
+ return i;
+}
+//#define SIZE STRSZ/2
+#define SIZE STRSZ
+int main() {
+ int ret;
+ char buf0[SIZE+1], buf1[SIZE+1];
+ char IV[BLOCK_SIZE];
+ CONTEXT_T ac;
+ serpent_set_key(&ac, (void *)KEY, KEY_SIZE);
+ memset(buf0, 0, sizeof (buf0));
+ memset(buf1, 0, sizeof (buf1));
+ serpent_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
+ pretty_print(buf0, SIZE);
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
+ ret=serpent_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
+ return 0;
+}
diff --git a/src/libfreeswan/libcrypto/libsha2/Makefile b/src/libfreeswan/libcrypto/libsha2/Makefile
new file mode 100644
index 000000000..cee7e6109
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libsha2/Makefile
@@ -0,0 +1,21 @@
+CFLAGS=-O3 -fomit-frame-pointer -I../include $(EXTRA_CFLAGS)
+
+LIBOBJ := hmac_sha2.o sha2.o
+
+BLIB := libsha2.a
+
+.S.o:
+ $(CC) $(AFLAGS) -c $< -o $@
+
+$(BLIB): $(LIBOBJ)
+ /bin/rm -f $(BLIB)
+ ar cr $(BLIB) $(LIBOBJ)
+ -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \
+ else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \
+ else exit 0; fi; fi
+
+test: test_main.o $(BLIB)
+ $(CC) -o $@ $^
+
+clean:
+ rm -f *.[oa] core $(TARGET) test
diff --git a/src/libfreeswan/libcrypto/libsha2/hmac_sha2.c b/src/libfreeswan/libcrypto/libsha2/hmac_sha2.c
new file mode 100644
index 000000000..ad107eb62
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libsha2/hmac_sha2.c
@@ -0,0 +1,32 @@
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/string.h>
+#else
+#include <sys/types.h>
+#include <string.h>
+#endif
+#include "hmac_generic.h"
+#include "sha2.h"
+#include "hmac_sha2.h"
+
+void inline sha256_result(sha256_context *ctx, u_int8_t * hash, int hashlen) {
+ sha256_final(ctx);
+ memcpy(hash, &ctx->sha_out[0], hashlen);
+}
+void inline sha512_result(sha512_context *ctx, u_int8_t * hash, int hashlen) {
+ sha512_final(ctx);
+ memcpy(hash, &ctx->sha_out[0], hashlen);
+}
+HMAC_SET_KEY_IMPL (sha256_hmac_set_key,
+ sha256_hmac_context, SHA256_BLOCKSIZE,
+ sha256_init, sha256_write)
+HMAC_HASH_IMPL (sha256_hmac_hash,
+ sha256_hmac_context, sha256_context, SHA256_HASHLEN,
+ sha256_write, sha256_result)
+
+HMAC_SET_KEY_IMPL (sha512_hmac_set_key,
+ sha512_hmac_context, SHA512_BLOCKSIZE,
+ sha512_init, sha512_write)
+HMAC_HASH_IMPL (sha512_hmac_hash,
+ sha512_hmac_context, sha512_context, SHA512_HASHLEN,
+ sha512_write, sha512_result)
diff --git a/src/libfreeswan/libcrypto/libsha2/hmac_sha2.h b/src/libfreeswan/libcrypto/libsha2/hmac_sha2.h
new file mode 100644
index 000000000..b7f8c747c
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libsha2/hmac_sha2.h
@@ -0,0 +1,17 @@
+typedef struct {
+ sha256_context ictx,octx;
+} sha256_hmac_context;
+typedef struct {
+ sha512_context ictx,octx;
+} sha512_hmac_context;
+#define SHA256_BLOCKSIZE 64
+#define SHA256_HASHLEN 32
+#define SHA384_BLOCKSIZE 128 /* XXX ok? */
+#define SHA384_HASHLEN 48
+#define SHA512_BLOCKSIZE 128
+#define SHA512_HASHLEN 64
+
+void sha256_hmac_hash(sha256_hmac_context *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen);
+void sha256_hmac_set_key(sha256_hmac_context *hctx, const u_int8_t * key, int keylen);
+void sha512_hmac_hash(sha512_hmac_context *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen);
+void sha512_hmac_set_key(sha512_hmac_context *hctx, const u_int8_t * key, int keylen);
diff --git a/src/libfreeswan/libcrypto/libsha2/sha2.c b/src/libfreeswan/libcrypto/libsha2/sha2.c
new file mode 100644
index 000000000..4debdad67
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libsha2/sha2.c
@@ -0,0 +1,437 @@
+/*
+ * sha512.c
+ *
+ * Written by Jari Ruusu, April 16 2001
+ *
+ * Copyright 2001 by Jari Ruusu.
+ * Redistribution of this file is permitted under the GNU Public License.
+ */
+
+#ifdef __KERNEL__
+#include <linux/string.h>
+#include <linux/types.h>
+#else
+#include <string.h>
+#include <sys/types.h>
+#endif
+#include "sha2.h"
+
+/* Define one or more of these. If none is defined, you get all of them */
+#if !defined(SHA256_NEEDED)&&!defined(SHA512_NEEDED)&&!defined(SHA384_NEEDED)
+# define SHA256_NEEDED 1
+# define SHA512_NEEDED 1
+# define SHA384_NEEDED 1
+#endif
+
+#if defined(SHA256_NEEDED)
+static const u_int32_t sha256_hashInit[8] = {
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
+ 0x1f83d9ab, 0x5be0cd19
+};
+static const u_int32_t sha256_K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
+ 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
+ 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
+ 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
+ 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+};
+#endif
+
+#if defined(SHA512_NEEDED)
+static const u_int64_t sha512_hashInit[8] = {
+ 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
+ 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
+ 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
+};
+#endif
+
+#if defined(SHA384_NEEDED)
+static const u_int64_t sha384_hashInit[8] = {
+ 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
+ 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
+};
+#endif
+
+#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
+static const u_int64_t sha512_K[80] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
+ 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
+ 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
+ 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
+ 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
+ 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
+ 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
+ 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
+ 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
+ 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
+ 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
+ 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
+ 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
+ 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
+ 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
+ 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
+ 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
+ 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
+ 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
+ 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
+ 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
+ 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+};
+#endif
+
+#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+#define R(x,y) ((y) >> (x))
+
+#if defined(SHA256_NEEDED)
+void sha256_init(sha256_context *ctx)
+{
+ memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
+ ctx->sha_blocks = 0;
+ ctx->sha_bufCnt = 0;
+}
+
+#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
+#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
+#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
+#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
+#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
+
+static void sha256_transform(sha256_context *ctx, const unsigned char *datap)
+{
+ register int j;
+ u_int32_t a, b, c, d, e, f, g, h;
+ u_int32_t T1, T2, W[64], Wm2, Wm15;
+
+ /* read the data, big endian byte order */
+ j = 0;
+ do {
+ W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
+ (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
+ datap += 4;
+ } while(++j < 16);
+
+ /* initialize variables a...h */
+ a = ctx->sha_H[0];
+ b = ctx->sha_H[1];
+ c = ctx->sha_H[2];
+ d = ctx->sha_H[3];
+ e = ctx->sha_H[4];
+ f = ctx->sha_H[5];
+ g = ctx->sha_H[6];
+ h = ctx->sha_H[7];
+
+ /* apply compression function */
+ j = 0;
+ do {
+ if(j >= 16) {
+ Wm2 = W[j - 2];
+ Wm15 = W[j - 15];
+ W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
+ }
+ T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
+ T2 = uSig0(a) + Maj(a,b,c);
+ h = g; g = f; f = e;
+ e = d + T1;
+ d = c; c = b; b = a;
+ a = T1 + T2;
+ } while(++j < 64);
+
+ /* compute intermediate hash value */
+ ctx->sha_H[0] += a;
+ ctx->sha_H[1] += b;
+ ctx->sha_H[2] += c;
+ ctx->sha_H[3] += d;
+ ctx->sha_H[4] += e;
+ ctx->sha_H[5] += f;
+ ctx->sha_H[6] += g;
+ ctx->sha_H[7] += h;
+
+ ctx->sha_blocks++;
+}
+
+void sha256_write(sha256_context *ctx, const unsigned char *datap, int length)
+{
+ while(length > 0) {
+ if(!ctx->sha_bufCnt) {
+ while(length >= sizeof(ctx->sha_out)) {
+ sha256_transform(ctx, datap);
+ datap += sizeof(ctx->sha_out);
+ length -= sizeof(ctx->sha_out);
+ }
+ if(!length) return;
+ }
+ ctx->sha_out[ctx->sha_bufCnt] = *datap++;
+ length--;
+ if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
+ sha256_transform(ctx, &ctx->sha_out[0]);
+ ctx->sha_bufCnt = 0;
+ }
+ }
+}
+
+void sha256_final(sha256_context *ctx)
+{
+ register int j;
+ u_int64_t bitLength;
+ u_int32_t i;
+ unsigned char padByte, *datap;
+
+ bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
+ padByte = 0x80;
+ sha256_write(ctx, &padByte, 1);
+
+ /* pad extra space with zeroes */
+ padByte = 0;
+ while(ctx->sha_bufCnt != 56) {
+ sha256_write(ctx, &padByte, 1);
+ }
+
+ /* write bit length, big endian byte order */
+ ctx->sha_out[56] = bitLength >> 56;
+ ctx->sha_out[57] = bitLength >> 48;
+ ctx->sha_out[58] = bitLength >> 40;
+ ctx->sha_out[59] = bitLength >> 32;
+ ctx->sha_out[60] = bitLength >> 24;
+ ctx->sha_out[61] = bitLength >> 16;
+ ctx->sha_out[62] = bitLength >> 8;
+ ctx->sha_out[63] = bitLength;
+ sha256_transform(ctx, &ctx->sha_out[0]);
+
+ /* return results in ctx->sha_out[0...31] */
+ datap = &ctx->sha_out[0];
+ j = 0;
+ do {
+ i = ctx->sha_H[j];
+ datap[0] = i >> 24;
+ datap[1] = i >> 16;
+ datap[2] = i >> 8;
+ datap[3] = i;
+ datap += 4;
+ } while(++j < 8);
+
+ /* clear sensitive information */
+ memset(&ctx->sha_out[32], 0, sizeof(sha256_context) - 32);
+}
+
+void sha256_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
+{
+ sha256_context ctx;
+
+ if(ole < 1) return;
+ memset(ob, 0, ole);
+ if(ole > 32) ole = 32;
+ sha256_init(&ctx);
+ sha256_write(&ctx, ib, ile);
+ sha256_final(&ctx);
+ memcpy(ob, &ctx.sha_out[0], ole);
+ memset(&ctx, 0, sizeof(ctx));
+}
+
+#endif
+
+#if defined(SHA512_NEEDED)
+void sha512_init(sha512_context *ctx)
+{
+ memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
+ ctx->sha_blocks = 0;
+ ctx->sha_blocksMSB = 0;
+ ctx->sha_bufCnt = 0;
+}
+#endif
+
+#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED)
+#undef S
+#undef uSig0
+#undef uSig1
+#undef lSig0
+#undef lSig1
+#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
+#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
+#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
+#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
+#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
+
+static void sha512_transform(sha512_context *ctx, const unsigned char *datap)
+{
+ register int j;
+ u_int64_t a, b, c, d, e, f, g, h;
+ u_int64_t T1, T2, W[80], Wm2, Wm15;
+
+ /* read the data, big endian byte order */
+ j = 0;
+ do {
+ W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
+ (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
+ (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
+ (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
+ datap += 8;
+ } while(++j < 16);
+
+ /* initialize variables a...h */
+ a = ctx->sha_H[0];
+ b = ctx->sha_H[1];
+ c = ctx->sha_H[2];
+ d = ctx->sha_H[3];
+ e = ctx->sha_H[4];
+ f = ctx->sha_H[5];
+ g = ctx->sha_H[6];
+ h = ctx->sha_H[7];
+
+ /* apply compression function */
+ j = 0;
+ do {
+ if(j >= 16) {
+ Wm2 = W[j - 2];
+ Wm15 = W[j - 15];
+ W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
+ }
+ T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
+ T2 = uSig0(a) + Maj(a,b,c);
+ h = g; g = f; f = e;
+ e = d + T1;
+ d = c; c = b; b = a;
+ a = T1 + T2;
+ } while(++j < 80);
+
+ /* compute intermediate hash value */
+ ctx->sha_H[0] += a;
+ ctx->sha_H[1] += b;
+ ctx->sha_H[2] += c;
+ ctx->sha_H[3] += d;
+ ctx->sha_H[4] += e;
+ ctx->sha_H[5] += f;
+ ctx->sha_H[6] += g;
+ ctx->sha_H[7] += h;
+
+ ctx->sha_blocks++;
+ if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
+}
+
+void sha512_write(sha512_context *ctx, const unsigned char *datap, int length)
+{
+ while(length > 0) {
+ if(!ctx->sha_bufCnt) {
+ while(length >= sizeof(ctx->sha_out)) {
+ sha512_transform(ctx, datap);
+ datap += sizeof(ctx->sha_out);
+ length -= sizeof(ctx->sha_out);
+ }
+ if(!length) return;
+ }
+ ctx->sha_out[ctx->sha_bufCnt] = *datap++;
+ length--;
+ if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) {
+ sha512_transform(ctx, &ctx->sha_out[0]);
+ ctx->sha_bufCnt = 0;
+ }
+ }
+}
+
+void sha512_final(sha512_context *ctx)
+{
+ register int j;
+ u_int64_t bitLength, bitLengthMSB;
+ u_int64_t i;
+ unsigned char padByte, *datap;
+
+ bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
+ bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
+ padByte = 0x80;
+ sha512_write(ctx, &padByte, 1);
+
+ /* pad extra space with zeroes */
+ padByte = 0;
+ while(ctx->sha_bufCnt != 112) {
+ sha512_write(ctx, &padByte, 1);
+ }
+
+ /* write bit length, big endian byte order */
+ ctx->sha_out[112] = bitLengthMSB >> 56;
+ ctx->sha_out[113] = bitLengthMSB >> 48;
+ ctx->sha_out[114] = bitLengthMSB >> 40;
+ ctx->sha_out[115] = bitLengthMSB >> 32;
+ ctx->sha_out[116] = bitLengthMSB >> 24;
+ ctx->sha_out[117] = bitLengthMSB >> 16;
+ ctx->sha_out[118] = bitLengthMSB >> 8;
+ ctx->sha_out[119] = bitLengthMSB;
+ ctx->sha_out[120] = bitLength >> 56;
+ ctx->sha_out[121] = bitLength >> 48;
+ ctx->sha_out[122] = bitLength >> 40;
+ ctx->sha_out[123] = bitLength >> 32;
+ ctx->sha_out[124] = bitLength >> 24;
+ ctx->sha_out[125] = bitLength >> 16;
+ ctx->sha_out[126] = bitLength >> 8;
+ ctx->sha_out[127] = bitLength;
+ sha512_transform(ctx, &ctx->sha_out[0]);
+
+ /* return results in ctx->sha_out[0...63] */
+ datap = &ctx->sha_out[0];
+ j = 0;
+ do {
+ i = ctx->sha_H[j];
+ datap[0] = i >> 56;
+ datap[1] = i >> 48;
+ datap[2] = i >> 40;
+ datap[3] = i >> 32;
+ datap[4] = i >> 24;
+ datap[5] = i >> 16;
+ datap[6] = i >> 8;
+ datap[7] = i;
+ datap += 8;
+ } while(++j < 8);
+
+ /* clear sensitive information */
+ memset(&ctx->sha_out[64], 0, sizeof(sha512_context) - 64);
+}
+
+void sha512_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
+{
+ sha512_context ctx;
+
+ if(ole < 1) return;
+ memset(ob, 0, ole);
+ if(ole > 64) ole = 64;
+ sha512_init(&ctx);
+ sha512_write(&ctx, ib, ile);
+ sha512_final(&ctx);
+ memcpy(ob, &ctx.sha_out[0], ole);
+ memset(&ctx, 0, sizeof(ctx));
+}
+#endif
+
+#if defined(SHA384_NEEDED)
+void sha384_init(sha512_context *ctx)
+{
+ memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
+ ctx->sha_blocks = 0;
+ ctx->sha_blocksMSB = 0;
+ ctx->sha_bufCnt = 0;
+}
+
+void sha384_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole)
+{
+ sha512_context ctx;
+
+ if(ole < 1) return;
+ memset(ob, 0, ole);
+ if(ole > 48) ole = 48;
+ sha384_init(&ctx);
+ sha512_write(&ctx, ib, ile);
+ sha512_final(&ctx);
+ memcpy(ob, &ctx.sha_out[0], ole);
+ memset(&ctx, 0, sizeof(ctx));
+}
+#endif
diff --git a/src/libfreeswan/libcrypto/libsha2/sha2.h b/src/libfreeswan/libcrypto/libsha2/sha2.h
new file mode 100644
index 000000000..2dc03cfa8
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libsha2/sha2.h
@@ -0,0 +1,52 @@
+#ifndef _SHA2_H
+#define _SHA2_H
+/*
+ * sha512.h
+ *
+ * Written by Jari Ruusu, April 16 2001
+ *
+ * Copyright 2001 by Jari Ruusu.
+ * Redistribution of this file is permitted under the GNU Public License.
+ */
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+
+typedef struct {
+ unsigned char sha_out[64]; /* results are here, bytes 0...31 */
+ u_int32_t sha_H[8];
+ u_int64_t sha_blocks;
+ int sha_bufCnt;
+} sha256_context;
+
+typedef struct {
+ unsigned char sha_out[128]; /* results are here, bytes 0...63 */
+ u_int64_t sha_H[8];
+ u_int64_t sha_blocks;
+ u_int64_t sha_blocksMSB;
+ int sha_bufCnt;
+} sha512_context;
+
+/* no sha384_context, use sha512_context */
+
+/* 256 bit hash, provides 128 bits of security against collision attacks */
+extern void sha256_init(sha256_context *);
+extern void sha256_write(sha256_context *, const unsigned char *, int);
+extern void sha256_final(sha256_context *);
+extern void sha256_hash_buffer(unsigned char *, int, unsigned char *, int);
+
+/* 512 bit hash, provides 256 bits of security against collision attacks */
+extern void sha512_init(sha512_context *);
+extern void sha512_write(sha512_context *, const unsigned char *, int);
+extern void sha512_final(sha512_context *);
+extern void sha512_hash_buffer(unsigned char *, int, unsigned char *, int);
+
+/* 384 bit hash, provides 192 bits of security against collision attacks */
+extern void sha384_init(sha512_context *);
+/* no sha384_write(), use sha512_write() */
+/* no sha384_final(), use sha512_final(), result in ctx->sha_out[0...47] */
+extern void sha384_hash_buffer(unsigned char *, int, unsigned char *, int);
+#endif /* _SHA2_H */
diff --git a/src/libfreeswan/libcrypto/libtwofish/Makefile b/src/libfreeswan/libcrypto/libtwofish/Makefile
new file mode 100644
index 000000000..714fd6115
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libtwofish/Makefile
@@ -0,0 +1,21 @@
+CFLAGS=-O3 -fomit-frame-pointer -D__KERNEL__ -Wall $(EXTRA_CFLAGS)
+INC=-I../include
+
+LIBOBJ=twofish.o twofish_cbc.o
+BLIB=libtwofish.a
+
+.c.o:
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@
+
+$(BLIB): $(LIBOBJ)
+ /bin/rm -f $(BLIB)
+ ar cr $(BLIB) $(LIBOBJ)
+ -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \
+ else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \
+ else exit 0; fi; fi
+
+test: test_main.o $(BLIB)
+ $(CC) -o $@ $^
+
+clean:
+ rm -f *.[oa] core $(TARGET) test
diff --git a/src/libfreeswan/libcrypto/libtwofish/test_main.c b/src/libfreeswan/libcrypto/libtwofish/test_main.c
new file mode 100644
index 000000000..1e8b0db56
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libtwofish/test_main.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+#include "twofish_cbc.h"
+#define BLOCK_SIZE 16
+#define KEY_SIZE 128 /* bits */
+#define KEY "1234567890123456"
+#define STR "hola guaso como estaisss ... 012"
+#define STRSZ (sizeof(STR)-1)
+
+#define BLKLEN BLOCK_SIZE
+#define CONTEXT_T twofish_context
+static int pretty_print(const unsigned char *buf, int count) {
+ int i=0;
+ for (;i<count;i++) printf ("%02hhx ", buf[i]);
+ putchar('\n');
+ return i;
+}
+//#define SIZE STRSZ/2
+#define SIZE STRSZ
+int main() {
+ int ret;
+ char buf0[SIZE+1], buf1[SIZE+1];
+ char IV[BLOCK_SIZE];
+ CONTEXT_T ac;
+ twofish_set_key(&ac, (void *)KEY, KEY_SIZE);
+ memset(buf0, 0, sizeof (buf0));
+ memset(buf1, 0, sizeof (buf1));
+ twofish_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
+ pretty_print(buf0, SIZE);
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
+ ret=twofish_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
+ return 0;
+}
diff --git a/src/libfreeswan/libcrypto/libtwofish/twofish.c b/src/libfreeswan/libcrypto/libtwofish/twofish.c
new file mode 100644
index 000000000..0e01a92d2
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libtwofish/twofish.c
@@ -0,0 +1,861 @@
+/* NOTE: This implementation has been changed from the original
+ * source. See ChangeLog for more information.
+ * Maintained by Marc Mutz <Marc@Mutz.com>
+ */
+
+/* Twofish for GPG
+ * By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ *
+ * The original author has disclaimed all copyright interest in this
+ * code and thus putting it in the public domain.
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ *
+ * Only the 128- and 256-bit key sizes are supported. This code is intended
+ * for GNU C on a 32-bit system, but it should work almost anywhere. Loops
+ * are unrolled, precomputation tables are used, etc., for maximum speed at
+ * some cost in memory consumption. */
+
+#ifdef __KERNEL__
+#include <linux/init.h>
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#define u8 u_int8_t
+#define u32 u_int32_t
+#endif
+
+#if 0 /* shouldn't this be #ifdef rotl32 ?
+ * Look at wordops.h: It includes asm/wordops.h.
+ * Anyway, we have to search in the macros for rot's,
+ * since they seem to be defined in a generic way. */
+#define rotl rotl32
+#define rotr rotr32
+#else
+#define rotl generic_rotl32
+#define rotr generic_rotr32
+#endif
+
+#include "twofish.h"
+/* The large precomputed tables for the Twofish cipher (twofish.c)
+ * Taken from the same source as twofish.c
+ * Marc Mutz <Marc@Mutz.com>
+ */
+
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const u8 q0[256] = {
+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+ 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+ 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+ 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+ 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+ 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+ 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+ 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+ 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+ 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+ 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+ 0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const u8 q1[256] = {
+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+ 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+ 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+ 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+ 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+ 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+ 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+ 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+ 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+ 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+ 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+ 0x55, 0x09, 0xBE, 0x91
+};
+
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing. Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs. Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+ {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+ 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+ 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+ 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+ 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+ 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+ 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+ 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+ 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+ 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+ 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+ 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+ 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+ 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+ 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+ 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+ 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+ 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+ 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+ 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+ 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+ 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+ 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+ 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+ 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+ 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+ 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+ 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+ 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+ 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+ 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+ 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+ 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+ 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+ 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+ 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+ 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+ 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+ 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+ 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+ 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+ 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+ 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+ {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+ 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+ 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+ 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+ 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+ 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+ 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+ 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+ 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+ 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+ 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+ 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+ 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+ 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+ 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+ 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+ 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+ 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+ 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+ 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+ 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+ 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+ 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+ 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+ 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+ 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+ 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+ 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+ 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+ 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+ 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+ 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+ 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+ 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+ 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+ 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+ 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+ 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+ 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+ 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+ 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+ 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+ 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+ {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+ 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+ 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+ 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+ 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+ 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+ 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+ 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+ 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+ 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+ 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+ 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+ 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+ 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+ 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+ 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+ 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+ 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+ 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+ 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+ 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+ 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+ 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+ 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+ 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+ 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+ 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+ 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+ 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+ 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+ 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+ 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+ 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+ 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+ 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+ 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+ 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+ 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+ 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+ 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+ 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+ 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+ 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+ {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+ 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+ 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+ 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+ 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+ 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+ 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+ 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+ 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+ 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+ 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+ 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+ 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+ 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+ 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+ 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+ 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+ 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+ 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+ 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+ 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+ 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+ 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+ 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+ 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+ 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+ 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+ 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+ 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+ 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+ 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+ 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+ 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+ 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+ 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+ 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+ 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+ 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+ 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+ 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+ 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+ 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+ 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule. Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2). In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support. To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation. So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ * 1. if p=0 or q=0 then pq=0
+ * 2. otherwise, find m and n such that p=x^m and q=x^n
+ * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
+ * in action, look at the CALC_S macro. As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper. I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491. I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch. I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const u8 poly_to_exp[255] = {
+ 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+ 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+ 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+ 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+ 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+ 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+ 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+ 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+ 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+ 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+ 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+ 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+ 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+ 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+ 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+ 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+ 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+ 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+ 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+ 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+ 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+ 0x85, 0xC8, 0xA1
+};
+
+static const u8 exp_to_poly[492] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+ 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+ 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+ 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+ 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+ 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+ 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+ 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+ 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+ 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+ 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+ 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+ 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+ 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+ 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+ 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+ 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+ 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+ 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+ 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+ 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+ 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+ 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+ 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+ 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+ 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+ 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+ 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+ 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+ 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+ 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+ 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+ 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+ 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+ 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+ 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+ 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+ 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+ 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+ 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static const u8 calc_sb_tbl[512] = {
+ 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+ 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+ 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+ 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+ 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+ 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+ 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+ 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+ 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+ 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+ 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+ 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+ 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+ 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+ 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+ 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+ 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+ 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+ 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+ 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+ 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+ 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+ 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+ 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+ 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+ 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+ 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+ 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+ 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+ 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+ 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+ 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+ 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+ 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+ 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+ 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+ 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+ 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+ 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+ 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+ 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+ 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+ 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+ 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+ 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+ 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+ 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+ 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+ 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+ 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+ 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+ 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+ 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+ 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+ 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+ 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+ 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+ 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+ 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+ 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+ 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+ 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+ 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+ 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+
+/* Macro to perform one column of the RS matrix multiplication. The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+ if (key[i]) { \
+ tmp = poly_to_exp[key[i] - 1]; \
+ (a) ^= exp_to_poly[tmp + (w)]; \
+ (b) ^= exp_to_poly[tmp + (x)]; \
+ (c) ^= exp_to_poly[tmp + (y)]; \
+ (d) ^= exp_to_poly[tmp + (z)]; \
+ }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S. CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively. */
+
+#define CALC_SB_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+ ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+ ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+ ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+/* Macro exactly like CALC_SB_2, but for 192-bit keys. */
+
+#define CALC_SB192_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \
+ ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \
+ ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \
+ ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl];
+
+/* Macro exactly like CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+ ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+ ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+ ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages. For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages. j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Psuedo-Hadamard Transform, and doing the necessary
+ * rotations. Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an
+ * additional lookup-and-XOR stage. The parameters a, b, c and d are the
+ * four bytes going into the last three stages. For 192-bit keys, c = d
+ * are the index preprocessed through q0, and a = b are the index
+ * preprocessed through q1; j is the index of the first key byte to use.
+ * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro
+ * instead of CALC_K_2.
+ * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an
+ * additional lookup-and-XOR stage. The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use. CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+ mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+ ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+ ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+ ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+ x = CALC_K_2 (k, l, k, l, 0); \
+ y = CALC_K_2 (m, n, m, n, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K192_2(a, b, c, d, j) \
+ CALC_K_2 (q0[a ^ key[(j) + 16]], \
+ q1[b ^ key[(j) + 17]], \
+ q0[c ^ key[(j) + 18]], \
+ q1[d ^ key[(j) + 19]], j)
+
+#define CALC_K192(a, j, k, l, m, n) \
+ x = CALC_K192_2 (l, l, k, k, 0); \
+ y = CALC_K192_2 (n, n, m, m, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+ CALC_K192_2 (q1[b ^ key[(j) + 24]], \
+ q1[a ^ key[(j) + 25]], \
+ q0[a ^ key[(j) + 26]], \
+ q0[b ^ key[(j) + 27]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+ x = CALC_K256_2 (k, l, 0); \
+ y = CALC_K256_2 (m, n, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+/* Perform the key setup. */
+
+int twofish_set_key (TWOFISH_context *ctx,
+ const unsigned char *key, int key_len)
+{
+
+ int i, j, k;
+
+ /* Temporaries for CALC_K. */
+ u32 x, y;
+
+ /* The S vector used to key the S-boxes, split up into individual bytes.
+ * 128-bit keys use only sa through sh; 256-bit use all of them. */
+ u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+ u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+ /* Temporary for CALC_S. */
+ u8 tmp;
+
+ /* Check key length. */
+ if (key_len != 16 && key_len != 24 && key_len != 32)
+ return -1; /* unsupported key length */
+
+ /* Compute the first two words of the S vector. The magic numbers are
+ * the entries of the RS matrix, preprocessed through poly_to_exp. The
+ * numbers in the comments are the original (polynomial form) matrix
+ * entries. */
+ CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+ CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+ if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */
+ /* Calculate the third word of the S vector */
+ CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+ }
+
+ if (key_len == 32) { /* 256-bit key */
+ /* Calculate the fourth word of the S vector */
+ CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+ /* Compute the S-boxes. */
+ for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+ CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ } else if (key_len == 24) { /* 192-bit key */
+ /* Compute the S-boxes. */
+ for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+ CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ } else { /* 128-bit key */
+ /* Compute the S-boxes. */
+ for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) {
+ CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ }
+
+ return 0;
+}
+
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds. G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+ (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+ ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+ (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+ ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds. Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations. The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+ x = G1 (a); y = G2 (b); \
+ x += y; y += x + ctx->k[2 * (n) + 1]; \
+ (c) ^= x + ctx->k[2 * (n)]; \
+ (c) = ((c) >> 1) + ((c) << 31); \
+ (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+ x = G1 (a); y = G2 (b); \
+ x += y; y += x; \
+ (d) ^= y + ctx->k[2 * (n) + 1]; \
+ (d) = ((d) >> 1) + ((d) << 31); \
+ (c) = (((c) << 1)+((c) >> 31)); \
+ (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+ ENCROUND (2 * (n), a, b, c, d); \
+ ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+ DECROUND (2 * (n) + 1, c, d, a, b); \
+ DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step. INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+ x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+ ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+ x ^= ctx->w[m]; \
+ out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+ out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+
+/* Encrypt one block. in and out may be the same. */
+
+int twofish_encrypt (TWOFISH_context *ctx,
+ const u8 *in, u8 *out)
+{
+ /* The four 32-bit chunks of the text. */
+ u32 a, b, c, d;
+
+ /* Temporaries used by the round function. */
+ u32 x, y;
+
+ /* Input whitening and packing. */
+ INPACK (0, a, 0);
+ INPACK (1, b, 1);
+ INPACK (2, c, 2);
+ INPACK (3, d, 3);
+
+ /* Encryption Feistel cycles. */
+ ENCCYCLE (0);
+ ENCCYCLE (1);
+ ENCCYCLE (2);
+ ENCCYCLE (3);
+ ENCCYCLE (4);
+ ENCCYCLE (5);
+ ENCCYCLE (6);
+ ENCCYCLE (7);
+
+ /* Output whitening and unpacking. */
+ OUTUNPACK (0, c, 4);
+ OUTUNPACK (1, d, 5);
+ OUTUNPACK (2, a, 6);
+ OUTUNPACK (3, b, 7);
+
+ return 0;
+}
+
+/* Decrypt one block. in and out may be the same. */
+
+int twofish_decrypt (TWOFISH_context *ctx,
+ const u8 *in, u8 *out)
+{
+ /* The four 32-bit chunks of the text. */
+ u32 a, b, c, d;
+
+ /* Temporaries used by the round function. */
+ u32 x, y;
+
+ /* Input whitening and packing. */
+ INPACK (0, c, 4);
+ INPACK (1, d, 5);
+ INPACK (2, a, 6);
+ INPACK (3, b, 7);
+
+ /* Encryption Feistel cycles. */
+ DECCYCLE (7);
+ DECCYCLE (6);
+ DECCYCLE (5);
+ DECCYCLE (4);
+ DECCYCLE (3);
+ DECCYCLE (2);
+ DECCYCLE (1);
+ DECCYCLE (0);
+
+ /* Output whitening and unpacking. */
+ OUTUNPACK (0, a, 0);
+ OUTUNPACK (1, b, 1);
+ OUTUNPACK (2, c, 2);
+ OUTUNPACK (3, d, 3);
+
+ return 0;
+}
+
+/* eof */
diff --git a/src/libfreeswan/libcrypto/libtwofish/twofish.h b/src/libfreeswan/libcrypto/libtwofish/twofish.h
new file mode 100644
index 000000000..9b289f265
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libtwofish/twofish.h
@@ -0,0 +1,20 @@
+#ifndef TWOFISH_H
+#define TWOFISH_H
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+/* Structure for an expanded Twofish key. s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+typedef struct {
+ u_int32_t s[4][256], w[8], k[32];
+} TWOFISH_context;
+
+typedef TWOFISH_context twofish_context;
+int twofish_set_key(twofish_context *tf_ctx, const u_int8_t * in_key, int key_len);
+int twofish_encrypt(twofish_context *tf_ctx, const u_int8_t * in, u_int8_t * out);
+int twofish_decrypt(twofish_context * tf_ctx, const u_int8_t * in, u_int8_t * out);
+#endif /* TWOFISH_H */
diff --git a/src/libfreeswan/libcrypto/libtwofish/twofish_cbc.c b/src/libfreeswan/libcrypto/libtwofish/twofish_cbc.c
new file mode 100644
index 000000000..6e5cf9025
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libtwofish/twofish_cbc.c
@@ -0,0 +1,8 @@
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+#include "twofish_cbc.h"
+#include "cbc_generic.h"
+CBC_IMPL_BLK16(twofish_cbc_encrypt, twofish_context, u_int8_t *, twofish_encrypt, twofish_decrypt);
diff --git a/src/libfreeswan/libcrypto/libtwofish/twofish_cbc.h b/src/libfreeswan/libcrypto/libtwofish/twofish_cbc.h
new file mode 100644
index 000000000..9fdea3526
--- /dev/null
+++ b/src/libfreeswan/libcrypto/libtwofish/twofish_cbc.h
@@ -0,0 +1,3 @@
+/* Glue header */
+#include "twofish.h"
+int twofish_cbc_encrypt(twofish_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t* iv, int encrypt);
diff --git a/src/libfreeswan/libcrypto/perlasm/LICENSE b/src/libfreeswan/libcrypto/perlasm/LICENSE
new file mode 100644
index 000000000..3fd259ac3
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/LICENSE
@@ -0,0 +1,127 @@
+
+ LICENSE ISSUES
+ ==============
+
+ The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts. Actually both licenses are BSD-style
+ Open Source licenses. In case of any license issues related to OpenSSL
+ please contact openssl-core@openssl.org.
+
+ OpenSSL License
+ ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
diff --git a/src/libfreeswan/libcrypto/perlasm/alpha.pl b/src/libfreeswan/libcrypto/perlasm/alpha.pl
new file mode 100644
index 000000000..fe69ca5a3
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/alpha.pl
@@ -0,0 +1,434 @@
+#!/usr/bin/perl
+
+package alpha;
+use Carp qw(croak cluck);
+
+$label="100";
+
+$n_debug=0;
+$smear_regs=1;
+$reg_alloc=1;
+
+$align="3";
+$com_start="#";
+
+sub main'asm_init_output { @out=(); }
+sub main'asm_get_output { return(@out); }
+sub main'get_labels { return(@labels); }
+sub main'external_label { push(@labels,@_); }
+
+# General registers
+
+%regs=( 'r0', '$0',
+ 'r1', '$1',
+ 'r2', '$2',
+ 'r3', '$3',
+ 'r4', '$4',
+ 'r5', '$5',
+ 'r6', '$6',
+ 'r7', '$7',
+ 'r8', '$8',
+ 'r9', '$22',
+ 'r10', '$23',
+ 'r11', '$24',
+ 'r12', '$25',
+ 'r13', '$27',
+ 'r14', '$28',
+ 'r15', '$21', # argc == 5
+ 'r16', '$20', # argc == 4
+ 'r17', '$19', # argc == 3
+ 'r18', '$18', # argc == 2
+ 'r19', '$17', # argc == 1
+ 'r20', '$16', # argc == 0
+ 'r21', '$9', # save 0
+ 'r22', '$10', # save 1
+ 'r23', '$11', # save 2
+ 'r24', '$12', # save 3
+ 'r25', '$13', # save 4
+ 'r26', '$14', # save 5
+
+ 'a0', '$16',
+ 'a1', '$17',
+ 'a2', '$18',
+ 'a3', '$19',
+ 'a4', '$20',
+ 'a5', '$21',
+
+ 's0', '$9',
+ 's1', '$10',
+ 's2', '$11',
+ 's3', '$12',
+ 's4', '$13',
+ 's5', '$14',
+ 'zero', '$31',
+ 'sp', '$30',
+ );
+
+$main'reg_s0="r21";
+$main'reg_s1="r22";
+$main'reg_s2="r23";
+$main'reg_s3="r24";
+$main'reg_s4="r25";
+$main'reg_s5="r26";
+
+@reg=( '$0', '$1' ,'$2' ,'$3' ,'$4' ,'$5' ,'$6' ,'$7' ,'$8',
+ '$22','$23','$24','$25','$20','$21','$27','$28');
+
+
+sub main'sub { &out3("subq",@_); }
+sub main'add { &out3("addq",@_); }
+sub main'mov { &out3("bis",$_[0],$_[0],$_[1]); }
+sub main'or { &out3("bis",@_); }
+sub main'bis { &out3("bis",@_); }
+sub main'br { &out1("br",@_); }
+sub main'ld { &out2("ldq",@_); }
+sub main'st { &out2("stq",@_); }
+sub main'cmpult { &out3("cmpult",@_); }
+sub main'cmplt { &out3("cmplt",@_); }
+sub main'bgt { &out2("bgt",@_); }
+sub main'ble { &out2("ble",@_); }
+sub main'blt { &out2("blt",@_); }
+sub main'mul { &out3("mulq",@_); }
+sub main'muh { &out3("umulh",@_); }
+
+$main'QWS=8;
+
+sub main'asm_add
+ {
+ push(@out,@_);
+ }
+
+sub main'asm_finish
+ {
+ &main'file_end();
+ print &main'asm_get_output();
+ }
+
+sub main'asm_init
+ {
+ ($type,$fn)=@_;
+ $filename=$fn;
+
+ &main'asm_init_output();
+ &main'comment("Don't even think of reading this code");
+ &main'comment("It was automatically generated by $filename");
+ &main'comment("Which is a perl program used to generate the alpha assember.");
+ &main'comment("eric <eay\@cryptsoft.com>");
+ &main'comment("");
+
+ $filename =~ s/\.pl$//;
+ &main'file($filename);
+ }
+
+sub conv
+ {
+ local($r)=@_;
+ local($v);
+
+ return($regs{$r}) if defined($regs{$r});
+ return($r);
+ }
+
+sub main'QWPw
+ {
+ local($off,$reg)=@_;
+
+ return(&main'QWP($off*8,$reg));
+ }
+
+sub main'QWP
+ {
+ local($off,$reg)=@_;
+
+ $ret="$off(".&conv($reg).")";
+ return($ret);
+ }
+
+sub out3
+ {
+ local($name,$p1,$p2,$p3)=@_;
+
+ $p1=&conv($p1);
+ $p2=&conv($p2);
+ $p3=&conv($p3);
+ push(@out,"\t$name\t");
+ $l=length($p1)+1;
+ push(@out,$p1.",");
+ $ll=3-($l+9)/8;
+ $tmp1=sprintf("\t" x $ll);
+ push(@out,$tmp1);
+
+ $l=length($p2)+1;
+ push(@out,$p2.",");
+ $ll=3-($l+9)/8;
+ $tmp1=sprintf("\t" x $ll);
+ push(@out,$tmp1);
+
+ push(@out,&conv($p3)."\n");
+ }
+
+sub out2
+ {
+ local($name,$p1,$p2,$p3)=@_;
+
+ $p1=&conv($p1);
+ $p2=&conv($p2);
+ push(@out,"\t$name\t");
+ $l=length($p1)+1;
+ push(@out,$p1.",");
+ $ll=3-($l+9)/8;
+ $tmp1=sprintf("\t" x $ll);
+ push(@out,$tmp1);
+
+ push(@out,&conv($p2)."\n");
+ }
+
+sub out1
+ {
+ local($name,$p1)=@_;
+
+ $p1=&conv($p1);
+ push(@out,"\t$name\t".$p1."\n");
+ }
+
+sub out0
+ {
+ push(@out,"\t$_[0]\n");
+ }
+
+sub main'file
+ {
+ local($file)=@_;
+
+ local($tmp)=<<"EOF";
+ # DEC Alpha assember
+ # Generated from perl scripts contains in SSLeay
+ .file 1 "$file.s"
+ .set noat
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'function_begin
+ {
+ local($func)=@_;
+
+print STDERR "$func\n";
+ local($tmp)=<<"EOF";
+ .text
+ .align $align
+ .globl $func
+ .ent $func
+${func}:
+${func}..ng:
+ .frame \$30,0,\$26,0
+ .prologue 0
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ }
+
+sub main'function_end
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ ret \$31,(\$26),1
+ .end $func
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ %label=();
+ }
+
+sub main'function_end_A
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ ret \$31,(\$26),1
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'function_end_B
+ {
+ local($func)=@_;
+
+ $func=$under.$func;
+
+ push(@out,"\t.end $func\n");
+ $stack=0;
+ %label=();
+ }
+
+sub main'wparam
+ {
+ local($num)=@_;
+
+ if ($num < 6)
+ {
+ $num=20-$num;
+ return("r$num");
+ }
+ else
+ { return(&main'QWP($stack+$num*8,"sp")); }
+ }
+
+sub main'stack_push
+ {
+ local($num)=@_;
+ $stack+=$num*8;
+ &main'sub("sp",$num*8,"sp");
+ }
+
+sub main'stack_pop
+ {
+ local($num)=@_;
+ $stack-=$num*8;
+ &main'add("sp",$num*8,"sp");
+ }
+
+sub main'swtmp
+ {
+ return(&main'QWP(($_[0])*8,"sp"));
+ }
+
+# Should use swtmp, which is above sp. Linix can trash the stack above esp
+#sub main'wtmp
+# {
+# local($num)=@_;
+#
+# return(&main'QWP(-($num+1)*4,"esp","",0));
+# }
+
+sub main'comment
+ {
+ foreach (@_)
+ {
+ if (/^\s*$/)
+ { push(@out,"\n"); }
+ else
+ { push(@out,"\t$com_start $_ $com_end\n"); }
+ }
+ }
+
+sub main'label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}=$label;
+ $label++;
+ }
+ return('$'.$label{$_[0]});
+ }
+
+sub main'set_label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}=$label;
+ $label++;
+ }
+# push(@out,".align $align\n") if ($_[1] != 0);
+ push(@out,'$'."$label{$_[0]}:\n");
+ }
+
+sub main'file_end
+ {
+ }
+
+sub main'data_word
+ {
+ push(@out,"\t.long $_[0]\n");
+ }
+
+@pool_free=();
+@pool_taken=();
+$curr_num=0;
+$max=0;
+
+sub main'init_pool
+ {
+ local($args)=@_;
+ local($i);
+
+ @pool_free=();
+ for ($i=(14+(6-$args)); $i >= 0; $i--)
+ {
+ push(@pool_free,"r$i");
+ }
+ print STDERR "START :register pool:@pool_free\n";
+ $curr_num=$max=0;
+ }
+
+sub main'fin_pool
+ {
+ printf STDERR "END %2d:register pool:@pool_free\n",$max;
+ }
+
+sub main'GR
+ {
+ local($r)=@_;
+ local($i,@n,$_);
+
+ foreach (@pool_free)
+ {
+ if ($r ne $_)
+ { push(@n,$_); }
+ else
+ {
+ $curr_num++;
+ $max=$curr_num if ($curr_num > $max);
+ }
+ }
+ @pool_free=@n;
+print STDERR "GR:@pool_free\n" if $reg_alloc;
+ return(@_);
+ }
+
+sub main'NR
+ {
+ local($num)=@_;
+ local(@ret);
+
+ $num=1 if $num == 0;
+ ($#pool_free >= ($num-1)) || croak "out of registers: want $num, have @pool_free";
+ while ($num > 0)
+ {
+ push(@ret,pop @pool_free);
+ $curr_num++;
+ $max=$curr_num if ($curr_num > $max);
+ $num--
+ }
+ print STDERR "nr @ret\n" if $n_debug;
+print STDERR "NR:@pool_free\n" if $reg_alloc;
+ return(@ret);
+
+ }
+
+sub main'FR
+ {
+ local(@r)=@_;
+ local(@a,$v,$w);
+
+ print STDERR "fr @r\n" if $n_debug;
+# cluck "fr @r";
+ for $w (@pool_free)
+ {
+ foreach $v (@r)
+ {
+ croak "double register free of $v (@pool_free)" if $w eq $v;
+ }
+ }
+ foreach $v (@r)
+ {
+ croak "bad argument to FR" if ($v !~ /^r\d+$/);
+ if ($smear_regs)
+ { unshift(@pool_free,$v); }
+ else { push(@pool_free,$v); }
+ $curr_num--;
+ }
+print STDERR "FR:@pool_free\n" if $reg_alloc;
+ }
+1;
diff --git a/src/libfreeswan/libcrypto/perlasm/cbc.pl b/src/libfreeswan/libcrypto/perlasm/cbc.pl
new file mode 100644
index 000000000..278930579
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/cbc.pl
@@ -0,0 +1,342 @@
+#!/usr/bin/perl
+
+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
+# des_cblock (*input);
+# des_cblock (*output);
+# long length;
+# des_key_schedule schedule;
+# des_cblock (*ivec);
+# int enc;
+#
+# calls
+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+#
+
+#&cbc("des_ncbc_encrypt","des_encrypt",0);
+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
+# 1,4,5,3,5,-1);
+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
+# 0,4,5,3,5,-1);
+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
+# 0,6,7,3,4,5);
+#
+# When doing a cipher that needs bigendian order,
+# for encrypt, the iv is kept in bigendian form,
+# while for decrypt, it is kept in little endian.
+sub cbc
+ {
+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
+ # name is the function name
+ # enc_func and dec_func and the functions to call for encrypt/decrypt
+ # swap is true if byte order needs to be reversed
+ # iv_off is parameter number for the iv
+ # enc_off is parameter number for the encrypt/decrypt flag
+ # p1,p2,p3 are the offsets for parameters to be passed to the
+ # underlying calls.
+
+ &function_begin_B($name,"");
+ &comment("");
+
+ $in="esi";
+ $out="edi";
+ $count="ebp";
+
+ &push("ebp");
+ &push("ebx");
+ &push("esi");
+ &push("edi");
+
+ $data_off=4;
+ $data_off+=4 if ($p1 > 0);
+ $data_off+=4 if ($p2 > 0);
+ $data_off+=4 if ($p3 > 0);
+
+ &mov($count, &wparam(2)); # length
+
+ &comment("getting iv ptr from parameter $iv_off");
+ &mov("ebx", &wparam($iv_off)); # Get iv ptr
+
+ &mov($in, &DWP(0,"ebx","",0));# iv[0]
+ &mov($out, &DWP(4,"ebx","",0));# iv[1]
+
+ &push($out);
+ &push($in);
+ &push($out); # used in decrypt for iv[1]
+ &push($in); # used in decrypt for iv[0]
+
+ &mov("ebx", "esp"); # This is the address of tin[2]
+
+ &mov($in, &wparam(0)); # in
+ &mov($out, &wparam(1)); # out
+
+ # We have loaded them all, how lets push things
+ &comment("getting encrypt flag from parameter $enc_off");
+ &mov("ecx", &wparam($enc_off)); # Get enc flag
+ if ($p3 > 0)
+ {
+ &comment("get and push parameter $p3");
+ if ($enc_off != $p3)
+ { &mov("eax", &wparam($p3)); &push("eax"); }
+ else { &push("ecx"); }
+ }
+ if ($p2 > 0)
+ {
+ &comment("get and push parameter $p2");
+ if ($enc_off != $p2)
+ { &mov("eax", &wparam($p2)); &push("eax"); }
+ else { &push("ecx"); }
+ }
+ if ($p1 > 0)
+ {
+ &comment("get and push parameter $p1");
+ if ($enc_off != $p1)
+ { &mov("eax", &wparam($p1)); &push("eax"); }
+ else { &push("ecx"); }
+ }
+ &push("ebx"); # push data/iv
+
+ &cmp("ecx",0);
+ &jz(&label("decrypt"));
+
+ &and($count,0xfffffff8);
+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0]
+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1]
+
+ &jz(&label("encrypt_finish"));
+
+ #############################################################
+
+ &set_label("encrypt_loop");
+ # encrypt start
+ # "eax" and "ebx" hold iv (or the last cipher text)
+
+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes
+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes
+
+ &xor("eax", "ecx");
+ &xor("ebx", "edx");
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($enc_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0));
+ &mov("ebx", &DWP($data_off+4,"esp","",0));
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP(0,$out,"",0),"eax");
+ &mov(&DWP(4,$out,"",0),"ebx");
+
+ # eax and ebx are the next iv.
+
+ &add($in, 8);
+ &add($out, 8);
+
+ &sub($count, 8);
+ &jnz(&label("encrypt_loop"));
+
+###################################################################3
+ &set_label("encrypt_finish");
+ &mov($count, &wparam(2)); # length
+ &and($count, 7);
+ &jz(&label("finish"));
+ &xor("ecx","ecx");
+ &xor("edx","edx");
+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
+ &jmp_ptr($count);
+
+&set_label("ej7");
+ &xor("edx", "edx") if $ppro; # ppro friendly
+ &movb(&HB("edx"), &BP(6,$in,"",0));
+ &shl("edx",8);
+&set_label("ej6");
+ &movb(&HB("edx"), &BP(5,$in,"",0));
+&set_label("ej5");
+ &movb(&LB("edx"), &BP(4,$in,"",0));
+&set_label("ej4");
+ &mov("ecx", &DWP(0,$in,"",0));
+ &jmp(&label("ejend"));
+&set_label("ej3");
+ &movb(&HB("ecx"), &BP(2,$in,"",0));
+ &xor("ecx", "ecx") if $ppro; # ppro friendly
+ &shl("ecx",8);
+&set_label("ej2");
+ &movb(&HB("ecx"), &BP(1,$in,"",0));
+&set_label("ej1");
+ &movb(&LB("ecx"), &BP(0,$in,"",0));
+&set_label("ejend");
+
+ &xor("eax", "ecx");
+ &xor("ebx", "edx");
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($enc_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0));
+ &mov("ebx", &DWP($data_off+4,"esp","",0));
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP(0,$out,"",0),"eax");
+ &mov(&DWP(4,$out,"",0),"ebx");
+
+ &jmp(&label("finish"));
+
+ #############################################################
+ #############################################################
+ &set_label("decrypt",1);
+ # decrypt start
+ &and($count,0xfffffff8);
+ # The next 2 instructions are only for if the jz is taken
+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0]
+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1]
+ &jz(&label("decrypt_finish"));
+
+ &set_label("decrypt_loop");
+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($dec_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
+
+ &xor("ecx", "eax");
+ &xor("edx", "ebx");
+
+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
+
+ &mov(&DWP(0,$out,"",0),"ecx");
+ &mov(&DWP(4,$out,"",0),"edx");
+
+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv
+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); #
+
+ &add($in, 8);
+ &add($out, 8);
+
+ &sub($count, 8);
+ &jnz(&label("decrypt_loop"));
+############################ ENDIT #######################3
+ &set_label("decrypt_finish");
+ &mov($count, &wparam(2)); # length
+ &and($count, 7);
+ &jz(&label("finish"));
+
+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($dec_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
+
+ &xor("ecx", "eax");
+ &xor("edx", "ebx");
+
+ # this is for when we exit
+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
+
+&set_label("dj7");
+ &rotr("edx", 16);
+ &movb(&BP(6,$out,"",0), &LB("edx"));
+ &shr("edx",16);
+&set_label("dj6");
+ &movb(&BP(5,$out,"",0), &HB("edx"));
+&set_label("dj5");
+ &movb(&BP(4,$out,"",0), &LB("edx"));
+&set_label("dj4");
+ &mov(&DWP(0,$out,"",0), "ecx");
+ &jmp(&label("djend"));
+&set_label("dj3");
+ &rotr("ecx", 16);
+ &movb(&BP(2,$out,"",0), &LB("ecx"));
+ &shl("ecx",16);
+&set_label("dj2");
+ &movb(&BP(1,$in,"",0), &HB("ecx"));
+&set_label("dj1");
+ &movb(&BP(0,$in,"",0), &LB("ecx"));
+&set_label("djend");
+
+ # final iv is still in eax:ebx
+ &jmp(&label("finish"));
+
+
+############################ FINISH #######################3
+ &set_label("finish",1);
+ &mov("ecx", &wparam($iv_off)); # Get iv ptr
+
+ #################################################
+ $total=16+4;
+ $total+=4 if ($p1 > 0);
+ $total+=4 if ($p2 > 0);
+ $total+=4 if ($p3 > 0);
+ &add("esp",$total);
+
+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv
+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv
+
+ &function_end_A($name);
+
+ &set_label("cbc_enc_jmp_table",1);
+ &data_word("0");
+ &data_word(&label("ej1"));
+ &data_word(&label("ej2"));
+ &data_word(&label("ej3"));
+ &data_word(&label("ej4"));
+ &data_word(&label("ej5"));
+ &data_word(&label("ej6"));
+ &data_word(&label("ej7"));
+ &set_label("cbc_dec_jmp_table",1);
+ &data_word("0");
+ &data_word(&label("dj1"));
+ &data_word(&label("dj2"));
+ &data_word(&label("dj3"));
+ &data_word(&label("dj4"));
+ &data_word(&label("dj5"));
+ &data_word(&label("dj6"));
+ &data_word(&label("dj7"));
+
+ &function_end_B($name);
+
+ }
+
+1;
diff --git a/src/libfreeswan/libcrypto/perlasm/readme b/src/libfreeswan/libcrypto/perlasm/readme
new file mode 100644
index 000000000..f02bbee75
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/readme
@@ -0,0 +1,124 @@
+The perl scripts in this directory are my 'hack' to generate
+multiple different assembler formats via the one origional script.
+
+The way to use this library is to start with adding the path to this directory
+and then include it.
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+The first thing we do is setup the file and type of assember
+
+&asm_init($ARGV[0],$0);
+
+The first argument is the 'type'. Currently
+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
+Argument 2 is the file name.
+
+The reciprocal function is
+&asm_finish() which should be called at the end.
+
+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
+and x86unix.pl which is the unix (gas) version.
+
+Functions of interest are:
+&external_label("des_SPtrans"); declare and external variable
+&LB(reg); Low byte for a register
+&HB(reg); High byte for a register
+&BP(off,base,index,scale) Byte pointer addressing
+&DWP(off,base,index,scale) Word pointer addressing
+&stack_push(num) Basically a 'sub esp, num*4' with extra
+&stack_pop(num) inverse of stack_push
+&function_begin(name,extra) Start a function with pushing of
+ edi, esi, ebx and ebp. extra is extra win32
+ external info that may be required.
+&function_begin_B(name,extra) Same as norma function_begin but no pushing.
+&function_end(name) Call at end of function.
+&function_end_A(name) Standard pop and ret, for use inside functions
+&function_end_B(name) Call at end but with poping or 'ret'.
+&swtmp(num) Address on stack temp word.
+&wparam(num) Parameter number num, that was push
+ in C convention. This all works over pushes
+ and pops.
+&comment("hello there") Put in a comment.
+&label("loop") Refer to a label, normally a jmp target.
+&set_label("loop") Set a label at this point.
+&data_word(word) Put in a word of data.
+
+So how does this all hold together? Given
+
+int calc(int len, int *data)
+ {
+ int i,j=0;
+
+ for (i=0; i<len; i++)
+ {
+ j+=other(data[i]);
+ }
+ }
+
+So a very simple version of this function could be coded as
+
+ push(@INC,"perlasm","../../perlasm");
+ require "x86asm.pl";
+
+ &asm_init($ARGV[0],"cacl.pl");
+
+ &external_label("other");
+
+ $tmp1= "eax";
+ $j= "edi";
+ $data= "esi";
+ $i= "ebp";
+
+ &comment("a simple function");
+ &function_begin("calc");
+ &mov( $data, &wparam(1)); # data
+ &xor( $j, $j);
+ &xor( $i, $i);
+
+ &set_label("loop");
+ &cmp( $i, &wparam(0));
+ &jge( &label("end"));
+
+ &mov( $tmp1, &DWP(0,$data,$i,4));
+ &push( $tmp1);
+ &call( "other");
+ &add( $j, "eax");
+ &pop( $tmp1);
+ &inc( $i);
+ &jmp( &label("loop"));
+
+ &set_label("end");
+ &mov( "eax", $j);
+
+ &function_end("calc");
+
+ &asm_finish();
+
+The above example is very very unoptimised but gives an idea of how
+things work.
+
+There is also a cbc mode function generator in cbc.pl
+
+&cbc( $name,
+ $encrypt_function_name,
+ $decrypt_function_name,
+ $true_if_byte_swap_needed,
+ $parameter_number_for_iv,
+ $parameter_number_for_encrypt_flag,
+ $first_parameter_to_pass,
+ $second_parameter_to_pass,
+ $third_parameter_to_pass);
+
+So for example, given
+void BF_encrypt(BF_LONG *data,BF_KEY *key);
+void BF_decrypt(BF_LONG *data,BF_KEY *key);
+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+ BF_KEY *ks, unsigned char *iv, int enc);
+
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
+
+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
+
diff --git a/src/libfreeswan/libcrypto/perlasm/version b/src/libfreeswan/libcrypto/perlasm/version
new file mode 100644
index 000000000..5e62822b4
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/version
@@ -0,0 +1,5 @@
+version,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
+
+This version of perlasm was copied from the openssl 0.9.6c distribution
+
+The license applying to it is enclose in the LICENSE file
diff --git a/src/libfreeswan/libcrypto/perlasm/x86asm.pl b/src/libfreeswan/libcrypto/perlasm/x86asm.pl
new file mode 100644
index 000000000..8af0fd17f
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/x86asm.pl
@@ -0,0 +1,118 @@
+#!/usr/bin/perl
+
+# require 'x86asm.pl';
+# &asm_init("cpp","des-586.pl");
+# XXX
+# XXX
+# main'asm_finish
+
+sub main'asm_finish
+ {
+ &file_end();
+ &asm_finish_cpp() if $cpp;
+ print &asm_get_output();
+ }
+
+sub main'asm_init
+ {
+ ($type,$fn,$i386)=@_;
+ $filename=$fn;
+
+ $cpp=$sol=$aout=$win32=$gaswin=0;
+ if ( ($type eq "elf"))
+ { require "x86unix.pl"; }
+ elsif ( ($type eq "a.out"))
+ { $aout=1; require "x86unix.pl"; }
+ elsif ( ($type eq "gaswin"))
+ { $gaswin=1; $aout=1; require "x86unix.pl"; }
+ elsif ( ($type eq "sol"))
+ { $sol=1; require "x86unix.pl"; }
+ elsif ( ($type eq "cpp"))
+ { $cpp=1; require "x86unix.pl"; }
+ elsif ( ($type eq "win32"))
+ { $win32=1; require "x86ms.pl"; }
+ elsif ( ($type eq "win32n"))
+ { $win32=1; require "x86nasm.pl"; }
+ else
+ {
+ print STDERR <<"EOF";
+Pick one target type from
+ elf - linux, FreeBSD etc
+ a.out - old linux
+ sol - x86 solaris
+ cpp - format so x86unix.cpp can be used
+ win32 - Windows 95/Windows NT
+ win32n - Windows 95/Windows NT NASM format
+EOF
+ exit(1);
+ }
+
+ &asm_init_output();
+
+&comment("Don't even think of reading this code");
+&comment("It was automatically generated by $filename");
+&comment("Which is a perl program used to generate the x86 assember for");
+&comment("any of elf, a.out, BSDI, Win32, gaswin (for GNU as on Win32) or Solaris");
+&comment("eric <eay\@cryptsoft.com>");
+&comment("");
+
+ $filename =~ s/\.pl$//;
+ &file($filename);
+ }
+
+sub asm_finish_cpp
+ {
+ return unless $cpp;
+
+ local($tmp,$i);
+ foreach $i (&get_labels())
+ {
+ $tmp.="#define $i _$i\n";
+ }
+ print <<"EOF";
+/* Run the C pre-processor over this file with one of the following defined
+ * ELF - elf object files,
+ * OUT - a.out object files,
+ * BSDI - BSDI style a.out object files
+ * SOL - Solaris style elf
+ */
+
+#define TYPE(a,b) .type a,b
+#define SIZE(a,b) .size a,b
+
+#if defined(OUT) || (defined(BSDI) && !defined(ELF))
+$tmp
+#endif
+
+#ifdef OUT
+#define OK 1
+#define ALIGN 4
+#endif
+
+#if defined(BSDI) && !defined(ELF)
+#define OK 1
+#define ALIGN 4
+#undef SIZE
+#undef TYPE
+#define SIZE(a,b)
+#define TYPE(a,b)
+#endif
+
+#if defined(ELF) || defined(SOL)
+#define OK 1
+#define ALIGN 16
+#endif
+
+#ifndef OK
+You need to define one of
+ELF - elf systems - linux-elf, NetBSD and DG-UX
+OUT - a.out systems - linux-a.out and FreeBSD
+SOL - solaris systems, which are elf with strange comment lines
+BSDI - a.out with a very primative version of as.
+#endif
+
+/* Let the Assembler begin :-) */
+EOF
+ }
+
+1;
diff --git a/src/libfreeswan/libcrypto/perlasm/x86ms.pl b/src/libfreeswan/libcrypto/perlasm/x86ms.pl
new file mode 100644
index 000000000..c6212f434
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/x86ms.pl
@@ -0,0 +1,365 @@
+#!/usr/bin/perl
+
+package x86ms;
+
+$label="L000";
+
+%lb=( 'eax', 'al',
+ 'ebx', 'bl',
+ 'ecx', 'cl',
+ 'edx', 'dl',
+ 'ax', 'al',
+ 'bx', 'bl',
+ 'cx', 'cl',
+ 'dx', 'dl',
+ );
+
+%hb=( 'eax', 'ah',
+ 'ebx', 'bh',
+ 'ecx', 'ch',
+ 'edx', 'dh',
+ 'ax', 'ah',
+ 'bx', 'bh',
+ 'cx', 'ch',
+ 'dx', 'dh',
+ );
+
+sub main'asm_init_output { @out=(); }
+sub main'asm_get_output { return(@out); }
+sub main'get_labels { return(@labels); }
+sub main'external_label { push(@labels,@_); }
+
+sub main'LB
+ {
+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+ return($lb{$_[0]});
+ }
+
+sub main'HB
+ {
+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+ return($hb{$_[0]});
+ }
+
+sub main'BP
+ {
+ &get_mem("BYTE",@_);
+ }
+
+sub main'DWP
+ {
+ &get_mem("DWORD",@_);
+ }
+
+sub main'BC
+ {
+ return @_;
+ }
+
+sub main'DWC
+ {
+ return @_;
+ }
+
+sub main'stack_push
+ {
+ local($num)=@_;
+ $stack+=$num*4;
+ &main'sub("esp",$num*4);
+ }
+
+sub main'stack_pop
+ {
+ local($num)=@_;
+ $stack-=$num*4;
+ &main'add("esp",$num*4);
+ }
+
+sub get_mem
+ {
+ local($size,$addr,$reg1,$reg2,$idx)=@_;
+ local($t,$post);
+ local($ret)="$size PTR ";
+
+ $addr =~ s/^\s+//;
+ if ($addr =~ /^(.+)\+(.+)$/)
+ {
+ $reg2=&conv($1);
+ $addr="_$2";
+ }
+ elsif ($addr =~ /^[_a-zA-Z]/)
+ {
+ $addr="_$addr";
+ }
+
+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
+ if (($addr ne "") && ($addr ne 0))
+ {
+ if ($addr !~ /^-/)
+ { $ret.=$addr; }
+ else { $post=$addr; }
+ }
+ if ($reg2 ne "")
+ {
+ $t="";
+ $t="*$idx" if ($idx != 0);
+ $reg1="+".$reg1 if ("$reg1$post" ne "");
+ $ret.="[$reg2$t$reg1$post]";
+ }
+ else
+ {
+ $ret.="[$reg1$post]"
+ }
+ return($ret);
+ }
+
+sub main'mov { &out2("mov",@_); }
+sub main'movb { &out2("mov",@_); }
+sub main'and { &out2("and",@_); }
+sub main'or { &out2("or",@_); }
+sub main'shl { &out2("shl",@_); }
+sub main'shr { &out2("shr",@_); }
+sub main'xor { &out2("xor",@_); }
+sub main'xorb { &out2("xor",@_); }
+sub main'add { &out2("add",@_); }
+sub main'adc { &out2("adc",@_); }
+sub main'sub { &out2("sub",@_); }
+sub main'rotl { &out2("rol",@_); }
+sub main'rotr { &out2("ror",@_); }
+sub main'exch { &out2("xchg",@_); }
+sub main'cmp { &out2("cmp",@_); }
+sub main'lea { &out2("lea",@_); }
+sub main'mul { &out1("mul",@_); }
+sub main'div { &out1("div",@_); }
+sub main'dec { &out1("dec",@_); }
+sub main'inc { &out1("inc",@_); }
+sub main'jmp { &out1("jmp",@_); }
+sub main'jmp_ptr { &out1p("jmp",@_); }
+sub main'je { &out1("je",@_); }
+sub main'jle { &out1("jle",@_); }
+sub main'jz { &out1("jz",@_); }
+sub main'jge { &out1("jge",@_); }
+sub main'jl { &out1("jl",@_); }
+sub main'jb { &out1("jb",@_); }
+sub main'jc { &out1("jc",@_); }
+sub main'jnc { &out1("jnc",@_); }
+sub main'jnz { &out1("jnz",@_); }
+sub main'jne { &out1("jne",@_); }
+sub main'jno { &out1("jno",@_); }
+sub main'push { &out1("push",@_); $stack+=4; }
+sub main'pop { &out1("pop",@_); $stack-=4; }
+sub main'bswap { &out1("bswap",@_); &using486(); }
+sub main'not { &out1("not",@_); }
+sub main'call { &out1("call",'_'.$_[0]); }
+sub main'ret { &out0("ret"); }
+sub main'nop { &out0("nop"); }
+
+sub out2
+ {
+ local($name,$p1,$p2)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t");
+ $t=&conv($p1).",";
+ $l=length($t);
+ push(@out,$t);
+ $l=4-($l+9)/8;
+ push(@out,"\t" x $l);
+ push(@out,&conv($p2));
+ push(@out,"\n");
+ }
+
+sub out0
+ {
+ local($name)=@_;
+
+ push(@out,"\t$name\n");
+ }
+
+sub out1
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t".&conv($p1)."\n");
+ }
+
+sub conv
+ {
+ local($p)=@_;
+
+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+ return $p;
+ }
+
+sub using486
+ {
+ return if $using486;
+ $using486++;
+ grep(s/\.386/\.486/,@out);
+ }
+
+sub main'file
+ {
+ local($file)=@_;
+
+ local($tmp)=<<"EOF";
+ TITLE $file.asm
+ .386
+.model FLAT
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'function_begin
+ {
+ local($func,$extra)=@_;
+
+ push(@labels,$func);
+
+ local($tmp)=<<"EOF";
+_TEXT SEGMENT
+PUBLIC _$func
+$extra
+_$func PROC NEAR
+ push ebp
+ push ebx
+ push esi
+ push edi
+EOF
+ push(@out,$tmp);
+ $stack=20;
+ }
+
+sub main'function_begin_B
+ {
+ local($func,$extra)=@_;
+
+ local($tmp)=<<"EOF";
+_TEXT SEGMENT
+PUBLIC _$func
+$extra
+_$func PROC NEAR
+EOF
+ push(@out,$tmp);
+ $stack=4;
+ }
+
+sub main'function_end
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_$func ENDP
+_TEXT ENDS
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ %label=();
+ }
+
+sub main'function_end_B
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+_$func ENDP
+_TEXT ENDS
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ %label=();
+ }
+
+sub main'function_end_A
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'file_end
+ {
+ push(@out,"END\n");
+ }
+
+sub main'wparam
+ {
+ local($num)=@_;
+
+ return(&main'DWP($stack+$num*4,"esp","",0));
+ }
+
+sub main'swtmp
+ {
+ return(&main'DWP($_[0]*4,"esp","",0));
+ }
+
+# Should use swtmp, which is above esp. Linix can trash the stack above esp
+#sub main'wtmp
+# {
+# local($num)=@_;
+#
+# return(&main'DWP(-(($num+1)*4),"esp","",0));
+# }
+
+sub main'comment
+ {
+ foreach (@_)
+ {
+ push(@out,"\t; $_\n");
+ }
+ }
+
+sub main'label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}="\$${label}${_[0]}";
+ $label++;
+ }
+ return($label{$_[0]});
+ }
+
+sub main'set_label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}="${label}${_[0]}";
+ $label++;
+ }
+ if((defined $_[2]) && ($_[2] == 1))
+ {
+ push(@out,"$label{$_[0]}::\n");
+ }
+ else
+ {
+ push(@out,"$label{$_[0]}:\n");
+ }
+ }
+
+sub main'data_word
+ {
+ push(@out,"\tDD\t$_[0]\n");
+ }
+
+sub out1p
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t ".&conv($p1)."\n");
+ }
diff --git a/src/libfreeswan/libcrypto/perlasm/x86nasm.pl b/src/libfreeswan/libcrypto/perlasm/x86nasm.pl
new file mode 100644
index 000000000..90d27fca9
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/x86nasm.pl
@@ -0,0 +1,366 @@
+#!/usr/bin/perl
+
+package x86nasm;
+
+$label="L000";
+
+%lb=( 'eax', 'al',
+ 'ebx', 'bl',
+ 'ecx', 'cl',
+ 'edx', 'dl',
+ 'ax', 'al',
+ 'bx', 'bl',
+ 'cx', 'cl',
+ 'dx', 'dl',
+ );
+
+%hb=( 'eax', 'ah',
+ 'ebx', 'bh',
+ 'ecx', 'ch',
+ 'edx', 'dh',
+ 'ax', 'ah',
+ 'bx', 'bh',
+ 'cx', 'ch',
+ 'dx', 'dh',
+ );
+
+%regs=( 'eax', 'eax',
+ 'ebx', 'ebx',
+ 'ecx', 'ecx',
+ 'edx', 'edx',
+ 'esi', 'esi',
+ 'edi', 'edi',
+ 'ebp', 'ebp',
+ 'esp', 'esp',
+ 'mm0', 'mm0',
+ 'mm1', 'mm1',
+ );
+
+sub main::asm_init_output { @out=(); }
+sub main::asm_get_output { return(@out); }
+sub main::get_labels { return(@labels); }
+
+sub main::external_label
+{
+ push(@labels,@_);
+ foreach (@_) {
+ push(@out, "extern\t_$_\n");
+ }
+}
+
+sub main::LB
+ {
+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+ return($lb{$_[0]});
+ }
+
+sub main::HB
+ {
+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+ return($hb{$_[0]});
+ }
+
+sub main::BP
+ {
+ &get_mem("BYTE",@_);
+ }
+
+sub main::DWP
+ {
+ &get_mem("DWORD",@_);
+ }
+
+sub main::BC
+ {
+ return "BYTE @_";
+ }
+
+sub main::DWC
+ {
+ return "DWORD @_";
+ }
+
+sub main::stack_push
+ {
+ my($num)=@_;
+ $stack+=$num*4;
+ &main::sub("esp",$num*4);
+ }
+
+sub main::stack_pop
+ {
+ my($num)=@_;
+ $stack-=$num*4;
+ &main::add("esp",$num*4);
+ }
+
+sub get_mem
+ {
+ my($size,$addr,$reg1,$reg2,$idx)=@_;
+ my($t,$post);
+ my($ret)="[";
+ $addr =~ s/^\s+//;
+ if ($addr =~ /^(.+)\+(.+)$/)
+ {
+ if (defined($regs{$reg2})) {
+ $addr=join('+', &conv($1), "_$2");
+ } else {
+ $reg2=&conv($1);
+ $addr="_$2";
+ }
+ }
+ elsif ($addr =~ /^[_a-zA-Z]/)
+ {
+ $addr="_$addr";
+ }
+
+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
+ if (($addr ne "") && ($addr ne 0))
+ {
+ if ($addr !~ /^-/)
+ { $ret.="${addr}+"; }
+ else { $post=$addr; }
+ }
+ if ($reg2 ne "")
+ {
+ $t="";
+ $t="*$idx" if ($idx != 0);
+ $reg1="+".$reg1 if ("$reg1$post" ne "");
+ $ret.="$reg2$t$reg1$post]";
+ }
+ else
+ {
+ $ret.="$reg1$post]"
+ }
+ return($ret);
+ }
+
+sub main::mov { &out2("mov",@_); }
+sub main::movb { &out2("mov",@_); }
+sub main::and { &out2("and",@_); }
+sub main::or { &out2("or",@_); }
+sub main::shl { &out2("shl",@_); }
+sub main::shr { &out2("shr",@_); }
+sub main::xor { &out2("xor",@_); }
+sub main::xorb { &out2("xor",@_); }
+sub main::add { &out2("add",@_); }
+sub main::adc { &out2("adc",@_); }
+sub main::sub { &out2("sub",@_); }
+sub main::rotl { &out2("rol",@_); }
+sub main::rotr { &out2("ror",@_); }
+sub main::exch { &out2("xchg",@_); }
+sub main::cmp { &out2("cmp",@_); }
+sub main::lea { &out2("lea",@_); }
+sub main::mul { &out1("mul",@_); }
+sub main::div { &out1("div",@_); }
+sub main::dec { &out1("dec",@_); }
+sub main::inc { &out1("inc",@_); }
+sub main::jmp { &out1("jmp",@_); }
+sub main::jmp_ptr { &out1p("jmp",@_); }
+
+# This is a bit of a kludge: declare all branches as NEAR.
+sub main::je { &out1("je NEAR",@_); }
+sub main::jle { &out1("jle NEAR",@_); }
+sub main::jz { &out1("jz NEAR",@_); }
+sub main::jge { &out1("jge NEAR",@_); }
+sub main::jl { &out1("jl NEAR",@_); }
+sub main::jb { &out1("jb NEAR",@_); }
+sub main::jc { &out1("jc NEAR",@_); }
+sub main::jnc { &out1("jnc NEAR",@_); }
+sub main::jnz { &out1("jnz NEAR",@_); }
+sub main::jne { &out1("jne NEAR",@_); }
+sub main::jno { &out1("jno NEAR",@_); }
+
+sub main::push { &out1("push",@_); $stack+=4; }
+sub main::pop { &out1("pop",@_); $stack-=4; }
+sub main::bswap { &out1("bswap",@_); &using486(); }
+sub main::not { &out1("not",@_); }
+sub main::call { &out1("call",'_'.$_[0]); }
+sub main::ret { &out0("ret"); }
+sub main::nop { &out0("nop"); }
+
+sub out2
+ {
+ my($name,$p1,$p2)=@_;
+ my($l,$t);
+
+ push(@out,"\t$name\t");
+ $t=&conv($p1).",";
+ $l=length($t);
+ push(@out,$t);
+ $l=4-($l+9)/8;
+ push(@out,"\t" x $l);
+ push(@out,&conv($p2));
+ push(@out,"\n");
+ }
+
+sub out0
+ {
+ my($name)=@_;
+
+ push(@out,"\t$name\n");
+ }
+
+sub out1
+ {
+ my($name,$p1)=@_;
+ my($l,$t);
+ push(@out,"\t$name\t".&conv($p1)."\n");
+ }
+
+sub conv
+ {
+ my($p)=@_;
+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+ return $p;
+ }
+
+sub using486
+ {
+ return if $using486;
+ $using486++;
+ grep(s/\.386/\.486/,@out);
+ }
+
+sub main::file
+ {
+ push(@out, "segment .text\n");
+ }
+
+sub main::function_begin
+ {
+ my($func,$extra)=@_;
+
+ push(@labels,$func);
+ my($tmp)=<<"EOF";
+global _$func
+_$func:
+ push ebp
+ push ebx
+ push esi
+ push edi
+EOF
+ push(@out,$tmp);
+ $stack=20;
+ }
+
+sub main::function_begin_B
+ {
+ my($func,$extra)=@_;
+ my($tmp)=<<"EOF";
+global _$func
+_$func:
+EOF
+ push(@out,$tmp);
+ $stack=4;
+ }
+
+sub main::function_end
+ {
+ my($func)=@_;
+
+ my($tmp)=<<"EOF";
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ %label=();
+ }
+
+sub main::function_end_B
+ {
+ $stack=0;
+ %label=();
+ }
+
+sub main::function_end_A
+ {
+ my($func)=@_;
+
+ my($tmp)=<<"EOF";
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+EOF
+ push(@out,$tmp);
+ }
+
+sub main::file_end
+ {
+ }
+
+sub main::wparam
+ {
+ my($num)=@_;
+
+ return(&main::DWP($stack+$num*4,"esp","",0));
+ }
+
+sub main::swtmp
+ {
+ return(&main::DWP($_[0]*4,"esp","",0));
+ }
+
+# Should use swtmp, which is above esp. Linix can trash the stack above esp
+#sub main::wtmp
+# {
+# my($num)=@_;
+#
+# return(&main::DWP(-(($num+1)*4),"esp","",0));
+# }
+
+sub main::comment
+ {
+ foreach (@_)
+ {
+ push(@out,"\t; $_\n");
+ }
+ }
+
+sub main::label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}="\$${label}${_[0]}";
+ $label++;
+ }
+ return($label{$_[0]});
+ }
+
+sub main::set_label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}="${label}${_[0]}";
+ $label++;
+ }
+ push(@out,"$label{$_[0]}:\n");
+ }
+
+sub main::data_word
+ {
+ push(@out,"\tDD\t$_[0]\n");
+ }
+
+sub out1p
+ {
+ my($name,$p1)=@_;
+ my($l,$t);
+
+ push(@out,"\t$name\t ".&conv($p1)."\n");
+ }
+
+##
+## Additional functions required for MMX and other ops
+##
+sub main::testb { &out2('test', @_) }
+sub main::movzx { &out2('movzx', @_) }
+sub main::movd { &out2('movd', @_) }
+sub main::emms { &out0('emms', @_) }
diff --git a/src/libfreeswan/libcrypto/perlasm/x86unix.pl b/src/libfreeswan/libcrypto/perlasm/x86unix.pl
new file mode 100644
index 000000000..f804b91c9
--- /dev/null
+++ b/src/libfreeswan/libcrypto/perlasm/x86unix.pl
@@ -0,0 +1,472 @@
+#!/usr/bin/perl
+
+package x86unix;
+
+$label="L000";
+
+$align=($main::aout)?"4":"16";
+$under=($main::aout)?"_":"";
+$com_start=($main::sol)?"/":"#";
+
+sub main::asm_init_output { @out=(); }
+sub main::asm_get_output { return(@out); }
+sub main::get_labels { return(@labels); }
+sub main::external_label { push(@labels,@_); }
+
+if ($main::cpp)
+ {
+ $align="ALIGN";
+ $under="";
+ $com_start='/*';
+ $com_end='*/';
+ }
+
+%lb=( 'eax', '%al',
+ 'ebx', '%bl',
+ 'ecx', '%cl',
+ 'edx', '%dl',
+ 'ax', '%al',
+ 'bx', '%bl',
+ 'cx', '%cl',
+ 'dx', '%dl',
+ );
+
+%hb=( 'eax', '%ah',
+ 'ebx', '%bh',
+ 'ecx', '%ch',
+ 'edx', '%dh',
+ 'ax', '%ah',
+ 'bx', '%bh',
+ 'cx', '%ch',
+ 'dx', '%dh',
+ );
+
+%regs=( 'eax', '%eax',
+ 'ebx', '%ebx',
+ 'ecx', '%ecx',
+ 'edx', '%edx',
+ 'esi', '%esi',
+ 'edi', '%edi',
+ 'ebp', '%ebp',
+ 'esp', '%esp',
+ 'mm0', '%mm0',
+ 'mm1', '%mm1',
+ );
+
+%reg_val=(
+ 'eax', 0x00,
+ 'ebx', 0x03,
+ 'ecx', 0x01,
+ 'edx', 0x02,
+ 'esi', 0x06,
+ 'edi', 0x07,
+ 'ebp', 0x05,
+ 'esp', 0x04,
+ );
+
+sub main::LB
+ {
+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+ return($lb{$_[0]});
+ }
+
+sub main::HB
+ {
+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+ return($hb{$_[0]});
+ }
+
+sub main::DWP
+ {
+ local($addr,$reg1,$reg2,$idx)=@_;
+
+ $ret="";
+ $addr =~ s/(^|[+ \t])([A-Za-z_]+[A-Za-z0-9_]+)($|[+ \t])/$1$under$2$3/;
+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
+ $ret.=$addr if ($addr ne "") && ($addr ne 0);
+ if ($reg2 ne "")
+ {
+ if($idx ne "")
+ { $ret.="($reg1,$reg2,$idx)"; }
+ else
+ { $ret.="($reg1,$reg2)"; }
+ }
+ else
+ { $ret.="($reg1)" }
+ return($ret);
+ }
+
+sub main::BP
+ {
+ return(&main::DWP(@_));
+ }
+
+sub main::BC
+ {
+ return @_;
+ }
+
+sub main::DWC
+ {
+ return @_;
+ }
+
+#sub main::BP
+# {
+# local($addr,$reg1,$reg2,$idx)=@_;
+#
+# $ret="";
+#
+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
+# $reg1="$regs{$reg1}" if defined($regs{$reg1});
+# $reg2="$regs{$reg2}" if defined($regs{$reg2});
+# $ret.=$addr if ($addr ne "") && ($addr ne 0);
+# if ($reg2 ne "")
+# { $ret.="($reg1,$reg2,$idx)"; }
+# else
+# { $ret.="($reg1)" }
+# return($ret);
+# }
+
+sub main::mov { &out2("movl",@_); }
+sub main::movb { &out2("movb",@_); }
+sub main::and { &out2("andl",@_); }
+sub main::or { &out2("orl",@_); }
+sub main::shl { &out2("sall",@_); }
+sub main::shr { &out2("shrl",@_); }
+sub main::xor { &out2("xorl",@_); }
+sub main::xorb { &out2("xorb",@_); }
+sub main::add { &out2("addl",@_); }
+sub main::adc { &out2("adcl",@_); }
+sub main::sub { &out2("subl",@_); }
+sub main::rotl { &out2("roll",@_); }
+sub main::rotr { &out2("rorl",@_); }
+sub main::exch { &out2("xchg",@_); }
+sub main::cmp { &out2("cmpl",@_); }
+sub main::lea { &out2("leal",@_); }
+sub main::mul { &out1("mull",@_); }
+sub main::div { &out1("divl",@_); }
+sub main::jmp { &out1("jmp",@_); }
+sub main::jmp_ptr { &out1p("jmp",@_); }
+sub main::je { &out1("je",@_); }
+sub main::jle { &out1("jle",@_); }
+sub main::jne { &out1("jne",@_); }
+sub main::jnz { &out1("jnz",@_); }
+sub main::jz { &out1("jz",@_); }
+sub main::jge { &out1("jge",@_); }
+sub main::jl { &out1("jl",@_); }
+sub main::jb { &out1("jb",@_); }
+sub main::jc { &out1("jc",@_); }
+sub main::jnc { &out1("jnc",@_); }
+sub main::jno { &out1("jno",@_); }
+sub main::dec { &out1("decl",@_); }
+sub main::inc { &out1("incl",@_); }
+sub main::push { &out1("pushl",@_); $stack+=4; }
+sub main::pop { &out1("popl",@_); $stack-=4; }
+sub main::not { &out1("notl",@_); }
+sub main::call { &out1("call",$under.$_[0]); }
+sub main::ret { &out0("ret"); }
+sub main::nop { &out0("nop"); }
+
+# The bswapl instruction is new for the 486. Emulate if i386.
+sub main::bswap
+ {
+ if ($main::i386)
+ {
+ &main::comment("bswapl @_");
+ &main::exch(main::HB(@_),main::LB(@_));
+ &main::rotr(@_,16);
+ &main::exch(main::HB(@_),main::LB(@_));
+ }
+ else
+ {
+ &out1("bswapl",@_);
+ }
+ }
+
+sub out2
+ {
+ local($name,$p1,$p2)=@_;
+ local($l,$ll,$t);
+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8,
+ "rcll",0xD1D0,"rcrl",0xD1D8,
+ "shll",0xD1E0,"shrl",0xD1E8,
+ "sarl",0xD1F8);
+
+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
+ {
+ $op=$special{$name}|$reg_val{$p1};
+ $tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
+ $tmp2=sprintf(".byte %d\t",$op &0xff);
+ push(@out,$tmp1);
+ push(@out,$tmp2);
+
+ $p2=&conv($p2);
+ $p1=&conv($p1);
+ &main::comment("$name $p2 $p1");
+ return;
+ }
+
+ push(@out,"\t$name\t");
+ $t=&conv($p2).",";
+ $l=length($t);
+ push(@out,$t);
+ $ll=4-($l+9)/8;
+ $tmp1=sprintf("\t" x $ll);
+ push(@out,$tmp1);
+ push(@out,&conv($p1)."\n");
+ }
+
+sub out1
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+ local(%special)=("bswapl",0x0FC8);
+
+ if ((defined($special{$name})) && defined($regs{$p1}))
+ {
+ $op=$special{$name}|$reg_val{$p1};
+ $tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
+ $tmp2=sprintf(".byte %d\t",$op &0xff);
+ push(@out,$tmp1);
+ push(@out,$tmp2);
+
+ $p2=&conv($p2);
+ $p1=&conv($p1);
+ &main::comment("$name $p2 $p1");
+ return;
+ }
+
+ push(@out,"\t$name\t".&conv($p1)."\n");
+ }
+
+sub out1p
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t*".&conv($p1)."\n");
+ }
+
+sub out0
+ {
+ push(@out,"\t$_[0]\n");
+ }
+
+sub conv
+ {
+ local($p)=@_;
+
+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+
+ $p=$regs{$p} if (defined($regs{$p}));
+
+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
+ return $p;
+ }
+
+sub main::file
+ {
+ local($file)=@_;
+
+ local($tmp)=<<"EOF";
+ .file "$file.s"
+ .version "01.01"
+EOF
+# Removed the next line from previous infile
+#gcc2_compiled.:
+ push(@out,$tmp);
+ }
+
+sub main::function_begin
+ {
+ local($func)=@_;
+
+ &main::external_label($func);
+ $func=$under.$func;
+
+ local($tmp)=<<"EOF";
+.text
+ .align $align
+.globl $func
+EOF
+ push(@out,$tmp);
+ if ($main::cpp)
+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
+ elsif ($main::gaswin)
+ { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
+ push(@out,"$func:\n");
+ $tmp=<<"EOF";
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+
+EOF
+ push(@out,$tmp);
+ $stack=20;
+ }
+
+sub main::function_begin_B
+ {
+ local($func,$extra)=@_;
+
+ &main::external_label($func);
+ $func=$under.$func;
+
+ local($tmp)=<<"EOF";
+.text
+ .align $align
+.globl $func
+EOF
+ push(@out,$tmp);
+ if ($main::cpp)
+ { push(@out,"\tTYPE($func,\@function)\n"); }
+ elsif ($main::gaswin)
+ { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
+ else { push(@out,"\t.type $func,\@function\n"); }
+ push(@out,"$func:\n");
+ $stack=4;
+ }
+
+sub main::function_end
+ {
+ local($func)=@_;
+
+ $func=$under.$func;
+
+ local($tmp)=<<"EOF";
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.${func}_end:
+EOF
+ push(@out,$tmp);
+ if ($main::cpp)
+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
+ elsif ($main::gaswin)
+ { $tmp=push(@out,"\t.align 4\n"); }
+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
+ push(@out,".ident \"$func\"\n");
+ $stack=0;
+ %label=();
+ }
+
+sub main::function_end_A
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+EOF
+ push(@out,$tmp);
+ }
+
+sub main::function_end_B
+ {
+ local($func)=@_;
+
+ $func=$under.$func;
+
+ push(@out,".L_${func}_end:\n");
+ if ($main::cpp)
+ { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); }
+ elsif ($main::gaswin)
+ { push(@out,"\t.align 4\n"); }
+ else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); }
+ push(@out,".ident \"desasm.pl\"\n");
+ $stack=0;
+ %label=();
+ }
+
+sub main::wparam
+ {
+ local($num)=@_;
+
+ return(&main::DWP($stack+$num*4,"esp","",0));
+ }
+
+sub main::stack_push
+ {
+ local($num)=@_;
+ $stack+=$num*4;
+ &main::sub("esp",$num*4);
+ }
+
+sub main::stack_pop
+ {
+ local($num)=@_;
+ $stack-=$num*4;
+ &main::add("esp",$num*4);
+ }
+
+sub main::swtmp
+ {
+ return(&main::DWP($_[0]*4,"esp","",0));
+ }
+
+# Should use swtmp, which is above esp. Linix can trash the stack above esp
+#sub main::wtmp
+# {
+# local($num)=@_;
+#
+# return(&main::DWP(-($num+1)*4,"esp","",0));
+# }
+
+sub main::comment
+ {
+ foreach (@_)
+ {
+ if (/^\s*$/)
+ { push(@out,"\n"); }
+ else
+ { push(@out,"\t$com_start $_ $com_end\n"); }
+ }
+ }
+
+sub main::label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}=".${label}${_[0]}";
+ $label++;
+ }
+ return($label{$_[0]});
+ }
+
+sub main::set_label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}=".${label}${_[0]}";
+ $label++;
+ }
+ push(@out,".align $align\n") if ($_[1] != 0);
+ push(@out,"$label{$_[0]}:\n");
+ }
+
+sub main::file_end
+ {
+ }
+
+sub main::data_word
+ {
+ push(@out,"\t.long $_[0]\n");
+ }
+
+##
+## Additional functions required for MMX and other ops
+##
+sub main::testb { &out2('testb', @_) }
+sub main::movzx { &out2('movzx', @_) }
+sub main::movd { &out2('movd', @_) }
+sub main::emms { &out0('emms', @_) }
diff --git a/src/libfreeswan/libdes/.cvsignore b/src/libfreeswan/libdes/.cvsignore
new file mode 100644
index 000000000..e06b80457
--- /dev/null
+++ b/src/libfreeswan/libdes/.cvsignore
@@ -0,0 +1,3 @@
+des_opts
+destest
+speed
diff --git a/src/libfreeswan/libdes/Makefile b/src/libfreeswan/libdes/Makefile
new file mode 100644
index 000000000..e00bb0073
--- /dev/null
+++ b/src/libfreeswan/libdes/Makefile
@@ -0,0 +1,245 @@
+ifndef FREESWANSRCDIR
+FREESWANSRCDIR=../..
+endif
+
+include ${FREESWANSRCDIR}/Makefile.inc
+
+KLIPSD=${FREESWANSRCDIR}/linux
+SRCDIR=${KLIPSD}/crypto/ciphers/des
+
+VPATH =${SRCDIR}
+
+# You must select the correct terminal control system to be used to
+# turn character echo off when reading passwords. There a 5 systems
+# SGTTY - the old BSD system
+# TERMIO - most system V boxes
+# TERMIOS - SGI (ala IRIX).
+# VMS - the DEC operating system
+# MSDOS - we all know what it is :-)
+# read_pwd.c makes a reasonable guess at what is correct.
+
+# Targets
+# make - twidle the options yourself :-)
+# make cc - standard cc options
+# make gcc - standard gcc options
+# make x86-elf - linux-elf etc
+# make x86-out - linux-a.out, FreeBSD etc
+# make x86-solaris
+# make x86-bdsi
+
+# If you are on a DEC Alpha, edit des.h and change the DES_LONG
+# define to 'unsigned int'. I have seen this give a %20 speedup.
+
+OPTS0= -DLIBDES_LIT -DRAND -DTERMIO #-DNOCONST
+
+# Version 1.94 has changed the strings_to_key function so that it is
+# now compatible with MITs when the string is longer than 8 characters.
+# If you wish to keep the old version, uncomment the following line.
+# This will affect the -E/-D options on des(1).
+#OPTS1= -DOLD_STR_TO_KEY
+
+# There are 4 possible performance options
+# -DDES_PTR
+# -DDES_RISC1
+# -DDES_RISC2 (only one of DES_RISC1 and DES_RISC2)
+# -DDES_UNROLL
+# after the initial build, run 'des_opts' to see which options are best
+# for your platform. There are some listed in options.txt
+#OPTS2= -DDES_PTR
+#OPTS3= -DDES_RISC1 # or DES_RISC2
+#OPTS4= -DDES_UNROLL
+
+OPTS= $(OPTS0) $(OPTS1) $(OPTS2) $(OPTS3) $(OPTS4)
+
+MAKE=make -f Makefile
+#CC=cc
+#CFLAG= -O
+
+#CC=gcc
+#CFLAG= -O4 -funroll-loops -fomit-frame-pointer
+# normally overridden by FreeS/WAN Makefiles anyway
+CFLAG= -O3 -fomit-frame-pointer -I${KLIPSD}/include -I${SRCDIR}
+
+CFLAGS=$(OPTS) $(CFLAG) $(USERCOMPILE)
+CPP=$(CC) -E
+
+# Assember version of des_encrypt*().
+DES_ENC=des_enc.o fcrypt_b.o # normal C version
+#DES_ENC=asm/dx86-elf.o asm/yx86-elf.o # elf format x86
+#DES_ENC=asm/dx86-out.o asm/yx86-out.o # a.out format x86
+#DES_ENC=asm/dx86-sol.o asm/yx86-sol.o # solaris format x86
+#DES_ENC=asm/dx86bsdi.o asm/yx86basi.o # bsdi format x86
+
+LIBDIR=$(DESTDIR)$(INC_USRLOCAL)/lib
+INCDIR=$(DESTDIR)$(INC_USRLOCAL)/include
+MANDIR=$(MANTREE)
+MAN1=1
+MAN3=3
+SHELL=/bin/sh
+MAN1=1
+MAN3=3
+SHELL=/bin/sh
+OBJ_LIT=cbc_enc.o ecb_enc.o $(DES_ENC) fcrypt.o set_key.o
+OBJ_FULL=cbc_cksm.o $(OBJ_LIT) pcbc_enc.o \
+ xcbc_enc.o qud_cksm.o \
+ cfb64ede.o cfb64enc.o cfb_enc.o ecb3_enc.o \
+ enc_read.o enc_writ.o ofb64ede.o ofb64enc.o ofb_enc.o \
+ rand_key.o read_pwd.o read2pwd.o rpc_enc.o str2key.o supp.o
+
+GENERAL_LIT=COPYRIGHT INSTALL README VERSION Makefile des_crypt.man \
+ des.doc options.txt asm
+
+GENERAL_FULL=$(GENERAL_LIT) FILES Imakefile times vms.com KERBEROS MODES.DES \
+ des.man DES.pm DES.pod DES.xs Makefile.PL dess.S des3s.S \
+ Makefile.uni typemap t Makefile.ssl makefile.bc Makefile.lit \
+ des.org des_locl.org
+
+TESTING_LIT= destest speed des_opts
+TESTING_FULL= rpw $(TESTING_LIT)
+TESTING_SRC_LIT=destest.c speed.c des_opts.c
+TESTING_SRC_FULL=rpw.c $(TESTING_SRC_LIT)
+HEADERS_LIT=des_ver.h des.h des_locl.h podd.h sk.h spr.h
+HEADERS_FULL= $(HEADERS_LIT) rpc_des.h
+LIBDES_LIT=cbc_enc.c ecb_enc.c fcrypt.c set_key.c des_enc.c fcrypt_b.c
+
+LIBDES_FULL= cbc_cksm.c pcbc_enc.c qud_cksm.c \
+ cfb64ede.c cfb64enc.c cfb_enc.c ecb3_enc.c \
+ enc_read.c enc_writ.c ofb64ede.c ofb64enc.c ofb_enc.c \
+ rand_key.c rpc_enc.c str2key.c supp.c \
+ xcbc_enc.c $(LIBDES_LIT) read_pwd.c read2pwd.c
+
+PERL= des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl
+
+OBJ= $(OBJ_LIT)
+GENERAL=$(GENERAL_LIT)
+TESTING=$(TESTING_LIT)
+TESTING_SRC=$(TESTING_SRC_LIT)
+HEADERS=$(HEADERS_LIT)
+LIBDES= $(LIBDES_LIT)
+
+ALL= $(GENERAL) $(TESTING_SRC) $(LIBDES) $(PERL) $(HEADERS)
+
+DLIB= libdes.a
+
+.PHONY: all cc gcc x86-elf x86-out x86-solaris x86-bsdi test tar_lit \
+ tar shar depend clean dclean install check checkprograms
+
+all: $(DLIB) $(TESTING)
+programs: $(DLIB)
+
+cc:
+ $(MAKE) CC=cc CFLAGS="-O $(OPTS) $(CFLAG)" all
+
+gcc:
+ $(MAKE) CC=gcc CFLAGS="-O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all
+
+x86-elf:
+ $(MAKE) DES_ENC='asm/dx86-elf.o asm/yx86-elf.o' CC='$(CC)' CFLAGS="-DELF $(OPTS) $(CFLAG)" all
+
+x86-out:
+ $(MAKE) DES_ENC='asm/dx86-out.o asm/yx86-out.o' CC='$(CC)' CFLAGS="-DOUT $(OPTS) $(CFLAG)" all
+
+x86-solaris:
+ $(MAKE) DES_ENC='asm/dx86-sol.o asm/yx86-sol.o' CC='$(CC)' CFLAGS="-DSOL $(OPTS) $(CFLAG)" all
+
+x86-bsdi:
+ $(MAKE) DES_ENC='asm/dx86bsdi.o asm/yx86bsdi.o' CC='$(CC)' CFLAGS="-DBSDI $(OPTS) $(CFLAG)" all
+
+# elf
+asm/dx86-elf.o: asm/dx86unix.S
+ $(CPP) -DELF asm/dx86unix.S | $(AS) -o asm/dx86-elf.o
+
+asm/yx86-elf.o: asm/yx86unix.S
+ $(CPP) -DELF asm/yx86unix.S | $(AS) -o asm/yx86-elf.o
+
+# solaris
+asm/dx86-sol.o: asm/dx86unix.S
+ $(CC) -E -DSOL asm/dx86unix.S | sed 's/^#.*//' > asm/dx86-sol.s
+ as -o asm/dx86-sol.o asm/dx86-sol.s
+ rm -f asm/dx86-sol.s
+
+asm/yx86-sol.o: asm/yx86unix.S
+ $(CC) -E -DSOL asm/yx86unix.S | sed 's/^#.*//' > asm/yx86-sol.s
+ as -o asm/yx86-sol.o asm/yx86-sol.s
+ rm -f asm/yx86-sol.s
+
+# a.out
+asm/dx86-out.o: asm/dx86unix.S
+ $(CPP) -DOUT asm/dx86unix.S | $(AS) -o asm/dx86-out.o
+
+asm/yx86-out.o: asm/yx86unix.S
+ $(CPP) -DOUT asm/yx86unix.S | $(AS) -o asm/yx86-out.o
+
+# bsdi
+asm/dx86bsdi.o: asm/dx86unix.S
+ $(CPP) -DBSDI asm/dx86unix.S | $(AS) -o asm/dx86bsdi.o
+
+asm/yx86bsdi.o: asm/yx86unix.S
+ $(CPP) -DBSDI asm/yx86unix.S | $(AS) -o asm/yx86bsdi.o
+
+asm/dx86unix.S:
+ (cd asm; perl des-586.pl cpp >dx86unix.S)
+
+asm/yx86unix.S:
+ (cd asm; perl crypt586.pl cpp >yx86unix.S)
+
+test: all
+ ./destest
+
+$(DLIB): $(OBJ)
+ rm -f $(DLIB)
+ $(AR) crs $(DLIB) $(OBJ)
+
+des_opts: des_opts.o $(DLIB)
+ $(CC) $(CFLAGS) -o des_opts des_opts.o $(DLIB)
+
+destest: destest.o $(DLIB)
+ $(CC) $(CFLAGS) -o destest destest.o $(DLIB)
+
+rpw: rpw.o $(DLIB)
+ $(CC) $(CFLAGS) -o rpw rpw.o $(DLIB)
+
+speed: speed.o $(DLIB)
+ $(CC) $(CFLAGS) -o speed speed.o $(DLIB)
+
+des: des.o $(DLIB)
+ $(CC) $(CFLAGS) -o des des.o $(DLIB)
+
+tags:
+ ctags $(TESTING_SRC) $(LIBDES)
+
+tar_lit:
+ /bin/mv Makefile Makefile.tmp
+ /bin/cp Makefile.lit Makefile
+ tar chf libdes-l.tar $(LIBDES_LIT) $(HEADERS_LIT) \
+ $(GENERAL_LIT) $(TESTING_SRC_LIT)
+ /bin/rm -f Makefile
+ /bin/mv Makefile.tmp Makefile
+
+tar:
+ tar chf libdes.tar $(ALL)
+
+shar:
+ shar $(ALL) >libdes.shar
+
+depend:
+ makedepend $(LIBDES) $(TESTING_SRC)
+
+clean:
+ /bin/rm -f *.o tags core $(TESTING) $(DLIB) .nfs* *.old *.bak asm/*.o \
+ asm/*.S
+
+dclean:
+ sed -e '/^# DO NOT DELETE THIS LINE/ q' Makefile >Makefile.new
+ mv -f Makefile.new Makefile
+
+install install_file_list:
+ @true
+
+check:
+ echo no checks in lib right now.
+
+checkprograms:
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
diff --git a/src/libfreeswan/libdes/des.h b/src/libfreeswan/libdes/des.h
new file mode 100644
index 000000000..baddf8647
--- /dev/null
+++ b/src/libfreeswan/libdes/des.h
@@ -0,0 +1,308 @@
+/* crypto/des/des.org */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * Always modify des.org since des.h is automatically generated from
+ * it during SSLeay configuration.
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+/* Must be unsigned int on ia64/Itanium or DES breaks badly */
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <sys/types.h>
+#endif
+
+#ifndef DES_LONG
+#define DES_LONG u_int32_t
+#endif
+
+typedef unsigned char des_cblock[8];
+typedef struct des_ks_struct
+ {
+ union {
+ des_cblock _;
+ /* make sure things are correct size on machines with
+ * 8 byte longs */
+ DES_LONG pad[2];
+ } ks;
+#undef _
+#define _ ks._
+ } des_key_schedule[16];
+
+#define DES_KEY_SZ (sizeof(des_cblock))
+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
+
+#define DES_ENCRYPT 1
+#define DES_DECRYPT 0
+
+#define DES_CBC_MODE 0
+#define DES_PCBC_MODE 1
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#ifdef KERBEROS
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#endif
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define set_key des_set_key
+#define key_sched des_key_sched
+#define ecb_encrypt des_ecb_encrypt
+#define cbc_encrypt des_cbc_encrypt
+#define ncbc_encrypt des_ncbc_encrypt
+#define xcbc_encrypt des_xcbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define quad_cksum des_quad_cksum
+
+/* For compatibility with the MIT lib - eay 20/05/92 */
+typedef des_key_schedule bit_64;
+#define des_fixup_key_parity des_set_odd_parity
+#define des_check_key_parity check_parity
+
+extern int des_check_key; /* defaults to false */
+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
+
+/* The next line is used to disable full ANSI prototypes, if your
+ * compiler has problems with the prototypes, make sure this line always
+ * evaluates to true :-) */
+#if defined(MSDOS) || defined(__STDC__)
+#undef NOPROTO
+#endif
+#ifndef NOPROTO
+char *des_options(void);
+void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
+ des_key_schedule ks1,des_key_schedule ks2,
+ des_key_schedule ks3, int enc);
+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
+ long length,des_key_schedule schedule,des_cblock *ivec);
+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,int enc);
+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,int enc);
+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,
+ des_cblock *inw,des_cblock *outw,int enc);
+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
+void des_ecb_encrypt(des_cblock *input,des_cblock *output,
+ des_key_schedule ks,int enc);
+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
+void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
+ des_key_schedule ks2, des_key_schedule ks3);
+void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
+ des_key_schedule ks2, des_key_schedule ks3);
+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
+ long length, des_key_schedule ks1, des_key_schedule ks2,
+ des_key_schedule ks3, des_cblock *ivec, int enc);
+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, des_key_schedule ks1, des_key_schedule ks2,
+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+ long length, des_key_schedule ks1, des_key_schedule ks2,
+ des_key_schedule ks3, des_cblock *ivec, int *num);
+
+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
+ des_cblock (*out_white));
+
+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
+ des_cblock *iv);
+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
+ des_cblock *iv);
+char *des_fcrypt(const char *buf,const char *salt, char *ret);
+#ifdef PERL5
+char *des_crypt(const char *buf,const char *salt);
+#else
+/* some stupid compilers complain because I have declared char instead
+ * of const char */
+#ifndef __KERNEL__
+#ifdef HEADER_DES_LOCL_H
+char *crypt(const char *buf,const char *salt);
+#else /* HEADER_DES_LOCL_H */
+char *crypt(void);
+#endif /* HEADER_DES_LOCL_H */
+#endif /* __KERNEL__ */
+#endif /* PERL5 */
+void des_ofb_encrypt(unsigned char *in,unsigned char *out,
+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+ des_key_schedule schedule,des_cblock *ivec,int enc);
+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
+ long length,int out_count,des_cblock *seed);
+void des_random_seed(des_cblock key);
+void des_random_key(des_cblock ret);
+int des_read_password(des_cblock *key,char *prompt,int verify);
+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
+ char *prompt,int verify);
+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
+void des_set_odd_parity(des_cblock *key);
+int des_is_weak_key(des_cblock *key);
+int des_set_key(des_cblock *key,des_key_schedule schedule);
+int des_key_sched(des_cblock *key,des_key_schedule schedule);
+void des_string_to_key(char *str,des_cblock *key);
+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+ des_key_schedule schedule, des_cblock *ivec, int *num);
+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
+
+/* Extra functions from Mark Murray <mark@grondar.za> */
+/* The following functions are not in the normal unix build or the
+ * SSLeay build. When using the SSLeay build, use RAND_seed()
+ * and RAND_bytes() instead. */
+int des_new_random_key(des_cblock *key);
+void des_init_random_number_generator(des_cblock *key);
+void des_set_random_generator_seed(des_cblock *key);
+void des_set_sequence_number(des_cblock new_sequence_number);
+void des_generate_random_block(des_cblock *block);
+
+#else
+
+char *des_options();
+void des_ecb3_encrypt();
+DES_LONG des_cbc_cksum();
+void des_cbc_encrypt();
+void des_ncbc_encrypt();
+void des_xcbc_encrypt();
+void des_cfb_encrypt();
+void des_ede3_cfb64_encrypt();
+void des_ede3_ofb64_encrypt();
+void des_ecb_encrypt();
+void des_encrypt();
+void des_encrypt2();
+void des_encrypt3();
+void des_decrypt3();
+void des_ede3_cbc_encrypt();
+int des_enc_read();
+int des_enc_write();
+char *des_fcrypt();
+#ifdef PERL5
+char *des_crypt();
+#else
+char *crypt();
+#endif
+void des_ofb_encrypt();
+void des_pcbc_encrypt();
+DES_LONG des_quad_cksum();
+void des_random_seed();
+void des_random_key();
+int des_read_password();
+int des_read_2passwords();
+int des_read_pw_string();
+void des_set_odd_parity();
+int des_is_weak_key();
+int des_set_key();
+int des_key_sched();
+void des_string_to_key();
+void des_string_to_2keys();
+void des_cfb64_encrypt();
+void des_ofb64_encrypt();
+int des_read_pw();
+void des_xwhite_in2out();
+
+/* Extra functions from Mark Murray <mark@grondar.za> */
+/* The following functions are not in the normal unix build or the
+ * SSLeay build. When using the SSLeay build, use RAND_seed()
+ * and RAND_bytes() instead. */
+#ifdef FreeBSD
+int des_new_random_key();
+void des_init_random_number_generator();
+void des_set_random_generator_seed();
+void des_set_sequence_number();
+void des_generate_random_block();
+#endif
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/libfreeswan/libdes/des/COPYRIGHT b/src/libfreeswan/libdes/des/COPYRIGHT
new file mode 100644
index 000000000..5469e1e46
--- /dev/null
+++ b/src/libfreeswan/libdes/des/COPYRIGHT
@@ -0,0 +1,50 @@
+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+All rights reserved.
+
+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
+The implementation was written so as to conform with MIT's libdes.
+
+This library is free for commercial and non-commercial use as long as
+the following conditions are aheared to. The following conditions
+apply to all code found in this distribution.
+
+Copyright remains Eric Young's, and as such any Copyright notices in
+the code are not to be removed.
+If this package is used in a product, Eric Young should be given attribution
+as the author of that the SSL library. This can be in the form of a textual
+message at program startup or in documentation (online or textual) provided
+with the package.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ This product includes software developed by Eric Young (eay@cryptsoft.com)
+
+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The license and distribution terms for any publically available version or
+derivative of this code cannot be changed. i.e. this code cannot simply be
+copied and put under another distrubution license
+[including the GNU Public License.]
+
+The reason behind this being stated in this direct manner is past
+experience in code simply being copied and the attribution removed
+from it and then being distributed as part of other packages. This
+implementation was a non-trivial and unpaid effort.
diff --git a/src/libfreeswan/libdes/des/INSTALL b/src/libfreeswan/libdes/des/INSTALL
new file mode 100644
index 000000000..32457d775
--- /dev/null
+++ b/src/libfreeswan/libdes/des/INSTALL
@@ -0,0 +1,69 @@
+Check the CC and CFLAGS lines in the makefile
+
+If your C library does not support the times(3) function, change the
+#define TIMES to
+#undef TIMES in speed.c
+If it does, check the HZ value for the times(3) function.
+If your system does not define CLK_TCK it will be assumed to
+be 100.0.
+
+If possible use gcc v 2.7.?
+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
+In recent times, some system compilers give better performace.
+
+type 'make'
+
+run './destest' to check things are ok.
+run './rpw' to check the tty code for reading passwords works.
+run './speed' to see how fast those optimisations make the library run :-)
+run './des_opts' to determin the best compile time options.
+
+The output from des_opts should be put in the makefile options and des_enc.c
+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
+and then you can use the 'DES_PTR' option.
+
+The file options.txt has the options listed for best speed on quite a
+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
+turn on the relevent option in the Makefile
+
+There are some special Makefile targets that make life easier.
+make cc - standard cc build
+make gcc - standard gcc build
+make x86-elf - x86 assembler (elf), linux-elf.
+make x86-out - x86 assembler (a.out), FreeBSD
+make x86-solaris- x86 assembler
+make x86-bsdi - x86 assembler (a.out with primative assembler).
+
+If at all possible use the assembler (for Windows NT/95, use
+asm/win32.obj to link with). The x86 assembler is very very fast.
+
+A make install will by default install
+libdes.a in /usr/local/lib/libdes.a
+des in /usr/local/bin/des
+des_crypt.man in /usr/local/man/man3/des_crypt.3
+des.man in /usr/local/man/man1/des.1
+des.h in /usr/include/des.h
+
+des(1) should be compatible with sunOS's but I have been unable to
+test it.
+
+These routines should compile on MSDOS, most 32bit and 64bit version
+of Unix (BSD and SYSV) and VMS, without modification.
+The only problems should be #include files that are in the wrong places.
+
+These routines can be compiled under MSDOS.
+I have successfully encrypted files using des(1) under MSDOS and then
+decrypted the files on a SparcStation.
+I have been able to compile and test the routines with
+Microsoft C v 5.1 and Turbo C v 2.0.
+The code in this library is in no way optimised for the 16bit
+operation of MSDOS.
+
+When building for glibc, ignore all of the above and just unpack into
+glibc-1.??/des and then gmake as per normal.
+
+As a final note on performace. Certain CPUs like sparcs and Alpha often give
+a %10 speed difference depending on the link order. It is rather anoying
+when one program reports 'x' DES encrypts a second and another reports
+'x*0.9' the speed.
diff --git a/src/libfreeswan/libdes/des/Makefile.objs b/src/libfreeswan/libdes/des/Makefile.objs
new file mode 100644
index 000000000..4cef95963
--- /dev/null
+++ b/src/libfreeswan/libdes/des/Makefile.objs
@@ -0,0 +1,20 @@
+obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o
+#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o
+obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o
+#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o
+obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o
+
+ifeq ($(strip ${SUBARCH}),)
+SUBARCH:=${ARCH}
+endif
+
+ifeq (${SUBARCH},i386)
+obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o
+else
+obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o
+endif
+
+
+
+
+
diff --git a/src/libfreeswan/libdes/des/README b/src/libfreeswan/libdes/des/README
new file mode 100644
index 000000000..621a5ab46
--- /dev/null
+++ b/src/libfreeswan/libdes/des/README
@@ -0,0 +1,54 @@
+
+ libdes, Version 4.01 10-Jan-97
+
+ Copyright (c) 1997, Eric Young
+ All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms specified in COPYRIGHT.
+
+--
+The primary ftp site for this library is
+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
+libdes is now also shipped with SSLeay. Primary ftp site of
+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
+
+The best way to build this library is to build it as part of SSLeay.
+
+This kit builds a DES encryption library and a DES encryption program.
+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
+implementation of crypt(3).
+It contains support routines to read keys from a terminal,
+generate a random key, generate a key from an arbitrary length string,
+read/write encrypted data from/to a file descriptor.
+
+The implementation was written so as to conform with the manual entry
+for the des_crypt(3) library routines from MIT's project Athena.
+
+destest should be run after compilation to test the des routines.
+rpw should be run after compilation to test the read password routines.
+The des program is a replacement for the sun des command. I believe it
+conforms to the sun version.
+
+The Imakefile is setup for use in the kerberos distribution.
+
+These routines are best compiled with gcc or any other good
+optimising compiler.
+Just turn you optimiser up to the highest settings and run destest
+after the build to make sure everything works.
+
+I believe these routines are close to the fastest and most portable DES
+routines that use small lookup tables (4.5k) that are publicly available.
+The fcrypt routine is faster than ufc's fcrypt (when compiling with
+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
+[ 10-Jan-97 and a function of an incorrect speed testing program in
+ ufc which gave much better test figures that reality ].
+
+It is worth noting that on sparc and Alpha CPUs, performance of the DES
+library can vary by upto %10 due to the positioning of files after application
+linkage.
+
+Eric Young (eay@cryptsoft.com)
+
diff --git a/src/libfreeswan/libdes/des/README.freeswan b/src/libfreeswan/libdes/des/README.freeswan
new file mode 100644
index 000000000..40874d5f8
--- /dev/null
+++ b/src/libfreeswan/libdes/des/README.freeswan
@@ -0,0 +1,33 @@
+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
+
+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
+on the Alpha, instead of just noting the issue in a comment.
+
+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
+is built as a module (depending on details of Linux configuration options).
+
+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
+it cope better with Linux kernel Makefile stupidities, and took out an
+explicit CC=gcc (unwise on systems with strange compilers).
+
+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
+of one function found only in the full libdes (not in libdes-lite), to
+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
+Schultz for spotting this and pointing out the fixes.)
+
+We deleted a couple of .obj files in the asm subdirectory, which appear to
+have been included in the original library by accident.
+
+We have added an include of our Makefile.inc file, to permit overriding
+things like choice of compiler (although the libdes Makefile would
+probably need some work to make this effective).
+
+
+
+Note that Eric Young is no longer at the email address listed in these
+files, and is (alas) no longer working on free crypto software.
+
+
+
+This file is RCSID $Id: README.freeswan,v 1.1 2004/03/15 20:35:25 as Exp $
diff --git a/src/libfreeswan/libdes/des/VERSION b/src/libfreeswan/libdes/des/VERSION
new file mode 100644
index 000000000..345035195
--- /dev/null
+++ b/src/libfreeswan/libdes/des/VERSION
@@ -0,0 +1,406 @@
+Version 4.04
+ Fixed a few tests in destest. Also added x86 assember for
+ des_ncbc_encrypt() which is the standard cbc mode function.
+ This makes a very very large performace difference.
+ Ariel Glenn ariel@columbia.edu reports that the terminal
+ 'turn echo off' can return (errno == EINVAL) under solaris
+ when redirection is used. So I now catch that as well as ENOTTY.
+
+
+Version 4.03
+ Left a static out of enc_write.c, which caused to buffer to be
+ continiously malloc()ed. Does anyone use these functions? I keep
+ on feeling like removing them since I only had these in there
+ for a version of kerberised login. Anyway, this was pointed out
+ by Theo de Raadt <deraadt@cvs.openbsd.org>
+ The 'n' bit ofb code was wrong, it was not shifting the shift
+ register. It worked correctly for n == 64. Thanks to
+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
+
+Version 4.02
+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
+ when checking for weak keys which is wrong :-(, pointed out by
+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
+
+Version 4.01
+ Even faster inner loop in the DES assembler for x86 and a modification
+ for IP/FP which is faster on x86. Both of these changes are
+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
+ changes make the assembler run %40 faster on a pentium. This is just
+ a case of getting the instruction sequence 'just right'.
+ All credit to 'Svend' :-)
+ Quite a few special x86 'make' targets.
+ A libdes-l (lite) distribution.
+
+Version 4.00
+ After a bit of a pause, I'll up the major version number since this
+ is mostly a performace release. I've added x86 assembler and
+ added more options for performance. A %28 speedup for gcc
+ on a pentium and the assembler is a %50 speedup.
+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
+ Run des_opts to work out which options should be used.
+ DES_RISC1/DES_RISC2 use alternative inner loops which use
+ more registers but should give speedups on any CPU that does
+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
+ which costs in code size.
+
+Version 3.26
+ I've finally removed one of the shifts in D_ENCRYPT. This
+ meant I've changed the des_SPtrans table (spr.h), the set_key()
+ function and some things in des_enc.c. This has definitly
+ made things faster :-). I've known about this one for some
+ time but I've been too lazy to follow it up :-).
+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
+ instead of L^=((..)|(..)|(..).. This should save a register at
+ least.
+ Assember for x86. The file to replace is des_enc.c, which is replaced
+ by one of the assembler files found in asm. Look at des/asm/readme
+ for more info.
+
+ /* Modification to fcrypt so it can be compiled to support
+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
+
+ SIGWINCH case put in des_read_passwd() so the function does not
+ 'exit' if this function is recieved.
+
+Version 3.25 17/07/96
+ Modified read_pwd.c so that stdin can be read if not a tty.
+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
+ des_init_random_number_generator() shortened due to VMS linker
+ limits.
+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
+ 8 byte quantites xored before and after encryption.
+ des_xcbc_encryption() - the name is funny to preserve the des_
+ prefix on all functions.
+
+Version 3.24 20/04/96
+ The DES_PTR macro option checked and used by SSLeay configuration
+
+Version 3.23 11/04/96
+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
+ it gives a %20 speedup :-)
+ Fixed the problem with des.pl under perl5. The patches were
+ sent by Ed Kubaitis (ejk@uiuc.edu).
+ if fcrypt.c, changed values to handle illegal salt values the way
+ normal crypt() implementations do. Some programs apparently use
+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
+
+Version 3.22 29/11/95
+ Bug in des(1), an error with the uuencoding stuff when the
+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
+ for the patch.
+
+Version 3.21 22/11/95
+ After some emailing back and forth with
+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
+ and in a future version I will probably put in some of the
+ optimisation he suggested for use with the DES_USE_PTR option.
+ Extra routines from Mark Murray <mark@grondar.za> for use in
+ freeBSD. They mostly involve random number generation for use
+ with kerberos. They involve evil machine specific system calls
+ etc so I would normally suggest pushing this stuff into the
+ application and/or using RAND_seed()/RAND_bytes() if you are
+ using this DES library as part of SSLeay.
+ Redone the read_pw() function so that it is cleaner and
+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
+ for the initial patches for this.
+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
+ done just to make things more consistent.
+ I have also now added triple DES versions of cfb and ofb.
+
+Version 3.20
+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
+ my des_random_seed() function was only copying 4 bytes of the
+ passed seed into the init structure. It is now fixed to copy 8.
+ My own suggestion is to used something like MD5 :-)
+
+Version 3.19
+ While looking at my code one day, I though, why do I keep on
+ calling des_encrypt(in,out,ks,enc) when every function that
+ calls it has in and out the same. So I dropped the 'out'
+ parameter, people should not be using this function.
+
+Version 3.18 30/08/95
+ Fixed a few bit with the distribution and the filenames.
+ 3.17 had been munged via a move to DOS and back again.
+ NO CODE CHANGES
+
+Version 3.17 14/07/95
+ Fixed ede3 cbc which I had broken in 3.16. I have also
+ removed some unneeded variables in 7-8 of the routines.
+
+Version 3.16 26/06/95
+ Added des_encrypt2() which does not use IP/FP, used by triple
+ des routines. Tweaked things a bit elsewhere. %13 speedup on
+ sparc and %6 on a R4400 for ede3 cbc mode.
+
+Version 3.15 06/06/95
+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
+ 'normal' and copies the new iv value back over the top of the
+ passed parameter.
+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
+ I need to update the documentation.
+
+Version 3.14 31/05/95
+ New release upon the world, as part of my SSL implementation.
+ New copyright and usage stuff. Basically free for all to use
+ as long as you say it came from me :-)
+
+Version 3.13 31/05/95
+ A fix in speed.c, if HZ is not defined, I set it to 100.0
+ which is reasonable for most unixes except SunOS 4.x.
+ I now have a #ifdef sun but timing for SunOS 4.x looked very
+ good :-(. At my last job where I used SunOS 4.x, it was
+ defined to be 60.0 (look at the old INSTALL documentation), at
+ the last release had it changed to 100.0 since I now work with
+ Solaris2 and SVR4 boxes.
+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
+ one out.
+
+Version 3.12 08/05/95
+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
+ It has been removed.
+
+Version 3.11 03/05/95
+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
+ and one iv. It is a standard and I needed it for my SSL code.
+ It makes more sense to use this for triple DES than
+ 3cbc_encrypt(). I have also added (or should I say tested :-)
+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
+ number of bytes - 3 bytes in 3 bytes out. Again this is for
+ my SSL library, as a form of encryption to use with SSL
+ telnet.
+
+Version 3.10 22/03/95
+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
+ to cbc3_encrypt, the 2 iv values that were being returned to
+ be used in the next call were reversed :-(.
+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
+ this error.
+
+Version 3.09 01/02/95
+ Fixed des_random_key to far more random, it was rather feeble
+ with regards to picking the initial seed. The problem was
+ pointed out by Olaf Kirch <okir@monad.swb.de>.
+
+Version 3.08 14/12/94
+ Added Makefile.PL so libdes can be built into perl5.
+ Changed des_locl.h so RAND is always defined.
+
+Version 3.07 05/12/94
+ Added GNUmake and stuff so the library can be build with
+ glibc.
+
+Version 3.06 30/08/94
+ Added rpc_enc.c which contains _des_crypt. This is for use in
+ secure_rpc v 4.0
+ Finally fixed the cfb_enc problems.
+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
+ to Rob McMillan <R.McMillan@its.gu.edu.au>
+
+Version 3.05 21/04/94
+ for unsigned long l; gcc does not produce ((l>>34) == 0)
+ This causes bugs in cfb_enc.
+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
+
+Version 3.04 20/04/94
+ Added a version number to des.c and libdes.a
+
+Version 3.03 12/01/94
+ Fixed a bug in non zero iv in 3cbc_enc.
+
+Version 3.02 29/10/93
+ I now work in a place where there are 6+ architectures and 14+
+ OS versions :-).
+ Fixed TERMIO definition so the most sys V boxes will work :-)
+
+Release upon comp.sources.misc
+Version 3.01 08/10/93
+ Added des_3cbc_encrypt()
+
+Version 3.00 07/10/93
+ Fixed up documentation.
+ quad_cksum definitely compatible with MIT's now.
+
+Version 2.30 24/08/93
+ Triple DES now defaults to triple cbc but can do triple ecb
+ with the -b flag.
+ Fixed some MSDOS uuen/uudecoding problems, thanks to
+ Added prototypes.
+
+Version 2.22 29/06/93
+ Fixed a bug in des_is_weak_key() which stopped it working :-(
+ thanks to engineering@MorningStar.Com.
+
+Version 2.21 03/06/93
+ des(1) with no arguments gives quite a bit of help.
+ Added -c (generate ckecksum) flag to des(1).
+ Added -3 (triple DES) flag to des(1).
+ Added cfb and ofb routines to the library.
+
+Version 2.20 11/03/93
+ Added -u (uuencode) flag to des(1).
+ I have been playing with byte order in quad_cksum to make it
+ compatible with MIT's version. All I can say is avid this
+ function if possible since MIT's output is endian dependent.
+
+Version 2.12 14/10/92
+ Added MSDOS specific macro in ecb_encrypt which gives a %70
+ speed up when the code is compiled with turbo C.
+
+Version 2.11 12/10/92
+ Speedup in set_key (recoding of PC-1)
+ I now do it in 47 simple operations, down from 60.
+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ for motivating me to look for a faster system :-)
+ The speedup is probably less that 1% but it is still 13
+ instructions less :-).
+
+Version 2.10 06/10/92
+ The code now works on the 64bit ETA10 and CRAY without modifications or
+ #defines. I believe the code should work on any machine that
+ defines long, int or short to be 8 bytes long.
+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
+ for helping me fix the code to run on 64bit machines (he had
+ access to an ETA10).
+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
+ for testing the routines on a CRAY.
+ read_password.c has been renamed to read_passwd.c
+ string_to_key.c has been renamed to string2key.c
+
+Version 2.00 14/09/92
+ Made mods so that the library should work on 64bit CPU's.
+ Removed all my uchar and ulong defs. To many different
+ versions of unix define them in their header files in too many
+ different combinations :-)
+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
+
+Version 1.99 26/08/92
+ Fixed a bug or 2 in enc_read.c
+ Fixed a bug in enc_write.c
+ Fixed a pseudo bug in fcrypt.c (very obscure).
+
+Version 1.98 31/07/92
+ Support for the ETA10. This is a strange machine that defines
+ longs and ints as 8 bytes and shorts as 4 bytes.
+ Since I do evil things with long * that assume that they are 4
+ bytes. Look in the Makefile for the option to compile for
+ this machine. quad_cksum appears to have problems but I
+ will don't have the time to fix it right now, and this is not
+ a function that uses DES and so will not effect the main uses
+ of the library.
+
+Version 1.97 20/05/92 eay
+ Fixed the Imakefile and made some changes to des.h to fix some
+ problems when building this package with Kerberos v 4.
+
+Version 1.96 18/05/92 eay
+ Fixed a small bug in string_to_key() where problems could
+ occur if des_check_key was set to true and the string
+ generated a weak key.
+
+Patch2 posted to comp.sources.misc
+Version 1.95 13/05/92 eay
+ Added an alternative version of the D_ENCRYPT macro in
+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
+ other will be faster. This was inspired by
+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
+ *(ulong *)((uchar *)ptr+(value&0xfc))
+ vs
+ ptr[value&0x3f]
+ to stop the C compiler doing a <<2 to convert the long array index.
+
+Version 1.94 05/05/92 eay
+ Fixed an incompatibility between my string_to_key and the MIT
+ version. When the key is longer than 8 chars, I was wrapping
+ with a different method. To use the old version, define
+ OLD_STR_TO_KEY in the makefile. Thanks to
+ viktor@newsu.shearson.com (Viktor Dukhovni).
+
+Version 1.93 28/04/92 eay
+ Fixed the VMS mods so that echo is now turned off in
+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
+ MSDOS support added. The routines can be compiled with
+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
+
+Patch1 posted to comp.sources.misc
+Version 1.92 13/04/92 eay
+ Changed D_ENCRYPT so that the rotation of R occurs outside of
+ the loop. This required rotating all the longs in sp.h (now
+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ speed.c has been changed so it will work without SIGALRM. If
+ times(3) is not present it will try to use ftime() instead.
+
+Version 1.91 08/04/92 eay
+ Added -E/-D options to des(1) so it can use string_to_key.
+ Added SVR4 mods suggested by witr@rwwa.COM
+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
+ anyone knows how to turn of tty echo in VMS please tell me or
+ implement it yourself :-).
+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
+ does not like IN/OUT being used.
+
+Libdes posted to comp.sources.misc
+Version 1.9 24/03/92 eay
+ Now contains a fast small crypt replacement.
+ Added des(1) command.
+ Added des_rw_mode so people can use cbc encryption with
+ enc_read and enc_write.
+
+Version 1.8 15/10/91 eay
+ Bug in cbc_cksum.
+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
+ one out.
+
+Version 1.7 24/09/91 eay
+ Fixed set_key :-)
+ set_key is 4 times faster and takes less space.
+ There are a few minor changes that could be made.
+
+Version 1.6 19/09/1991 eay
+ Finally go IP and FP finished.
+ Now I need to fix set_key.
+ This version is quite a bit faster that 1.51
+
+Version 1.52 15/06/1991 eay
+ 20% speedup in ecb_encrypt by changing the E bit selection
+ to use 2 32bit words. This also required modification of the
+ sp table. There is still a way to speedup the IP and IP-1
+ (hints from outer@sq.com) still working on this one :-(.
+
+Version 1.51 07/06/1991 eay
+ Faster des_encrypt by loop unrolling
+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
+
+Version 1.50 28/05/1991 eay
+ Optimised the code a bit more for the sparc. I have improved the
+ speed of the inner des_encrypt by speeding up the initial and
+ final permutations.
+
+Version 1.40 23/10/1990 eay
+ Fixed des_random_key, it did not produce a random key :-(
+
+Version 1.30 2/10/1990 eay
+ Have made des_quad_cksum the same as MIT's, the full package
+ should be compatible with MIT's
+ Have tested on a DECstation 3100
+ Still need to fix des_set_key (make it faster).
+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
+
+Version 1.20 18/09/1990 eay
+ Fixed byte order dependencies.
+ Fixed (I hope) all the word alignment problems.
+ Speedup in des_ecb_encrypt.
+
+Version 1.10 11/09/1990 eay
+ Added des_enc_read and des_enc_write.
+ Still need to fix des_quad_cksum.
+ Still need to document des_enc_read and des_enc_write.
+
+Version 1.00 27/08/1990 eay
+
diff --git a/src/libfreeswan/libdes/des/asm/crypt586.pl b/src/libfreeswan/libdes/des/asm/crypt586.pl
new file mode 100644
index 000000000..297e38dec
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/crypt586.pl
@@ -0,0 +1,204 @@
+#!/usr/bin/perl
+#
+# The inner loop instruction sequence and the IP/FP modifications are from
+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
+# I've added the stuff needed for crypt() but I've not worried about making
+# things perfect.
+#
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],"crypt586.pl");
+
+$L="edi";
+$R="esi";
+
+&external_label("des_SPtrans");
+&fcrypt_body("fcrypt_body");
+&asm_finish();
+
+sub fcrypt_body
+ {
+ local($name,$do_ip)=@_;
+
+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
+
+ &comment("");
+ &comment("Load the 2 words");
+ $ks="ebp";
+
+ &xor( $L, $L);
+ &xor( $R, $R);
+ &mov($ks,&wparam(1));
+
+ &push(25); # add a variable
+
+ &set_label("start");
+ for ($i=0; $i<16; $i+=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
+
+ &comment("");
+ &comment("Round ".sprintf("%d",$i+1));
+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
+ }
+ &mov("ebx", &swtmp(0));
+ &mov("eax", $L);
+ &dec("ebx");
+ &mov($L, $R);
+ &mov($R, "eax");
+ &mov(&swtmp(0), "ebx");
+ &jnz(&label("start"));
+
+ &comment("");
+ &comment("FP");
+ &mov("edx",&wparam(0));
+
+ &FP_new($R,$L,"eax",3);
+ &mov(&DWP(0,"edx","",0),"eax");
+ &mov(&DWP(4,"edx","",0),$L);
+
+ &pop("ecx"); # remove variable
+
+ &function_end($name);
+ }
+
+sub D_ENCRYPT
+ {
+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
+
+ &mov( $u, &wparam(2)); # 2
+ &mov( $t, $R);
+ &shr( $t, 16); # 1
+ &mov( $tmp2, &wparam(3)); # 2
+ &xor( $t, $R); # 1
+
+ &and( $u, $t); # 2
+ &and( $t, $tmp2); # 2
+
+ &mov( $tmp1, $u);
+ &shl( $tmp1, 16); # 1
+ &mov( $tmp2, $t);
+ &shl( $tmp2, 16); # 1
+ &xor( $u, $tmp1); # 2
+ &xor( $t, $tmp2); # 2
+ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2
+ &xor( $u, $tmp1);
+ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2
+ &xor( $u, $R);
+ &xor( $t, $R);
+ &xor( $t, $tmp2);
+
+ &and( $u, "0xfcfcfcfc" ); # 2
+ &xor( $tmp1, $tmp1); # 1
+ &and( $t, "0xcfcfcfcf" ); # 2
+ &xor( $tmp2, $tmp2);
+ &movb( &LB($tmp1), &LB($u) );
+ &movb( &LB($tmp2), &HB($u) );
+ &rotr( $t, 4 );
+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
+ &movb( &LB($tmp1), &LB($t) );
+ &xor( $L, $ks);
+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
+ &xor( $L, $ks);
+ &movb( &LB($tmp2), &HB($t) );
+ &shr( $u, 16);
+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
+ &xor( $L, $ks);
+ &movb( &LB($tmp1), &HB($u) );
+ &shr( $t, 16);
+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
+ &xor( $L, $ks);
+ &mov( $ks, &wparam(1));
+ &movb( &LB($tmp2), &HB($t) );
+ &and( $u, "0xff" );
+ &and( $t, "0xff" );
+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
+ &xor( $L, $tmp1);
+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
+ &xor( $L, $tmp1);
+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
+ &xor( $L, $tmp1);
+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
+ &xor( $L, $tmp1);
+ }
+
+sub n2a
+ {
+ sprintf("%d",$_[0]);
+ }
+
+# now has a side affect of rotating $a by $shift
+sub R_PERM_OP
+ {
+ local($a,$b,$tt,$shift,$mask,$last)=@_;
+
+ &rotl( $a, $shift ) if ($shift != 0);
+ &mov( $tt, $a );
+ &xor( $a, $b );
+ &and( $a, $mask );
+ if ($notlast eq $b)
+ {
+ &xor( $b, $a );
+ &xor( $tt, $a );
+ }
+ else
+ {
+ &xor( $tt, $a );
+ &xor( $b, $a );
+ }
+ &comment("");
+ }
+
+sub IP_new
+ {
+ local($l,$r,$tt,$lr)=@_;
+
+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
+
+ if ($lr != 3)
+ {
+ if (($lr-3) < 0)
+ { &rotr($tt, 3-$lr); }
+ else { &rotl($tt, $lr-3); }
+ }
+ if ($lr != 2)
+ {
+ if (($lr-2) < 0)
+ { &rotr($r, 2-$lr); }
+ else { &rotl($r, $lr-2); }
+ }
+ }
+
+sub FP_new
+ {
+ local($l,$r,$tt,$lr)=@_;
+
+ if ($lr != 2)
+ {
+ if (($lr-2) < 0)
+ { &rotl($r, 2-$lr); }
+ else { &rotr($r, $lr-2); }
+ }
+ if ($lr != 3)
+ {
+ if (($lr-3) < 0)
+ { &rotl($l, 3-$lr); }
+ else { &rotr($l, $lr-3); }
+ }
+
+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
+ &rotr($tt , 4);
+ }
+
diff --git a/src/libfreeswan/libdes/des/asm/des-586.pl b/src/libfreeswan/libdes/des/asm/des-586.pl
new file mode 100644
index 000000000..7f2e09fa7
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/des-586.pl
@@ -0,0 +1,251 @@
+#!/usr/bin/perl
+#
+# The inner loop instruction sequence and the IP/FP modifications are from
+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
+#
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+require "cbc.pl";
+require "desboth.pl";
+
+# base code is in microsft
+# op dest, source
+# format.
+#
+
+&asm_init($ARGV[0],"des-586.pl");
+
+$L="edi";
+$R="esi";
+
+&external_label("des_SPtrans");
+&des_encrypt("des_encrypt",1);
+&des_encrypt("des_encrypt2",0);
+&des_encrypt3("des_encrypt3",1);
+&des_encrypt3("des_decrypt3",0);
+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
+
+&asm_finish();
+
+sub des_encrypt
+ {
+ local($name,$do_ip)=@_;
+
+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
+
+ &push("esi");
+ &push("edi");
+
+ &comment("");
+ &comment("Load the 2 words");
+ $ks="ebp";
+
+ if ($do_ip)
+ {
+ &mov($R,&wparam(0));
+ &xor( "ecx", "ecx" );
+
+ &push("ebx");
+ &push("ebp");
+
+ &mov("eax",&DWP(0,$R,"",0));
+ &mov("ebx",&wparam(2)); # get encrypt flag
+ &mov($L,&DWP(4,$R,"",0));
+ &comment("");
+ &comment("IP");
+ &IP_new("eax",$L,$R,3);
+ }
+ else
+ {
+ &mov("eax",&wparam(0));
+ &xor( "ecx", "ecx" );
+
+ &push("ebx");
+ &push("ebp");
+
+ &mov($R,&DWP(0,"eax","",0));
+ &mov("ebx",&wparam(2)); # get encrypt flag
+ &rotl($R,3);
+ &mov($L,&DWP(4,"eax","",0));
+ &rotl($L,3);
+ }
+
+ &mov( $ks, &wparam(1) );
+ &cmp("ebx","0");
+ &je(&label("start_decrypt"));
+
+ for ($i=0; $i<16; $i+=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
+
+ &comment("");
+ &comment("Round ".sprintf("%d",$i+1));
+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
+ }
+ &jmp(&label("end"));
+
+ &set_label("start_decrypt");
+
+ for ($i=15; $i>0; $i-=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
+ &comment("");
+ &comment("Round ".sprintf("%d",$i-1));
+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
+ }
+
+ &set_label("end");
+
+ if ($do_ip)
+ {
+ &comment("");
+ &comment("FP");
+ &mov("edx",&wparam(0));
+ &FP_new($L,$R,"eax",3);
+
+ &mov(&DWP(0,"edx","",0),"eax");
+ &mov(&DWP(4,"edx","",0),$R);
+ }
+ else
+ {
+ &comment("");
+ &comment("Fixup");
+ &rotr($L,3); # r
+ &mov("eax",&wparam(0));
+ &rotr($R,3); # l
+ &mov(&DWP(0,"eax","",0),$L);
+ &mov(&DWP(4,"eax","",0),$R);
+ }
+
+ &pop("ebp");
+ &pop("ebx");
+ &pop("edi");
+ &pop("esi");
+ &ret();
+
+ &function_end_B($name);
+ }
+
+sub D_ENCRYPT
+ {
+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
+
+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
+ &xor( $tmp1, $tmp1);
+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
+ &xor( $u, $R);
+ &xor( $t, $R);
+ &and( $u, "0xfcfcfcfc" );
+ &and( $t, "0xcfcfcfcf" );
+ &movb( &LB($tmp1), &LB($u) );
+ &movb( &LB($tmp2), &HB($u) );
+ &rotr( $t, 4 );
+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
+ &movb( &LB($tmp1), &LB($t) );
+ &xor( $L, $ks);
+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
+ &xor( $L, $ks); ######
+ &movb( &LB($tmp2), &HB($t) );
+ &shr( $u, 16);
+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
+ &xor( $L, $ks); ######
+ &movb( &LB($tmp1), &HB($u) );
+ &shr( $t, 16);
+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
+ &xor( $L, $ks);
+ &mov( $ks, &wparam(1) );
+ &movb( &LB($tmp2), &HB($t) );
+ &and( $u, "0xff" );
+ &and( $t, "0xff" );
+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
+ &xor( $L, $tmp1);
+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
+ &xor( $L, $tmp1);
+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
+ &xor( $L, $tmp1);
+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
+ &xor( $L, $tmp1);
+ }
+
+sub n2a
+ {
+ sprintf("%d",$_[0]);
+ }
+
+# now has a side affect of rotating $a by $shift
+sub R_PERM_OP
+ {
+ local($a,$b,$tt,$shift,$mask,$last)=@_;
+
+ &rotl( $a, $shift ) if ($shift != 0);
+ &mov( $tt, $a );
+ &xor( $a, $b );
+ &and( $a, $mask );
+ if (!$last eq $b)
+ {
+ &xor( $b, $a );
+ &xor( $tt, $a );
+ }
+ else
+ {
+ &xor( $tt, $a );
+ &xor( $b, $a );
+ }
+ &comment("");
+ }
+
+sub IP_new
+ {
+ local($l,$r,$tt,$lr)=@_;
+
+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
+
+ if ($lr != 3)
+ {
+ if (($lr-3) < 0)
+ { &rotr($tt, 3-$lr); }
+ else { &rotl($tt, $lr-3); }
+ }
+ if ($lr != 2)
+ {
+ if (($lr-2) < 0)
+ { &rotr($r, 2-$lr); }
+ else { &rotl($r, $lr-2); }
+ }
+ }
+
+sub FP_new
+ {
+ local($l,$r,$tt,$lr)=@_;
+
+ if ($lr != 2)
+ {
+ if (($lr-2) < 0)
+ { &rotl($r, 2-$lr); }
+ else { &rotr($r, $lr-2); }
+ }
+ if ($lr != 3)
+ {
+ if (($lr-3) < 0)
+ { &rotl($l, 3-$lr); }
+ else { &rotr($l, $lr-3); }
+ }
+
+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
+ &rotr($tt , 4);
+ }
+
diff --git a/src/libfreeswan/libdes/des/asm/des686.pl b/src/libfreeswan/libdes/des/asm/des686.pl
new file mode 100644
index 000000000..cf1a82fb5
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/des686.pl
@@ -0,0 +1,230 @@
+#!/usr/bin/perl
+
+$prog="des686.pl";
+
+# base code is in microsft
+# op dest, source
+# format.
+#
+
+# WILL NOT WORK ANYMORE WITH desboth.pl
+require "desboth.pl";
+
+if ( ($ARGV[0] eq "elf"))
+ { require "x86unix.pl"; }
+elsif ( ($ARGV[0] eq "a.out"))
+ { $aout=1; require "x86unix.pl"; }
+elsif ( ($ARGV[0] eq "sol"))
+ { $sol=1; require "x86unix.pl"; }
+elsif ( ($ARGV[0] eq "cpp"))
+ { $cpp=1; require "x86unix.pl"; }
+elsif ( ($ARGV[0] eq "win32"))
+ { require "x86ms.pl"; }
+else
+ {
+ print STDERR <<"EOF";
+Pick one target type from
+ elf - linux, FreeBSD etc
+ a.out - old linux
+ sol - x86 solaris
+ cpp - format so x86unix.cpp can be used
+ win32 - Windows 95/Windows NT
+EOF
+ exit(1);
+ }
+
+&comment("Don't even think of reading this code");
+&comment("It was automatically generated by $prog");
+&comment("Which is a perl program used to generate the x86 assember for");
+&comment("any of elf, a.out, Win32, or Solaris");
+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
+&comment("eric <eay\@cryptsoft.com>");
+&comment("");
+
+&file("dx86xxxx");
+
+$L="edi";
+$R="esi";
+
+&des_encrypt("des_encrypt",1);
+&des_encrypt("des_encrypt2",0);
+
+&des_encrypt3("des_encrypt3",1);
+&des_encrypt3("des_decrypt3",0);
+
+&file_end();
+
+sub des_encrypt
+ {
+ local($name,$do_ip)=@_;
+
+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
+
+ &comment("");
+ &comment("Load the 2 words");
+ &mov("eax",&wparam(0));
+ &mov($L,&DWP(0,"eax","",0));
+ &mov($R,&DWP(4,"eax","",0));
+
+ $ksp=&wparam(1);
+
+ if ($do_ip)
+ {
+ &comment("");
+ &comment("IP");
+ &IP_new($L,$R,"eax");
+ }
+
+ &comment("");
+ &comment("fixup rotate");
+ &rotl($R,3);
+ &rotl($L,3);
+ &exch($L,$R);
+
+ &comment("");
+ &comment("load counter, key_schedule and enc flag");
+ &mov("eax",&wparam(2)); # get encrypt flag
+ &mov("ebp",&wparam(1)); # get ks
+ &cmp("eax","0");
+ &je(&label("start_decrypt"));
+
+ # encrypting part
+
+ for ($i=0; $i<16; $i+=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
+
+ &comment("");
+ &comment("Round ".sprintf("%d",$i+1));
+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
+ }
+ &jmp(&label("end"));
+
+ &set_label("start_decrypt");
+
+ for ($i=15; $i>0; $i-=2)
+ {
+ &comment("");
+ &comment("Round $i");
+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
+ &comment("");
+ &comment("Round ".sprintf("%d",$i-1));
+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
+ }
+
+ &set_label("end");
+
+ &comment("");
+ &comment("Fixup");
+ &rotr($L,3); # r
+ &rotr($R,3); # l
+
+ if ($do_ip)
+ {
+ &comment("");
+ &comment("FP");
+ &FP_new($R,$L,"eax");
+ }
+
+ &mov("eax",&wparam(0));
+ &mov(&DWP(0,"eax","",0),$L);
+ &mov(&DWP(4,"eax","",0),$R);
+
+ &function_end($name);
+ }
+
+
+# The logic is to load R into 2 registers and operate on both at the same time.
+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
+# while also masking the other copy and doing a lookup. We then also accumulate the
+# L value in 2 registers then combine them at the end.
+sub D_ENCRYPT
+ {
+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
+
+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
+ &xor( $u, $R );
+ &xor( $t, $R );
+ &rotr( $t, 4 );
+
+ # the numbers at the end of the line are origional instruction order
+ &mov( $tmp2, $u ); # 1 2
+ &mov( $tmp1, $t ); # 1 1
+ &and( $tmp2, "0xfc" ); # 1 4
+ &and( $tmp1, "0xfc" ); # 1 3
+ &shr( $t, 8 ); # 1 5
+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
+ &shr( $u, 8 ); # 1 6
+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
+
+ &mov( $tmp2, $u ); # 2 2
+ &xor( $L, $tmp1 ); # 1 9
+ &and( $tmp2, "0xfc" ); # 2 4
+ &mov( $tmp1, $t ); # 2 1
+ &and( $tmp1, "0xfc" ); # 2 3
+ &shr( $t, 8 ); # 2 5
+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
+ &shr( $u, 8 ); # 2 6
+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
+ &mov( $tmp2, $u ); # 3 2
+
+ &xor( $L, $tmp1 ); # 2 9
+ &and( $tmp2, "0xfc" ); # 3 4
+
+ &mov( $tmp1, $t ); # 3 1
+ &shr( $u, 8 ); # 3 6
+ &and( $tmp1, "0xfc" ); # 3 3
+ &shr( $t, 8 ); # 3 5
+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
+
+ &and( $t, "0xfc" ); # 4 1
+ &xor( $L, $tmp1 ); # 3 9
+
+ &and( $u, "0xfc" ); # 4 2
+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
+ }
+
+sub PERM_OP
+ {
+ local($a,$b,$tt,$shift,$mask)=@_;
+
+ &mov( $tt, $a );
+ &shr( $tt, $shift );
+ &xor( $tt, $b );
+ &and( $tt, $mask );
+ &xor( $b, $tt );
+ &shl( $tt, $shift );
+ &xor( $a, $tt );
+ }
+
+sub IP_new
+ {
+ local($l,$r,$tt)=@_;
+
+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
+ }
+
+sub FP_new
+ {
+ local($l,$r,$tt)=@_;
+
+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
+ }
+
+sub n2a
+ {
+ sprintf("%d",$_[0]);
+ }
diff --git a/src/libfreeswan/libdes/des/asm/desboth.pl b/src/libfreeswan/libdes/des/asm/desboth.pl
new file mode 100644
index 000000000..8f939953a
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/desboth.pl
@@ -0,0 +1,79 @@
+#!/usr/bin/perl
+
+$L="edi";
+$R="esi";
+
+sub des_encrypt3
+ {
+ local($name,$enc)=@_;
+
+ &function_begin_B($name,"");
+ &push("ebx");
+ &mov("ebx",&wparam(0));
+
+ &push("ebp");
+ &push("esi");
+
+ &push("edi");
+
+ &comment("");
+ &comment("Load the data words");
+ &mov($L,&DWP(0,"ebx","",0));
+ &mov($R,&DWP(4,"ebx","",0));
+ &stack_push(3);
+
+ &comment("");
+ &comment("IP");
+ &IP_new($L,$R,"edx",0);
+
+ # put them back
+
+ if ($enc)
+ {
+ &mov(&DWP(4,"ebx","",0),$R);
+ &mov("eax",&wparam(1));
+ &mov(&DWP(0,"ebx","",0),"edx");
+ &mov("edi",&wparam(2));
+ &mov("esi",&wparam(3));
+ }
+ else
+ {
+ &mov(&DWP(4,"ebx","",0),$R);
+ &mov("esi",&wparam(1));
+ &mov(&DWP(0,"ebx","",0),"edx");
+ &mov("edi",&wparam(2));
+ &mov("eax",&wparam(3));
+ }
+ &mov(&swtmp(2), (($enc)?"1":"0"));
+ &mov(&swtmp(1), "eax");
+ &mov(&swtmp(0), "ebx");
+ &call("des_encrypt2");
+ &mov(&swtmp(2), (($enc)?"0":"1"));
+ &mov(&swtmp(1), "edi");
+ &mov(&swtmp(0), "ebx");
+ &call("des_encrypt2");
+ &mov(&swtmp(2), (($enc)?"1":"0"));
+ &mov(&swtmp(1), "esi");
+ &mov(&swtmp(0), "ebx");
+ &call("des_encrypt2");
+
+ &stack_pop(3);
+ &mov($L,&DWP(0,"ebx","",0));
+ &mov($R,&DWP(4,"ebx","",0));
+
+ &comment("");
+ &comment("FP");
+ &FP_new($L,$R,"eax",0);
+
+ &mov(&DWP(0,"ebx","",0),"eax");
+ &mov(&DWP(4,"ebx","",0),$R);
+
+ &pop("edi");
+ &pop("esi");
+ &pop("ebp");
+ &pop("ebx");
+ &ret();
+ &function_end_B($name);
+ }
+
+
diff --git a/src/libfreeswan/libdes/des/asm/perlasm/cbc.pl b/src/libfreeswan/libdes/des/asm/perlasm/cbc.pl
new file mode 100644
index 000000000..278930579
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/perlasm/cbc.pl
@@ -0,0 +1,342 @@
+#!/usr/bin/perl
+
+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
+# des_cblock (*input);
+# des_cblock (*output);
+# long length;
+# des_key_schedule schedule;
+# des_cblock (*ivec);
+# int enc;
+#
+# calls
+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+#
+
+#&cbc("des_ncbc_encrypt","des_encrypt",0);
+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
+# 1,4,5,3,5,-1);
+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
+# 0,4,5,3,5,-1);
+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
+# 0,6,7,3,4,5);
+#
+# When doing a cipher that needs bigendian order,
+# for encrypt, the iv is kept in bigendian form,
+# while for decrypt, it is kept in little endian.
+sub cbc
+ {
+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
+ # name is the function name
+ # enc_func and dec_func and the functions to call for encrypt/decrypt
+ # swap is true if byte order needs to be reversed
+ # iv_off is parameter number for the iv
+ # enc_off is parameter number for the encrypt/decrypt flag
+ # p1,p2,p3 are the offsets for parameters to be passed to the
+ # underlying calls.
+
+ &function_begin_B($name,"");
+ &comment("");
+
+ $in="esi";
+ $out="edi";
+ $count="ebp";
+
+ &push("ebp");
+ &push("ebx");
+ &push("esi");
+ &push("edi");
+
+ $data_off=4;
+ $data_off+=4 if ($p1 > 0);
+ $data_off+=4 if ($p2 > 0);
+ $data_off+=4 if ($p3 > 0);
+
+ &mov($count, &wparam(2)); # length
+
+ &comment("getting iv ptr from parameter $iv_off");
+ &mov("ebx", &wparam($iv_off)); # Get iv ptr
+
+ &mov($in, &DWP(0,"ebx","",0));# iv[0]
+ &mov($out, &DWP(4,"ebx","",0));# iv[1]
+
+ &push($out);
+ &push($in);
+ &push($out); # used in decrypt for iv[1]
+ &push($in); # used in decrypt for iv[0]
+
+ &mov("ebx", "esp"); # This is the address of tin[2]
+
+ &mov($in, &wparam(0)); # in
+ &mov($out, &wparam(1)); # out
+
+ # We have loaded them all, how lets push things
+ &comment("getting encrypt flag from parameter $enc_off");
+ &mov("ecx", &wparam($enc_off)); # Get enc flag
+ if ($p3 > 0)
+ {
+ &comment("get and push parameter $p3");
+ if ($enc_off != $p3)
+ { &mov("eax", &wparam($p3)); &push("eax"); }
+ else { &push("ecx"); }
+ }
+ if ($p2 > 0)
+ {
+ &comment("get and push parameter $p2");
+ if ($enc_off != $p2)
+ { &mov("eax", &wparam($p2)); &push("eax"); }
+ else { &push("ecx"); }
+ }
+ if ($p1 > 0)
+ {
+ &comment("get and push parameter $p1");
+ if ($enc_off != $p1)
+ { &mov("eax", &wparam($p1)); &push("eax"); }
+ else { &push("ecx"); }
+ }
+ &push("ebx"); # push data/iv
+
+ &cmp("ecx",0);
+ &jz(&label("decrypt"));
+
+ &and($count,0xfffffff8);
+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0]
+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1]
+
+ &jz(&label("encrypt_finish"));
+
+ #############################################################
+
+ &set_label("encrypt_loop");
+ # encrypt start
+ # "eax" and "ebx" hold iv (or the last cipher text)
+
+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes
+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes
+
+ &xor("eax", "ecx");
+ &xor("ebx", "edx");
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($enc_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0));
+ &mov("ebx", &DWP($data_off+4,"esp","",0));
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP(0,$out,"",0),"eax");
+ &mov(&DWP(4,$out,"",0),"ebx");
+
+ # eax and ebx are the next iv.
+
+ &add($in, 8);
+ &add($out, 8);
+
+ &sub($count, 8);
+ &jnz(&label("encrypt_loop"));
+
+###################################################################3
+ &set_label("encrypt_finish");
+ &mov($count, &wparam(2)); # length
+ &and($count, 7);
+ &jz(&label("finish"));
+ &xor("ecx","ecx");
+ &xor("edx","edx");
+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
+ &jmp_ptr($count);
+
+&set_label("ej7");
+ &xor("edx", "edx") if $ppro; # ppro friendly
+ &movb(&HB("edx"), &BP(6,$in,"",0));
+ &shl("edx",8);
+&set_label("ej6");
+ &movb(&HB("edx"), &BP(5,$in,"",0));
+&set_label("ej5");
+ &movb(&LB("edx"), &BP(4,$in,"",0));
+&set_label("ej4");
+ &mov("ecx", &DWP(0,$in,"",0));
+ &jmp(&label("ejend"));
+&set_label("ej3");
+ &movb(&HB("ecx"), &BP(2,$in,"",0));
+ &xor("ecx", "ecx") if $ppro; # ppro friendly
+ &shl("ecx",8);
+&set_label("ej2");
+ &movb(&HB("ecx"), &BP(1,$in,"",0));
+&set_label("ej1");
+ &movb(&LB("ecx"), &BP(0,$in,"",0));
+&set_label("ejend");
+
+ &xor("eax", "ecx");
+ &xor("ebx", "edx");
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($enc_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0));
+ &mov("ebx", &DWP($data_off+4,"esp","",0));
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP(0,$out,"",0),"eax");
+ &mov(&DWP(4,$out,"",0),"ebx");
+
+ &jmp(&label("finish"));
+
+ #############################################################
+ #############################################################
+ &set_label("decrypt",1);
+ # decrypt start
+ &and($count,0xfffffff8);
+ # The next 2 instructions are only for if the jz is taken
+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0]
+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1]
+ &jz(&label("decrypt_finish"));
+
+ &set_label("decrypt_loop");
+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($dec_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
+
+ &xor("ecx", "eax");
+ &xor("edx", "ebx");
+
+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
+
+ &mov(&DWP(0,$out,"",0),"ecx");
+ &mov(&DWP(4,$out,"",0),"edx");
+
+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv
+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); #
+
+ &add($in, 8);
+ &add($out, 8);
+
+ &sub($count, 8);
+ &jnz(&label("decrypt_loop"));
+############################ ENDIT #######################3
+ &set_label("decrypt_finish");
+ &mov($count, &wparam(2)); # length
+ &and($count, 7);
+ &jz(&label("finish"));
+
+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
+
+ &call($dec_func);
+
+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
+
+ &bswap("eax") if $swap;
+ &bswap("ebx") if $swap;
+
+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
+
+ &xor("ecx", "eax");
+ &xor("edx", "ebx");
+
+ # this is for when we exit
+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
+
+&set_label("dj7");
+ &rotr("edx", 16);
+ &movb(&BP(6,$out,"",0), &LB("edx"));
+ &shr("edx",16);
+&set_label("dj6");
+ &movb(&BP(5,$out,"",0), &HB("edx"));
+&set_label("dj5");
+ &movb(&BP(4,$out,"",0), &LB("edx"));
+&set_label("dj4");
+ &mov(&DWP(0,$out,"",0), "ecx");
+ &jmp(&label("djend"));
+&set_label("dj3");
+ &rotr("ecx", 16);
+ &movb(&BP(2,$out,"",0), &LB("ecx"));
+ &shl("ecx",16);
+&set_label("dj2");
+ &movb(&BP(1,$in,"",0), &HB("ecx"));
+&set_label("dj1");
+ &movb(&BP(0,$in,"",0), &LB("ecx"));
+&set_label("djend");
+
+ # final iv is still in eax:ebx
+ &jmp(&label("finish"));
+
+
+############################ FINISH #######################3
+ &set_label("finish",1);
+ &mov("ecx", &wparam($iv_off)); # Get iv ptr
+
+ #################################################
+ $total=16+4;
+ $total+=4 if ($p1 > 0);
+ $total+=4 if ($p2 > 0);
+ $total+=4 if ($p3 > 0);
+ &add("esp",$total);
+
+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv
+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv
+
+ &function_end_A($name);
+
+ &set_label("cbc_enc_jmp_table",1);
+ &data_word("0");
+ &data_word(&label("ej1"));
+ &data_word(&label("ej2"));
+ &data_word(&label("ej3"));
+ &data_word(&label("ej4"));
+ &data_word(&label("ej5"));
+ &data_word(&label("ej6"));
+ &data_word(&label("ej7"));
+ &set_label("cbc_dec_jmp_table",1);
+ &data_word("0");
+ &data_word(&label("dj1"));
+ &data_word(&label("dj2"));
+ &data_word(&label("dj3"));
+ &data_word(&label("dj4"));
+ &data_word(&label("dj5"));
+ &data_word(&label("dj6"));
+ &data_word(&label("dj7"));
+
+ &function_end_B($name);
+
+ }
+
+1;
diff --git a/src/libfreeswan/libdes/des/asm/perlasm/readme b/src/libfreeswan/libdes/des/asm/perlasm/readme
new file mode 100644
index 000000000..f02bbee75
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/perlasm/readme
@@ -0,0 +1,124 @@
+The perl scripts in this directory are my 'hack' to generate
+multiple different assembler formats via the one origional script.
+
+The way to use this library is to start with adding the path to this directory
+and then include it.
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+The first thing we do is setup the file and type of assember
+
+&asm_init($ARGV[0],$0);
+
+The first argument is the 'type'. Currently
+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
+Argument 2 is the file name.
+
+The reciprocal function is
+&asm_finish() which should be called at the end.
+
+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
+and x86unix.pl which is the unix (gas) version.
+
+Functions of interest are:
+&external_label("des_SPtrans"); declare and external variable
+&LB(reg); Low byte for a register
+&HB(reg); High byte for a register
+&BP(off,base,index,scale) Byte pointer addressing
+&DWP(off,base,index,scale) Word pointer addressing
+&stack_push(num) Basically a 'sub esp, num*4' with extra
+&stack_pop(num) inverse of stack_push
+&function_begin(name,extra) Start a function with pushing of
+ edi, esi, ebx and ebp. extra is extra win32
+ external info that may be required.
+&function_begin_B(name,extra) Same as norma function_begin but no pushing.
+&function_end(name) Call at end of function.
+&function_end_A(name) Standard pop and ret, for use inside functions
+&function_end_B(name) Call at end but with poping or 'ret'.
+&swtmp(num) Address on stack temp word.
+&wparam(num) Parameter number num, that was push
+ in C convention. This all works over pushes
+ and pops.
+&comment("hello there") Put in a comment.
+&label("loop") Refer to a label, normally a jmp target.
+&set_label("loop") Set a label at this point.
+&data_word(word) Put in a word of data.
+
+So how does this all hold together? Given
+
+int calc(int len, int *data)
+ {
+ int i,j=0;
+
+ for (i=0; i<len; i++)
+ {
+ j+=other(data[i]);
+ }
+ }
+
+So a very simple version of this function could be coded as
+
+ push(@INC,"perlasm","../../perlasm");
+ require "x86asm.pl";
+
+ &asm_init($ARGV[0],"cacl.pl");
+
+ &external_label("other");
+
+ $tmp1= "eax";
+ $j= "edi";
+ $data= "esi";
+ $i= "ebp";
+
+ &comment("a simple function");
+ &function_begin("calc");
+ &mov( $data, &wparam(1)); # data
+ &xor( $j, $j);
+ &xor( $i, $i);
+
+ &set_label("loop");
+ &cmp( $i, &wparam(0));
+ &jge( &label("end"));
+
+ &mov( $tmp1, &DWP(0,$data,$i,4));
+ &push( $tmp1);
+ &call( "other");
+ &add( $j, "eax");
+ &pop( $tmp1);
+ &inc( $i);
+ &jmp( &label("loop"));
+
+ &set_label("end");
+ &mov( "eax", $j);
+
+ &function_end("calc");
+
+ &asm_finish();
+
+The above example is very very unoptimised but gives an idea of how
+things work.
+
+There is also a cbc mode function generator in cbc.pl
+
+&cbc( $name,
+ $encrypt_function_name,
+ $decrypt_function_name,
+ $true_if_byte_swap_needed,
+ $parameter_number_for_iv,
+ $parameter_number_for_encrypt_flag,
+ $first_parameter_to_pass,
+ $second_parameter_to_pass,
+ $third_parameter_to_pass);
+
+So for example, given
+void BF_encrypt(BF_LONG *data,BF_KEY *key);
+void BF_decrypt(BF_LONG *data,BF_KEY *key);
+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
+ BF_KEY *ks, unsigned char *iv, int enc);
+
+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
+
+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
+
diff --git a/src/libfreeswan/libdes/des/asm/perlasm/x86asm.pl b/src/libfreeswan/libdes/des/asm/perlasm/x86asm.pl
new file mode 100644
index 000000000..164a942c5
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/perlasm/x86asm.pl
@@ -0,0 +1,111 @@
+#!/usr/bin/perl
+
+# require 'x86asm.pl';
+# &asm_init("cpp","des-586.pl");
+# XXX
+# XXX
+# main'asm_finish
+
+sub main'asm_finish
+ {
+ &file_end();
+ &asm_finish_cpp() if $cpp;
+ print &asm_get_output();
+ }
+
+sub main'asm_init
+ {
+ ($type,$fn)=@_;
+ $filename=$fn;
+
+ $cpp=$sol=$aout=$win32=0;
+ if ( ($type eq "elf"))
+ { require "x86unix.pl"; }
+ elsif ( ($type eq "a.out"))
+ { $aout=1; require "x86unix.pl"; }
+ elsif ( ($type eq "sol"))
+ { $sol=1; require "x86unix.pl"; }
+ elsif ( ($type eq "cpp"))
+ { $cpp=1; require "x86unix.pl"; }
+ elsif ( ($type eq "win32"))
+ { $win32=1; require "x86ms.pl"; }
+ else
+ {
+ print STDERR <<"EOF";
+Pick one target type from
+ elf - linux, FreeBSD etc
+ a.out - old linux
+ sol - x86 solaris
+ cpp - format so x86unix.cpp can be used
+ win32 - Windows 95/Windows NT
+EOF
+ exit(1);
+ }
+
+ &asm_init_output();
+
+&comment("Don't even think of reading this code");
+&comment("It was automatically generated by $filename");
+&comment("Which is a perl program used to generate the x86 assember for");
+&comment("any of elf, a.out, BSDI,Win32, or Solaris");
+&comment("eric <eay\@cryptsoft.com>");
+&comment("");
+
+ $filename =~ s/\.pl$//;
+ &file($filename);
+ }
+
+sub asm_finish_cpp
+ {
+ return unless $cpp;
+
+ local($tmp,$i);
+ foreach $i (&get_labels())
+ {
+ $tmp.="#define $i _$i\n";
+ }
+ print <<"EOF";
+/* Run the C pre-processor over this file with one of the following defined
+ * ELF - elf object files,
+ * OUT - a.out object files,
+ * BSDI - BSDI style a.out object files
+ * SOL - Solaris style elf
+ */
+
+#define TYPE(a,b) .type a,b
+#define SIZE(a,b) .size a,b
+
+#if defined(OUT) || defined(BSDI)
+$tmp
+#endif
+
+#ifdef OUT
+#define OK 1
+#define ALIGN 4
+#endif
+
+#ifdef BSDI
+#define OK 1
+#define ALIGN 4
+#undef SIZE
+#undef TYPE
+#endif
+
+#if defined(ELF) || defined(SOL)
+#define OK 1
+#define ALIGN 16
+#endif
+
+#ifndef OK
+You need to define one of
+ELF - elf systems - linux-elf, NetBSD and DG-UX
+OUT - a.out systems - linux-a.out and FreeBSD
+SOL - solaris systems, which are elf with strange comment lines
+BSDI - a.out with a very primative version of as.
+#endif
+
+/* Let the Assembler begin :-) */
+EOF
+ }
+
+1;
diff --git a/src/libfreeswan/libdes/des/asm/perlasm/x86ms.pl b/src/libfreeswan/libdes/des/asm/perlasm/x86ms.pl
new file mode 100644
index 000000000..0681ea18c
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/perlasm/x86ms.pl
@@ -0,0 +1,345 @@
+#!/usr/bin/perl
+
+package x86ms;
+
+$label="L000";
+
+%lb=( 'eax', 'al',
+ 'ebx', 'bl',
+ 'ecx', 'cl',
+ 'edx', 'dl',
+ 'ax', 'al',
+ 'bx', 'bl',
+ 'cx', 'cl',
+ 'dx', 'dl',
+ );
+
+%hb=( 'eax', 'ah',
+ 'ebx', 'bh',
+ 'ecx', 'ch',
+ 'edx', 'dh',
+ 'ax', 'ah',
+ 'bx', 'bh',
+ 'cx', 'ch',
+ 'dx', 'dh',
+ );
+
+sub main'asm_init_output { @out=(); }
+sub main'asm_get_output { return(@out); }
+sub main'get_labels { return(@labels); }
+sub main'external_label { push(@labels,@_); }
+
+sub main'LB
+ {
+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+ return($lb{$_[0]});
+ }
+
+sub main'HB
+ {
+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+ return($hb{$_[0]});
+ }
+
+sub main'BP
+ {
+ &get_mem("BYTE",@_);
+ }
+
+sub main'DWP
+ {
+ &get_mem("DWORD",@_);
+ }
+
+sub main'stack_push
+ {
+ local($num)=@_;
+ $stack+=$num*4;
+ &main'sub("esp",$num*4);
+ }
+
+sub main'stack_pop
+ {
+ local($num)=@_;
+ $stack-=$num*4;
+ &main'add("esp",$num*4);
+ }
+
+sub get_mem
+ {
+ local($size,$addr,$reg1,$reg2,$idx)=@_;
+ local($t,$post);
+ local($ret)="$size PTR ";
+
+ $addr =~ s/^\s+//;
+ if ($addr =~ /^(.+)\+(.+)$/)
+ {
+ $reg2=&conv($1);
+ $addr="_$2";
+ }
+ elsif ($addr =~ /^[_a-zA-Z]/)
+ {
+ $addr="_$addr";
+ }
+
+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
+ if (($addr ne "") && ($addr ne 0))
+ {
+ if ($addr !~ /^-/)
+ { $ret.=$addr; }
+ else { $post=$addr; }
+ }
+ if ($reg2 ne "")
+ {
+ $t="";
+ $t="*$idx" if ($idx != 0);
+ $reg1="+".$reg1 if ("$reg1$post" ne "");
+ $ret.="[$reg2$t$reg1$post]";
+ }
+ else
+ {
+ $ret.="[$reg1$post]"
+ }
+ return($ret);
+ }
+
+sub main'mov { &out2("mov",@_); }
+sub main'movb { &out2("mov",@_); }
+sub main'and { &out2("and",@_); }
+sub main'or { &out2("or",@_); }
+sub main'shl { &out2("shl",@_); }
+sub main'shr { &out2("shr",@_); }
+sub main'xor { &out2("xor",@_); }
+sub main'xorb { &out2("xor",@_); }
+sub main'add { &out2("add",@_); }
+sub main'adc { &out2("adc",@_); }
+sub main'sub { &out2("sub",@_); }
+sub main'rotl { &out2("rol",@_); }
+sub main'rotr { &out2("ror",@_); }
+sub main'exch { &out2("xchg",@_); }
+sub main'cmp { &out2("cmp",@_); }
+sub main'lea { &out2("lea",@_); }
+sub main'mul { &out1("mul",@_); }
+sub main'div { &out1("div",@_); }
+sub main'dec { &out1("dec",@_); }
+sub main'inc { &out1("inc",@_); }
+sub main'jmp { &out1("jmp",@_); }
+sub main'jmp_ptr { &out1p("jmp",@_); }
+sub main'je { &out1("je",@_); }
+sub main'jle { &out1("jle",@_); }
+sub main'jz { &out1("jz",@_); }
+sub main'jge { &out1("jge",@_); }
+sub main'jl { &out1("jl",@_); }
+sub main'jb { &out1("jb",@_); }
+sub main'jnz { &out1("jnz",@_); }
+sub main'jne { &out1("jne",@_); }
+sub main'push { &out1("push",@_); $stack+=4; }
+sub main'pop { &out1("pop",@_); $stack-=4; }
+sub main'bswap { &out1("bswap",@_); &using486(); }
+sub main'not { &out1("not",@_); }
+sub main'call { &out1("call",'_'.$_[0]); }
+sub main'ret { &out0("ret"); }
+sub main'nop { &out0("nop"); }
+
+sub out2
+ {
+ local($name,$p1,$p2)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t");
+ $t=&conv($p1).",";
+ $l=length($t);
+ push(@out,$t);
+ $l=4-($l+9)/8;
+ push(@out,"\t" x $l);
+ push(@out,&conv($p2));
+ push(@out,"\n");
+ }
+
+sub out0
+ {
+ local($name)=@_;
+
+ push(@out,"\t$name\n");
+ }
+
+sub out1
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t".&conv($p1)."\n");
+ }
+
+sub conv
+ {
+ local($p)=@_;
+
+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+ return $p;
+ }
+
+sub using486
+ {
+ return if $using486;
+ $using486++;
+ grep(s/\.386/\.486/,@out);
+ }
+
+sub main'file
+ {
+ local($file)=@_;
+
+ local($tmp)=<<"EOF";
+ TITLE $file.asm
+ .386
+.model FLAT
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'function_begin
+ {
+ local($func,$extra)=@_;
+
+ push(@labels,$func);
+
+ local($tmp)=<<"EOF";
+_TEXT SEGMENT
+PUBLIC _$func
+$extra
+_$func PROC NEAR
+ push ebp
+ push ebx
+ push esi
+ push edi
+EOF
+ push(@out,$tmp);
+ $stack=20;
+ }
+
+sub main'function_begin_B
+ {
+ local($func,$extra)=@_;
+
+ local($tmp)=<<"EOF";
+_TEXT SEGMENT
+PUBLIC _$func
+$extra
+_$func PROC NEAR
+EOF
+ push(@out,$tmp);
+ $stack=4;
+ }
+
+sub main'function_end
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+_$func ENDP
+_TEXT ENDS
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ %label=();
+ }
+
+sub main'function_end_B
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+_$func ENDP
+_TEXT ENDS
+EOF
+ push(@out,$tmp);
+ $stack=0;
+ %label=();
+ }
+
+sub main'function_end_A
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
+ ret
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'file_end
+ {
+ push(@out,"END\n");
+ }
+
+sub main'wparam
+ {
+ local($num)=@_;
+
+ return(&main'DWP($stack+$num*4,"esp","",0));
+ }
+
+sub main'swtmp
+ {
+ return(&main'DWP($_[0]*4,"esp","",0));
+ }
+
+# Should use swtmp, which is above esp. Linix can trash the stack above esp
+#sub main'wtmp
+# {
+# local($num)=@_;
+#
+# return(&main'DWP(-(($num+1)*4),"esp","",0));
+# }
+
+sub main'comment
+ {
+ foreach (@_)
+ {
+ push(@out,"\t; $_\n");
+ }
+ }
+
+sub main'label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}="\$${label}${_[0]}";
+ $label++;
+ }
+ return($label{$_[0]});
+ }
+
+sub main'set_label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}="${label}${_[0]}";
+ $label++;
+ }
+ push(@out,"$label{$_[0]}:\n");
+ }
+
+sub main'data_word
+ {
+ push(@out,"\tDD\t$_[0]\n");
+ }
+
+sub out1p
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t ".&conv($p1)."\n");
+ }
diff --git a/src/libfreeswan/libdes/des/asm/perlasm/x86unix.pl b/src/libfreeswan/libdes/des/asm/perlasm/x86unix.pl
new file mode 100644
index 000000000..1d661221c
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/perlasm/x86unix.pl
@@ -0,0 +1,403 @@
+#!/usr/bin/perl
+
+package x86unix;
+
+$label="L000";
+
+$align=($main'aout)?"4":"16";
+$under=($main'aout)?"_":"";
+$com_start=($main'sol)?"/":"#";
+
+sub main'asm_init_output { @out=(); }
+sub main'asm_get_output { return(@out); }
+sub main'get_labels { return(@labels); }
+sub main'external_label { push(@labels,@_); }
+
+if ($main'cpp)
+ {
+ $align="ALIGN";
+ $under="";
+ $com_start='/*';
+ $com_end='*/';
+ }
+
+%lb=( 'eax', '%al',
+ 'ebx', '%bl',
+ 'ecx', '%cl',
+ 'edx', '%dl',
+ 'ax', '%al',
+ 'bx', '%bl',
+ 'cx', '%cl',
+ 'dx', '%dl',
+ );
+
+%hb=( 'eax', '%ah',
+ 'ebx', '%bh',
+ 'ecx', '%ch',
+ 'edx', '%dh',
+ 'ax', '%ah',
+ 'bx', '%bh',
+ 'cx', '%ch',
+ 'dx', '%dh',
+ );
+
+%regs=( 'eax', '%eax',
+ 'ebx', '%ebx',
+ 'ecx', '%ecx',
+ 'edx', '%edx',
+ 'esi', '%esi',
+ 'edi', '%edi',
+ 'ebp', '%ebp',
+ 'esp', '%esp',
+ );
+
+%reg_val=(
+ 'eax', 0x00,
+ 'ebx', 0x03,
+ 'ecx', 0x01,
+ 'edx', 0x02,
+ 'esi', 0x06,
+ 'edi', 0x07,
+ 'ebp', 0x05,
+ 'esp', 0x04,
+ );
+
+sub main'LB
+ {
+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+ return($lb{$_[0]});
+ }
+
+sub main'HB
+ {
+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+ return($hb{$_[0]});
+ }
+
+sub main'DWP
+ {
+ local($addr,$reg1,$reg2,$idx)=@_;
+
+ $ret="";
+ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
+ $ret.=$addr if ($addr ne "") && ($addr ne 0);
+ if ($reg2 ne "")
+ { $ret.="($reg1,$reg2,$idx)"; }
+ else
+ { $ret.="($reg1)" }
+ return($ret);
+ }
+
+sub main'BP
+ {
+ return(&main'DWP(@_));
+ }
+
+#sub main'BP
+# {
+# local($addr,$reg1,$reg2,$idx)=@_;
+#
+# $ret="";
+#
+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
+# $reg1="$regs{$reg1}" if defined($regs{$reg1});
+# $reg2="$regs{$reg2}" if defined($regs{$reg2});
+# $ret.=$addr if ($addr ne "") && ($addr ne 0);
+# if ($reg2 ne "")
+# { $ret.="($reg1,$reg2,$idx)"; }
+# else
+# { $ret.="($reg1)" }
+# return($ret);
+# }
+
+sub main'mov { &out2("movl",@_); }
+sub main'movb { &out2("movb",@_); }
+sub main'and { &out2("andl",@_); }
+sub main'or { &out2("orl",@_); }
+sub main'shl { &out2("sall",@_); }
+sub main'shr { &out2("shrl",@_); }
+sub main'xor { &out2("xorl",@_); }
+sub main'xorb { &out2("xorb",@_); }
+sub main'add { &out2("addl",@_); }
+sub main'adc { &out2("adcl",@_); }
+sub main'sub { &out2("subl",@_); }
+sub main'rotl { &out2("roll",@_); }
+sub main'rotr { &out2("rorl",@_); }
+sub main'exch { &out2("xchg",@_); }
+sub main'cmp { &out2("cmpl",@_); }
+sub main'lea { &out2("leal",@_); }
+sub main'mul { &out1("mull",@_); }
+sub main'div { &out1("divl",@_); }
+sub main'jmp { &out1("jmp",@_); }
+sub main'jmp_ptr { &out1p("jmp",@_); }
+sub main'je { &out1("je",@_); }
+sub main'jle { &out1("jle",@_); }
+sub main'jne { &out1("jne",@_); }
+sub main'jnz { &out1("jnz",@_); }
+sub main'jz { &out1("jz",@_); }
+sub main'jge { &out1("jge",@_); }
+sub main'jl { &out1("jl",@_); }
+sub main'jb { &out1("jb",@_); }
+sub main'dec { &out1("decl",@_); }
+sub main'inc { &out1("incl",@_); }
+sub main'push { &out1("pushl",@_); $stack+=4; }
+sub main'pop { &out1("popl",@_); $stack-=4; }
+sub main'bswap { &out1("bswapl",@_); }
+sub main'not { &out1("notl",@_); }
+sub main'call { &out1("call",$under.$_[0]); }
+sub main'ret { &out0("ret"); }
+sub main'nop { &out0("nop"); }
+
+sub out2
+ {
+ local($name,$p1,$p2)=@_;
+ local($l,$ll,$t);
+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8,
+ "rcll",0xD1D0,"rcrl",0xD1D8,
+ "shll",0xD1E0,"shrl",0xD1E8,
+ "sarl",0xD1F8);
+
+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
+ {
+ $op=$special{$name}|$reg_val{$p1};
+ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff;
+ $tmp2=sprintf ".byte %d\t",$op &0xff;
+ push(@out,$tmp1);
+ push(@out,$tmp2);
+
+ $p2=&conv($p2);
+ $p1=&conv($p1);
+ &main'comment("$name $p2 $p1");
+ return;
+ }
+
+ push(@out,"\t$name\t");
+ $t=&conv($p2).",";
+ $l=length($t);
+ push(@out,$t);
+ $ll=4-($l+9)/8;
+ $tmp1=sprintf "\t" x $ll;
+ push(@out,$tmp1);
+ push(@out,&conv($p1)."\n");
+ }
+
+sub out1
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t".&conv($p1)."\n");
+ }
+
+sub out1p
+ {
+ local($name,$p1)=@_;
+ local($l,$t);
+
+ push(@out,"\t$name\t*".&conv($p1)."\n");
+ }
+
+sub out0
+ {
+ push(@out,"\t$_[0]\n");
+ }
+
+sub conv
+ {
+ local($p)=@_;
+
+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+
+ $p=$regs{$p} if (defined($regs{$p}));
+
+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
+ return $p;
+ }
+
+sub main'file
+ {
+ local($file)=@_;
+
+ local($tmp)=<<"EOF";
+ .file "$file.s"
+ .version "01.01"
+gcc2_compiled.:
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'function_begin
+ {
+ local($func)=@_;
+
+ $func=$under.$func;
+
+ local($tmp)=<<"EOF";
+.text
+ .align $align
+.globl $func
+EOF
+ push(@out,$tmp);
+ if ($main'cpp)
+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
+ push(@out,"$func:\n");
+ $tmp=<<"EOF";
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+
+EOF
+ push(@out,$tmp);
+ $stack=20;
+ }
+
+sub main'function_begin_B
+ {
+ local($func,$extra)=@_;
+
+ $func=$under.$func;
+
+ local($tmp)=<<"EOF";
+.text
+ .align $align
+.globl $func
+EOF
+ push(@out,$tmp);
+ if ($main'cpp)
+ { push(@out,"\tTYPE($func,\@function)\n"); }
+ else { push(@out,"\t.type $func,\@function\n"); }
+ push(@out,"$func:\n");
+ $stack=4;
+ }
+
+sub main'function_end
+ {
+ local($func)=@_;
+
+ $func=$under.$func;
+
+ local($tmp)=<<"EOF";
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.${func}_end:
+EOF
+ push(@out,$tmp);
+ if ($main'cpp)
+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
+ push(@out,".ident \"$func\"\n");
+ $stack=0;
+ %label=();
+ }
+
+sub main'function_end_A
+ {
+ local($func)=@_;
+
+ local($tmp)=<<"EOF";
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+EOF
+ push(@out,$tmp);
+ }
+
+sub main'function_end_B
+ {
+ local($func)=@_;
+
+ $func=$under.$func;
+
+ push(@out,".${func}_end:\n");
+ if ($main'cpp)
+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
+ push(@out,".ident \"desasm.pl\"\n");
+ $stack=0;
+ %label=();
+ }
+
+sub main'wparam
+ {
+ local($num)=@_;
+
+ return(&main'DWP($stack+$num*4,"esp","",0));
+ }
+
+sub main'stack_push
+ {
+ local($num)=@_;
+ $stack+=$num*4;
+ &main'sub("esp",$num*4);
+ }
+
+sub main'stack_pop
+ {
+ local($num)=@_;
+ $stack-=$num*4;
+ &main'add("esp",$num*4);
+ }
+
+sub main'swtmp
+ {
+ return(&main'DWP($_[0]*4,"esp","",0));
+ }
+
+# Should use swtmp, which is above esp. Linix can trash the stack above esp
+#sub main'wtmp
+# {
+# local($num)=@_;
+#
+# return(&main'DWP(-($num+1)*4,"esp","",0));
+# }
+
+sub main'comment
+ {
+ foreach (@_)
+ {
+ if (/^\s*$/)
+ { push(@out,"\n"); }
+ else
+ { push(@out,"\t$com_start $_ $com_end\n"); }
+ }
+ }
+
+sub main'label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}=".${label}${_[0]}";
+ $label++;
+ }
+ return($label{$_[0]});
+ }
+
+sub main'set_label
+ {
+ if (!defined($label{$_[0]}))
+ {
+ $label{$_[0]}=".${label}${_[0]}";
+ $label++;
+ }
+ push(@out,".align $align\n") if ($_[1] != 0);
+ push(@out,"$label{$_[0]}:\n");
+ }
+
+sub main'file_end
+ {
+ }
+
+sub main'data_word
+ {
+ push(@out,"\t.long $_[0]\n");
+ }
diff --git a/src/libfreeswan/libdes/des/asm/readme b/src/libfreeswan/libdes/des/asm/readme
new file mode 100644
index 000000000..f8529d930
--- /dev/null
+++ b/src/libfreeswan/libdes/des/asm/readme
@@ -0,0 +1,131 @@
+First up, let me say I don't like writing in assembler. It is not portable,
+dependant on the particular CPU architecture release and is generally a pig
+to debug and get right. Having said that, the x86 architecture is probably
+the most important for speed due to number of boxes and since
+it appears to be the worst architecture to to get
+good C compilers for. So due to this, I have lowered myself to do
+assembler for the inner DES routines in libdes :-).
+
+The file to implement in assembler is des_enc.c. Replace the following
+4 functions
+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
+
+They encrypt/decrypt the 64 bits held in 'data' using
+the 'ks' key schedules. The only difference between the 4 functions is that
+des_encrypt2() does not perform IP() or FP() on the data (this is an
+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
+perform triple des. The triple DES routines are in here because it does
+make a big difference to have them located near the des_encrypt2 function
+at link time..
+
+Now as we all know, there are lots of different operating systems running on
+x86 boxes, and unfortunately they normally try to make sure their assembler
+formating is not the same as the other peoples.
+The 4 main formats I know of are
+Microsoft Windows 95/Windows NT
+Elf Includes Linux and FreeBSD(?).
+a.out The older Linux.
+Solaris Same as Elf but different comments :-(.
+
+Now I was not overly keen to write 4 different copies of the same code,
+so I wrote a few perl routines to output the correct assembler, given
+a target assembler type. This code is ugly and is just a hack.
+The libraries are x86unix.pl and x86ms.pl.
+des586.pl, des686.pl and des-som[23].pl are the programs to actually
+generate the assembler.
+
+So to generate elf assembler
+perl des-som3.pl elf >dx86-elf.s
+For Windows 95/NT
+perl des-som2.pl win32 >win32.asm
+
+[ update 4 Jan 1996 ]
+I have added another way to do things.
+perl des-som3.pl cpp >dx86-cpp.s
+generates a file that will be included by dx86unix.cpp when it is compiled.
+To build for elf, a.out, solaris, bsdi etc,
+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
+This was done to cut down the number of files in the distribution.
+
+Now the ugly part. I acquired my copy of Intels
+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
+things. First, the aim of the exersize is to 'extract' one byte at a time
+from a word and do an array lookup. This involves getting the byte from
+the 4 locations in the word and moving it to a new word and doing the lookup.
+The most obvious way to do this is
+xor eax, eax # clear word
+movb al, cl # get low byte
+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
+movb al, ch # get next byte
+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
+shr ecx 16
+which seems ok. For the pentium, this system appears to be the best.
+One has to do instruction interleaving to keep both functional units
+operating, but it is basically very efficient.
+
+Now the crunch. When a full register is used after a partial write, eg.
+mov al, cl
+xor edi, DWORD PTR 0x100+des_SP[eax]
+386 - 1 cycle stall
+486 - 1 cycle stall
+586 - 0 cycle stall
+686 - at least 7 cycle stall (page 22 of the above mentioned document).
+
+So the technique that produces the best results on a pentium, according to
+the documentation, will produce hideous results on a pentium pro.
+
+To get around this, des686.pl will generate code that is not as fast on
+a pentium, should be very good on a pentium pro.
+mov eax, ecx # copy word
+shr ecx, 8 # line up next byte
+and eax, 0fch # mask byte
+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
+mov eax, ecx # get word
+shr ecx 8 # line up next byte
+and eax, 0fch # mask byte
+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
+
+Due to the execution units in the pentium, this actually works quite well.
+For a pentium pro it should be very good. This is the type of output
+Visual C++ generates.
+
+There is a third option. instead of using
+mov al, ch
+which is bad on the pentium pro, one may be able to use
+movzx eax, ch
+which may not incur the partial write penalty. On the pentium,
+this instruction takes 4 cycles so is not worth using but on the
+pentium pro it appears it may be worth while. I need access to one to
+experiment :-).
+
+eric (20 Oct 1996)
+
+22 Nov 1996 - I have asked people to run the 2 different version on pentium
+pros and it appears that the intel documentation is wrong. The
+mov al,bh is still faster on a pentium pro, so just use the des586.pl
+install des686.pl
+
+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
+functions into des_enc.c because it does make a massive performance
+difference on some boxes to have the functions code located close to
+the des_encrypt2() function.
+
+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
+pentiums. It contains an inner loop from
+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
+273,000 per second. He had a previous version at 250,000 and the best
+I was able to get was 203,000. The content has not changed, this is all
+due to instruction sequencing (and actual instructions choice) which is able
+to keep both functional units of the pentium going.
+We may have lost the ugly register usage restrictions when x86 went 32 bit
+but for the pentium it has been replaced by evil instruction ordering tricks.
+
+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
+raw DES at 281,000 per second on a pentium 100.
+
diff --git a/src/libfreeswan/libdes/des/cbc_enc.c b/src/libfreeswan/libdes/des/cbc_enc.c
new file mode 100644
index 000000000..a06f9f99e
--- /dev/null
+++ b/src/libfreeswan/libdes/des/cbc_enc.c
@@ -0,0 +1,135 @@
+/* crypto/des/cbc_enc.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
+des_cblock (*input);
+des_cblock (*output);
+long length;
+des_key_schedule schedule;
+des_cblock (*ivec);
+int enc;
+ {
+ register DES_LONG tin0,tin1;
+ register DES_LONG tout0,tout1,xor0,xor1;
+ register unsigned char *in,*out;
+ register long l=length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (enc)
+ {
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ tin0^=tout0; tin[0]=tin0;
+ tin1^=tout1; tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+ tout0=tin[0]; l2c(tout0,out);
+ tout1=tin[1]; l2c(tout1,out);
+ }
+ if (l != -8)
+ {
+ c2ln(in,tin0,tin1,l+8);
+ tin0^=tout0; tin[0]=tin0;
+ tin1^=tout1; tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+ tout0=tin[0]; l2c(tout0,out);
+ tout1=tin[1]; l2c(tout1,out);
+ }
+ }
+ else
+ {
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0); tin[0]=tin0;
+ c2l(in,tin1); tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2c(tout0,out);
+ l2c(tout1,out);
+ xor0=tin0;
+ xor1=tin1;
+ }
+ if (l != -8)
+ {
+ c2l(in,tin0); tin[0]=tin0;
+ c2l(in,tin1); tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2cn(tout0,tout1,out,l+8);
+ /* xor0=tin0;
+ xor1=tin1; */
+ }
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=0;
+ }
+
diff --git a/src/libfreeswan/libdes/des/des.doc b/src/libfreeswan/libdes/des/des.doc
new file mode 100644
index 000000000..1e3015812
--- /dev/null
+++ b/src/libfreeswan/libdes/des/des.doc
@@ -0,0 +1,505 @@
+The DES library.
+
+Please note that this library was originally written to operate with
+eBones, a version of Kerberos that had had encryption removed when it left
+the USA and then put back in. As such there are some routines that I will
+advise not using but they are still in the library for historical reasons.
+For all calls that have an 'input' and 'output' variables, they can be the
+same.
+
+This library requires the inclusion of 'des.h'.
+
+All of the encryption functions take what is called a des_key_schedule as an
+argument. A des_key_schedule is an expanded form of the des key.
+A des_key is 8 bytes of odd parity, the type used to hold the key is a
+des_cblock. A des_cblock is an array of 8 bytes, often in this library
+description I will refer to input bytes when the function specifies
+des_cblock's as input or output, this just means that the variable should
+be a multiple of 8 bytes.
+
+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
+specify decryption. The functions and global variable are as follows:
+
+int des_check_key;
+ DES keys are supposed to be odd parity. If this variable is set to
+ a non-zero value, des_set_key() will check that the key has odd
+ parity and is not one of the known weak DES keys. By default this
+ variable is turned off;
+
+void des_set_odd_parity(
+des_cblock *key );
+ This function takes a DES key (8 bytes) and sets the parity to odd.
+
+int des_is_weak_key(
+des_cblock *key );
+ This function returns a non-zero value if the DES key passed is a
+ weak, DES key. If it is a weak key, don't use it, try a different
+ one. If you are using 'random' keys, the chances of hitting a weak
+ key are 1/2^52 so it is probably not worth checking for them.
+
+int des_set_key(
+des_cblock *key,
+des_key_schedule schedule);
+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
+ A des_key_schedule is an expanded form of the key which is used to
+ perform actual encryption. It can be regenerated from the DES key
+ so it only needs to be kept when encryption or decryption is about
+ to occur. Don't save or pass around des_key_schedule's since they
+ are CPU architecture dependent, DES keys are not. If des_check_key
+ is non zero, zero is returned if the key has the wrong parity or
+ the key is a weak key, else 1 is returned.
+
+int des_key_sched(
+des_cblock *key,
+des_key_schedule schedule);
+ An alternative name for des_set_key().
+
+int des_rw_mode; /* defaults to DES_PCBC_MODE */
+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
+ This specifies the function to use in the enc_read() and enc_write()
+ functions.
+
+void des_encrypt(
+unsigned long *data,
+des_key_schedule ks,
+int enc);
+ This is the DES encryption function that gets called by just about
+ every other DES routine in the library. You should not use this
+ function except to implement 'modes' of DES. I say this because the
+ functions that call this routine do the conversion from 'char *' to
+ long, and this needs to be done to make sure 'non-aligned' memory
+ access do not occur. The characters are loaded 'little endian',
+ have a look at my source code for more details on how I use this
+ function.
+ Data is a pointer to 2 unsigned long's and ks is the
+ des_key_schedule to use. enc, is non zero specifies encryption,
+ zero if decryption.
+
+void des_encrypt2(
+unsigned long *data,
+des_key_schedule ks,
+int enc);
+ This functions is the same as des_encrypt() except that the DES
+ initial permutation (IP) and final permutation (FP) have been left
+ out. As for des_encrypt(), you should not use this function.
+ It is used by the routines in my library that implement triple DES.
+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
+
+void des_ecb_encrypt(
+des_cblock *input,
+des_cblock *output,
+des_key_schedule ks,
+int enc);
+ This is the basic Electronic Code Book form of DES, the most basic
+ form. Input is encrypted into output using the key represented by
+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
+ (the des_cblock structure is 8 chars).
+
+void des_ecb3_encrypt(
+des_cblock *input,
+des_cblock *output,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+int enc);
+ This is the 3 key EDE mode of ECB DES. What this means is that
+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
+ then encrypted again with ks3, before being put into output;
+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
+ that only takes 2 des_key_schedules that implements,
+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
+
+void des_cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+ This routine implements DES in Cipher Block Chaining mode.
+ Input, which should be a multiple of 8 bytes is encrypted
+ (or decrypted) to output which will also be a multiple of 8 bytes.
+ The number of bytes is in length (and from what I've said above,
+ should be a multiple of 8). If length is not a multiple of 8, I'm
+ not being held responsible :-). ivec is the initialisation vector.
+ This function does not modify this variable. To correctly implement
+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
+ cipher text for use as the next ivec in your application,
+ or use des_ncbc_encrypt().
+ Only this routine has this problem with updating the ivec, all
+ other routines that are implementing cbc mode update ivec.
+
+void des_ncbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk,
+des_cblock *ivec,
+int enc);
+ For historical reasons, des_cbc_encrypt() did not update the
+ ivec with the value requires so that subsequent calls to
+ des_cbc_encrypt() would 'chain'. This was needed so that the same
+ 'length' values would not need to be used when decrypting.
+ des_ncbc_encrypt() does the right thing. It is the same as
+ des_cbc_encrypt accept that ivec is updates with the correct value
+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
+ des_ncbc_encrypt() instead of des_cbc_encrypt();
+
+void des_xcbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk,
+des_cblock *ivec,
+des_cblock *inw,
+des_cblock *outw,
+int enc);
+ This is RSA's DESX mode of DES. It uses inw and outw to
+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
+ and are as such, part of the key. So the key is sort of 24 bytes.
+ This is much better than cbc des.
+
+void des_3cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk1,
+des_key_schedule sk2,
+des_cblock *ivec1,
+des_cblock *ivec2,
+int enc);
+ This function is flawed, do not use it. I have left it in the
+ library because it is used in my des(1) program and will function
+ correctly when used by des(1). If I removed the function, people
+ could end up unable to decrypt files.
+ This routine implements outer triple cbc encryption using 2 ks and
+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
+
+void des_ede3_cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int enc);
+ This function implements inner triple CBC DES encryption with 3
+ keys. What this means is that each 'DES' operation
+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
+ Again, this is cbc mode so an ivec is requires.
+ This mode is used by SSL.
+ There is also a des_ede2_cbc_encrypt() that only uses 2
+ des_key_schedule's, the first being reused for the final
+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
+ is used by the RSAref library.
+
+void des_pcbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+ This is Propagating Cipher Block Chaining mode of DES. It is used
+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
+
+void des_cfb_encrypt(
+unsigned char *in,
+unsigned char *out,
+int numbits,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
+ in numbit blocks. The input (and output) is in multiples of numbits
+ bits. numbits should to be a multiple of 8 bits. Length is the
+ number of bytes input. If numbits is not a multiple of 8 bits,
+ the extra bits in the bytes will be considered padding. So if
+ numbits is 12, for each 2 input bytes, the 4 high bits of the
+ second byte will be ignored. So to encode 72 bits when using
+ a numbits of 12 take 12 bytes. To encode 72 bits when using
+ numbits of 9 will take 16 bytes. To encode 80 bits when using
+ numbits of 16 will take 10 bytes. etc, etc. This padding will
+ apply to both input and output.
+
+
+void des_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num,
+int enc);
+ This is one of the more useful functions in this DES library, it
+ implements CFB mode of DES with 64bit feedback. Why is this
+ useful you ask? Because this routine will allow you to encrypt an
+ arbitrary number of bytes, no 8 byte padding. Each call to this
+ routine will encrypt the input bytes to output and then update ivec
+ and num. num contains 'how far' we are though ivec. If this does
+ not make much sense, read more about cfb mode of DES :-).
+
+void des_ede3_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int *num,
+int enc);
+ Same as des_cfb64_encrypt() accept that the DES operation is
+ triple DES. As usual, there is a macro for
+ des_ede2_cfb64_encrypt() which reuses ks1.
+
+void des_ofb_encrypt(
+unsigned char *in,
+unsigned char *out,
+int numbits,
+long length,
+des_key_schedule ks,
+des_cblock *ivec);
+ This is a implementation of Output Feed Back mode of DES. It is
+ the same as des_cfb_encrypt() in that numbits is the size of the
+ units dealt with during input and output (in bits).
+
+void des_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num);
+ The same as des_cfb64_encrypt() except that it is Output Feed Back
+ mode.
+
+void des_ede3_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int *num);
+ Same as des_ofb64_encrypt() accept that the DES operation is
+ triple DES. As usual, there is a macro for
+ des_ede2_ofb64_encrypt() which reuses ks1.
+
+int des_read_pw_string(
+char *buf,
+int length,
+char *prompt,
+int verify);
+ This routine is used to get a password from the terminal with echo
+ turned off. Buf is where the string will end up and length is the
+ size of buf. Prompt is a string presented to the 'user' and if
+ verify is set, the key is asked for twice and unless the 2 copies
+ match, an error is returned. A return code of -1 indicates a
+ system error, 1 failure due to use interaction, and 0 is success.
+
+unsigned long des_cbc_cksum(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec);
+ This function produces an 8 byte checksum from input that it puts in
+ output and returns the last 4 bytes as a long. The checksum is
+ generated via cbc mode of DES in which only the last 8 byes are
+ kept. I would recommend not using this function but instead using
+ the EVP_Digest routines, or at least using MD5 or SHA. This
+ function is used by Kerberos v4 so that is why it stays in the
+ library.
+
+char *des_fcrypt(
+const char *buf,
+const char *salt
+char *ret);
+ This is my fast version of the unix crypt(3) function. This version
+ takes only a small amount of space relative to other fast
+ crypt() implementations. This is different to the normal crypt
+ in that the third parameter is the buffer that the return value
+ is written into. It needs to be at least 14 bytes long. This
+ function is thread safe, unlike the normal crypt.
+
+char *crypt(
+const char *buf,
+const char *salt);
+ This function calls des_fcrypt() with a static array passed as the
+ third parameter. This emulates the normal non-thread safe semantics
+ of crypt(3).
+
+void des_string_to_key(
+char *str,
+des_cblock *key);
+ This function takes str and converts it into a DES key. I would
+ recommend using MD5 instead and use the first 8 bytes of output.
+ When I wrote the first version of these routines back in 1990, MD5
+ did not exist but I feel these routines are still sound. This
+ routines is compatible with the one in MIT's libdes.
+
+void des_string_to_2keys(
+char *str,
+des_cblock *key1,
+des_cblock *key2);
+ This function takes str and converts it into 2 DES keys.
+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
+ I have nothing against these 2 'string_to_key' routines, it's just
+ that if you say that your encryption key is generated by using the
+ 16 bytes of an MD5 hash, every-one knows how you generated your
+ keys.
+
+int des_read_password(
+des_cblock *key,
+char *prompt,
+int verify);
+ This routine combines des_read_pw_string() with des_string_to_key().
+
+int des_read_2passwords(
+des_cblock *key1,
+des_cblock *key2,
+char *prompt,
+int verify);
+ This routine combines des_read_pw_string() with des_string_to_2key().
+
+void des_random_seed(
+des_cblock key);
+ This routine sets a starting point for des_random_key().
+
+void des_random_key(
+des_cblock ret);
+ This function return a random key. Make sure to 'seed' the random
+ number generator (with des_random_seed()) before using this function.
+ I personally now use a MD5 based random number system.
+
+int des_enc_read(
+int fd,
+char *buf,
+int len,
+des_key_schedule ks,
+des_cblock *iv);
+ This function will write to a file descriptor the encrypted data
+ from buf. This data will be preceded by a 4 byte 'byte count' and
+ will be padded out to 8 bytes. The encryption is either CBC of
+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
+ DES_PCBC_MODE.
+
+int des_enc_write(
+int fd,
+char *buf,
+int len,
+des_key_schedule ks,
+des_cblock *iv);
+ This routines read stuff written by des_enc_read() and decrypts it.
+ I have used these routines quite a lot but I don't believe they are
+ suitable for non-blocking io. If you are after a full
+ authentication/encryption over networks, have a look at SSL instead.
+
+unsigned long des_quad_cksum(
+des_cblock *input,
+des_cblock *output,
+long length,
+int out_count,
+des_cblock *seed);
+ This is a function from Kerberos v4 that is not anything to do with
+ DES but was needed. It is a cksum that is quicker to generate than
+ des_cbc_cksum(); I personally would use MD5 routines now.
+=====
+Modes of DES
+Quite a bit of the following information has been taken from
+ AS 2805.5.2
+ Australian Standard
+ Electronic funds transfer - Requirements for interfaces,
+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
+ Appendix A
+
+There are several different modes in which DES can be used, they are
+as follows.
+
+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
+- 64 bits are enciphered at a time.
+- The order of the blocks can be rearranged without detection.
+- The same plaintext block always produces the same ciphertext block
+ (for the same key) making it vulnerable to a 'dictionary attack'.
+- An error will only affect one ciphertext block.
+
+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
+- a multiple of 64 bits are enciphered at a time.
+- The CBC mode produces the same ciphertext whenever the same
+ plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext blocks dependent on the
+ current and all preceding plaintext blocks and therefore blocks can not
+ be rearranged.
+- The use of different starting variables prevents the same plaintext
+ enciphering to the same ciphertext.
+- An error will affect the current and the following ciphertext blocks.
+
+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The CFB mode produces the same ciphertext whenever the same
+ plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext variables dependent on the
+ current and all preceding variables and therefore j-bit variables are
+ chained together and can not be rearranged.
+- The use of different starting variables prevents the same plaintext
+ enciphering to the same ciphertext.
+- The strength of the CFB mode depends on the size of k (maximal if
+ j == k). In my implementation this is always the case.
+- Selection of a small value for j will require more cycles through
+ the encipherment algorithm per unit of plaintext and thus cause
+ greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- An error will affect the current and the following ciphertext variables.
+
+Output Feedback Mode (OFB) (des_ofb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The OFB mode produces the same ciphertext whenever the same
+ plaintext enciphered using the same key and starting variable. More
+ over, in the OFB mode the same key stream is produced when the same
+ key and start variable are used. Consequently, for security reasons
+ a specific start variable should be used only once for a given key.
+- The absence of chaining makes the OFB more vulnerable to specific attacks.
+- The use of different start variables values prevents the same
+ plaintext enciphering to the same ciphertext, by producing different
+ key streams.
+- Selection of a small value for j will require more cycles through
+ the encipherment algorithm per unit of plaintext and thus cause
+ greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- OFB mode of operation does not extend ciphertext errors in the
+ resultant plaintext output. Every bit error in the ciphertext causes
+ only one bit to be in error in the deciphered plaintext.
+- OFB mode is not self-synchronising. If the two operation of
+ encipherment and decipherment get out of synchronism, the system needs
+ to be re-initialised.
+- Each re-initialisation should use a value of the start variable
+ different from the start variable values used before with the same
+ key. The reason for this is that an identical bit stream would be
+ produced each time from the same parameters. This would be
+ susceptible to a ' known plaintext' attack.
+
+Triple ECB Mode (des_ecb3_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
+- As for ECB encryption but increases the key length to 168 bits.
+ There are theoretic attacks that can be used that make the effective
+ key length 112 bits, but this attack also requires 2^56 blocks of
+ memory, not very likely, even for the NSA.
+- If both keys are the same it is equivalent to encrypting once with
+ just one key.
+- If the first and last key are the same, the key length is 112 bits.
+ There are attacks that could reduce the key space to 55 bit's but it
+ requires 2^56 blocks of memory.
+- If all 3 keys are the same, this is effectively the same as normal
+ ecb mode.
+
+Triple CBC Mode (des_ede3_cbc_encrypt())
+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
+- As for CBC encryption but increases the key length to 168 bits with
+ the same restrictions as for triple ecb mode.
diff --git a/src/libfreeswan/libdes/des/des_crypt.man b/src/libfreeswan/libdes/des/des_crypt.man
new file mode 100644
index 000000000..0ecc41687
--- /dev/null
+++ b/src/libfreeswan/libdes/des/des_crypt.man
@@ -0,0 +1,508 @@
+.TH DES_CRYPT 3
+.SH NAME
+des_read_password, des_read_2password,
+des_string_to_key, des_string_to_2key, des_read_pw_string,
+des_random_key, des_set_key,
+des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt,
+des_3cbc_encrypt,
+des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt,
+des_cbc_cksum, des_quad_cksum,
+des_enc_read, des_enc_write, des_set_odd_parity,
+des_is_weak_key, crypt \- (non USA) DES encryption
+.SH SYNOPSIS
+.nf
+.nj
+.ft B
+#include <des.h>
+.PP
+.B int des_read_password(key,prompt,verify)
+des_cblock *key;
+char *prompt;
+int verify;
+.PP
+.B int des_read_2password(key1,key2,prompt,verify)
+des_cblock *key1,*key2;
+char *prompt;
+int verify;
+.PP
+.B int des_string_to_key(str,key)
+char *str;
+des_cblock *key;
+.PP
+.B int des_string_to_2keys(str,key1,key2)
+char *str;
+des_cblock *key1,*key2;
+.PP
+.B int des_read_pw_string(buf,length,prompt,verify)
+char *buf;
+int length;
+char *prompt;
+int verify;
+.PP
+.B int des_random_key(key)
+des_cblock *key;
+.PP
+.B int des_set_key(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+.PP
+.B int des_key_sched(key,schedule)
+des_cblock *key;
+des_key_schedule schedule;
+.PP
+.B int des_ecb_encrypt(input,output,schedule,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule schedule;
+int encrypt;
+.PP
+.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt)
+des_cblock *input;
+des_cblock *output;
+des_key_schedule ks1,ks2;
+int encrypt;
+.PP
+.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule sk1;
+des_key_schedule sk2;
+des_cblock *ivec1;
+des_cblock *ivec2;
+int encrypt;
+.PP
+.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt)
+unsigned char *input;
+unsigned char *output;
+int numbits;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+int encrypt;
+.PP
+.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec)
+unsigned char *input,*output;
+int numbits;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+.PP
+.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
+des_cblock *input;
+des_cblock *output;
+long length;
+des_key_schedule schedule;
+des_cblock *ivec;
+.PP
+.B unsigned long des_quad_cksum(input,output,length,out_count,seed)
+des_cblock *input;
+des_cblock *output;
+long length;
+int out_count;
+des_cblock *seed;
+.PP
+.B int des_check_key;
+.PP
+.B int des_enc_read(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+.PP
+.B int des_enc_write(fd,buf,len,sched,iv)
+int fd;
+char *buf;
+int len;
+des_key_schedule sched;
+des_cblock *iv;
+.PP
+.B extern int des_rw_mode;
+.PP
+.B void des_set_odd_parity(key)
+des_cblock *key;
+.PP
+.B int des_is_weak_key(key)
+des_cblock *key;
+.PP
+.B char *crypt(passwd,salt)
+char *passwd;
+char *salt;
+.PP
+.fi
+.SH DESCRIPTION
+This library contains a fast implementation of the DES encryption
+algorithm.
+.PP
+There are two phases to the use of DES encryption.
+The first is the generation of a
+.I des_key_schedule
+from a key,
+the second is the actual encryption.
+A des key is of type
+.I des_cblock.
+This type is made from 8 characters with odd parity.
+The least significant bit in the character is the parity bit.
+The key schedule is an expanded form of the key; it is used to speed the
+encryption process.
+.PP
+.I des_read_password
+writes the string specified by prompt to the standard output,
+turns off echo and reads an input string from standard input
+until terminated with a newline.
+If verify is non-zero, it prompts and reads the input again and verifies
+that both entered passwords are the same.
+The entered string is converted into a des key by using the
+.I des_string_to_key
+routine.
+The new key is placed in the
+.I des_cblock
+that was passed (by reference) to the routine.
+If there were no errors,
+.I des_read_password
+returns 0,
+-1 is returned if there was a terminal error and 1 is returned for
+any other error.
+.PP
+.I des_read_2password
+operates in the same way as
+.I des_read_password
+except that it generates 2 keys by using the
+.I des_string_to_2key
+function.
+.PP
+.I des_read_pw_string
+is called by
+.I des_read_password
+to read and verify a string from a terminal device.
+The string is returned in
+.I buf.
+The size of
+.I buf
+is passed to the routine via the
+.I length
+parameter.
+.PP
+.I des_string_to_key
+converts a string into a valid des key.
+.PP
+.I des_string_to_2key
+converts a string into 2 valid des keys.
+This routine is best suited for used to generate keys for use with
+.I des_ecb3_encrypt.
+.PP
+.I des_random_key
+returns a random key that is made of a combination of process id,
+time and an increasing counter.
+.PP
+Before a des key can be used it is converted into a
+.I des_key_schedule
+via the
+.I des_set_key
+routine.
+If the
+.I des_check_key
+flag is non-zero,
+.I des_set_key
+will check that the key passed is of odd parity and is not a week or
+semi-weak key.
+If the parity is wrong,
+then -1 is returned.
+If the key is a weak key,
+then -2 is returned.
+If an error is returned,
+the key schedule is not generated.
+.PP
+.I des_key_sched
+is another name for the
+.I des_set_key
+function.
+.PP
+The following routines mostly operate on an input and output stream of
+.I des_cblock's.
+.PP
+.I des_ecb_encrypt
+is the basic DES encryption routine that encrypts or decrypts a single 8-byte
+.I des_cblock
+in
+.I electronic code book
+mode.
+It always transforms the input data, pointed to by
+.I input,
+into the output data,
+pointed to by the
+.I output
+argument.
+If the
+.I encrypt
+argument is non-zero (DES_ENCRYPT),
+the
+.I input
+(cleartext) is encrypted in to the
+.I output
+(ciphertext) using the key_schedule specified by the
+.I schedule
+argument,
+previously set via
+.I des_set_key.
+If
+.I encrypt
+is zero (DES_DECRYPT),
+the
+.I input
+(now ciphertext)
+is decrypted into the
+.I output
+(now cleartext).
+Input and output may overlap.
+No meaningful value is returned.
+.PP
+.I des_ecb3_encrypt
+encrypts/decrypts the
+.I input
+block by using triple ecb DES encryption.
+This involves encrypting the input with
+.I ks1,
+decryption with the key schedule
+.I ks2,
+and then encryption with the first again.
+This routine greatly reduces the chances of brute force breaking of
+DES and has the advantage of if
+.I ks1
+and
+.I ks2
+are the same, it is equivalent to just encryption using ecb mode and
+.I ks1
+as the key.
+.PP
+.I des_cbc_encrypt
+encrypts/decrypts using the
+.I cipher-block-chaining
+mode of DES.
+If the
+.I encrypt
+argument is non-zero,
+the routine cipher-block-chain encrypts the cleartext data pointed to by the
+.I input
+argument into the ciphertext pointed to by the
+.I output
+argument,
+using the key schedule provided by the
+.I schedule
+argument,
+and initialisation vector provided by the
+.I ivec
+argument.
+If the
+.I length
+argument is not an integral multiple of eight bytes,
+the last block is copied to a temporary area and zero filled.
+The output is always
+an integral multiple of eight bytes.
+To make multiple cbc encrypt calls on a large amount of data appear to
+be one
+.I des_cbc_encrypt
+call, the
+.I ivec
+of subsequent calls should be the last 8 bytes of the output.
+.PP
+.I des_3cbc_encrypt
+encrypts/decrypts the
+.I input
+block by using triple cbc DES encryption.
+This involves encrypting the input with key schedule
+.I ks1,
+decryption with the key schedule
+.I ks2,
+and then encryption with the first again.
+2 initialisation vectors are required,
+.I ivec1
+and
+.I ivec2.
+Unlike
+.I des_cbc_encrypt,
+these initialisation vectors are modified by the subroutine.
+This routine greatly reduces the chances of brute force breaking of
+DES and has the advantage of if
+.I ks1
+and
+.I ks2
+are the same, it is equivalent to just encryption using cbc mode and
+.I ks1
+as the key.
+.PP
+.I des_pcbc_encrypt
+encrypt/decrypts using a modified block chaining mode.
+It provides better error propagation characteristics than cbc
+encryption.
+.PP
+.I des_cfb_encrypt
+encrypt/decrypts using cipher feedback mode. This method takes an
+array of characters as input and outputs and array of characters. It
+does not require any padding to 8 character groups. Note: the ivec
+variable is changed and the new changed value needs to be passed to
+the next call to this function. Since this function runs a complete
+DES ecb encryption per numbits, this function is only suggested for
+use when sending small numbers of characters.
+.PP
+.I des_ofb_encrypt
+encrypt using output feedback mode. This method takes an
+array of characters as input and outputs and array of characters. It
+does not require any padding to 8 character groups. Note: the ivec
+variable is changed and the new changed value needs to be passed to
+the next call to this function. Since this function runs a complete
+DES ecb encryption per numbits, this function is only suggested for
+use when sending small numbers of characters.
+.PP
+.I des_cbc_cksum
+produces an 8 byte checksum based on the input stream (via cbc encryption).
+The last 4 bytes of the checksum is returned and the complete 8 bytes is
+placed in
+.I output.
+.PP
+.I des_quad_cksum
+returns a 4 byte checksum from the input bytes.
+The algorithm can be iterated over the input,
+depending on
+.I out_count,
+1, 2, 3 or 4 times.
+If
+.I output
+is non-NULL,
+the 8 bytes generated by each pass are written into
+.I output.
+.PP
+.I des_enc_write
+is used to write
+.I len
+bytes
+to file descriptor
+.I fd
+from buffer
+.I buf.
+The data is encrypted via
+.I pcbc_encrypt
+(default) using
+.I sched
+for the key and
+.I iv
+as a starting vector.
+The actual data send down
+.I fd
+consists of 4 bytes (in network byte order) containing the length of the
+following encrypted data. The encrypted data then follows, padded with random
+data out to a multiple of 8 bytes.
+.PP
+.I des_enc_read
+is used to read
+.I len
+bytes
+from file descriptor
+.I fd
+into buffer
+.I buf.
+The data being read from
+.I fd
+is assumed to have come from
+.I des_enc_write
+and is decrypted using
+.I sched
+for the key schedule and
+.I iv
+for the initial vector.
+The
+.I des_enc_read/des_enc_write
+pair can be used to read/write to files, pipes and sockets.
+I have used them in implementing a version of rlogin in which all
+data is encrypted.
+.PP
+.I des_rw_mode
+is used to specify the encryption mode to use with
+.I des_enc_read
+and
+.I des_end_write.
+If set to
+.I DES_PCBC_MODE
+(the default), des_pcbc_encrypt is used.
+If set to
+.I DES_CBC_MODE
+des_cbc_encrypt is used.
+These two routines and the variable are not part of the normal MIT library.
+.PP
+.I des_set_odd_parity
+sets the parity of the passed
+.I key
+to odd. This routine is not part of the standard MIT library.
+.PP
+.I des_is_weak_key
+returns 1 is the passed key is a weak key (pick again :-),
+0 if it is ok.
+This routine is not part of the standard MIT library.
+.PP
+.I crypt
+is a replacement for the normal system crypt.
+It is much faster than the system crypt.
+.PP
+.SH FILES
+/usr/include/des.h
+.br
+/usr/lib/libdes.a
+.PP
+The encryption routines have been tested on 16bit, 32bit and 64bit
+machines of various endian and even works under VMS.
+.PP
+.SH BUGS
+.PP
+If you think this manual is sparse,
+read the des_crypt(3) manual from the MIT kerberos (or bones outside
+of the USA) distribution.
+.PP
+.I des_cfb_encrypt
+and
+.I des_ofb_encrypt
+operates on input of 8 bits. What this means is that if you set
+numbits to 12, and length to 2, the first 12 bits will come from the 1st
+input byte and the low half of the second input byte. The second 12
+bits will have the low 8 bits taken from the 3rd input byte and the
+top 4 bits taken from the 4th input byte. The same holds for output.
+This function has been implemented this way because most people will
+be using a multiple of 8 and because once you get into pulling bytes input
+bytes apart things get ugly!
+.PP
+.I des_read_pw_string
+is the most machine/OS dependent function and normally generates the
+most problems when porting this code.
+.PP
+.I des_string_to_key
+is probably different from the MIT version since there are lots
+of fun ways to implement one-way encryption of a text string.
+.PP
+The routines are optimised for 32 bit machines and so are not efficient
+on IBM PCs.
+.PP
+NOTE: extensive work has been done on this library since this document
+was origionally written. Please try to read des.doc from the libdes
+distribution since it is far more upto date and documents more of the
+functions. Libdes is now also being shipped as part of SSLeay, a
+general cryptographic library that amonst other things implements
+netscapes SSL protocoll. The most recent version can be found in
+SSLeay distributions.
+.SH AUTHOR
+Eric Young (eay@cryptsoft.com)
diff --git a/src/libfreeswan/libdes/des/des_enc.c b/src/libfreeswan/libdes/des/des_enc.c
new file mode 100644
index 000000000..1e1906d25
--- /dev/null
+++ b/src/libfreeswan/libdes/des/des_enc.c
@@ -0,0 +1,502 @@
+/* crypto/des/des_enc.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+
+void des_encrypt(data, ks, enc)
+DES_LONG *data;
+des_key_schedule ks;
+int enc;
+ {
+ register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+#ifndef DES_UNROLL
+ register int i;
+#endif
+ register DES_LONG *s;
+
+ r=data[0];
+ l=data[1];
+
+ IP(r,l);
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out. */
+ /* clear the top bits on machines with 8byte longs */
+ /* shift left by 2 */
+ r=ROTATE(r,29)&0xffffffffL;
+ l=ROTATE(l,29)&0xffffffffL;
+
+ s=(DES_LONG *)ks;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (enc)
+ {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r, 0); /* 1 */
+ D_ENCRYPT(r,l, 2); /* 2 */
+ D_ENCRYPT(l,r, 4); /* 3 */
+ D_ENCRYPT(r,l, 6); /* 4 */
+ D_ENCRYPT(l,r, 8); /* 5 */
+ D_ENCRYPT(r,l,10); /* 6 */
+ D_ENCRYPT(l,r,12); /* 7 */
+ D_ENCRYPT(r,l,14); /* 8 */
+ D_ENCRYPT(l,r,16); /* 9 */
+ D_ENCRYPT(r,l,18); /* 10 */
+ D_ENCRYPT(l,r,20); /* 11 */
+ D_ENCRYPT(r,l,22); /* 12 */
+ D_ENCRYPT(l,r,24); /* 13 */
+ D_ENCRYPT(r,l,26); /* 14 */
+ D_ENCRYPT(l,r,28); /* 15 */
+ D_ENCRYPT(r,l,30); /* 16 */
+#else
+ for (i=0; i<32; i+=8)
+ {
+ D_ENCRYPT(l,r,i+0); /* 1 */
+ D_ENCRYPT(r,l,i+2); /* 2 */
+ D_ENCRYPT(l,r,i+4); /* 3 */
+ D_ENCRYPT(r,l,i+6); /* 4 */
+ }
+#endif
+ }
+ else
+ {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r,30); /* 16 */
+ D_ENCRYPT(r,l,28); /* 15 */
+ D_ENCRYPT(l,r,26); /* 14 */
+ D_ENCRYPT(r,l,24); /* 13 */
+ D_ENCRYPT(l,r,22); /* 12 */
+ D_ENCRYPT(r,l,20); /* 11 */
+ D_ENCRYPT(l,r,18); /* 10 */
+ D_ENCRYPT(r,l,16); /* 9 */
+ D_ENCRYPT(l,r,14); /* 8 */
+ D_ENCRYPT(r,l,12); /* 7 */
+ D_ENCRYPT(l,r,10); /* 6 */
+ D_ENCRYPT(r,l, 8); /* 5 */
+ D_ENCRYPT(l,r, 6); /* 4 */
+ D_ENCRYPT(r,l, 4); /* 3 */
+ D_ENCRYPT(l,r, 2); /* 2 */
+ D_ENCRYPT(r,l, 0); /* 1 */
+#else
+ for (i=30; i>0; i-=8)
+ {
+ D_ENCRYPT(l,r,i-0); /* 16 */
+ D_ENCRYPT(r,l,i-2); /* 15 */
+ D_ENCRYPT(l,r,i-4); /* 14 */
+ D_ENCRYPT(r,l,i-6); /* 13 */
+ }
+#endif
+ }
+
+ /* rotate and clear the top bits on machines with 8byte longs */
+ l=ROTATE(l,3)&0xffffffffL;
+ r=ROTATE(r,3)&0xffffffffL;
+
+ FP(r,l);
+ data[0]=l;
+ data[1]=r;
+ l=r=t=u=0;
+ }
+
+void des_encrypt2(data, ks, enc)
+DES_LONG *data;
+des_key_schedule ks;
+int enc;
+ {
+ register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+#ifndef DES_UNROLL
+ register int i;
+#endif
+ register DES_LONG *s;
+
+ r=data[0];
+ l=data[1];
+
+ /* Things have been modified so that the initial rotate is
+ * done outside the loop. This required the
+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
+ * One perl script later and things have a 5% speed up on a sparc2.
+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
+ * for pointing this out. */
+ /* clear the top bits on machines with 8byte longs */
+ r=ROTATE(r,29)&0xffffffffL;
+ l=ROTATE(l,29)&0xffffffffL;
+
+ s=(DES_LONG *)ks;
+ /* I don't know if it is worth the effort of loop unrolling the
+ * inner loop */
+ if (enc)
+ {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r, 0); /* 1 */
+ D_ENCRYPT(r,l, 2); /* 2 */
+ D_ENCRYPT(l,r, 4); /* 3 */
+ D_ENCRYPT(r,l, 6); /* 4 */
+ D_ENCRYPT(l,r, 8); /* 5 */
+ D_ENCRYPT(r,l,10); /* 6 */
+ D_ENCRYPT(l,r,12); /* 7 */
+ D_ENCRYPT(r,l,14); /* 8 */
+ D_ENCRYPT(l,r,16); /* 9 */
+ D_ENCRYPT(r,l,18); /* 10 */
+ D_ENCRYPT(l,r,20); /* 11 */
+ D_ENCRYPT(r,l,22); /* 12 */
+ D_ENCRYPT(l,r,24); /* 13 */
+ D_ENCRYPT(r,l,26); /* 14 */
+ D_ENCRYPT(l,r,28); /* 15 */
+ D_ENCRYPT(r,l,30); /* 16 */
+#else
+ for (i=0; i<32; i+=8)
+ {
+ D_ENCRYPT(l,r,i+0); /* 1 */
+ D_ENCRYPT(r,l,i+2); /* 2 */
+ D_ENCRYPT(l,r,i+4); /* 3 */
+ D_ENCRYPT(r,l,i+6); /* 4 */
+ }
+#endif
+ }
+ else
+ {
+#ifdef DES_UNROLL
+ D_ENCRYPT(l,r,30); /* 16 */
+ D_ENCRYPT(r,l,28); /* 15 */
+ D_ENCRYPT(l,r,26); /* 14 */
+ D_ENCRYPT(r,l,24); /* 13 */
+ D_ENCRYPT(l,r,22); /* 12 */
+ D_ENCRYPT(r,l,20); /* 11 */
+ D_ENCRYPT(l,r,18); /* 10 */
+ D_ENCRYPT(r,l,16); /* 9 */
+ D_ENCRYPT(l,r,14); /* 8 */
+ D_ENCRYPT(r,l,12); /* 7 */
+ D_ENCRYPT(l,r,10); /* 6 */
+ D_ENCRYPT(r,l, 8); /* 5 */
+ D_ENCRYPT(l,r, 6); /* 4 */
+ D_ENCRYPT(r,l, 4); /* 3 */
+ D_ENCRYPT(l,r, 2); /* 2 */
+ D_ENCRYPT(r,l, 0); /* 1 */
+#else
+ for (i=30; i>0; i-=8)
+ {
+ D_ENCRYPT(l,r,i-0); /* 16 */
+ D_ENCRYPT(r,l,i-2); /* 15 */
+ D_ENCRYPT(l,r,i-4); /* 14 */
+ D_ENCRYPT(r,l,i-6); /* 13 */
+ }
+#endif
+ }
+ /* rotate and clear the top bits on machines with 8byte longs */
+ data[0]=ROTATE(l,3)&0xffffffffL;
+ data[1]=ROTATE(r,3)&0xffffffffL;
+ l=r=t=u=0;
+ }
+
+void des_encrypt3(data,ks1,ks2,ks3)
+DES_LONG *data;
+des_key_schedule ks1;
+des_key_schedule ks2;
+des_key_schedule ks3;
+ {
+ register DES_LONG l,r;
+
+ l=data[0];
+ r=data[1];
+ IP(l,r);
+ data[0]=l;
+ data[1]=r;
+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
+ l=data[0];
+ r=data[1];
+ FP(r,l);
+ data[0]=l;
+ data[1]=r;
+ }
+
+void des_decrypt3(data,ks1,ks2,ks3)
+DES_LONG *data;
+des_key_schedule ks1;
+des_key_schedule ks2;
+des_key_schedule ks3;
+ {
+ register DES_LONG l,r;
+
+ l=data[0];
+ r=data[1];
+ IP(l,r);
+ data[0]=l;
+ data[1]=r;
+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
+ l=data[0];
+ r=data[1];
+ FP(r,l);
+ data[0]=l;
+ data[1]=r;
+ }
+
+#ifndef DES_DEFAULT_OPTIONS
+
+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
+des_cblock (*input);
+des_cblock (*output);
+long length;
+des_key_schedule schedule;
+des_cblock (*ivec);
+int enc;
+ {
+ register DES_LONG tin0,tin1;
+ register DES_LONG tout0,tout1,xor0,xor1;
+ register unsigned char *in,*out;
+ register long l=length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (enc)
+ {
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ tin0^=tout0; tin[0]=tin0;
+ tin1^=tout1; tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+ tout0=tin[0]; l2c(tout0,out);
+ tout1=tin[1]; l2c(tout1,out);
+ }
+ if (l != -8)
+ {
+ c2ln(in,tin0,tin1,l+8);
+ tin0^=tout0; tin[0]=tin0;
+ tin1^=tout1; tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
+ tout0=tin[0]; l2c(tout0,out);
+ tout1=tin[1]; l2c(tout1,out);
+ }
+ iv=(unsigned char *)ivec;
+ l2c(tout0,iv);
+ l2c(tout1,iv);
+ }
+ else
+ {
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0); tin[0]=tin0;
+ c2l(in,tin1); tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2c(tout0,out);
+ l2c(tout1,out);
+ xor0=tin0;
+ xor1=tin1;
+ }
+ if (l != -8)
+ {
+ c2l(in,tin0); tin[0]=tin0;
+ c2l(in,tin1); tin[1]=tin1;
+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
+ tout0=tin[0]^xor0;
+ tout1=tin[1]^xor1;
+ l2cn(tout0,tout1,out,l+8);
+ xor0=tin0;
+ xor1=tin1;
+ }
+
+ iv=(unsigned char *)ivec;
+ l2c(xor0,iv);
+ l2c(xor1,iv);
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=0;
+ }
+
+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
+des_cblock (*input);
+des_cblock (*output);
+long length;
+des_key_schedule ks1;
+des_key_schedule ks2;
+des_key_schedule ks3;
+des_cblock (*ivec);
+int enc;
+ {
+ register DES_LONG tin0,tin1;
+ register DES_LONG tout0,tout1,xor0,xor1;
+ register unsigned char *in,*out;
+ register long l=length;
+ DES_LONG tin[2];
+ unsigned char *iv;
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ iv=(unsigned char *)ivec;
+
+ if (enc)
+ {
+ c2l(iv,tout0);
+ c2l(iv,tout1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+ tin0^=tout0;
+ tin1^=tout1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ if (l != -8)
+ {
+ c2ln(in,tin0,tin1,l+8);
+ tin0^=tout0;
+ tin1^=tout1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ l2c(tout0,out);
+ l2c(tout1,out);
+ }
+ iv=(unsigned char *)ivec;
+ l2c(tout0,iv);
+ l2c(tout1,iv);
+ }
+ else
+ {
+ register DES_LONG t0,t1;
+
+ c2l(iv,xor0);
+ c2l(iv,xor1);
+ for (l-=8; l>=0; l-=8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+
+ t0=tin0;
+ t1=tin1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ tout0^=xor0;
+ tout1^=xor1;
+ l2c(tout0,out);
+ l2c(tout1,out);
+ xor0=t0;
+ xor1=t1;
+ }
+ if (l != -8)
+ {
+ c2l(in,tin0);
+ c2l(in,tin1);
+
+ t0=tin0;
+ t1=tin1;
+
+ tin[0]=tin0;
+ tin[1]=tin1;
+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
+ tout0=tin[0];
+ tout1=tin[1];
+
+ tout0^=xor0;
+ tout1^=xor1;
+ l2cn(tout0,tout1,out,l+8);
+ xor0=t0;
+ xor1=t1;
+ }
+
+ iv=(unsigned char *)ivec;
+ l2c(xor0,iv);
+ l2c(xor1,iv);
+ }
+ tin0=tin1=tout0=tout1=xor0=xor1=0;
+ tin[0]=tin[1]=0;
+ }
+
+#endif /* DES_DEFAULT_OPTIONS */
diff --git a/src/libfreeswan/libdes/des/des_locl.h b/src/libfreeswan/libdes/des/des_locl.h
new file mode 100644
index 000000000..020d6b7ca
--- /dev/null
+++ b/src/libfreeswan/libdes/des/des_locl.h
@@ -0,0 +1,515 @@
+/* crypto/des/des_locl.org */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * Always modify des_locl.org since des_locl.h is automatically generated from
+ * it during SSLeay configuration.
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+#ifndef HEADER_DES_LOCL_H
+#define HEADER_DES_LOCL_H
+
+#if defined(WIN32) || defined(WIN16)
+#ifndef MSDOS
+#define MSDOS
+#endif
+#endif
+
+#include "crypto/des.h"
+
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#define DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units. It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#define DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#define DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+ even newer MIPS CPU's, but at the moment one size fits all for
+ optimization options. Older Sparc's work better with only UNROLL, but
+ there's no way to tell at compile time what it is you're running on */
+
+#if defined( sun ) /* Newer Sparc's */
+ #define DES_PTR
+ #define DES_RISC1
+ #define DES_UNROLL
+#elif defined( __ultrix ) /* Older MIPS */
+ #define DES_PTR
+ #define DES_RISC2
+ #define DES_UNROLL
+#elif defined( __osf1__ ) /* Alpha */
+ #define DES_PTR
+ #define DES_RISC2
+#elif defined ( _AIX ) /* RS6000 */
+ /* Unknown */
+#elif defined( __hpux ) /* HP-PA */
+ /* Unknown */
+#elif defined( __aux ) /* 68K */
+ /* Unknown */
+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
+ #define DES_UNROLL
+#elif defined( __sgi ) /* Newer MIPS */
+ #define DES_PTR
+ #define DES_RISC2
+ #define DES_UNROLL
+#elif defined( i386 ) /* x86 boxes, should be gcc */
+ #define DES_PTR
+ #define DES_RISC1
+ #define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+
+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <io.h>
+#ifndef RAND
+#define RAND
+#endif
+#undef NOPROTO
+#endif
+
+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
+#ifndef __KERNEL__
+#include <string.h>
+#else
+#include <linux/string.h>
+#endif
+#endif
+
+#ifndef RAND
+#define RAND
+#endif
+
+#ifdef linux
+#undef RAND
+#endif
+
+#ifdef MSDOS
+#define getpid() 2
+#define RAND
+#undef NOPROTO
+#endif
+
+#if defined(NOCONST)
+#define const
+#endif
+
+#ifdef __STDC__
+#undef NOPROTO
+#endif
+
+#ifdef RAND
+#define srandom(s) srand(s)
+#define random rand
+#endif
+
+#define ITERATIONS 16
+#define HALF_ITERATIONS 8
+
+/* used in des_read and des_write */
+#define MAXWRITE (1024*16)
+#define BSIZE (MAXWRITE+4)
+
+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
+ l|=((DES_LONG)(*((c)++)))<<16L, \
+ l|=((DES_LONG)(*((c)++)))<<24L)
+
+/* NOTE - c is not incremented as per c2l */
+#define c2ln(c,l1,l2,n) { \
+ c+=n; \
+ l1=l2=0; \
+ switch (n) { \
+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
+ case 5: l2|=((DES_LONG)(*(--(c)))); \
+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
+ case 1: l1|=((DES_LONG)(*(--(c)))); \
+ } \
+ }
+
+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
+
+/* replacements for htonl and ntohl since I have no idea what to do
+ * when faced with machines with 8 byte longs. */
+#define HDRSIZE 4
+
+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
+ l|=((DES_LONG)(*((c)++)))<<16L, \
+ l|=((DES_LONG)(*((c)++)))<< 8L, \
+ l|=((DES_LONG)(*((c)++))))
+
+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
+ *((c)++)=(unsigned char)(((l) )&0xff))
+
+/* NOTE - c is not incremented as per l2c */
+#define l2cn(l1,l2,c,n) { \
+ c+=n; \
+ switch (n) { \
+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
+ } \
+ }
+
+#if defined(WIN32)
+#define ROTATE(a,n) (_lrotr(a,n))
+#else
+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
+#endif
+
+/* Don't worry about the LOAD_DATA() stuff, that is used by
+ * fcrypt() to add it's little bit to the front */
+
+#ifdef DES_FCRYPT
+
+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
+
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+ t=R^(R>>16L); \
+ u=t&E0; t&=E1; \
+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
+#else
+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
+ u=R^s[S ]; \
+ t=R^s[S+1]
+#endif
+
+/* The changes to this macro may help or hinder, depending on the
+ * compiler and the achitecture. gcc2 always seems to do well :-).
+ * Inspired by Dana How <how@isl.stanford.edu>
+ * DO NOT use the alternative version on machines with 8 byte longs.
+ * It does not seem to work on the Alpha, even when DES_LONG is 4
+ * bytes, probably an issue of accessing non-word aligned objects :-( */
+#ifdef DES_PTR
+
+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
+ * is no reason to not xor all the sub items together. This potentially
+ * saves a register since things can be xored directly into L */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) { \
+ unsigned int u1,u2,u3; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0xfc; \
+ u2&=0xfc; \
+ t=ROTATE(t,4); \
+ u>>=16L; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
+ u3=(int)(u>>8L); \
+ u1=(int)u&0xfc; \
+ u3&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
+ u2=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u2&=0xfc; \
+ t>>=16L; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
+ u3=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u3&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) { \
+ unsigned int u1,u2,s1,s2; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0xfc; \
+ u2&=0xfc; \
+ t=ROTATE(t,4); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
+ s1=(int)(u>>16L); \
+ s2=(int)(u>>24L); \
+ s1&=0xfc; \
+ s2&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
+ u2=(int)t>>8L; \
+ u1=(int)t&0xfc; \
+ u2&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
+ s1=(int)(t>>16L); \
+ s2=(int)(t>>24L); \
+ s1&=0xfc; \
+ s2&=0xfc; \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
+#endif
+#else
+#define D_ENCRYPT(LL,R,S) { \
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+ t=ROTATE(t,4); \
+ LL^= \
+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
+#endif
+
+#else /* original version */
+
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+#define D_ENCRYPT(LL,R,S) {\
+ unsigned int u1,u2,u3; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u>>=2L; \
+ t=ROTATE(t,6); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u2&=0x3f; \
+ u>>=16L; \
+ LL^=des_SPtrans[0][u1]; \
+ LL^=des_SPtrans[2][u2]; \
+ u3=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u3&=0x3f; \
+ LL^=des_SPtrans[4][u1]; \
+ LL^=des_SPtrans[6][u3]; \
+ u2=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u2&=0x3f; \
+ t>>=16L; \
+ LL^=des_SPtrans[1][u1]; \
+ LL^=des_SPtrans[3][u2]; \
+ u3=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u3&=0x3f; \
+ LL^=des_SPtrans[5][u1]; \
+ LL^=des_SPtrans[7][u3]; }
+#endif
+#ifdef DES_RISC2
+#define D_ENCRYPT(LL,R,S) {\
+ unsigned int u1,u2,s1,s2; \
+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
+ u>>=2L; \
+ t=ROTATE(t,6); \
+ u2=(int)u>>8L; \
+ u1=(int)u&0x3f; \
+ u2&=0x3f; \
+ LL^=des_SPtrans[0][u1]; \
+ LL^=des_SPtrans[2][u2]; \
+ s1=(int)u>>16L; \
+ s2=(int)u>>24L; \
+ s1&=0x3f; \
+ s2&=0x3f; \
+ LL^=des_SPtrans[4][s1]; \
+ LL^=des_SPtrans[6][s2]; \
+ u2=(int)t>>8L; \
+ u1=(int)t&0x3f; \
+ u2&=0x3f; \
+ LL^=des_SPtrans[1][u1]; \
+ LL^=des_SPtrans[3][u2]; \
+ s1=(int)t>>16; \
+ s2=(int)t>>24L; \
+ s1&=0x3f; \
+ s2&=0x3f; \
+ LL^=des_SPtrans[5][s1]; \
+ LL^=des_SPtrans[7][s2]; }
+#endif
+
+#else
+
+#define D_ENCRYPT(LL,R,S) {\
+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
+ t=ROTATE(t,4); \
+ LL^=\
+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
+ des_SPtrans[2][(u>>10L)&0x3f]^ \
+ des_SPtrans[4][(u>>18L)&0x3f]^ \
+ des_SPtrans[6][(u>>26L)&0x3f]^ \
+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
+ des_SPtrans[3][(t>>10L)&0x3f]^ \
+ des_SPtrans[5][(t>>18L)&0x3f]^ \
+ des_SPtrans[7][(t>>26L)&0x3f]; }
+#endif
+#endif
+
+ /* IP and FP
+ * The problem is more of a geometric problem that random bit fiddling.
+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
+
+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
+
+ The output has been subject to swaps of the form
+ 0 1 -> 3 1 but the odd and even bits have been put into
+ 2 3 2 0
+ different words. The main trick is to remember that
+ t=((l>>size)^r)&(mask);
+ r^=t;
+ l^=(t<<size);
+ can be used to swap and move bits between words.
+
+ So l = 0 1 2 3 r = 16 17 18 19
+ 4 5 6 7 20 21 22 23
+ 8 9 10 11 24 25 26 27
+ 12 13 14 15 28 29 30 31
+ becomes (for size == 2 and mask == 0x3333)
+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
+
+ Thanks for hints from Richard Outerbridge - he told me IP&FP
+ could be done in 15 xor, 10 shifts and 5 ands.
+ When I finally started to think of the problem in 2D
+ I first got ~42 operations without xors. When I remembered
+ how to use xors :-) I got it to its final state.
+ */
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#define IP(l,r) \
+ { \
+ register DES_LONG tt; \
+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
+ PERM_OP(l,r,tt,16,0x0000ffffL); \
+ PERM_OP(r,l,tt, 2,0x33333333L); \
+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
+ PERM_OP(r,l,tt, 1,0x55555555L); \
+ }
+
+#define FP(l,r) \
+ { \
+ register DES_LONG tt; \
+ PERM_OP(l,r,tt, 1,0x55555555L); \
+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
+ PERM_OP(l,r,tt, 2,0x33333333L); \
+ PERM_OP(r,l,tt,16,0x0000ffffL); \
+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
+ }
+
+extern const DES_LONG des_SPtrans[8][64];
+
+#ifndef NOPROTO
+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
+ DES_LONG Eswap0, DES_LONG Eswap1);
+#else
+void fcrypt_body();
+#endif
+
+#endif
diff --git a/src/libfreeswan/libdes/des/des_opts.c b/src/libfreeswan/libdes/des/des_opts.c
new file mode 100644
index 000000000..b6693c405
--- /dev/null
+++ b/src/libfreeswan/libdes/des/des_opts.c
@@ -0,0 +1,620 @@
+/* crypto/des/des_opts.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
+ * This is for machines with 64k code segment size restrictions. */
+
+#ifndef MSDOS
+#define TIMES
+#endif
+
+#include <stdio.h>
+#ifndef MSDOS
+#include <unistd.h>
+#else
+#include <io.h>
+extern void exit();
+#endif
+#include <signal.h>
+#ifndef VMS
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+#else /* VMS */
+#include <types.h>
+struct tms {
+ time_t tms_utime;
+ time_t tms_stime;
+ time_t tms_uchild; /* I dunno... */
+ time_t tms_uchildsys; /* so these names are a guess :-) */
+ }
+#endif
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#ifdef sun
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include "des_locl.h"
+#include "spr.h"
+
+#define DES_DEFAULT_OPTIONS
+
+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
+#define PART1
+#define PART2
+#define PART3
+#define PART4
+#endif
+
+#ifdef PART1
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#define des_encrypt des_encrypt_u4_cisc_idx
+#define des_encrypt2 des_encrypt2_u4_cisc_idx
+#define des_encrypt3 des_encrypt3_u4_cisc_idx
+#define des_decrypt3 des_decrypt3_u4_cisc_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u16_cisc_idx
+#define des_encrypt2 des_encrypt2_u16_cisc_idx
+#define des_encrypt3 des_encrypt3_u16_cisc_idx
+#define des_decrypt3 des_decrypt3_u16_cisc_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#undef DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u4_risc1_idx
+#define des_encrypt2 des_encrypt2_u4_risc1_idx
+#define des_encrypt3 des_encrypt3_u4_risc1_idx
+#define des_decrypt3 des_decrypt3_u4_risc1_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+#ifdef PART2
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u4_risc2_idx
+#define des_encrypt2 des_encrypt2_u4_risc2_idx
+#define des_encrypt3 des_encrypt3_u4_risc2_idx
+#define des_decrypt3 des_decrypt3_u4_risc2_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u16_risc1_idx
+#define des_encrypt2 des_encrypt2_u16_risc1_idx
+#define des_encrypt3 des_encrypt3_u16_risc1_idx
+#define des_decrypt3 des_decrypt3_u16_risc1_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#undef DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u16_risc2_idx
+#define des_encrypt2 des_encrypt2_u16_risc2_idx
+#define des_encrypt3 des_encrypt3_u16_risc2_idx
+#define des_decrypt3 des_decrypt3_u16_risc2_idx
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+#ifdef PART3
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u4_cisc_ptr
+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u16_cisc_ptr
+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#undef DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u4_risc1_ptr
+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+#ifdef PART4
+
+#undef DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u4_risc2_ptr
+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#define DES_RISC1
+#undef DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u16_risc1_ptr
+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#define DES_UNROLL
+#undef DES_RISC1
+#define DES_RISC2
+#define DES_PTR
+#undef D_ENCRYPT
+#undef des_encrypt
+#undef des_encrypt2
+#undef des_encrypt3
+#undef des_decrypt3
+#define des_encrypt des_encrypt_u16_risc2_ptr
+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
+#undef HEADER_DES_LOCL_H
+#include "des_enc.c"
+
+#endif
+
+/* The following if from times(3) man page. It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
+# ifndef VMS
+# define HZ 100.0
+# else /* VMS */
+# define HZ 100.0
+# endif
+# else /* _BSD_CLK_TCK_ */
+# define HZ ((double)_BSD_CLK_TCK_)
+# endif
+# else /* CLK_TCK */
+# define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#define BUFSIZE ((long)1024)
+long run=0;
+
+#ifndef NOPROTO
+double Time_F(int s);
+#else
+double Time_F();
+#endif
+
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+#ifndef NOPROTO
+SIGRETTYPE sig_done(int sig);
+#else
+SIGRETTYPE sig_done();
+#endif
+
+SIGRETTYPE sig_done(sig)
+int sig;
+ {
+ signal(SIGALRM,sig_done);
+ run=0;
+#ifdef LINT
+ sig=sig;
+#endif
+ }
+#endif
+
+#define START 0
+#define STOP 1
+
+double Time_F(s)
+int s;
+ {
+ double ret;
+#ifdef TIMES
+ static struct tms tstart,tend;
+
+ if (s == START)
+ {
+ times(&tstart);
+ return(0);
+ }
+ else
+ {
+ times(&tend);
+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+ return((ret == 0.0)?1e-6:ret);
+ }
+#else /* !times() */
+ static struct timeb tstart,tend;
+ long i;
+
+ if (s == START)
+ {
+ ftime(&tstart);
+ return(0);
+ }
+ else
+ {
+ ftime(&tend);
+ i=(long)tend.millitm-(long)tstart.millitm;
+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
+ return((ret == 0.0)?1e-6:ret);
+ }
+#endif
+ }
+
+#ifdef SIGALRM
+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
+#else
+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
+#endif
+
+#define time_it(func,name,index) \
+ print_name(name); \
+ Time_F(START); \
+ for (count=0,run=1; COND(cb); count++) \
+ { \
+ unsigned long d[2]; \
+ func(d,&(sch[0]),DES_ENCRYPT); \
+ } \
+ tm[index]=Time_F(STOP); \
+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
+ tm[index]=((double)COUNT(cb))/tm[index];
+
+#define print_it(name,index) \
+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
+ tm[index]*8,1.0e6/tm[index]);
+
+int main(argc,argv)
+int argc;
+char **argv;
+ {
+ long count;
+ static unsigned char buf[BUFSIZE];
+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+ des_key_schedule sch,sch2,sch3;
+ double d,tm[16],max=0;
+ int rank[16];
+ char *str[16];
+ int max_idx=0,i,num=0,j;
+#ifndef SIGALARM
+ long ca,cb,cc,cd,ce;
+#endif
+
+ for (i=0; i<12; i++)
+ {
+ tm[i]=0.0;
+ rank[i]=0;
+ }
+
+#ifndef TIMES
+ fprintf(stderr,"To get the most acurate results, try to run this\n");
+ fprintf(stderr,"program when this computer is idle.\n");
+#endif
+
+ des_set_key((C_Block *)key,sch);
+ des_set_key((C_Block *)key2,sch2);
+ des_set_key((C_Block *)key3,sch3);
+
+#ifndef SIGALRM
+ fprintf(stderr,"First we calculate the approximate speed ...\n");
+ des_set_key((C_Block *)key,sch);
+ count=10;
+ do {
+ long i;
+ unsigned long data[2];
+
+ count*=2;
+ Time_F(START);
+ for (i=count; i; i--)
+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
+ d=Time_F(STOP);
+ } while (d < 3.0);
+ ca=count;
+ cb=count*3;
+ cc=count*3*8/BUFSIZE+1;
+ cd=count*8/BUFSIZE+1;
+
+ ce=count/20+1;
+#define COND(d) (count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c) (run)
+#define COUNT(d) (count)
+ signal(SIGALRM,sig_done);
+ alarm(10);
+#endif
+
+#ifdef PART1
+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
+ num+=3;
+#endif
+#ifdef PART2
+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
+ num+=3;
+#endif
+#ifdef PART3
+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
+ num+=3;
+#endif
+#ifdef PART4
+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
+ num+=3;
+#endif
+
+#ifdef PART1
+ str[0]=" 4 c i";
+ print_it("des_encrypt_u4_cisc_idx ",0);
+ max=tm[0];
+ max_idx=0;
+ str[1]="16 c i";
+ print_it("des_encrypt_u16_cisc_idx ",1);
+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
+ str[2]=" 4 r1 i";
+ print_it("des_encrypt_u4_risc1_idx ",2);
+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
+#endif
+#ifdef PART2
+ str[3]="16 r1 i";
+ print_it("des_encrypt_u16_risc1_idx",3);
+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
+ str[4]=" 4 r2 i";
+ print_it("des_encrypt_u4_risc2_idx ",4);
+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
+ str[5]="16 r2 i";
+ print_it("des_encrypt_u16_risc2_idx",5);
+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
+#endif
+#ifdef PART3
+ str[6]=" 4 c p";
+ print_it("des_encrypt_u4_cisc_ptr ",6);
+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
+ str[7]="16 c p";
+ print_it("des_encrypt_u16_cisc_ptr ",7);
+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
+ str[8]=" 4 r1 p";
+ print_it("des_encrypt_u4_risc1_ptr ",8);
+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
+#endif
+#ifdef PART4
+ str[9]="16 r1 p";
+ print_it("des_encrypt_u16_risc1_ptr",9);
+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
+ str[10]=" 4 r2 p";
+ print_it("des_encrypt_u4_risc2_ptr ",10);
+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
+ str[11]="16 r2 p";
+ print_it("des_encrypt_u16_risc2_ptr",11);
+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
+#endif
+ printf("options des ecb/s\n");
+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
+ d=tm[max_idx];
+ tm[max_idx]= -2.0;
+ max= -1.0;
+ for (;;)
+ {
+ for (i=0; i<12; i++)
+ {
+ if (max < tm[i]) { max=tm[i]; j=i; }
+ }
+ if (max < 0.0) break;
+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
+ tm[j]= -2.0;
+ max= -1.0;
+ }
+
+ switch (max_idx)
+ {
+ case 0:
+ printf("-DDES_DEFAULT_OPTIONS\n");
+ break;
+ case 1:
+ printf("-DDES_UNROLL\n");
+ break;
+ case 2:
+ printf("-DDES_RISC1\n");
+ break;
+ case 3:
+ printf("-DDES_UNROLL -DDES_RISC1\n");
+ break;
+ case 4:
+ printf("-DDES_RISC2\n");
+ break;
+ case 5:
+ printf("-DDES_UNROLL -DDES_RISC2\n");
+ break;
+ case 6:
+ printf("-DDES_PTR\n");
+ break;
+ case 7:
+ printf("-DDES_UNROLL -DDES_PTR\n");
+ break;
+ case 8:
+ printf("-DDES_RISC1 -DDES_PTR\n");
+ break;
+ case 9:
+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
+ break;
+ case 10:
+ printf("-DDES_RISC2 -DDES_PTR\n");
+ break;
+ case 11:
+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
+ break;
+ }
+ exit(0);
+#if defined(LINT) || defined(MSDOS)
+ return(0);
+#endif
+ }
diff --git a/src/libfreeswan/libdes/des/des_ver.h b/src/libfreeswan/libdes/des/des_ver.h
new file mode 100644
index 000000000..98352bc0d
--- /dev/null
+++ b/src/libfreeswan/libdes/des/des_ver.h
@@ -0,0 +1,60 @@
+/* crypto/des/des_ver.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+extern char *DES_version; /* SSLeay version string */
+extern char *libdes_version; /* old libdes version string */
diff --git a/src/libfreeswan/libdes/des/destest.c b/src/libfreeswan/libdes/des/destest.c
new file mode 100644
index 000000000..ae896499e
--- /dev/null
+++ b/src/libfreeswan/libdes/des/destest.c
@@ -0,0 +1,871 @@
+/* crypto/des/destest.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
+#ifndef MSDOS
+#define MSDOS
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef MSDOS
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+#include <string.h>
+#include "des_locl.h"
+
+/* tisk tisk - the test keys don't all have odd parity :-( */
+/* test data */
+#define NUM_TESTS 34
+static unsigned char key_data[NUM_TESTS][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
+
+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
+
+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static char cbc_data[40]="7654321 Now is the time for \0001";
+
+static unsigned char cbc_ok[32]={
+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static unsigned char xcbc_ok[32]={
+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
+ };
+
+static unsigned char cbc3_ok[32]={
+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
+
+static unsigned char pcbc_ok[32]={
+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+static unsigned char plain[24]=
+ {
+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
+ 0x20,0x74,0x68,0x65,0x20,0x74,
+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
+ 0x72,0x20,0x61,0x6c,0x6c,0x20
+ };
+static unsigned char cfb_cipher8[24]= {
+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
+static unsigned char cfb_cipher16[24]={
+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
+static unsigned char cfb_cipher32[24]={
+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
+static unsigned char cfb_cipher48[24]={
+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
+static unsigned char cfb_cipher64[24]={
+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]=
+ {
+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
+ };
+
+DES_LONG cbc_cksum_ret=0xB462FEF7L;
+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#ifndef NOPROTO
+static char *pt(unsigned char *p);
+static int cfb_test(int bits, unsigned char *cfb_cipher);
+static int cfb64_test(unsigned char *cfb_cipher);
+static int ede_cfb64_test(unsigned char *cfb_cipher);
+#else
+static char *pt();
+static int cfb_test();
+static int cfb64_test();
+static int ede_cfb64_test();
+#endif
+
+int main(argc,argv)
+int argc;
+char *argv[];
+ {
+ int i,j,err=0;
+ des_cblock in,out,outin,iv3;
+ des_key_schedule ks,ks2,ks3;
+ unsigned char cbc_in[40];
+ unsigned char cbc_out[40];
+ DES_LONG cs;
+ unsigned char qret[4][4],cret[8];
+ DES_LONG lqret[4];
+ int num;
+ char *str;
+
+ printf("Doing ecb\n");
+ for (i=0; i<NUM_TESTS; i++)
+ {
+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
+ {
+ printf("Key error %2d:%d\n",i+1,j);
+ err=1;
+ }
+ memcpy(in,plain_data[i],8);
+ memset(out,0,8);
+ memset(outin,0,8);
+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
+
+ if (memcmp(out,cipher_data[i],8) != 0)
+ {
+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
+ pt(out));
+ err=1;
+ }
+ if (memcmp(in,outin,8) != 0)
+ {
+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+ err=1;
+ }
+ }
+
+#ifndef LIBDES_LIT
+ printf("Doing ede ecb\n");
+ for (i=0; i<(NUM_TESTS-1); i++)
+ {
+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
+ {
+ err=1;
+ printf("Key error %2d:%d\n",i+1,j);
+ }
+ if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
+ {
+ printf("Key error %2d:%d\n",i+2,j);
+ err=1;
+ }
+ if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
+ {
+ printf("Key error %2d:%d\n",i+3,j);
+ err=1;
+ }
+ memcpy(in,plain_data[i],8);
+ memset(out,0,8);
+ memset(outin,0,8);
+ des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
+ DES_ENCRYPT);
+ des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
+ DES_DECRYPT);
+
+ if (memcmp(out,cipher_ecb2[i],8) != 0)
+ {
+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
+ pt(out));
+ err=1;
+ }
+ if (memcmp(in,outin,8) != 0)
+ {
+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+ err=1;
+ }
+ }
+#endif
+
+ printf("Doing cbc\n");
+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+ (long)strlen((char *)cbc_data)+1,ks,
+ (C_Block *)iv3,DES_ENCRYPT);
+ if (memcmp(cbc_out,cbc_ok,32) != 0)
+ printf("cbc_encrypt encrypt error\n");
+
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+ (long)strlen((char *)cbc_data)+1,ks,
+ (C_Block *)iv3,DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
+ {
+ printf("cbc_encrypt decrypt error\n");
+ err=1;
+ }
+
+#ifndef LIBDES_LIT
+ printf("Doing desx cbc\n");
+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+ (long)strlen((char *)cbc_data)+1,ks,
+ (C_Block *)iv3,
+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
+ if (memcmp(cbc_out,xcbc_ok,32) != 0)
+ {
+ printf("des_xcbc_encrypt encrypt error\n");
+ }
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+ (long)strlen((char *)cbc_data)+1,ks,
+ (C_Block *)iv3,
+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
+ {
+ printf("des_xcbc_encrypt decrypt error\n");
+ err=1;
+ }
+#endif
+
+ printf("Doing ede cbc\n");
+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ i=strlen((char *)cbc_data)+1;
+ /* i=((i+7)/8)*8; */
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+
+ des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+ 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
+ des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
+ (C_Block *)&(cbc_out[16]),
+ (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
+ if (memcmp(cbc_out,cbc3_ok,
+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
+ {
+ printf("des_ede3_cbc_encrypt encrypt error\n");
+ err=1;
+ }
+
+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+ des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+ (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
+ {
+ printf("des_ede3_cbc_encrypt decrypt error\n");
+ err=1;
+ }
+
+#ifndef LIBDES_LIT
+ printf("Doing pcbc\n");
+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+ {
+ printf("Key error %d\n",j);
+ err=1;
+ }
+ memset(cbc_out,0,40);
+ memset(cbc_in,0,40);
+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
+ if (memcmp(cbc_out,pcbc_ok,32) != 0)
+ {
+ printf("pcbc_encrypt encrypt error\n");
+ err=1;
+ }
+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
+ {
+ printf("pcbc_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("Doing ");
+ printf("cfb8 ");
+ err+=cfb_test(8,cfb_cipher8);
+ printf("cfb16 ");
+ err+=cfb_test(16,cfb_cipher16);
+ printf("cfb32 ");
+ err+=cfb_test(32,cfb_cipher32);
+ printf("cfb48 ");
+ err+=cfb_test(48,cfb_cipher48);
+ printf("cfb64 ");
+ err+=cfb_test(64,cfb_cipher64);
+
+ printf("cfb64() ");
+ err+=cfb64_test(cfb_cipher64);
+
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ for (i=0; i<sizeof(plain); i++)
+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
+ {
+ printf("cfb_encrypt small encrypt error\n");
+ err=1;
+ }
+
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ for (i=0; i<sizeof(plain); i++)
+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ printf("cfb_encrypt small decrypt error\n");
+ err=1;
+ }
+
+ printf("ede_cfb64() ");
+ err+=ede_cfb64_test(cfb_cipher64);
+
+ printf("done\n");
+
+ printf("Doing ofb\n");
+ des_key_sched((C_Block *)ofb_key,ks);
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
+ (C_Block *)ofb_tmp);
+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ {
+ printf("ofb_encrypt encrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
+ err=1;
+ }
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
+ (C_Block *)ofb_tmp);
+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ {
+ printf("ofb_encrypt decrypt error\n");
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
+ err=1;
+ }
+
+ printf("Doing ofb64\n");
+ des_key_sched((C_Block *)ofb_key,ks);
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ memset(ofb_buf1,0,sizeof(ofb_buf1));
+ memset(ofb_buf2,0,sizeof(ofb_buf1));
+ num=0;
+ for (i=0; i<sizeof(plain); i++)
+ {
+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
+ (C_Block *)ofb_tmp,&num);
+ }
+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ {
+ printf("ofb64_encrypt encrypt error\n");
+ err=1;
+ }
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ num=0;
+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
+ (C_Block *)ofb_tmp,&num);
+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ {
+ printf("ofb64_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("Doing ede_ofb64\n");
+ des_key_sched((C_Block *)ofb_key,ks);
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ memset(ofb_buf1,0,sizeof(ofb_buf1));
+ memset(ofb_buf2,0,sizeof(ofb_buf1));
+ num=0;
+ for (i=0; i<sizeof(plain); i++)
+ {
+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
+ (C_Block *)ofb_tmp,&num);
+ }
+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+ {
+ printf("ede_ofb64_encrypt encrypt error\n");
+ err=1;
+ }
+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+ num=0;
+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
+ ks,ks,(C_Block *)ofb_tmp,&num);
+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+ {
+ printf("ede_ofb64_encrypt decrypt error\n");
+ err=1;
+ }
+
+ printf("Doing cbc_cksum\n");
+ des_key_sched((C_Block *)cbc_key,ks);
+ cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
+ if (cs != cbc_cksum_ret)
+ {
+ printf("bad return value (%08lX), should be %08lX\n",
+ (unsigned long)cs,(unsigned long)cbc_cksum_ret);
+ err=1;
+ }
+ if (memcmp(cret,cbc_cksum_data,8) != 0)
+ {
+ printf("bad cbc_cksum block returned\n");
+ err=1;
+ }
+
+ printf("Doing quad_cksum\n");
+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
+ for (i=0; i<4; i++)
+ {
+ lqret[i]=0;
+ memcpy(&(lqret[i]),&(qret[i][0]),4);
+ }
+ { /* Big-endian fix */
+ static DES_LONG l=1;
+ static unsigned char *c=(unsigned char *)&l;
+ DES_LONG ll;
+
+ if (!c[0])
+ {
+ ll=lqret[0]^lqret[3];
+ lqret[0]^=ll;
+ lqret[3]^=ll;
+ ll=lqret[1]^lqret[2];
+ lqret[1]^=ll;
+ lqret[2]^=ll;
+ }
+ }
+ if (cs != 0x70d7a63aL)
+ {
+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
+ (unsigned long)cs);
+ err=1;
+ }
+ if (lqret[0] != 0x327eba8dL)
+ {
+ printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+ (unsigned long)lqret[0],0x327eba8dL);
+ err=1;
+ }
+ if (lqret[1] != 0x201a49ccL)
+ {
+ printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+ (unsigned long)lqret[1],0x201a49ccL);
+ err=1;
+ }
+ if (lqret[2] != 0x70d7a63aL)
+ {
+ printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+ (unsigned long)lqret[2],0x70d7a63aL);
+ err=1;
+ }
+ if (lqret[3] != 0x501c2c26L)
+ {
+ printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+ (unsigned long)lqret[3],0x501c2c26L);
+ err=1;
+ }
+#endif
+
+ printf("input word alignment test");
+ for (i=0; i<4; i++)
+ {
+ printf(" %d",i);
+ des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
+ DES_ENCRYPT);
+ }
+ printf("\noutput word alignment test");
+ for (i=0; i<4; i++)
+ {
+ printf(" %d",i);
+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
+ DES_ENCRYPT);
+ }
+ printf("\n");
+ printf("fast crypt test ");
+ str=crypt("testing","ef");
+ if (strcmp("efGnQx2725bI2",str) != 0)
+ {
+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
+ err=1;
+ }
+ str=crypt("bca76;23","yA");
+ if (strcmp("yA1Rp/1hZXIJk",str) != 0)
+ {
+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
+ err=1;
+ }
+ printf("\n");
+ exit(err);
+ return(0);
+ }
+
+static char *pt(p)
+unsigned char *p;
+ {
+ static char bufs[10][20];
+ static int bnum=0;
+ char *ret;
+ int i;
+ static char *f="0123456789ABCDEF";
+
+ ret= &(bufs[bnum++][0]);
+ bnum%=10;
+ for (i=0; i<8; i++)
+ {
+ ret[i*2]=f[(p[i]>>4)&0xf];
+ ret[i*2+1]=f[p[i]&0xf];
+ }
+ ret[16]='\0';
+ return(ret);
+ }
+
+#ifndef LIBDES_LIT
+
+static int cfb_test(bits, cfb_cipher)
+int bits;
+unsigned char *cfb_cipher;
+ {
+ des_key_schedule ks;
+ int i,err=0;
+
+ des_key_sched((C_Block *)cfb_key,ks);
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
+ (C_Block *)cfb_tmp,DES_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt encrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
+ (C_Block *)cfb_tmp,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ return(err);
+ }
+
+static int cfb64_test(cfb_cipher)
+unsigned char *cfb_cipher;
+ {
+ des_key_schedule ks;
+ int err=0,i,n;
+
+ des_key_sched((C_Block *)cfb_key,ks);
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+ (long)sizeof(plain)-12,ks,
+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt encrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+ (long)sizeof(plain)-17,ks,
+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf2[i])));
+ }
+ return(err);
+ }
+
+static int ede_cfb64_test(cfb_cipher)
+unsigned char *cfb_cipher;
+ {
+ des_key_schedule ks;
+ int err=0,i,n;
+
+ des_key_sched((C_Block *)cfb_key,ks);
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+ (long)sizeof(plain)-12,ks,ks,ks,
+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("ede_cfb_encrypt encrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf1[i])));
+ }
+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+ n=0;
+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+ (long)sizeof(plain)-17,ks,ks,ks,
+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+ {
+ err=1;
+ printf("ede_cfb_encrypt decrypt error\n");
+ for (i=0; i<24; i+=8)
+ printf("%s\n",pt(&(cfb_buf2[i])));
+ }
+ return(err);
+ }
+
+#endif
+
diff --git a/src/libfreeswan/libdes/des/dx86unix.S b/src/libfreeswan/libdes/des/dx86unix.S
new file mode 100644
index 000000000..31dc0d0e1
--- /dev/null
+++ b/src/libfreeswan/libdes/des/dx86unix.S
@@ -0,0 +1,3160 @@
+/*
+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
+ * via the perl scripts found in the ASM subdir. It remains copyright of
+ * Eric Young, see the file COPYRIGHT.
+ *
+ * This was last done on October 9, 2002.
+ *
+ * While this file does not need to go through cpp, we pass it through
+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
+ * which may contain stuff that AS doesn't understand instead of
+ * referencing EXTRA_AFLAGS.
+ */
+
+ .file "dx86unix.S"
+ .version "01.01"
+.text
+ .align 16
+.globl des_encrypt
+ .type des_encrypt , @function
+des_encrypt:
+ pushl %esi
+ pushl %edi
+
+
+ movl 12(%esp), %esi
+ xorl %ecx, %ecx
+ pushl %ebx
+ pushl %ebp
+ movl (%esi), %eax
+ movl 28(%esp), %ebx
+ movl 4(%esi), %edi
+
+
+ roll $4, %eax
+ movl %eax, %esi
+ xorl %edi, %eax
+ andl $0xf0f0f0f0, %eax
+ xorl %eax, %esi
+ xorl %eax, %edi
+
+ roll $20, %edi
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0xfff0000f, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $14, %eax
+ movl %eax, %edi
+ xorl %esi, %eax
+ andl $0x33333333, %eax
+ xorl %eax, %edi
+ xorl %eax, %esi
+
+ roll $22, %esi
+ movl %esi, %eax
+ xorl %edi, %esi
+ andl $0x03fc03fc, %esi
+ xorl %esi, %eax
+ xorl %esi, %edi
+
+ roll $9, %eax
+ movl %eax, %esi
+ xorl %edi, %eax
+ andl $0xaaaaaaaa, %eax
+ xorl %eax, %esi
+ xorl %eax, %edi
+
+.byte 209
+.byte 199
+ movl 24(%esp), %ebp
+ cmpl $0, %ebx
+ je .L000start_decrypt
+
+
+ movl (%ebp), %eax
+ xorl %ebx, %ebx
+ movl 4(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 8(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 12(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 16(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 20(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 24(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 28(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 32(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 36(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 40(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 44(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 48(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 52(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 56(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 60(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 64(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 68(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 72(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 76(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 80(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 84(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 88(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 92(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 96(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 100(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 104(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 108(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 112(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 116(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 120(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 124(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+ jmp .L001end
+.L000start_decrypt:
+
+
+ movl 120(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 124(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 112(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 116(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 104(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 108(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 96(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 100(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 88(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 92(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 80(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 84(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 72(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 76(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 64(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 68(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 56(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 60(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 48(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 52(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 40(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 44(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 32(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 36(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 24(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 28(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 16(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 20(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 8(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 12(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl (%ebp), %eax
+ xorl %ebx, %ebx
+ movl 4(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+.L001end:
+
+
+ movl 20(%esp), %edx
+.byte 209
+.byte 206
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0xaaaaaaaa, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $23, %eax
+ movl %eax, %edi
+ xorl %esi, %eax
+ andl $0x03fc03fc, %eax
+ xorl %eax, %edi
+ xorl %eax, %esi
+
+ roll $10, %edi
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0x33333333, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $18, %esi
+ movl %esi, %edi
+ xorl %eax, %esi
+ andl $0xfff0000f, %esi
+ xorl %esi, %edi
+ xorl %esi, %eax
+
+ roll $12, %edi
+ movl %edi, %esi
+ xorl %eax, %edi
+ andl $0xf0f0f0f0, %edi
+ xorl %edi, %esi
+ xorl %edi, %eax
+
+ rorl $4, %eax
+ movl %eax, (%edx)
+ movl %esi, 4(%edx)
+ popl %ebp
+ popl %ebx
+ popl %edi
+ popl %esi
+ ret
+.des_encrypt_end:
+ .size des_encrypt , .des_encrypt_end-des_encrypt
+.ident "desasm.pl"
+.text
+ .align 16
+.globl des_encrypt2
+ .type des_encrypt2 , @function
+des_encrypt2:
+ pushl %esi
+ pushl %edi
+
+
+ movl 12(%esp), %eax
+ xorl %ecx, %ecx
+ pushl %ebx
+ pushl %ebp
+ movl (%eax), %esi
+ movl 28(%esp), %ebx
+ roll $3, %esi
+ movl 4(%eax), %edi
+ roll $3, %edi
+ movl 24(%esp), %ebp
+ cmpl $0, %ebx
+ je .L002start_decrypt
+
+
+ movl (%ebp), %eax
+ xorl %ebx, %ebx
+ movl 4(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 8(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 12(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 16(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 20(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 24(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 28(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 32(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 36(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 40(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 44(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 48(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 52(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 56(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 60(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 64(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 68(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 72(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 76(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 80(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 84(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 88(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 92(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 96(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 100(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 104(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 108(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 112(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 116(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 120(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 124(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+ jmp .L003end
+.L002start_decrypt:
+
+
+ movl 120(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 124(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 112(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 116(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 104(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 108(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 96(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 100(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 88(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 92(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 80(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 84(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 72(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 76(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 64(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 68(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 56(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 60(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 48(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 52(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 40(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 44(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 32(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 36(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 24(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 28(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl 16(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 20(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+
+
+ movl 8(%ebp), %eax
+ xorl %ebx, %ebx
+ movl 12(%ebp), %edx
+ xorl %esi, %eax
+ xorl %esi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %edi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %edi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %edi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %edi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %edi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %edi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %edi
+
+
+ movl (%ebp), %eax
+ xorl %ebx, %ebx
+ movl 4(%ebp), %edx
+ xorl %edi, %eax
+ xorl %edi, %edx
+ andl $0xfcfcfcfc, %eax
+ andl $0xcfcfcfcf, %edx
+ movb %al, %bl
+ movb %ah, %cl
+ rorl $4, %edx
+ movl des_SPtrans(%ebx),%ebp
+ movb %dl, %bl
+ xorl %ebp, %esi
+ movl 0x200+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movb %dh, %cl
+ shrl $16, %eax
+ movl 0x100+des_SPtrans(%ebx),%ebp
+ xorl %ebp, %esi
+ movb %ah, %bl
+ shrl $16, %edx
+ movl 0x300+des_SPtrans(%ecx),%ebp
+ xorl %ebp, %esi
+ movl 24(%esp), %ebp
+ movb %dh, %cl
+ andl $0xff, %eax
+ andl $0xff, %edx
+ movl 0x600+des_SPtrans(%ebx),%ebx
+ xorl %ebx, %esi
+ movl 0x700+des_SPtrans(%ecx),%ebx
+ xorl %ebx, %esi
+ movl 0x400+des_SPtrans(%eax),%ebx
+ xorl %ebx, %esi
+ movl 0x500+des_SPtrans(%edx),%ebx
+ xorl %ebx, %esi
+.L003end:
+
+
+ rorl $3, %edi
+ movl 20(%esp), %eax
+ rorl $3, %esi
+ movl %edi, (%eax)
+ movl %esi, 4(%eax)
+ popl %ebp
+ popl %ebx
+ popl %edi
+ popl %esi
+ ret
+.des_encrypt2_end:
+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
+.ident "desasm.pl"
+.text
+ .align 16
+.globl des_encrypt3
+ .type des_encrypt3 , @function
+des_encrypt3:
+ pushl %ebx
+ movl 8(%esp), %ebx
+ pushl %ebp
+ pushl %esi
+ pushl %edi
+
+
+ movl (%ebx), %edi
+ movl 4(%ebx), %esi
+ subl $12, %esp
+
+
+ roll $4, %edi
+ movl %edi, %edx
+ xorl %esi, %edi
+ andl $0xf0f0f0f0, %edi
+ xorl %edi, %edx
+ xorl %edi, %esi
+
+ roll $20, %esi
+ movl %esi, %edi
+ xorl %edx, %esi
+ andl $0xfff0000f, %esi
+ xorl %esi, %edi
+ xorl %esi, %edx
+
+ roll $14, %edi
+ movl %edi, %esi
+ xorl %edx, %edi
+ andl $0x33333333, %edi
+ xorl %edi, %esi
+ xorl %edi, %edx
+
+ roll $22, %edx
+ movl %edx, %edi
+ xorl %esi, %edx
+ andl $0x03fc03fc, %edx
+ xorl %edx, %edi
+ xorl %edx, %esi
+
+ roll $9, %edi
+ movl %edi, %edx
+ xorl %esi, %edi
+ andl $0xaaaaaaaa, %edi
+ xorl %edi, %edx
+ xorl %edi, %esi
+
+ rorl $3, %edx
+ rorl $2, %esi
+ movl %esi, 4(%ebx)
+ movl 36(%esp), %eax
+ movl %edx, (%ebx)
+ movl 40(%esp), %edi
+ movl 44(%esp), %esi
+ movl $1, 8(%esp)
+ movl %eax, 4(%esp)
+ movl %ebx, (%esp)
+ call des_encrypt2
+ movl $0, 8(%esp)
+ movl %edi, 4(%esp)
+ movl %ebx, (%esp)
+ call des_encrypt2
+ movl $1, 8(%esp)
+ movl %esi, 4(%esp)
+ movl %ebx, (%esp)
+ call des_encrypt2
+ addl $12, %esp
+ movl (%ebx), %edi
+ movl 4(%ebx), %esi
+
+
+ roll $2, %esi
+ roll $3, %edi
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0xaaaaaaaa, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $23, %eax
+ movl %eax, %edi
+ xorl %esi, %eax
+ andl $0x03fc03fc, %eax
+ xorl %eax, %edi
+ xorl %eax, %esi
+
+ roll $10, %edi
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0x33333333, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $18, %esi
+ movl %esi, %edi
+ xorl %eax, %esi
+ andl $0xfff0000f, %esi
+ xorl %esi, %edi
+ xorl %esi, %eax
+
+ roll $12, %edi
+ movl %edi, %esi
+ xorl %eax, %edi
+ andl $0xf0f0f0f0, %edi
+ xorl %edi, %esi
+ xorl %edi, %eax
+
+ rorl $4, %eax
+ movl %eax, (%ebx)
+ movl %esi, 4(%ebx)
+ popl %edi
+ popl %esi
+ popl %ebp
+ popl %ebx
+ ret
+.des_encrypt3_end:
+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
+.ident "desasm.pl"
+.text
+ .align 16
+.globl des_decrypt3
+ .type des_decrypt3 , @function
+des_decrypt3:
+ pushl %ebx
+ movl 8(%esp), %ebx
+ pushl %ebp
+ pushl %esi
+ pushl %edi
+
+
+ movl (%ebx), %edi
+ movl 4(%ebx), %esi
+ subl $12, %esp
+
+
+ roll $4, %edi
+ movl %edi, %edx
+ xorl %esi, %edi
+ andl $0xf0f0f0f0, %edi
+ xorl %edi, %edx
+ xorl %edi, %esi
+
+ roll $20, %esi
+ movl %esi, %edi
+ xorl %edx, %esi
+ andl $0xfff0000f, %esi
+ xorl %esi, %edi
+ xorl %esi, %edx
+
+ roll $14, %edi
+ movl %edi, %esi
+ xorl %edx, %edi
+ andl $0x33333333, %edi
+ xorl %edi, %esi
+ xorl %edi, %edx
+
+ roll $22, %edx
+ movl %edx, %edi
+ xorl %esi, %edx
+ andl $0x03fc03fc, %edx
+ xorl %edx, %edi
+ xorl %edx, %esi
+
+ roll $9, %edi
+ movl %edi, %edx
+ xorl %esi, %edi
+ andl $0xaaaaaaaa, %edi
+ xorl %edi, %edx
+ xorl %edi, %esi
+
+ rorl $3, %edx
+ rorl $2, %esi
+ movl %esi, 4(%ebx)
+ movl 36(%esp), %esi
+ movl %edx, (%ebx)
+ movl 40(%esp), %edi
+ movl 44(%esp), %eax
+ movl $0, 8(%esp)
+ movl %eax, 4(%esp)
+ movl %ebx, (%esp)
+ call des_encrypt2
+ movl $1, 8(%esp)
+ movl %edi, 4(%esp)
+ movl %ebx, (%esp)
+ call des_encrypt2
+ movl $0, 8(%esp)
+ movl %esi, 4(%esp)
+ movl %ebx, (%esp)
+ call des_encrypt2
+ addl $12, %esp
+ movl (%ebx), %edi
+ movl 4(%ebx), %esi
+
+
+ roll $2, %esi
+ roll $3, %edi
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0xaaaaaaaa, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $23, %eax
+ movl %eax, %edi
+ xorl %esi, %eax
+ andl $0x03fc03fc, %eax
+ xorl %eax, %edi
+ xorl %eax, %esi
+
+ roll $10, %edi
+ movl %edi, %eax
+ xorl %esi, %edi
+ andl $0x33333333, %edi
+ xorl %edi, %eax
+ xorl %edi, %esi
+
+ roll $18, %esi
+ movl %esi, %edi
+ xorl %eax, %esi
+ andl $0xfff0000f, %esi
+ xorl %esi, %edi
+ xorl %esi, %eax
+
+ roll $12, %edi
+ movl %edi, %esi
+ xorl %eax, %edi
+ andl $0xf0f0f0f0, %edi
+ xorl %edi, %esi
+ xorl %edi, %eax
+
+ rorl $4, %eax
+ movl %eax, (%ebx)
+ movl %esi, 4(%ebx)
+ popl %edi
+ popl %esi
+ popl %ebp
+ popl %ebx
+ ret
+.des_decrypt3_end:
+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
+.ident "desasm.pl"
+.text
+ .align 16
+.globl des_ncbc_encrypt
+ .type des_ncbc_encrypt , @function
+des_ncbc_encrypt:
+
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 28(%esp), %ebp
+
+ movl 36(%esp), %ebx
+ movl (%ebx), %esi
+ movl 4(%ebx), %edi
+ pushl %edi
+ pushl %esi
+ pushl %edi
+ pushl %esi
+ movl %esp, %ebx
+ movl 36(%esp), %esi
+ movl 40(%esp), %edi
+
+ movl 56(%esp), %ecx
+
+ pushl %ecx
+
+ movl 52(%esp), %eax
+ pushl %eax
+ pushl %ebx
+ cmpl $0, %ecx
+ jz .L004decrypt
+ andl $4294967288, %ebp
+ movl 12(%esp), %eax
+ movl 16(%esp), %ebx
+ jz .L005encrypt_finish
+.L006encrypt_loop:
+ movl (%esi), %ecx
+ movl 4(%esi), %edx
+ xorl %ecx, %eax
+ xorl %edx, %ebx
+ movl %eax, 12(%esp)
+ movl %ebx, 16(%esp)
+ call des_encrypt
+ movl 12(%esp), %eax
+ movl 16(%esp), %ebx
+ movl %eax, (%edi)
+ movl %ebx, 4(%edi)
+ addl $8, %esi
+ addl $8, %edi
+ subl $8, %ebp
+ jnz .L006encrypt_loop
+.L005encrypt_finish:
+ movl 56(%esp), %ebp
+ andl $7, %ebp
+ jz .L007finish
+ xorl %ecx, %ecx
+ xorl %edx, %edx
+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
+ jmp *%ebp
+.L009ej7:
+ movb 6(%esi), %dh
+ sall $8, %edx
+.L010ej6:
+ movb 5(%esi), %dh
+.L011ej5:
+ movb 4(%esi), %dl
+.L012ej4:
+ movl (%esi), %ecx
+ jmp .L013ejend
+.L014ej3:
+ movb 2(%esi), %ch
+ sall $8, %ecx
+.L015ej2:
+ movb 1(%esi), %ch
+.L016ej1:
+ movb (%esi), %cl
+.L013ejend:
+ xorl %ecx, %eax
+ xorl %edx, %ebx
+ movl %eax, 12(%esp)
+ movl %ebx, 16(%esp)
+ call des_encrypt
+ movl 12(%esp), %eax
+ movl 16(%esp), %ebx
+ movl %eax, (%edi)
+ movl %ebx, 4(%edi)
+ jmp .L007finish
+.align 16
+.L004decrypt:
+ andl $4294967288, %ebp
+ movl 20(%esp), %eax
+ movl 24(%esp), %ebx
+ jz .L017decrypt_finish
+.L018decrypt_loop:
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, 12(%esp)
+ movl %ebx, 16(%esp)
+ call des_encrypt
+ movl 12(%esp), %eax
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ movl 24(%esp), %edx
+ xorl %eax, %ecx
+ xorl %ebx, %edx
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %ecx, (%edi)
+ movl %edx, 4(%edi)
+ movl %eax, 20(%esp)
+ movl %ebx, 24(%esp)
+ addl $8, %esi
+ addl $8, %edi
+ subl $8, %ebp
+ jnz .L018decrypt_loop
+.L017decrypt_finish:
+ movl 56(%esp), %ebp
+ andl $7, %ebp
+ jz .L007finish
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, 12(%esp)
+ movl %ebx, 16(%esp)
+ call des_encrypt
+ movl 12(%esp), %eax
+ movl 16(%esp), %ebx
+ movl 20(%esp), %ecx
+ movl 24(%esp), %edx
+ xorl %eax, %ecx
+ xorl %ebx, %edx
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+.L019dj7:
+ rorl $16, %edx
+ movb %dl, 6(%edi)
+ shrl $16, %edx
+.L020dj6:
+ movb %dh, 5(%edi)
+.L021dj5:
+ movb %dl, 4(%edi)
+.L022dj4:
+ movl %ecx, (%edi)
+ jmp .L023djend
+.L024dj3:
+ rorl $16, %ecx
+ movb %cl, 2(%edi)
+ sall $16, %ecx
+.L025dj2:
+ movb %ch, 1(%esi)
+.L026dj1:
+ movb %cl, (%esi)
+.L023djend:
+ jmp .L007finish
+.align 16
+.L007finish:
+ movl 64(%esp), %ecx
+ addl $28, %esp
+ movl %eax, (%ecx)
+ movl %ebx, 4(%ecx)
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.align 16
+.L008cbc_enc_jmp_table:
+ .long 0
+ .long .L016ej1
+ .long .L015ej2
+ .long .L014ej3
+ .long .L012ej4
+ .long .L011ej5
+ .long .L010ej6
+ .long .L009ej7
+.align 16
+.L027cbc_dec_jmp_table:
+ .long 0
+ .long .L026dj1
+ .long .L025dj2
+ .long .L024dj3
+ .long .L022dj4
+ .long .L021dj5
+ .long .L020dj6
+ .long .L019dj7
+.des_ncbc_encrypt_end:
+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
+.ident "desasm.pl"
+.text
+ .align 16
+.globl des_ede3_cbc_encrypt
+ .type des_ede3_cbc_encrypt , @function
+des_ede3_cbc_encrypt:
+
+ pushl %ebp
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+ movl 28(%esp), %ebp
+
+ movl 44(%esp), %ebx
+ movl (%ebx), %esi
+ movl 4(%ebx), %edi
+ pushl %edi
+ pushl %esi
+ pushl %edi
+ pushl %esi
+ movl %esp, %ebx
+ movl 36(%esp), %esi
+ movl 40(%esp), %edi
+
+ movl 64(%esp), %ecx
+
+ movl 56(%esp), %eax
+ pushl %eax
+
+ movl 56(%esp), %eax
+ pushl %eax
+
+ movl 56(%esp), %eax
+ pushl %eax
+ pushl %ebx
+ cmpl $0, %ecx
+ jz .L028decrypt
+ andl $4294967288, %ebp
+ movl 16(%esp), %eax
+ movl 20(%esp), %ebx
+ jz .L029encrypt_finish
+.L030encrypt_loop:
+ movl (%esi), %ecx
+ movl 4(%esi), %edx
+ xorl %ecx, %eax
+ xorl %edx, %ebx
+ movl %eax, 16(%esp)
+ movl %ebx, 20(%esp)
+ call des_encrypt3
+ movl 16(%esp), %eax
+ movl 20(%esp), %ebx
+ movl %eax, (%edi)
+ movl %ebx, 4(%edi)
+ addl $8, %esi
+ addl $8, %edi
+ subl $8, %ebp
+ jnz .L030encrypt_loop
+.L029encrypt_finish:
+ movl 60(%esp), %ebp
+ andl $7, %ebp
+ jz .L031finish
+ xorl %ecx, %ecx
+ xorl %edx, %edx
+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
+ jmp *%ebp
+.L033ej7:
+ movb 6(%esi), %dh
+ sall $8, %edx
+.L034ej6:
+ movb 5(%esi), %dh
+.L035ej5:
+ movb 4(%esi), %dl
+.L036ej4:
+ movl (%esi), %ecx
+ jmp .L037ejend
+.L038ej3:
+ movb 2(%esi), %ch
+ sall $8, %ecx
+.L039ej2:
+ movb 1(%esi), %ch
+.L040ej1:
+ movb (%esi), %cl
+.L037ejend:
+ xorl %ecx, %eax
+ xorl %edx, %ebx
+ movl %eax, 16(%esp)
+ movl %ebx, 20(%esp)
+ call des_encrypt3
+ movl 16(%esp), %eax
+ movl 20(%esp), %ebx
+ movl %eax, (%edi)
+ movl %ebx, 4(%edi)
+ jmp .L031finish
+.align 16
+.L028decrypt:
+ andl $4294967288, %ebp
+ movl 24(%esp), %eax
+ movl 28(%esp), %ebx
+ jz .L041decrypt_finish
+.L042decrypt_loop:
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, 16(%esp)
+ movl %ebx, 20(%esp)
+ call des_decrypt3
+ movl 16(%esp), %eax
+ movl 20(%esp), %ebx
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ xorl %eax, %ecx
+ xorl %ebx, %edx
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %ecx, (%edi)
+ movl %edx, 4(%edi)
+ movl %eax, 24(%esp)
+ movl %ebx, 28(%esp)
+ addl $8, %esi
+ addl $8, %edi
+ subl $8, %ebp
+ jnz .L042decrypt_loop
+.L041decrypt_finish:
+ movl 60(%esp), %ebp
+ andl $7, %ebp
+ jz .L031finish
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+ movl %eax, 16(%esp)
+ movl %ebx, 20(%esp)
+ call des_decrypt3
+ movl 16(%esp), %eax
+ movl 20(%esp), %ebx
+ movl 24(%esp), %ecx
+ movl 28(%esp), %edx
+ xorl %eax, %ecx
+ xorl %ebx, %edx
+ movl (%esi), %eax
+ movl 4(%esi), %ebx
+.L043dj7:
+ rorl $16, %edx
+ movb %dl, 6(%edi)
+ shrl $16, %edx
+.L044dj6:
+ movb %dh, 5(%edi)
+.L045dj5:
+ movb %dl, 4(%edi)
+.L046dj4:
+ movl %ecx, (%edi)
+ jmp .L047djend
+.L048dj3:
+ rorl $16, %ecx
+ movb %cl, 2(%edi)
+ sall $16, %ecx
+.L049dj2:
+ movb %ch, 1(%esi)
+.L050dj1:
+ movb %cl, (%esi)
+.L047djend:
+ jmp .L031finish
+.align 16
+.L031finish:
+ movl 76(%esp), %ecx
+ addl $32, %esp
+ movl %eax, (%ecx)
+ movl %ebx, 4(%ecx)
+ popl %edi
+ popl %esi
+ popl %ebx
+ popl %ebp
+ ret
+.align 16
+.L032cbc_enc_jmp_table:
+ .long 0
+ .long .L040ej1
+ .long .L039ej2
+ .long .L038ej3
+ .long .L036ej4
+ .long .L035ej5
+ .long .L034ej6
+ .long .L033ej7
+.align 16
+.L051cbc_dec_jmp_table:
+ .long 0
+ .long .L050dj1
+ .long .L049dj2
+ .long .L048dj3
+ .long .L046dj4
+ .long .L045dj5
+ .long .L044dj6
+ .long .L043dj7
+.des_ede3_cbc_encrypt_end:
+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
+.ident "desasm.pl"
diff --git a/src/libfreeswan/libdes/des/ecb_enc.c b/src/libfreeswan/libdes/des/ecb_enc.c
new file mode 100644
index 000000000..0b7afcf3a
--- /dev/null
+++ b/src/libfreeswan/libdes/des/ecb_enc.c
@@ -0,0 +1,128 @@
+/* crypto/des/ecb_enc.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include "des_locl.h"
+#include "spr.h"
+
+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
+
+/* RCSID $Id: ecb_enc.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+/* This function ifdef'ed out for FreeS/WAN project. */
+#ifdef notdef
+char *des_options()
+ {
+ static int init=1;
+ static char buf[32];
+
+ if (init)
+ {
+ char *ptr,*unroll,*risc,*size;
+
+ init=0;
+#ifdef DES_PTR
+ ptr="ptr";
+#else
+ ptr="idx";
+#endif
+#if defined(DES_RISC1) || defined(DES_RISC2)
+#ifdef DES_RISC1
+ risc="risc1";
+#endif
+#ifdef DES_RISC2
+ risc="risc2";
+#endif
+#else
+ risc="cisc";
+#endif
+#ifdef DES_UNROLL
+ unroll="16";
+#else
+ unroll="4";
+#endif
+ if (sizeof(DES_LONG) != sizeof(long))
+ size="int";
+ else
+ size="long";
+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
+ }
+ return(buf);
+ }
+#endif
+
+
+void des_ecb_encrypt(input, output, ks, enc)
+des_cblock (*input);
+des_cblock (*output);
+des_key_schedule ks;
+int enc;
+ {
+ register DES_LONG l;
+ register unsigned char *in,*out;
+ DES_LONG ll[2];
+
+ in=(unsigned char *)input;
+ out=(unsigned char *)output;
+ c2l(in,l); ll[0]=l;
+ c2l(in,l); ll[1]=l;
+ des_encrypt(ll,ks,enc);
+ l=ll[0]; l2c(l,out);
+ l=ll[1]; l2c(l,out);
+ l=ll[0]=ll[1]=0;
+ }
+
diff --git a/src/libfreeswan/libdes/des/fcrypt.c b/src/libfreeswan/libdes/des/fcrypt.c
new file mode 100644
index 000000000..8b9d0495b
--- /dev/null
+++ b/src/libfreeswan/libdes/des/fcrypt.c
@@ -0,0 +1,152 @@
+/* NOCW */
+
+/* This version of crypt has been developed from my MIT compatable
+ * DES library.
+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+/* Modification by Jens Kupferschmidt (Cu)
+ * I have included directive PARA for shared memory computers.
+ * I have included a directive LONGCRYPT to using this routine to cipher
+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
+ * definition is the maximum of lenght of password and can changed. I have
+ * defined 24.
+ */
+
+#include "des_locl.h"
+
+/* Added more values to handle illegal salt values the way normal
+ * crypt() implementations do. The patch was sent by
+ * Bjorn Gronvall <bg@sics.se>
+ */
+static unsigned const char con_salt[128]={
+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
+};
+
+static unsigned const char cov_2char[64]={
+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
+};
+
+#ifndef NOPROTO
+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
+ DES_LONG Eswap0, DES_LONG Eswap1);
+
+#ifdef PERL5
+char *des_crypt(const char *buf,const char *salt);
+#else
+char *crypt(const char *buf,const char *salt);
+#endif
+#else
+void fcrypt_body();
+#ifdef PERL5
+char *des_crypt();
+#else
+char *crypt();
+#endif
+#endif
+
+#ifdef PERL5
+char *des_crypt(buf,salt)
+#else
+char *crypt(buf,salt)
+#endif
+const char *buf;
+const char *salt;
+ {
+ static char buff[14];
+
+ return(des_fcrypt(buf,salt,buff));
+ }
+
+
+char *des_fcrypt(buf,salt,ret)
+const char *buf;
+const char *salt;
+char *ret;
+ {
+ unsigned int i,j,x,y;
+ DES_LONG Eswap0,Eswap1;
+ DES_LONG out[2],ll;
+ des_cblock key;
+ des_key_schedule ks;
+ unsigned char bb[9];
+ unsigned char *b=bb;
+ unsigned char c,u;
+
+ /* eay 25/08/92
+ * If you call crypt("pwd","*") as often happens when you
+ * have * as the pwd field in /etc/passwd, the function
+ * returns *\0XXXXXXXXX
+ * The \0 makes the string look like * so the pwd "*" would
+ * crypt to "*". This was found when replacing the crypt in
+ * our shared libraries. People found that the disbled
+ * accounts effectivly had no passwd :-(. */
+ x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
+ Eswap0=con_salt[x]<<2;
+ x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
+ Eswap1=con_salt[x]<<6;
+
+/* EAY
+r=strlen(buf);
+r=(r+7)/8;
+*/
+ for (i=0; i<8; i++)
+ {
+ c= *(buf++);
+ if (!c) break;
+ key[i]=(c<<1);
+ }
+ for (; i<8; i++)
+ key[i]=0;
+
+ des_set_key((des_cblock *)(key),ks);
+ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
+
+ ll=out[0]; l2c(ll,b);
+ ll=out[1]; l2c(ll,b);
+ y=0;
+ u=0x80;
+ bb[8]=0;
+ for (i=2; i<13; i++)
+ {
+ c=0;
+ for (j=0; j<6; j++)
+ {
+ c<<=1;
+ if (bb[y] & u) c|=1;
+ u>>=1;
+ if (!u)
+ {
+ y++;
+ u=0x80;
+ }
+ }
+ ret[i]=cov_2char[c];
+ }
+ ret[13]='\0';
+ return(ret);
+ }
+
diff --git a/src/libfreeswan/libdes/des/fcrypt_b.c b/src/libfreeswan/libdes/des/fcrypt_b.c
new file mode 100644
index 000000000..5900645e7
--- /dev/null
+++ b/src/libfreeswan/libdes/des/fcrypt_b.c
@@ -0,0 +1,148 @@
+/* crypto/des/fcrypt_b.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* #include <stdio.h> */
+
+/* This version of crypt has been developed from my MIT compatable
+ * DES library.
+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
+ * Eric Young (eay@cryptsoft.com)
+ */
+
+#define DES_FCRYPT
+#include "des_locl.h"
+#undef DES_FCRYPT
+
+#undef PERM_OP
+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ (b)^=(t),\
+ (a)^=((t)<<(n)))
+
+#undef HPERM_OP
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))\
+
+void fcrypt_body(out, ks, Eswap0, Eswap1)
+DES_LONG *out;
+des_key_schedule ks;
+DES_LONG Eswap0;
+DES_LONG Eswap1;
+ {
+ register DES_LONG l,r,t,u;
+#ifdef DES_PTR
+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
+#endif
+ register DES_LONG *s;
+ register int j;
+ register DES_LONG E0,E1;
+
+ l=0;
+ r=0;
+
+ s=(DES_LONG *)ks;
+ E0=Eswap0;
+ E1=Eswap1;
+
+ for (j=0; j<25; j++)
+ {
+#ifdef DES_UNROLL
+ register int i;
+
+ for (i=0; i<32; i+=8)
+ {
+ D_ENCRYPT(l,r,i+0); /* 1 */
+ D_ENCRYPT(r,l,i+2); /* 2 */
+ D_ENCRYPT(l,r,i+4); /* 1 */
+ D_ENCRYPT(r,l,i+6); /* 2 */
+ }
+#else
+ D_ENCRYPT(l,r, 0); /* 1 */
+ D_ENCRYPT(r,l, 2); /* 2 */
+ D_ENCRYPT(l,r, 4); /* 3 */
+ D_ENCRYPT(r,l, 6); /* 4 */
+ D_ENCRYPT(l,r, 8); /* 5 */
+ D_ENCRYPT(r,l,10); /* 6 */
+ D_ENCRYPT(l,r,12); /* 7 */
+ D_ENCRYPT(r,l,14); /* 8 */
+ D_ENCRYPT(l,r,16); /* 9 */
+ D_ENCRYPT(r,l,18); /* 10 */
+ D_ENCRYPT(l,r,20); /* 11 */
+ D_ENCRYPT(r,l,22); /* 12 */
+ D_ENCRYPT(l,r,24); /* 13 */
+ D_ENCRYPT(r,l,26); /* 14 */
+ D_ENCRYPT(l,r,28); /* 15 */
+ D_ENCRYPT(r,l,30); /* 16 */
+#endif
+
+ t=l;
+ l=r;
+ r=t;
+ }
+ l=ROTATE(l,3)&0xffffffffL;
+ r=ROTATE(r,3)&0xffffffffL;
+
+ PERM_OP(l,r,t, 1,0x55555555L);
+ PERM_OP(r,l,t, 8,0x00ff00ffL);
+ PERM_OP(l,r,t, 2,0x33333333L);
+ PERM_OP(r,l,t,16,0x0000ffffL);
+ PERM_OP(l,r,t, 4,0x0f0f0f0fL);
+
+ out[0]=r;
+ out[1]=l;
+ }
+
diff --git a/src/libfreeswan/libdes/des/options.txt b/src/libfreeswan/libdes/des/options.txt
new file mode 100644
index 000000000..6e2b50f76
--- /dev/null
+++ b/src/libfreeswan/libdes/des/options.txt
@@ -0,0 +1,39 @@
+Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds
+instead of the default 4.
+RISC1 and RISC2 are 2 alternatives for the inner loop and
+PTR means to use pointers arithmatic instead of arrays.
+
+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s
+IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s
+solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s
+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s
+solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s
+linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s
+NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s
+AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s
+IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s
+IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s
+NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s
+DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s
+linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s
+HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s
+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s
+IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s
+DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s
+solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s
+HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s
+solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s
+AIX - old slow one :-) - cc - 39,000 312k/s
+
+Notes.
+[1] For the ultra sparc, SunC 4.0
+ cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts'
+ gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s.
+ I'll record the higher since it is coming from the library but it
+ is all rather weird.
+[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000.
+[3] I was unable to get access to this machine when it was not heavily loaded.
+ As such, my timing program was never able to get more that %30 of the CPU.
+ This would cause the program to give much lower speed numbers because
+ it would be 'fighting' to stay in the cache with the other CPU burning
+ processes.
diff --git a/src/libfreeswan/libdes/des/podd.h b/src/libfreeswan/libdes/des/podd.h
new file mode 100644
index 000000000..c00cd6ba0
--- /dev/null
+++ b/src/libfreeswan/libdes/des/podd.h
@@ -0,0 +1,75 @@
+/* crypto/des/podd.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static const unsigned char odd_parity[256]={
+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
diff --git a/src/libfreeswan/libdes/des/set_key.c b/src/libfreeswan/libdes/des/set_key.c
new file mode 100644
index 000000000..99ac27348
--- /dev/null
+++ b/src/libfreeswan/libdes/des/set_key.c
@@ -0,0 +1,246 @@
+/* crypto/des/set_key.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* set_key.c v 1.4 eay 24/9/91
+ * 1.4 Speed up by 400% :-)
+ * 1.3 added register declarations.
+ * 1.2 unrolled make_key_sched a bit more
+ * 1.1 added norm_expand_bits
+ * 1.0 First working version
+ */
+#include "des_locl.h"
+#include "podd.h"
+#include "sk.h"
+
+#ifndef NOPROTO
+static int check_parity(des_cblock (*key));
+#else
+static int check_parity();
+#endif
+
+int des_check_key=0;
+
+void des_set_odd_parity(key)
+des_cblock (*key);
+ {
+ int i;
+
+ for (i=0; i<DES_KEY_SZ; i++)
+ (*key)[i]=odd_parity[(*key)[i]];
+ }
+
+static int check_parity(key)
+des_cblock (*key);
+ {
+ int i;
+
+ for (i=0; i<DES_KEY_SZ; i++)
+ {
+ if ((*key)[i] != odd_parity[(*key)[i]])
+ return(0);
+ }
+ return(1);
+ }
+
+/* Weak and semi week keys as take from
+ * %A D.W. Davies
+ * %A W.L. Price
+ * %T Security for Computer Networks
+ * %I John Wiley & Sons
+ * %D 1984
+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
+ * (and actual cblock values).
+ */
+#define NUM_WEAK_KEY 16
+static des_cblock weak_keys[NUM_WEAK_KEY]={
+ /* weak keys */
+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
+ /* semi-weak keys */
+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
+
+int des_is_weak_key(key)
+des_cblock (*key);
+ {
+ int i;
+
+ for (i=0; i<NUM_WEAK_KEY; i++)
+ /* Added == 0 to comparision, I obviously don't run
+ * this section very often :-(, thanks to
+ * engineering@MorningStar.Com for the fix
+ * eay 93/06/29
+ * Another problem, I was comparing only the first 4
+ * bytes, 97/03/18 */
+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
+ return(0);
+ }
+
+/* NOW DEFINED IN des_local.h
+ * See ecb_encrypt.c for a pseudo description of these macros.
+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
+ * (b)^=(t),\
+ * (a)=((a)^((t)<<(n))))
+ */
+
+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
+ (a)=(a)^(t)^(t>>(16-(n))))
+
+/* return 0 if key parity is odd (correct),
+ * return -1 if key parity error,
+ * return -2 if illegal weak key.
+ */
+int des_set_key(key, schedule)
+des_cblock (*key);
+des_key_schedule schedule;
+ {
+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
+ register DES_LONG c,d,t,s,t2;
+ register unsigned char *in;
+ register DES_LONG *k;
+ register int i;
+
+ if (des_check_key)
+ {
+ if (!check_parity(key))
+ return(-1);
+
+ if (des_is_weak_key(key))
+ return(-2);
+ }
+
+ k=(DES_LONG *)schedule;
+ in=(unsigned char *)key;
+
+ c2l(in,c);
+ c2l(in,d);
+
+ /* do PC1 in 60 simple operations */
+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
+ HPERM_OP(c,t,-2, 0xcccc0000L);
+ HPERM_OP(c,t,-1, 0xaaaa0000L);
+ HPERM_OP(c,t, 8, 0x00ff0000L);
+ HPERM_OP(c,t,-1, 0xaaaa0000L);
+ HPERM_OP(d,t,-8, 0xff000000L);
+ HPERM_OP(d,t, 8, 0x00ff0000L);
+ HPERM_OP(d,t, 2, 0x33330000L);
+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
+ d=(d>>8)|((c&0xf0000000L)>>4);
+ c&=0x0fffffffL; */
+
+ /* I now do it in 47 simple operations :-)
+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
+ * for the inspiration. :-) */
+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
+ HPERM_OP(c,t,-2,0xcccc0000L);
+ HPERM_OP(d,t,-2,0xcccc0000L);
+ PERM_OP (d,c,t,1,0x55555555L);
+ PERM_OP (c,d,t,8,0x00ff00ffL);
+ PERM_OP (d,c,t,1,0x55555555L);
+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
+ c&=0x0fffffffL;
+
+ for (i=0; i<ITERATIONS; i++)
+ {
+ if (shifts2[i])
+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
+ else
+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
+ c&=0x0fffffffL;
+ d&=0x0fffffffL;
+ /* could be a few less shifts but I am to lazy at this
+ * point in time to investigate */
+ s= des_skb[0][ (c )&0x3f ]|
+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
+ ((c>>22L)&0x38)];
+ t= des_skb[4][ (d )&0x3f ]|
+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
+ des_skb[6][ (d>>15L)&0x3f ]|
+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
+
+ /* table contained 0213 4657 */
+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
+ *(k++)=ROTATE(t2,30)&0xffffffffL;
+
+ t2=((s>>16L)|(t&0xffff0000L));
+ *(k++)=ROTATE(t2,26)&0xffffffffL;
+ }
+ return(0);
+ }
+
+int des_key_sched(key, schedule)
+des_cblock (*key);
+des_key_schedule schedule;
+ {
+ return(des_set_key(key,schedule));
+ }
diff --git a/src/libfreeswan/libdes/des/sk.h b/src/libfreeswan/libdes/des/sk.h
new file mode 100644
index 000000000..240703070
--- /dev/null
+++ b/src/libfreeswan/libdes/des/sk.h
@@ -0,0 +1,204 @@
+/* crypto/des/sk.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+static const DES_LONG des_skb[8][64]={
+{
+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000L,0x00000010L,0x20000000L,0x20000010L,
+0x00010000L,0x00010010L,0x20010000L,0x20010010L,
+0x00000800L,0x00000810L,0x20000800L,0x20000810L,
+0x00010800L,0x00010810L,0x20010800L,0x20010810L,
+0x00000020L,0x00000030L,0x20000020L,0x20000030L,
+0x00010020L,0x00010030L,0x20010020L,0x20010030L,
+0x00000820L,0x00000830L,0x20000820L,0x20000830L,
+0x00010820L,0x00010830L,0x20010820L,0x20010830L,
+0x00080000L,0x00080010L,0x20080000L,0x20080010L,
+0x00090000L,0x00090010L,0x20090000L,0x20090010L,
+0x00080800L,0x00080810L,0x20080800L,0x20080810L,
+0x00090800L,0x00090810L,0x20090800L,0x20090810L,
+0x00080020L,0x00080030L,0x20080020L,0x20080030L,
+0x00090020L,0x00090030L,0x20090020L,0x20090030L,
+0x00080820L,0x00080830L,0x20080820L,0x20080830L,
+0x00090820L,0x00090830L,0x20090820L,0x20090830L,
+},{
+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
+0x00000000L,0x02000000L,0x00002000L,0x02002000L,
+0x00200000L,0x02200000L,0x00202000L,0x02202000L,
+0x00000004L,0x02000004L,0x00002004L,0x02002004L,
+0x00200004L,0x02200004L,0x00202004L,0x02202004L,
+0x00000400L,0x02000400L,0x00002400L,0x02002400L,
+0x00200400L,0x02200400L,0x00202400L,0x02202400L,
+0x00000404L,0x02000404L,0x00002404L,0x02002404L,
+0x00200404L,0x02200404L,0x00202404L,0x02202404L,
+0x10000000L,0x12000000L,0x10002000L,0x12002000L,
+0x10200000L,0x12200000L,0x10202000L,0x12202000L,
+0x10000004L,0x12000004L,0x10002004L,0x12002004L,
+0x10200004L,0x12200004L,0x10202004L,0x12202004L,
+0x10000400L,0x12000400L,0x10002400L,0x12002400L,
+0x10200400L,0x12200400L,0x10202400L,0x12202400L,
+0x10000404L,0x12000404L,0x10002404L,0x12002404L,
+0x10200404L,0x12200404L,0x10202404L,0x12202404L,
+},{
+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
+0x00000000L,0x00000001L,0x00040000L,0x00040001L,
+0x01000000L,0x01000001L,0x01040000L,0x01040001L,
+0x00000002L,0x00000003L,0x00040002L,0x00040003L,
+0x01000002L,0x01000003L,0x01040002L,0x01040003L,
+0x00000200L,0x00000201L,0x00040200L,0x00040201L,
+0x01000200L,0x01000201L,0x01040200L,0x01040201L,
+0x00000202L,0x00000203L,0x00040202L,0x00040203L,
+0x01000202L,0x01000203L,0x01040202L,0x01040203L,
+0x08000000L,0x08000001L,0x08040000L,0x08040001L,
+0x09000000L,0x09000001L,0x09040000L,0x09040001L,
+0x08000002L,0x08000003L,0x08040002L,0x08040003L,
+0x09000002L,0x09000003L,0x09040002L,0x09040003L,
+0x08000200L,0x08000201L,0x08040200L,0x08040201L,
+0x09000200L,0x09000201L,0x09040200L,0x09040201L,
+0x08000202L,0x08000203L,0x08040202L,0x08040203L,
+0x09000202L,0x09000203L,0x09040202L,0x09040203L,
+},{
+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
+0x00000000L,0x00100000L,0x00000100L,0x00100100L,
+0x00000008L,0x00100008L,0x00000108L,0x00100108L,
+0x00001000L,0x00101000L,0x00001100L,0x00101100L,
+0x00001008L,0x00101008L,0x00001108L,0x00101108L,
+0x04000000L,0x04100000L,0x04000100L,0x04100100L,
+0x04000008L,0x04100008L,0x04000108L,0x04100108L,
+0x04001000L,0x04101000L,0x04001100L,0x04101100L,
+0x04001008L,0x04101008L,0x04001108L,0x04101108L,
+0x00020000L,0x00120000L,0x00020100L,0x00120100L,
+0x00020008L,0x00120008L,0x00020108L,0x00120108L,
+0x00021000L,0x00121000L,0x00021100L,0x00121100L,
+0x00021008L,0x00121008L,0x00021108L,0x00121108L,
+0x04020000L,0x04120000L,0x04020100L,0x04120100L,
+0x04020008L,0x04120008L,0x04020108L,0x04120108L,
+0x04021000L,0x04121000L,0x04021100L,0x04121100L,
+0x04021008L,0x04121008L,0x04021108L,0x04121108L,
+},{
+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
+0x00000000L,0x10000000L,0x00010000L,0x10010000L,
+0x00000004L,0x10000004L,0x00010004L,0x10010004L,
+0x20000000L,0x30000000L,0x20010000L,0x30010000L,
+0x20000004L,0x30000004L,0x20010004L,0x30010004L,
+0x00100000L,0x10100000L,0x00110000L,0x10110000L,
+0x00100004L,0x10100004L,0x00110004L,0x10110004L,
+0x20100000L,0x30100000L,0x20110000L,0x30110000L,
+0x20100004L,0x30100004L,0x20110004L,0x30110004L,
+0x00001000L,0x10001000L,0x00011000L,0x10011000L,
+0x00001004L,0x10001004L,0x00011004L,0x10011004L,
+0x20001000L,0x30001000L,0x20011000L,0x30011000L,
+0x20001004L,0x30001004L,0x20011004L,0x30011004L,
+0x00101000L,0x10101000L,0x00111000L,0x10111000L,
+0x00101004L,0x10101004L,0x00111004L,0x10111004L,
+0x20101000L,0x30101000L,0x20111000L,0x30111000L,
+0x20101004L,0x30101004L,0x20111004L,0x30111004L,
+},{
+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
+0x00000000L,0x08000000L,0x00000008L,0x08000008L,
+0x00000400L,0x08000400L,0x00000408L,0x08000408L,
+0x00020000L,0x08020000L,0x00020008L,0x08020008L,
+0x00020400L,0x08020400L,0x00020408L,0x08020408L,
+0x00000001L,0x08000001L,0x00000009L,0x08000009L,
+0x00000401L,0x08000401L,0x00000409L,0x08000409L,
+0x00020001L,0x08020001L,0x00020009L,0x08020009L,
+0x00020401L,0x08020401L,0x00020409L,0x08020409L,
+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
+},{
+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
+0x00000000L,0x00000100L,0x00080000L,0x00080100L,
+0x01000000L,0x01000100L,0x01080000L,0x01080100L,
+0x00000010L,0x00000110L,0x00080010L,0x00080110L,
+0x01000010L,0x01000110L,0x01080010L,0x01080110L,
+0x00200000L,0x00200100L,0x00280000L,0x00280100L,
+0x01200000L,0x01200100L,0x01280000L,0x01280100L,
+0x00200010L,0x00200110L,0x00280010L,0x00280110L,
+0x01200010L,0x01200110L,0x01280010L,0x01280110L,
+0x00000200L,0x00000300L,0x00080200L,0x00080300L,
+0x01000200L,0x01000300L,0x01080200L,0x01080300L,
+0x00000210L,0x00000310L,0x00080210L,0x00080310L,
+0x01000210L,0x01000310L,0x01080210L,0x01080310L,
+0x00200200L,0x00200300L,0x00280200L,0x00280300L,
+0x01200200L,0x01200300L,0x01280200L,0x01280300L,
+0x00200210L,0x00200310L,0x00280210L,0x00280310L,
+0x01200210L,0x01200310L,0x01280210L,0x01280310L,
+},{
+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
+0x00000000L,0x04000000L,0x00040000L,0x04040000L,
+0x00000002L,0x04000002L,0x00040002L,0x04040002L,
+0x00002000L,0x04002000L,0x00042000L,0x04042000L,
+0x00002002L,0x04002002L,0x00042002L,0x04042002L,
+0x00000020L,0x04000020L,0x00040020L,0x04040020L,
+0x00000022L,0x04000022L,0x00040022L,0x04040022L,
+0x00002020L,0x04002020L,0x00042020L,0x04042020L,
+0x00002022L,0x04002022L,0x00042022L,0x04042022L,
+0x00000800L,0x04000800L,0x00040800L,0x04040800L,
+0x00000802L,0x04000802L,0x00040802L,0x04040802L,
+0x00002800L,0x04002800L,0x00042800L,0x04042800L,
+0x00002802L,0x04002802L,0x00042802L,0x04042802L,
+0x00000820L,0x04000820L,0x00040820L,0x04040820L,
+0x00000822L,0x04000822L,0x00040822L,0x04040822L,
+0x00002820L,0x04002820L,0x00042820L,0x04042820L,
+0x00002822L,0x04002822L,0x00042822L,0x04042822L,
+}};
diff --git a/src/libfreeswan/libdes/des/speed.c b/src/libfreeswan/libdes/des/speed.c
new file mode 100644
index 000000000..e3d753b2e
--- /dev/null
+++ b/src/libfreeswan/libdes/des/speed.c
@@ -0,0 +1,329 @@
+/* crypto/des/speed.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */
+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */
+
+#ifndef MSDOS
+#define TIMES
+#endif
+
+#include <stdio.h>
+#ifndef MSDOS
+#include <unistd.h>
+#else
+#include <io.h>
+extern int exit();
+#endif
+#include <signal.h>
+#ifndef VMS
+#ifndef _IRIX
+#include <time.h>
+#endif
+#ifdef TIMES
+#include <sys/types.h>
+#include <sys/times.h>
+#endif
+#else /* VMS */
+#include <types.h>
+struct tms {
+ time_t tms_utime;
+ time_t tms_stime;
+ time_t tms_uchild; /* I dunno... */
+ time_t tms_uchildsys; /* so these names are a guess :-) */
+ }
+#endif
+#ifndef TIMES
+#include <sys/timeb.h>
+#endif
+
+#ifdef sun
+#include <limits.h>
+#include <sys/param.h>
+#endif
+
+#include "des_locl.h"
+
+/* The following if from times(3) man page. It may need to be changed */
+#ifndef HZ
+# ifndef CLK_TCK
+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
+# ifndef VMS
+# define HZ 100.0
+# else /* VMS */
+# define HZ 100.0
+# endif
+# else /* _BSD_CLK_TCK_ */
+# define HZ ((double)_BSD_CLK_TCK_)
+# endif
+# else /* CLK_TCK */
+# define HZ ((double)CLK_TCK)
+# endif
+#endif
+
+#define BUFSIZE ((long)1024)
+long run=0;
+
+#ifndef NOPROTO
+double Time_F(int s);
+#else
+double Time_F();
+#endif
+
+#ifdef SIGALRM
+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
+#define SIGRETTYPE void
+#else
+#define SIGRETTYPE int
+#endif
+
+#ifndef NOPROTO
+SIGRETTYPE sig_done(int sig);
+#else
+SIGRETTYPE sig_done();
+#endif
+
+SIGRETTYPE sig_done(sig)
+int sig;
+ {
+ signal(SIGALRM,sig_done);
+ run=0;
+#ifdef LINT
+ sig=sig;
+#endif
+ }
+#endif
+
+#define START 0
+#define STOP 1
+
+double Time_F(s)
+int s;
+ {
+ double ret;
+#ifdef TIMES
+ static struct tms tstart,tend;
+
+ if (s == START)
+ {
+ times(&tstart);
+ return(0);
+ }
+ else
+ {
+ times(&tend);
+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
+ return((ret == 0.0)?1e-6:ret);
+ }
+#else /* !times() */
+ static struct timeb tstart,tend;
+ long i;
+
+ if (s == START)
+ {
+ ftime(&tstart);
+ return(0);
+ }
+ else
+ {
+ ftime(&tend);
+ i=(long)tend.millitm-(long)tstart.millitm;
+ ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
+ return((ret == 0.0)?1e-6:ret);
+ }
+#endif
+ }
+
+int main(argc,argv)
+int argc;
+char **argv;
+ {
+ long count;
+ static unsigned char buf[BUFSIZE];
+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
+ des_key_schedule sch,sch2,sch3;
+ double a,b,c,d,e;
+#ifndef SIGALRM
+ long ca,cb,cc,cd,ce;
+#endif
+
+#ifndef TIMES
+ printf("To get the most acurate results, try to run this\n");
+ printf("program when this computer is idle.\n");
+#endif
+
+ des_set_key((C_Block *)key2,sch2);
+ des_set_key((C_Block *)key3,sch3);
+
+#ifndef SIGALRM
+ printf("First we calculate the approximate speed ...\n");
+ des_set_key((C_Block *)key,sch);
+ count=10;
+ do {
+ long i;
+ DES_LONG data[2];
+
+ count*=2;
+ Time_F(START);
+ for (i=count; i; i--)
+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
+ d=Time_F(STOP);
+ } while (d < 3.0);
+ ca=count;
+ cb=count*3;
+ cc=count*3*8/BUFSIZE+1;
+ cd=count*8/BUFSIZE+1;
+ ce=count/20+1;
+ printf("Doing set_key %ld times\n",ca);
+#define COND(d) (count != (d))
+#define COUNT(d) (d)
+#else
+#define COND(c) (run)
+#define COUNT(d) (count)
+ signal(SIGALRM,sig_done);
+ printf("Doing set_key for 10 seconds\n");
+ alarm(10);
+#endif
+
+ Time_F(START);
+ for (count=0,run=1; COND(ca); count++)
+ des_set_key((C_Block *)key,sch);
+ d=Time_F(STOP);
+ printf("%ld set_key's in %.2f seconds\n",count,d);
+ a=((double)COUNT(ca))/d;
+
+#ifdef SIGALRM
+ printf("Doing des_encrypt's for 10 seconds\n");
+ alarm(10);
+#else
+ printf("Doing des_encrypt %ld times\n",cb);
+#endif
+ Time_F(START);
+ for (count=0,run=1; COND(cb); count++)
+ {
+ DES_LONG data[2];
+
+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
+ }
+ d=Time_F(STOP);
+ printf("%ld des_encrypt's in %.2f second\n",count,d);
+ b=((double)COUNT(cb)*8)/d;
+
+#ifdef SIGALRM
+ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+ BUFSIZE);
+ alarm(10);
+#else
+ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc,
+ BUFSIZE);
+#endif
+ Time_F(START);
+ for (count=0,run=1; COND(cc); count++)
+ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]),
+ (C_Block *)&(key[0]),DES_ENCRYPT);
+ d=Time_F(STOP);
+ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+ count,BUFSIZE,d);
+ c=((double)COUNT(cc)*BUFSIZE)/d;
+
+#ifdef SIGALRM
+ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
+ BUFSIZE);
+ alarm(10);
+#else
+ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
+ BUFSIZE);
+#endif
+ Time_F(START);
+ for (count=0,run=1; COND(cd); count++)
+ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,
+ &(sch[0]),
+ &(sch2[0]),
+ &(sch3[0]),
+ (C_Block *)&(key[0]),
+ DES_ENCRYPT);
+ d=Time_F(STOP);
+ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
+ count,BUFSIZE,d);
+ d=((double)COUNT(cd)*BUFSIZE)/d;
+
+#ifdef SIGALRM
+ printf("Doing crypt for 10 seconds\n");
+ alarm(10);
+#else
+ printf("Doing crypt %ld times\n",ce);
+#endif
+ Time_F(START);
+ for (count=0,run=1; COND(ce); count++)
+ crypt("testing1","ef");
+ e=Time_F(STOP);
+ printf("%ld crypts in %.2f second\n",count,e);
+ e=((double)COUNT(ce))/e;
+
+ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
+ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
+ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
+ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
+ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
+ exit(0);
+#if defined(LINT) || defined(MSDOS)
+ return(0);
+#endif
+ }
diff --git a/src/libfreeswan/libdes/des/spr.h b/src/libfreeswan/libdes/des/spr.h
new file mode 100644
index 000000000..a84d6a723
--- /dev/null
+++ b/src/libfreeswan/libdes/des/spr.h
@@ -0,0 +1,204 @@
+/* crypto/des/spr.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+const DES_LONG des_SPtrans[8][64]={
+{
+/* nibble 0 */
+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
+},{
+/* nibble 1 */
+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
+},{
+/* nibble 2 */
+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
+},{
+/* nibble 3 */
+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
+},{
+/* nibble 4 */
+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
+},{
+/* nibble 5 */
+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
+},{
+/* nibble 6 */
+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
+},{
+/* nibble 7 */
+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
+}};
diff --git a/src/libfreeswan/libfreeswan/.cvsignore b/src/libfreeswan/libfreeswan/.cvsignore
new file mode 100644
index 000000000..49cc19caa
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/.cvsignore
@@ -0,0 +1,9 @@
+try
+try1a
+try2
+try3
+try4
+try4a
+try6
+try7
+version.c
diff --git a/src/libfreeswan/libfreeswan/Makefile b/src/libfreeswan/libfreeswan/Makefile
new file mode 100644
index 000000000..50a98b40d
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/Makefile
@@ -0,0 +1,174 @@
+# FreeS/WAN library
+# Copyright (C) 1998-2001 Henry Spencer.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: Makefile,v 1.2 2004/03/22 21:53:17 as Exp $
+
+
+FREESWANSRCDIR=../..
+
+include ${FREESWANSRCDIR}/Makefile.inc
+include ${FREESWANSRCDIR}/Makefile.ver
+
+
+MANDIR=$(MANTREE)/man3
+
+SRCS=addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c \
+ atoasr.c atosa.c atosubnet.c atoul.c copyright.c datatot.c \
+ goodmask.c initaddr.c initsaid.c initsubnet.c keyblobtoid.c \
+ optionsfrom.c pfkey_v2_build.c pfkey_v2_ext_bits.c pfkey_v2_parse.c \
+ pfkey_v2_debug.c prng.c \
+ portof.c rangetoa.c rangetosubnet.c sameaddr.c \
+ satoa.c satot.c subnetof.c subnettoa.c subnettot.c \
+ subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c \
+ ttosa.c ttosubnet.c ttoul.c ultoa.c ultot.c
+
+OBJS=${SRCS:.c=.o} version.o
+
+KLIPSD=${FREESWANSRCDIR}/linux/include
+SRCDIR=${FREESWANSRCDIR}/linux/lib/libfreeswan
+
+VPATH = ${SRCDIR}
+
+HDRS=${KLIPSD}/freeswan.h ${SRCDIR}/internal.h
+
+LIB=libfreeswan.a
+# Original flags
+CFLAGS=-I. -I${SRCDIR} -I${KLIPSD} -I${FREESWANSRCDIR} $(USERCOMPILE)
+CFLAGS+= -Wall
+#CFLAGS+= -Wconversion
+#CFLAGS+= -Wmissing-prototypes
+CFLAGS+= -Wpointer-arith
+CFLAGS+= -Wcast-qual
+#CFLAGS+= -Wmissing-declarations
+CFLAGS+= -Wstrict-prototypes
+#CFLAGS+= -pedantic
+#CFLAGS+= -W
+#CFLAGS+= -Wwrite-strings
+CFLAGS+= -Wbad-function-cast
+CFLAGS+= -DNAT_TRAVERSAL
+
+
+ARFLAGS=crvs
+EXTHDRS=des.h
+EXTLIBS=libdes.a
+MANS=anyaddr.3 atoaddr.3 atoasr.3 atosa.3 atoul.3 goodmask.3 \
+ initaddr.3 initsubnet.3 optionsfrom.3 portof.3 rangetosubnet.3 \
+ sameaddr.3 subnetof.3 ttoaddr.3 ttodata.3 ttosa.3 ttoul.3 version.3
+
+.PHONY: all install clean l t lt tar check depend checkprograms
+
+all: $(LIB)
+programs: $(LIB)
+
+install:
+ @mkdir -p $(MANDIR)
+ @for f in $(MANS) ; \
+ do \
+ $(INSTALL) $(INSTMANFLAGS) $(SRCDIR)/$$f $(MANDIR)/ipsec_$$f || exit 1 ; \
+ done
+ @$(FREESWANSRCDIR)/utils/manlink $(foreach man, $(MANS), ${SRCDIR}/$(man)) | \
+ while read from to; \
+ do \
+ ln -s -f ipsec_$$from $(MANDIR)/$$to; \
+ done
+
+
+install_file_list:
+ @for f in $(MANS) ; \
+ do \
+ echo $(MANDIR)/ipsec_$$f;\
+ done;
+ @$(FREESWANSRCDIR)/utils/manlink $(foreach man, $(MANS), ${SRCDIR}/$(man)) | \
+ while read from to; \
+ do \
+ echo $(MANDIR)/$$to; \
+ done
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $(LIB) $(OBJS)
+
+$(OBJS): $(HDRS)
+
+# build version.c using version number from Makefile.ver
+version.c: ${SRCDIR}/version.in.c ${FREESWANSRCDIR}/Makefile.ver
+ sed '/"/s/xxx/$(IPSECVERSION)/' ${SRCDIR}/version.in.c >$@
+
+#libdes.a: ../libdes/libdes.a
+# ln -f -s ../libdes/libdes.a
+#
+# yes, that's CFLAG=, not CFLAGS=
+#../libdes/libdes.a:
+# cd ../libdes ; \
+# if test " `arch | sed 's/^i[3456]/x/'`" = " x86" ; \
+# then $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' TESTING='' x86-elf ; \
+# else $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' libdes.a ; \
+# fi
+
+clean:
+ rm -f $(LIB) *.o try* core *.core $(EXTHDRS) $(EXTLIBS) version.c
+
+
+# developer-only stuff
+l:
+ $(MAKE) $(LIB) ARFLAGS=crv CFLAGS=-O
+ $(RANLIB) $(LIB)
+
+t: $(LIB)
+ ln -f -s ${SRCDIR}/atosubnet.c try.c
+ ${CC} ${CFLAGS} -DATOSUBNET_MAIN try.c $(LIB) -o try
+ ./try -r
+ ln -f -s ${SRCDIR}/ttosubnet.c try1a.c
+ ${CC} ${CFLAGS} -DTTOSUBNET_MAIN try1a.c $(LIB) -o try1a
+ ./try1a -r
+ ln -f -s ${SRCDIR}/ttodata.c try2.c
+ ${CC} ${CFLAGS} -DTTODATA_MAIN try2.c $(LIB) -o try2
+ ./try2 -r
+ ln -f -s ${SRCDIR}/atoasr.c try3.c
+ ${CC} ${CFLAGS} -DATOASR_MAIN try3.c $(LIB) -o try3
+ ./try3 -r
+ ln -f -s ${SRCDIR}/atosa.c try4.c
+ ${CC} ${CFLAGS} -DATOSA_MAIN try4.c $(LIB) -o try4
+ ./try4 -r
+ ln -f -s ${SRCDIR}/ttosa.c try4a.c
+ ${CC} ${CFLAGS} -DTTOSA_MAIN try4a.c $(LIB) -o try4a
+ ./try4a -r
+ ln -f -s ${SRCDIR}/rangetosubnet.c try6.c
+ ${CC} ${CFLAGS} -DRANGETOSUBNET_MAIN try6.c $(LIB) -o try6
+ ./try6 -r
+ ln -f -s ${SRCDIR}/addrtot.c try7.c
+ ${CC} ${CFLAGS} -DADDRTOT_MAIN try7.c $(LIB) -o try7
+ ./try7 -r
+
+lt: $(LIB)
+ $(MAKE) t
+ cp optionsfrom.c try5.c
+ cc -DTEST try5.c $(LIB) -o try5
+ echo --foo --bar >try5in1
+ echo --optionsfrom >>try5in1
+ echo try5in2 >>try5in1
+ echo --foo >try5in2
+ ./try5 --foo --bar --optionsfrom try5in1 --bar something
+
+tar: clean
+ tar -cvf /tmp/lib.tar Makefile [a-z]*
+
+check:
+ echo no checks in lib right now.
+
+depend:
+ makedepend -Y -- $(CFLAGS) -- $(SRCS)
+
+checkprograms:
+
+# DO NOT DELETE
+
diff --git a/src/libfreeswan/libfreeswan/Makefile.objs b/src/libfreeswan/libfreeswan/Makefile.objs
new file mode 100644
index 000000000..41a89dba9
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/Makefile.objs
@@ -0,0 +1,18 @@
+obj-y += ultoa.o
+obj-y += addrtoa.o
+obj-y += subnettoa.o
+obj-y += subnetof.o
+obj-y += goodmask.o
+obj-y += datatot.o
+obj-y += rangetoa.o
+obj-y += satoa.o
+obj-y += prng.o
+obj-y += pfkey_v2_parse.o
+obj-y += pfkey_v2_build.o
+obj-y += pfkey_v2_debug.o
+obj-y += pfkey_v2_ext_bits.o
+obj-y += version.o
+
+
+version.c: ${LIBFREESWANDIR}/version.in.c ${FREESWANSRCDIR}/Makefile.ver
+ sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
diff --git a/src/libfreeswan/libfreeswan/addrtoa.c b/src/libfreeswan/libfreeswan/addrtoa.c
new file mode 100644
index 000000000..b1cc038ed
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/addrtoa.c
@@ -0,0 +1,68 @@
+/*
+ * addresses to ASCII
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: addrtoa.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+#define NBYTES 4 /* bytes in an address */
+#define PERBYTE 4 /* three digits plus a dot or NUL */
+#define BUFLEN (NBYTES*PERBYTE)
+
+#if BUFLEN != ADDRTOA_BUF
+#error "ADDRTOA_BUF in freeswan.h inconsistent with addrtoa() code"
+#endif
+
+/*
+ - addrtoa - convert binary address to ASCII dotted decimal
+ */
+size_t /* space needed for full conversion */
+addrtoa(addr, format, dst, dstlen)
+struct in_addr addr;
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ unsigned long a = ntohl(addr.s_addr);
+ int i;
+ size_t n;
+ unsigned long byte;
+ char buf[BUFLEN];
+ char *p;
+
+ switch (format) {
+ case 0:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ p = buf;
+ for (i = NBYTES-1; i >= 0; i--) {
+ byte = (a >> (i*8)) & 0xff;
+ p += ultoa(byte, 10, p, PERBYTE);
+ if (i != 0)
+ *(p-1) = '.';
+ }
+ n = p - buf;
+
+ if (dstlen > 0) {
+ if (n > dstlen)
+ buf[dstlen - 1] = '\0';
+ strcpy(dst, buf);
+ }
+ return n;
+}
diff --git a/src/libfreeswan/libfreeswan/addrtot.c b/src/libfreeswan/libfreeswan/addrtot.c
new file mode 100644
index 000000000..f229789f0
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/addrtot.c
@@ -0,0 +1,302 @@
+/*
+ * addresses to text
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: addrtot.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+#define IP4BYTES 4 /* bytes in an IPv4 address */
+#define PERBYTE 4 /* three digits plus a dot or NUL */
+#define IP6BYTES 16 /* bytes in an IPv6 address */
+
+/* forwards */
+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
+
+/*
+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
+ */
+size_t /* space needed for full conversion */
+addrtot(src, format, dst, dstlen)
+const ip_address *src;
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ const unsigned char *b;
+ size_t n;
+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
+ char *p;
+ int t = addrtypeof(src);
+# define TF(t, f) (((t)<<8) | (f))
+
+ n = addrbytesptr(src, &b);
+ if (n == 0)
+ return 0;
+
+ switch (TF(t, format)) {
+ case TF(AF_INET, 0):
+ n = normal4(b, n, buf, &p);
+ break;
+ case TF(AF_INET6, 0):
+ n = normal6(b, n, buf, &p, 1);
+ break;
+ case TF(AF_INET, 'Q'):
+ n = normal4(b, n, buf, &p);
+ break;
+ case TF(AF_INET6, 'Q'):
+ n = normal6(b, n, buf, &p, 0);
+ break;
+ case TF(AF_INET, 'r'):
+ n = reverse4(b, n, buf, &p);
+ break;
+ case TF(AF_INET6, 'r'):
+ n = reverse6(b, n, buf, &p);
+ break;
+ default: /* including (AF_INET, 'R') */
+ return 0;
+ break;
+ }
+
+ if (dstlen > 0) {
+ if (dstlen < n)
+ p[dstlen - 1] = '\0';
+ strcpy(dst, p);
+ }
+ return n;
+}
+
+/*
+ - normal4 - normal IPv4 address-text conversion
+ */
+static size_t /* size of text, including NUL */
+normal4(srcp, srclen, buf, dstp)
+const unsigned char *srcp;
+size_t srclen;
+char *buf; /* guaranteed large enough */
+char **dstp; /* where to put result pointer */
+{
+ int i;
+ char *p;
+
+ if (srclen != IP4BYTES) /* "can't happen" */
+ return 0;
+ p = buf;
+ for (i = 0; i < IP4BYTES; i++) {
+ p += ultot(srcp[i], 10, p, PERBYTE);
+ if (i != IP4BYTES - 1)
+ *(p-1) = '.'; /* overwrites the NUL */
+ }
+ *dstp = buf;
+ return p - buf;
+}
+
+/*
+ - normal6 - normal IPv6 address-text conversion
+ */
+static size_t /* size of text, including NUL */
+normal6(srcp, srclen, buf, dstp, squish)
+const unsigned char *srcp;
+size_t srclen;
+char *buf; /* guaranteed large enough, plus 2 */
+char **dstp; /* where to put result pointer */
+int squish; /* whether to squish out 0:0 */
+{
+ int i;
+ unsigned long piece;
+ char *p;
+ char *q;
+
+ if (srclen != IP6BYTES) /* "can't happen" */
+ return 0;
+ p = buf;
+ *p++ = ':';
+ for (i = 0; i < IP6BYTES/2; i++) {
+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
+ *(p-1) = ':'; /* overwrites the NUL */
+ }
+ *p = '\0';
+ q = strstr(buf, ":0:0:");
+ if (squish && q != NULL) { /* zero squishing is possible */
+ p = q + 1;
+ while (*p == '0' && *(p+1) == ':')
+ p += 2;
+ q++;
+ *q++ = ':'; /* overwrite first 0 */
+ while (*p != '\0')
+ *q++ = *p++;
+ *q = '\0';
+ if (!(*(q-1) == ':' && *(q-2) == ':'))
+ *--q = '\0'; /* strip final : unless :: */
+ p = buf;
+ if (!(*p == ':' && *(p+1) == ':'))
+ p++; /* skip initial : unless :: */
+ } else {
+ q = p;
+ *--q = '\0'; /* strip final : */
+ p = buf + 1; /* skip initial : */
+ }
+ *dstp = p;
+ return q - p + 1;
+}
+
+/*
+ - reverse4 - IPv4 reverse-lookup conversion
+ */
+static size_t /* size of text, including NUL */
+reverse4(srcp, srclen, buf, dstp)
+const unsigned char *srcp;
+size_t srclen;
+char *buf; /* guaranteed large enough */
+char **dstp; /* where to put result pointer */
+{
+ int i;
+ char *p;
+
+ if (srclen != IP4BYTES) /* "can't happen" */
+ return 0;
+ p = buf;
+ for (i = IP4BYTES-1; i >= 0; i--) {
+ p += ultot(srcp[i], 10, p, PERBYTE);
+ *(p-1) = '.'; /* overwrites the NUL */
+ }
+ strcpy(p, "IN-ADDR.ARPA.");
+ *dstp = buf;
+ return strlen(buf) + 1;
+}
+
+/*
+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
+ * A trifle inefficient, really shouldn't use ultot...
+ */
+static size_t /* size of text, including NUL */
+reverse6(srcp, srclen, buf, dstp)
+const unsigned char *srcp;
+size_t srclen;
+char *buf; /* guaranteed large enough */
+char **dstp; /* where to put result pointer */
+{
+ int i;
+ unsigned long piece;
+ char *p;
+
+ if (srclen != IP6BYTES) /* "can't happen" */
+ return 0;
+ p = buf;
+ for (i = IP6BYTES-1; i >= 0; i--) {
+ piece = srcp[i];
+ p += ultot(piece&0xf, 16, p, 2);
+ *(p-1) = '.';
+ p += ultot(piece>>4, 16, p, 2);
+ *(p-1) = '.';
+ }
+ strcpy(p, "IP6.ARPA.");
+ *dstp = buf;
+ return strlen(buf) + 1;
+}
+
+/*
+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
+ * this version removed as it was obsoleted in the end.
+ */
+
+#ifdef ADDRTOT_MAIN
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+void regress(void);
+
+int
+main(int argc, char *argv[])
+{
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
+ argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+ exit(0);
+}
+
+struct rtab {
+ char *input;
+ char format;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {"1.2.3.0", 0, "1.2.3.0"},
+ {"1:2::3:4", 0, "1:2::3:4"},
+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
+ {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
+ {NULL, 0, NULL}
+};
+
+void
+regress()
+{
+ struct rtab *r;
+ int status = 0;
+ ip_address a;
+ char in[100];
+ char buf[100];
+ const char *oops;
+ size_t n;
+
+ for (r = rtab; r->input != NULL; r++) {
+ strcpy(in, r->input);
+
+ /* convert it *to* internal format */
+ oops = ttoaddr(in, strlen(in), 0, &a);
+
+ /* now convert it back */
+
+ n = addrtot(&a, r->format, buf, sizeof(buf));
+
+ if (n == 0 && r->output == NULL)
+ {} /* okay, error expected */
+
+ else if (n == 0) {
+ printf("`%s' atoasr failed\n", r->input);
+ status = 1;
+
+ } else if (r->output == NULL) {
+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
+ r->input, r->format);
+ status = 1;
+ } else {
+ if (strcasecmp(r->output, buf) != 0) {
+ printf("`%s' '%c' gave `%s', expected `%s'\n",
+ r->input, r->format, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* ADDRTOT_MAIN */
diff --git a/src/libfreeswan/libfreeswan/addrtypeof.c b/src/libfreeswan/libfreeswan/addrtypeof.c
new file mode 100644
index 000000000..e63509911
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/addrtypeof.c
@@ -0,0 +1,94 @@
+/*
+ * extract parts of an ip_address
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: addrtypeof.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - addrtypeof - get the type of an ip_address
+ */
+int
+addrtypeof(src)
+const ip_address *src;
+{
+ return src->u.v4.sin_family;
+}
+
+/*
+ - addrbytesptr - get pointer to the address bytes of an ip_address
+ */
+size_t /* 0 for error */
+addrbytesptr(src, dstp)
+const ip_address *src;
+const unsigned char **dstp; /* NULL means just a size query */
+{
+ const unsigned char *p;
+ size_t n;
+
+ switch (src->u.v4.sin_family) {
+ case AF_INET:
+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
+ n = 4;
+ break;
+ case AF_INET6:
+ p = (const unsigned char *)&src->u.v6.sin6_addr;
+ n = 16;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ if (dstp != NULL)
+ *dstp = p;
+ return n;
+}
+
+/*
+ - addrlenof - get length of the address bytes of an ip_address
+ */
+size_t /* 0 for error */
+addrlenof(src)
+const ip_address *src;
+{
+ return addrbytesptr(src, NULL);
+}
+
+/*
+ - addrbytesof - get the address bytes of an ip_address
+ */
+size_t /* 0 for error */
+addrbytesof(src, dst, dstlen)
+const ip_address *src;
+unsigned char *dst;
+size_t dstlen;
+{
+ const unsigned char *p;
+ size_t n;
+ size_t ncopy;
+
+ n = addrbytesptr(src, &p);
+ if (n == 0)
+ return 0;
+
+ if (dstlen > 0) {
+ ncopy = n;
+ if (ncopy > dstlen)
+ ncopy = dstlen;
+ memcpy(dst, p, ncopy);
+ }
+ return n;
+}
diff --git a/src/libfreeswan/libfreeswan/anyaddr.3 b/src/libfreeswan/libfreeswan/anyaddr.3
new file mode 100644
index 000000000..4594a9ff9
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/anyaddr.3
@@ -0,0 +1,87 @@
+.TH IPSEC_ANYADDR 3 "8 Sept 2000"
+.\" RCSID $Id: anyaddr.3,v 1.1 2004/03/15 20:35:25 as Exp $
+.SH NAME
+ipsec anyaddr \- get "any" address
+.br
+ipsec isanyaddr \- test address for equality to "any" address
+.br
+ipsec unspecaddr \- get "unspecified" address
+.br
+ipsec isunspecaddr \- test address for equality to "unspecified" address
+.br
+ipsec loopbackaddr \- get loopback address
+.br
+ipsec isloopbackaddr \- test address for equality to loopback address
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *anyaddr(int af, ip_address *dst);"
+.br
+.B "int isanyaddr(const ip_address *src);"
+.br
+.B "const char *unspecaddr(int af, ip_address *dst);"
+.br
+.B "int isunspecaddr(const ip_address *src);"
+.br
+.B "const char *loopbackaddr(int af, ip_address *dst);"
+.br
+.B "int isloopbackaddr(const ip_address *src);"
+.SH DESCRIPTION
+These functions fill in, and test for, special values of the
+.I ip_address
+type.
+.PP
+.I Anyaddr
+fills in the destination
+.I *dst
+with the ``any'' address of address family
+.IR af
+(normally
+.B AF_INET
+or
+.BR AF_INET6 ).
+The IPv4 ``any'' address is the one embodied in the old
+.B INADDR_ANY
+macro.
+.PP
+.I Isanyaddr
+returns
+.B 1
+if the
+.I src
+address equals the ``any'' address,
+and
+.B 0
+otherwise.
+.PP
+Similarly,
+.I unspecaddr
+supplies, and
+.I isunspecaddr
+tests for,
+the ``unspecified'' address,
+which may be the same as the ``any'' address.
+.PP
+Similarly,
+.I loopbackaddr
+supplies, and
+.I islookbackaddr
+tests for,
+the loopback address.
+.PP
+.IR Anyaddr ,
+.IR unspecaddr ,
+and
+.I loopbackaddr
+return
+.B NULL
+for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.SH SEE ALSO
+inet(3), ipsec_addrtot(3), ipsec_sameaddr(3)
+.SH DIAGNOSTICS
+Fatal errors in the address-supplying functions are:
+unknown address family.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/libfreeswan/anyaddr.c b/src/libfreeswan/libfreeswan/anyaddr.c
new file mode 100644
index 000000000..08aae6334
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/anyaddr.c
@@ -0,0 +1,146 @@
+/*
+ * special addresses
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: anyaddr.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
+#ifndef IN6ADDR_ANY_INIT
+#define IN6ADDR_ANY_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}
+#endif
+#ifndef IN6ADDR_LOOPBACK_INIT
+#define IN6ADDR_LOOPBACK_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
+#endif
+
+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
+
+/*
+ - anyaddr - initialize to the any-address value
+ */
+err_t /* NULL for success, else string literal */
+anyaddr(af, dst)
+int af; /* address family */
+ip_address *dst;
+{
+ uint32_t v4any = htonl(INADDR_ANY);
+
+ switch (af) {
+ case AF_INET:
+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
+ break;
+ case AF_INET6:
+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
+ break;
+ default:
+ return "unknown address family in anyaddr/unspecaddr";
+ break;
+ }
+}
+
+/*
+ - unspecaddr - initialize to the unspecified-address value
+ */
+err_t /* NULL for success, else string literal */
+unspecaddr(af, dst)
+int af; /* address family */
+ip_address *dst;
+{
+ return anyaddr(af, dst);
+}
+
+/*
+ - loopbackaddr - initialize to the loopback-address value
+ */
+err_t /* NULL for success, else string literal */
+loopbackaddr(af, dst)
+int af; /* address family */
+ip_address *dst;
+{
+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
+
+ switch (af) {
+ case AF_INET:
+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
+ break;
+ case AF_INET6:
+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
+ break;
+ default:
+ return "unknown address family in loopbackaddr";
+ break;
+ }
+}
+
+/*
+ - isanyaddr - test for the any-address value
+ */
+int
+isanyaddr(src)
+const ip_address *src;
+{
+ uint32_t v4any = htonl(INADDR_ANY);
+ int cmp;
+
+ switch (src->u.v4.sin_family) {
+ case AF_INET:
+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
+ break;
+ case AF_INET6:
+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return (cmp == 0) ? 1 : 0;
+}
+
+/*
+ - isunspecaddr - test for the unspecified-address value
+ */
+int
+isunspecaddr(src)
+const ip_address *src;
+{
+ return isanyaddr(src);
+}
+
+/*
+ - isloopbackaddr - test for the loopback-address value
+ */
+int
+isloopbackaddr(src)
+const ip_address *src;
+{
+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
+ int cmp;
+
+ switch (src->u.v4.sin_family) {
+ case AF_INET:
+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
+ break;
+ case AF_INET6:
+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ return (cmp == 0) ? 1 : 0;
+}
diff --git a/src/libfreeswan/libfreeswan/atoaddr.3 b/src/libfreeswan/libfreeswan/atoaddr.3
new file mode 100644
index 000000000..a7dc8dca3
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atoaddr.3
@@ -0,0 +1,294 @@
+.TH IPSEC_ATOADDR 3 "11 June 2001"
+.\" RCSID $Id: atoaddr.3,v 1.1 2004/03/15 20:35:25 as Exp $
+.SH NAME
+ipsec atoaddr, addrtoa \- convert Internet addresses to and from ASCII
+.br
+ipsec atosubnet, subnettoa \- convert subnet/mask ASCII form to and from addresses
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *atoaddr(const char *src, size_t srclen,"
+.ti +1c
+.B "struct in_addr *addr);"
+.br
+.B "size_t addrtoa(struct in_addr addr, int format,"
+.ti +1c
+.B "char *dst, size_t dstlen);"
+.sp
+.B "const char *atosubnet(const char *src, size_t srclen,"
+.ti +1c
+.B "struct in_addr *addr, struct in_addr *mask);"
+.br
+.B "size_t subnettoa(struct in_addr addr, struct in_addr mask,"
+.ti +1c
+.B "int format, char *dst, size_t dstlen);"
+.SH DESCRIPTION
+These functions are obsolete; see
+.IR ipsec_ttoaddr (3)
+for their replacements.
+.PP
+.I Atoaddr
+converts an ASCII name or dotted-decimal address into a binary address
+(in network byte order).
+.I Addrtoa
+does the reverse conversion, back to an ASCII dotted-decimal address.
+.I Atosubnet
+and
+.I subnettoa
+do likewise for the ``address/mask'' ASCII form used to write a
+specification of a subnet.
+.PP
+An address is specified in ASCII as a
+dotted-decimal address (e.g.
+.BR 1.2.3.4 ),
+an eight-digit network-order hexadecimal number with the usual C prefix (e.g.
+.BR 0x01020304 ,
+which is synonymous with
+.BR 1.2.3.4 ),
+an eight-digit host-order hexadecimal number with a
+.B 0h
+prefix (e.g.
+.BR 0h01020304 ,
+which is synonymous with
+.B 1.2.3.4
+on a big-endian host and
+.B 4.3.2.1
+on a little-endian host),
+a DNS name to be looked up via
+.IR gethostbyname (3),
+or an old-style network name to be looked up via
+.IR getnetbyname (3).
+.PP
+A dotted-decimal address may be incomplete, in which case
+ASCII-to-binary conversion implicitly appends
+as many instances of
+.B .0
+as necessary to bring it up to four components.
+The components of a dotted-decimal address are always taken as
+decimal, and leading zeros are ignored.
+For example,
+.B 10
+is synonymous with
+.BR 10.0.0.0 ,
+and
+.B 128.009.000.032
+is synonymous with
+.BR 128.9.0.32
+(the latter example is verbatim from RFC 1166).
+The result of
+.I addrtoa
+is always complete and does not contain leading zeros.
+.PP
+The letters in
+a hexadecimal address may be uppercase or lowercase or any mixture thereof.
+Use of hexadecimal addresses is
+.B strongly
+.BR discouraged ;
+they are included only to save hassles when dealing with
+the handful of perverted programs which already print
+network addresses in hexadecimal.
+.PP
+DNS names may be complete (optionally terminated with a ``.'')
+or incomplete, and are looked up as specified by local system configuration
+(see
+.IR resolver (5)).
+The
+.I h_addr
+value returned by
+.IR gethostbyname (3)
+is used,
+so with current DNS implementations,
+the result when the name corresponds to more than one address is
+difficult to predict.
+Name lookup resorts to
+.IR getnetbyname (3)
+only if
+.IR gethostbyname (3)
+fails.
+.PP
+A subnet specification is of the form \fInetwork\fB/\fImask\fR.
+The
+.I network
+and
+.I mask
+can be any form acceptable to
+.IR atoaddr .
+In addition, the
+.I mask
+can be a decimal integer (leading zeros ignored) giving a bit count,
+in which case
+it stands for a mask with that number of high bits on and all others off
+(e.g.,
+.B 24
+means
+.BR 255.255.255.0 ).
+In any case, the mask must be contiguous
+(a sequence of high bits on and all remaining low bits off).
+As a special case, the subnet specification
+.B %default
+is a synonym for
+.BR 0.0.0.0/0 .
+.PP
+.I Atosubnet
+ANDs the mask with the address before returning,
+so that any non-network bits in the address are turned off
+(e.g.,
+.B 10.1.2.3/24
+is synonymous with
+.BR 10.1.2.0/24 ).
+.I Subnettoa
+generates the decimal-integer-bit-count
+form of the mask,
+with no leading zeros,
+unless the mask is non-contiguous.
+.PP
+The
+.I srclen
+parameter of
+.I atoaddr
+and
+.I atosubnet
+specifies the length of the ASCII string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I dstlen
+parameter of
+.I addrtoa
+and
+.I subnettoa
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.I freeswan.h
+header file defines constants,
+.B ADDRTOA_BUF
+and
+.BR SUBNETTOA_BUF ,
+which are the sizes of buffers just large enough for worst-case results.
+.PP
+The
+.I format
+parameter of
+.I addrtoa
+and
+.I subnettoa
+specifies what format is to be used for the conversion.
+The value
+.B 0
+(not the ASCII character
+.BR '0' ,
+but a zero value)
+specifies a reasonable default,
+and is in fact the only format currently available.
+This parameter is a hedge against future needs.
+.PP
+The ASCII-to-binary functions return NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+The binary-to-ASCII functions return
+.B 0
+for a failure, and otherwise
+always return the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.SH SEE ALSO
+inet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I atoaddr
+are:
+empty input;
+attempt to allocate temporary storage for a very long name failed;
+name lookup failed;
+syntax error in dotted-decimal form;
+dotted-decimal component too large to fit in 8 bits.
+.PP
+Fatal errors in
+.I atosubnet
+are:
+no
+.B /
+in
+.IR src ;
+.I atoaddr
+error in conversion of
+.I network
+or
+.IR mask ;
+bit-count mask too big;
+mask non-contiguous.
+.PP
+Fatal errors in
+.I addrtoa
+and
+.I subnettoa
+are:
+unknown format.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The interpretation of incomplete dotted-decimal addresses
+(e.g.
+.B 10/24
+means
+.BR 10.0.0.0/24 )
+differs from that of some older conversion
+functions, e.g. those of
+.IR inet (3).
+The behavior of the older functions has never been
+particularly consistent or particularly useful.
+.PP
+Ignoring leading zeros in dotted-decimal components and bit counts
+is arguably the most useful behavior in this application,
+but it might occasionally cause confusion with the historical use of leading
+zeros to denote octal numbers.
+.PP
+It is barely possible that somebody, somewhere,
+might have a legitimate use for non-contiguous subnet masks.
+.PP
+.IR Getnetbyname (3)
+is a historical dreg.
+.PP
+The restriction of ASCII-to-binary error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The ASCII-to-binary error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = atoaddr( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/atoaddr.c b/src/libfreeswan/libfreeswan/atoaddr.c
new file mode 100644
index 000000000..0c787b10d
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atoaddr.c
@@ -0,0 +1,238 @@
+/*
+ * conversion from ASCII forms of addresses to internal ones
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: atoaddr.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ * Define NOLEADINGZEROS to interpret 032 as an error, not as 32. There
+ * is deliberately no way to interpret it as 26 (i.e., as octal).
+ */
+
+/*
+ * Legal characters in a domain name. Underscore technically is not,
+ * but is a common misunderstanding.
+ */
+static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
+
+static const char *try8hex(const char *, size_t, struct in_addr *);
+static const char *try8hosthex(const char *, size_t, struct in_addr *);
+static const char *trydotted(const char *, size_t, struct in_addr *);
+static const char *getbyte(const char **, const char *, int *);
+
+/*
+ - atoaddr - convert ASCII name or dotted-decimal address to binary address
+ */
+const char * /* NULL for success, else string literal */
+atoaddr(src, srclen, addrp)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+struct in_addr *addrp;
+{
+ struct hostent *h;
+ struct netent *ne = NULL;
+ const char *oops;
+# define HEXLEN 10 /* strlen("0x11223344") */
+# ifndef ATOADDRBUF
+# define ATOADDRBUF 100
+# endif
+ char namebuf[ATOADDRBUF];
+ char *p = namebuf;
+ char *q;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+
+ /* might it be hex? */
+ if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'x'))
+ return try8hex(src+2, srclen-2, addrp);
+ if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'h'))
+ return try8hosthex(src+2, srclen-2, addrp);
+
+ /* try it as dotted decimal */
+ oops = trydotted(src, srclen, addrp);
+ if (oops == NULL)
+ return NULL; /* it worked */
+ if (*oops != '?')
+ return oops; /* it *was* probably meant as a d.q. */
+
+ /* try it as a name -- first, NUL-terminate it */
+ if (srclen > sizeof(namebuf)-1) {
+ p = (char *) MALLOC(srclen+1);
+ if (p == NULL)
+ return "unable to allocate temporary space for name";
+ }
+ p[0] = '\0';
+ strncat(p, src, srclen);
+
+ /* next, check that it's a vaguely legal name */
+ for (q = p; *q != '\0'; q++)
+ if (!isprint(*q))
+ return "unprintable character in name";
+ if (strspn(p, namechars) != srclen)
+ return "illegal (non-DNS-name) character in name";
+
+ /* try as host name, failing that as /etc/networks network name */
+ h = gethostbyname(p);
+ if (h == NULL)
+ ne = getnetbyname(p);
+ if (p != namebuf)
+ FREE(p);
+ if (h == NULL && ne == NULL)
+ return "name lookup failed";
+
+ if (h != NULL)
+ memcpy(&addrp->s_addr, h->h_addr, sizeof(addrp->s_addr));
+ else
+ addrp->s_addr = htonl(ne->n_net);
+ return NULL;
+}
+
+/*
+ - try8hosthex - try conversion as an eight-digit host-order hex number
+ */
+const char * /* NULL for success, else string literal */
+try8hosthex(src, srclen, addrp)
+const char *src;
+size_t srclen; /* should be 8 */
+struct in_addr *addrp;
+{
+ const char *oops;
+ unsigned long addr;
+
+ if (srclen != 8)
+ return "internal error, try8hex called with bad length";
+
+ oops = atoul(src, srclen, 16, &addr);
+ if (oops != NULL)
+ return oops;
+
+ addrp->s_addr = addr;
+ return NULL;
+}
+
+/*
+ - try8hex - try conversion as an eight-digit network-order hex number
+ */
+const char * /* NULL for success, else string literal */
+try8hex(src, srclen, addrp)
+const char *src;
+size_t srclen; /* should be 8 */
+struct in_addr *addrp;
+{
+ const char *oops;
+
+ oops = try8hosthex(src, srclen, addrp);
+ if (oops != NULL)
+ return oops;
+
+ addrp->s_addr = htonl(addrp->s_addr);
+ return NULL;
+}
+
+/*
+ - trydotted - try conversion as dotted decimal
+ *
+ * If the first char of a complaint is '?', that means "didn't look like
+ * dotted decimal at all".
+ */
+const char * /* NULL for success, else string literal */
+trydotted(src, srclen, addrp)
+const char *src;
+size_t srclen;
+struct in_addr *addrp;
+{
+ const char *stop = src + srclen; /* just past end */
+ int byte;
+ const char *oops;
+ unsigned long addr;
+ int i;
+# define NBYTES 4
+# define BYTE 8
+
+ addr = 0;
+ for (i = 0; i < NBYTES && src < stop; i++) {
+ oops = getbyte(&src, stop, &byte);
+ if (oops != NULL) {
+ if (*oops != '?')
+ return oops; /* bad number */
+ if (i > 1)
+ return oops+1; /* failed number */
+ return oops; /* with leading '?' */
+ }
+ addr = (addr << BYTE) | byte;
+ if (i < 3 && src < stop && *src++ != '.') {
+ if (i == 0)
+ return "?syntax error in dotted-decimal address";
+ else
+ return "syntax error in dotted-decimal address";
+ }
+ }
+ addr <<= (NBYTES - i) * BYTE;
+ if (src != stop)
+ return "extra garbage on end of dotted-decimal address";
+
+ addrp->s_addr = htonl(addr);
+ return NULL;
+}
+
+/*
+ - getbyte - try to scan a byte in dotted decimal
+ * A subtlety here is that all this arithmetic on ASCII digits really is
+ * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
+ * It's easier to just do it ourselves than set up for a call to atoul().
+ *
+ * If the first char of a complaint is '?', that means "didn't look like a
+ * number at all".
+ */
+const char * /* NULL for success, else string literal */
+getbyte(srcp, stop, retp)
+const char **srcp; /* *srcp is updated */
+const char *stop; /* first untouchable char */
+int *retp; /* return-value pointer */
+{
+ char c;
+ const char *p;
+ int no;
+
+ if (*srcp >= stop)
+ return "?empty number in dotted-decimal address";
+
+ if (stop - *srcp >= 3 && **srcp == '0' && CIEQ(*(*srcp+1), 'x'))
+ return "hex numbers not supported in dotted-decimal addresses";
+#ifdef NOLEADINGZEROS
+ if (stop - *srcp >= 2 && **srcp == '0' && isdigit(*(*srcp+1)))
+ return "octal numbers not supported in dotted-decimal addresses";
+#endif /* NOLEADINGZEROS */
+
+ /* must be decimal, if it's numeric at all */
+ no = 0;
+ p = *srcp;
+ while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
+ no = no*10 + (c - '0');
+ p++;
+ }
+ if (p == *srcp)
+ return "?non-numeric component in dotted-decimal address";
+ *srcp = p;
+ if (no > 255)
+ return "byte overflow in dotted-decimal address";
+ *retp = no;
+ return NULL;
+}
diff --git a/src/libfreeswan/libfreeswan/atoasr.3 b/src/libfreeswan/libfreeswan/atoasr.3
new file mode 100644
index 000000000..1bd805db1
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atoasr.3
@@ -0,0 +1,186 @@
+.TH IPSEC_ATOASR 3 "11 June 2001"
+.\" RCSID $Id: atoasr.3,v 1.1 2004/03/15 20:35:25 as Exp $
+.SH NAME
+ipsec atoasr \- convert ASCII to Internet address, subnet, or range
+.br
+ipsec rangetoa \- convert Internet address range to ASCII
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *atoasr(const char *src, size_t srclen,"
+.ti +1c
+.B "char *type, struct in_addr *addrs);"
+.br
+.B "size_t rangetoa(struct in_addr *addrs, int format,
+.ti +1c
+.B "char *dst, size_t dstlen);"
+.SH DESCRIPTION
+These functions are obsolete;
+there is no current equivalent,
+because so far they have not proved useful.
+.PP
+.I Atoasr
+converts an ASCII address, subnet, or address range
+into a suitable combination of binary addresses
+(in network byte order).
+.I Rangetoa
+converts an address range back into ASCII,
+using dotted-decimal form for the addresses
+(the other reverse conversions are handled by
+.IR ipsec_addrtoa (3)
+and
+.IR ipsec_subnettoa (3)).
+.PP
+A single address can be any form acceptable to
+.IR ipsec_atoaddr (3):
+dotted decimal, DNS name, or hexadecimal number.
+A subnet
+specification uses the form \fInetwork\fB/\fImask\fR
+interpreted by
+.IR ipsec_atosubnet (3).
+.PP
+An address range is two
+.IR ipsec_atoaddr (3)
+addresses separated by a
+.B ...
+delimiter.
+If there are four dots rather than three, the first is taken as
+part of the begin address,
+e.g. for a complete DNS name which ends with
+.B .
+to suppress completion attempts.
+The begin address of a range must be
+less than or equal to the end address.
+.PP
+The
+.I srclen
+parameter of
+.I atoasr
+specifies the length of the ASCII string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I type
+parameter of
+.I atoasr
+must point to a
+.B char
+variable used to record which form was found.
+The
+.I addrs
+parameter must point to a two-element array of
+.B "struct in_addr"
+which receives the results.
+The values stored into
+.BR *type ,
+and the corresponding values in the array, are:
+.PP
+.ta 3c +2c +3c
+ *type addrs[0] addrs[1]
+.sp 0.8
+address \&\fB'a'\fR address -
+.br
+subnet \&\fB's'\fR network mask
+.br
+range \&\fB'r'\fR begin end
+.PP
+The
+.I dstlen
+parameter of
+.I rangetoa
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.I freeswan.h
+header file defines a constant,
+.BR RANGETOA_BUF ,
+which is the size of a buffer just large enough for worst-case results.
+.PP
+The
+.I format
+parameter of
+.I rangetoa
+specifies what format is to be used for the conversion.
+The value
+.B 0
+(not the ASCII character
+.BR '0' ,
+but a zero value)
+specifies a reasonable default,
+and is in fact the only format currently available.
+This parameter is a hedge against future needs.
+.PP
+.I Atoasr
+returns NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.I Rangetoa
+returns
+.B 0
+for a failure, and otherwise
+always returns the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.SH SEE ALSO
+ipsec_atoaddr(3), ipsec_atosubnet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I atoasr
+are:
+empty input;
+error in
+.IR ipsec_atoaddr (3)
+or
+.IR ipsec_atosubnet (3)
+during conversion;
+begin address of range exceeds end address.
+.PP
+Fatal errors in
+.I rangetoa
+are:
+unknown format.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The restriction of error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = atoasr( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/atoasr.c b/src/libfreeswan/libfreeswan/atoasr.c
new file mode 100644
index 000000000..a68409bfb
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atoasr.c
@@ -0,0 +1,212 @@
+/*
+ * convert from ASCII form of address/subnet/range to binary
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: atoasr.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - atoasr - convert ASCII to address, subnet, or range
+ */
+const char * /* NULL for success, else string literal */
+atoasr(src, srclen, typep, addrsp)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+char *typep; /* return type code: 'a', 's', 'r' */
+struct in_addr addrsp[2];
+{
+ const char *punct;
+ const char *stop;
+ const char *oops;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+
+ /* subnet is easy to spot */
+ punct = memchr(src, '/', srclen);
+ if (punct != NULL) {
+ *typep = 's';
+ return atosubnet(src, srclen, &addrsp[0], &addrsp[1]);
+ }
+
+ /* try for a range */
+ stop = src + srclen;
+ for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL;
+ punct++)
+ if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.')
+ break; /* NOTE BREAK OUT */
+ if (punct == NULL) {
+ /* didn't find the range delimiter, must be plain address */
+ *typep = 'a';
+ return atoaddr(src, srclen, &addrsp[0]);
+ }
+
+ /* looks like a range */
+ *typep = 'r';
+ if (stop - punct > 4 && *(punct+3) == '.')
+ punct++; /* first dot is trailing dot of name */
+ oops = atoaddr(src, punct - src, &addrsp[0]);
+ if (oops != NULL)
+ return oops;
+ oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]);
+ if (oops != NULL)
+ return oops;
+ if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr))
+ return "invalid range, begin > end";
+ return NULL;
+}
+
+
+
+#ifdef ATOASR_MAIN
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+void regress(void);
+
+int
+main(int argc, char *argv[])
+{
+ struct in_addr a[2];
+ char buf[100];
+ const char *oops;
+ size_t n;
+ char type;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
+ argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ oops = atoasr(argv[1], 0, &type, a);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ switch (type) {
+ case 'a':
+ n = addrtoa(a[0], 0, buf, sizeof(buf));
+ break;
+ case 's':
+ n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
+ break;
+ case 'r':
+ n = rangetoa(a, 0, buf, sizeof(buf));
+ break;
+ default:
+ fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type);
+ exit(1);
+ break;
+ }
+ if (n > sizeof(buf)) {
+ fprintf(stderr, "%s: reverse conversion of ", argv[0]);
+ fprintf(stderr, "%s ", inet_ntoa(a[0]));
+ fprintf(stderr, "%s", inet_ntoa(a[1]));
+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
+ (long)n, (long)sizeof(buf));
+ exit(1);
+ }
+ printf("%s\n", buf);
+
+ exit(0);
+}
+
+struct rtab {
+ char *input;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {"1.2.3.0", "1.2.3.0"},
+ {"1.2.3.0/255.255.255.0", "1.2.3.0/24"},
+ {"1.2.3.0...1.2.3.5", "1.2.3.0...1.2.3.5"},
+ {"1.2.3.4.5", NULL},
+ {"1.2.3.4/", NULL},
+ {"1.2.3.4...", NULL},
+ {"1.2.3.4....", NULL},
+ {"localhost/32", "127.0.0.1/32"},
+ {"localhost...127.0.0.3", "127.0.0.1...127.0.0.3"},
+ {"127.0.0.0...localhost", "127.0.0.0...127.0.0.1"},
+ {"127.0.0.3...localhost", NULL},
+ {NULL, NULL}
+};
+
+void
+regress(void)
+{
+ struct rtab *r;
+ int status = 0;
+ struct in_addr a[2];
+ char in[100];
+ char buf[100];
+ const char *oops;
+ size_t n;
+ char type;
+
+ for (r = rtab; r->input != NULL; r++) {
+ strcpy(in, r->input);
+ oops = atoasr(in, 0, &type, a);
+ if (oops != NULL && r->output == NULL)
+ {} /* okay, error expected */
+ else if (oops != NULL) {
+ printf("`%s' atoasr failed: %s\n", r->input, oops);
+ status = 1;
+ } else if (r->output == NULL) {
+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
+ r->input, type);
+ status = 1;
+ } else {
+ switch (type) {
+ case 'a':
+ n = addrtoa(a[0], 0, buf, sizeof(buf));
+ break;
+ case 's':
+ n = subnettoa(a[0], a[1], 0, buf, sizeof(buf));
+ break;
+ case 'r':
+ n = rangetoa(a, 0, buf, sizeof(buf));
+ break;
+ default:
+ fprintf(stderr, "`%s' unknown type '%c'\n",
+ r->input, type);
+ n = 0;
+ status = 1;
+ break;
+ }
+ if (n > sizeof(buf)) {
+ printf("`%s' '%c' reverse failed: need %ld\n",
+ r->input, type, (long)n);
+ status = 1;
+ } else if (n > 0 && strcmp(r->output, buf) != 0) {
+ printf("`%s' '%c' gave `%s', expected `%s'\n",
+ r->input, type, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* ATOASR_MAIN */
diff --git a/src/libfreeswan/libfreeswan/atosa.3 b/src/libfreeswan/libfreeswan/atosa.3
new file mode 100644
index 000000000..116483a73
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atosa.3
@@ -0,0 +1,218 @@
+.TH IPSEC_ATOSA 3 "11 June 2001"
+.\" RCSID $Id: atosa.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec atosa, satoa \- convert IPsec Security Association IDs to and from ASCII
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *atosa(const char *src, size_t srclen,"
+.ti +1c
+.B "struct sa_id *sa);
+.br
+.B "size_t satoa(struct sa_id sa, int format,"
+.ti +1c
+.B "char *dst, size_t dstlen);"
+.sp
+.B "struct sa_id {"
+.ti +1c
+.B "struct in_addr dst;"
+.ti +1c
+.B "ipsec_spi_t spi;"
+.ti +1c
+.B "int proto;"
+.br
+.B "};"
+.SH DESCRIPTION
+These functions are obsolete; see
+.IR ipsec_ttosa (3)
+for their replacements.
+.PP
+.I Atosa
+converts an ASCII Security Association (SA) specifier into an
+.B sa_id
+structure (containing
+a destination-host address
+in network byte order,
+an SPI number in network byte order, and
+a protocol code).
+.I Satoa
+does the reverse conversion, back to an ASCII SA specifier.
+.PP
+An SA is specified in ASCII with a mail-like syntax, e.g.
+.BR esp507@1.2.3.4 .
+An SA specifier contains
+a protocol prefix (currently
+.BR ah ,
+.BR esp ,
+or
+.BR tun ),
+an unsigned integer SPI number,
+and an IP address.
+The SPI number can be decimal or hexadecimal
+(with
+.B 0x
+prefix), as accepted by
+.IR ipsec_atoul (3).
+The IP address can be any form accepted by
+.IR ipsec_atoaddr (3),
+e.g. dotted-decimal address or DNS name.
+.PP
+As a special case, the SA specifier
+.B %passthrough
+signifies the special SA used to indicate that packets should be
+passed through unaltered.
+(At present, this is a synonym for
+.BR tun0x0@0.0.0.0 ,
+but that is subject to change without notice.)
+This form is known to both
+.I atosa
+and
+.IR satoa ,
+so the internal form of
+.B %passthrough
+is never visible.
+.PP
+The
+.B <freeswan.h>
+header file supplies the
+.B sa_id
+structure, as well as a data type
+.B ipsec_spi_t
+which is an unsigned 32-bit integer.
+(There is no consistency between kernel and user on what such a type
+is called, hence the header hides the differences.)
+.PP
+The protocol code uses the same numbers that IP does.
+For user convenience, given the difficulty in acquiring the exact set of
+protocol names used by the kernel,
+.B <freeswan.h>
+defines the names
+.BR SA_ESP ,
+.BR SA_AH ,
+and
+.B SA_IPIP
+to have the same values as the kernel names
+.BR IPPROTO_ESP ,
+.BR IPPROTO_AH ,
+and
+.BR IPPROTO_IPIP .
+.PP
+The
+.I srclen
+parameter of
+.I atosa
+specifies the length of the ASCII string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I dstlen
+parameter of
+.I satoa
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.I freeswan.h
+header file defines a constant,
+.BR SATOA_BUF ,
+which is the size of a buffer just large enough for worst-case results.
+.PP
+The
+.I format
+parameter of
+.I satoa
+specifies what format is to be used for the conversion.
+The value
+.B 0
+(not the ASCII character
+.BR '0' ,
+but a zero value)
+specifies a reasonable default
+(currently
+lowercase protocol prefix, lowercase hexadecimal SPI, dotted-decimal address).
+The value
+.B d
+causes the SPI to be generated in decimal instead.
+.PP
+.I Atosa
+returns
+.B NULL
+for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.I Satoa
+returns
+.B 0
+for a failure, and otherwise
+always returns the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.SH SEE ALSO
+ipsec_atoul(3), ipsec_atoaddr(3), inet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I atosa
+are:
+empty input;
+input too small to be a legal SA specifier;
+no
+.B @
+in input;
+unknown protocol prefix;
+conversion error in
+.I atoul
+or
+.IR atoaddr .
+.PP
+Fatal errors in
+.I satoa
+are:
+unknown format; unknown protocol code.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The
+.B tun
+protocol code is a FreeS/WANism which may eventually disappear.
+.PP
+The restriction of ASCII-to-binary error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The ASCII-to-binary error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = atoaddr( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/atosa.c b/src/libfreeswan/libfreeswan/atosa.c
new file mode 100644
index 000000000..cc3b055d0
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atosa.c
@@ -0,0 +1,200 @@
+/*
+ * convert from ASCII form of SA ID to binary
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: atosa.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static struct satype {
+ char *prefix;
+ size_t prelen; /* strlen(prefix) */
+ int proto;
+} satypes[] = {
+ { "ah", 2, SA_AH },
+ { "esp", 3, SA_ESP },
+ { "tun", 3, SA_IPIP },
+ { "comp", 4, SA_COMP },
+ { NULL, 0, 0, }
+};
+
+/*
+ - atosa - convert ASCII "ah507@10.0.0.1" to SA identifier
+ */
+const char * /* NULL for success, else string literal */
+atosa(src, srclen, sa)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+struct sa_id *sa;
+{
+ const char *at;
+ const char *addr;
+ const char *spi = NULL;
+ struct satype *sat;
+ unsigned long ul;
+ const char *oops;
+# define MINLEN 5 /* ah0@0 is as short as it can get */
+ static char ptname[] = PASSTHROUGHNAME;
+# define PTNLEN (sizeof(ptname)-1) /* -1 for NUL */
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+ if (srclen < MINLEN)
+ return "string too short to be SA specifier";
+ if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) {
+ src = PASSTHROUGHIS;
+ srclen = strlen(src);
+ }
+
+ at = memchr(src, '@', srclen);
+ if (at == NULL)
+ return "no @ in SA specifier";
+
+ for (sat = satypes; sat->prefix != NULL; sat++)
+ if (sat->prelen < srclen &&
+ strncmp(src, sat->prefix, sat->prelen) == 0) {
+ sa->proto = sat->proto;
+ spi = src + sat->prelen;
+ break; /* NOTE BREAK OUT */
+ }
+ if (sat->prefix == NULL)
+ return "SA specifier lacks valid protocol prefix";
+
+ if (spi >= at)
+ return "no SPI in SA specifier";
+ oops = atoul(spi, at - spi, 13, &ul);
+ if (oops != NULL)
+ return oops;
+ sa->spi = htonl(ul);
+
+ addr = at + 1;
+ oops = atoaddr(addr, srclen - (addr - src), &sa->dst);
+ if (oops != NULL)
+ return oops;
+
+ return NULL;
+}
+
+
+
+#ifdef ATOSA_MAIN
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+void regress(void);
+
+int
+main(int argc, char *argv[])
+{
+ struct sa_id sa;
+ char buf[100];
+ const char *oops;
+ size_t n;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ oops = atosa(argv[1], 0, &sa);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ n = satoa(sa, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
+ fprintf(stderr, "%lu@", (long unsigned int)sa.spi);
+ fprintf(stderr, "%s", inet_ntoa(sa.dst));
+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
+ (long)n, (long)sizeof(buf));
+ exit(1);
+ }
+ printf("%s\n", buf);
+
+ exit(0);
+}
+
+struct rtab {
+ char *input;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {"esp257@1.2.3.0", "esp257@1.2.3.0"},
+ {"ah0x20@1.2.3.4", "ah32@1.2.3.4"},
+ {"tun011@111.2.3.99", "tun11@111.2.3.99"},
+ {"", NULL},
+ {"_", NULL},
+ {"ah2.2", NULL},
+ {"goo2@1.2.3.4", NULL},
+ {"esp9@1.2.3.4", "esp9@1.2.3.4"},
+ {"espp9@1.2.3.4", NULL},
+ {"es9@1.2.3.4", NULL},
+ {"ah@1.2.3.4", NULL},
+ {"esp7x7@1.2.3.4", NULL},
+ {"esp77@1.0x2.3.4", NULL},
+ {PASSTHROUGHNAME, PASSTHROUGHNAME},
+ {NULL, NULL}
+};
+
+void
+regress(void)
+{
+ struct rtab *r;
+ int status = 0;
+ struct sa_id sa;
+ char in[100];
+ char buf[100];
+ const char *oops;
+ size_t n;
+
+ for (r = rtab; r->input != NULL; r++) {
+ strcpy(in, r->input);
+ oops = atosa(in, 0, &sa);
+ if (oops != NULL && r->output == NULL)
+ {} /* okay, error expected */
+ else if (oops != NULL) {
+ printf("`%s' atosa failed: %s\n", r->input, oops);
+ status = 1;
+ } else if (r->output == NULL) {
+ printf("`%s' atosa succeeded unexpectedly\n",
+ r->input);
+ status = 1;
+ } else {
+ n = satoa(sa, 'd', buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ printf("`%s' satoa failed: need %ld\n",
+ r->input, (long)n);
+ status = 1;
+ } else if (strcmp(r->output, buf) != 0) {
+ printf("`%s' gave `%s', expected `%s'\n",
+ r->input, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* ATOSA_MAIN */
diff --git a/src/libfreeswan/libfreeswan/atosubnet.c b/src/libfreeswan/libfreeswan/atosubnet.c
new file mode 100644
index 000000000..9300c2895
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atosubnet.c
@@ -0,0 +1,216 @@
+/*
+ * convert from ASCII form of subnet specification to binary
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: atosubnet.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+#ifndef DEFAULTSUBNET
+#define DEFAULTSUBNET "%default"
+#endif
+
+/*
+ - atosubnet - convert ASCII "addr/mask" to address and mask
+ * Mask can be integer bit count.
+ */
+const char * /* NULL for success, else string literal */
+atosubnet(src, srclen, addrp, maskp)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+struct in_addr *addrp;
+struct in_addr *maskp;
+{
+ const char *slash;
+ const char *mask;
+ size_t mlen;
+ const char *oops;
+ unsigned long bc;
+ static char def[] = DEFAULTSUBNET;
+# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */
+ static char defis[] = "0/0";
+# define DEFILEN (sizeof(defis) - 1)
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+
+ if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
+ src = defis;
+ srclen = DEFILEN;
+ }
+
+ slash = memchr(src, '/', srclen);
+ if (slash == NULL)
+ return "no / in subnet specification";
+ mask = slash + 1;
+ mlen = srclen - (mask - src);
+
+ oops = atoaddr(src, slash-src, addrp);
+ if (oops != NULL)
+ return oops;
+
+ oops = atoul(mask, mlen, 10, &bc);
+ if (oops == NULL) {
+ /* atoul succeeded, it's a bit-count mask */
+ if (bc > ABITS)
+ return "bit-count mask too large";
+#ifdef NOLEADINGZEROS
+ if (mlen > 1 && *mask == '0')
+ return "octal not allowed in mask";
+#endif /* NOLEADINGZEROS */
+ *maskp = bitstomask((int)bc);
+ } else {
+ oops = atoaddr(mask, mlen, maskp);
+ if (oops != NULL)
+ return oops;
+ if (!goodmask(*maskp))
+ return "non-contiguous mask";
+ }
+
+ addrp->s_addr &= maskp->s_addr;
+ return NULL;
+}
+
+
+
+#ifdef ATOSUBNET_MAIN
+
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+void regress(void);
+
+int
+main(int argc, char *argv[])
+{
+ struct in_addr a;
+ struct in_addr m;
+ char buf[100];
+ const char *oops;
+ size_t n;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {addr/mask|-r}\n", argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ oops = atosubnet(argv[1], 0, &a, &m);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ n = subnettoa(a, m, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ fprintf(stderr, "%s: reverse conversion of ", argv[0]);
+ fprintf(stderr, "%s/", inet_ntoa(a));
+ fprintf(stderr, "%s", inet_ntoa(m));
+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
+ (long)n, (long)sizeof(buf));
+ exit(1);
+ }
+ printf("%s\n", buf);
+
+ exit(0);
+}
+
+struct rtab {
+ char *input;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {"1.2.3.0/255.255.255.0", "1.2.3.0/24"},
+ {"1.2.3.0/24", "1.2.3.0/24"},
+ {"1.2.3.1/255.255.255.240", "1.2.3.0/28"},
+ {"1.2.3.1/32", "1.2.3.1/32"},
+ {"1.2.3.1/0", "0.0.0.0/0"},
+/* "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */
+ {"1.2.3.1/255.255.127.0", NULL},
+ {"128.009.000.032/32", "128.9.0.32/32"},
+ {"128.0x9.0.32/32", NULL},
+ {"0x80090020/32", "128.9.0.32/32"},
+ {"0x800x0020/32", NULL},
+ {"128.9.0.32/0xffFF0000", "128.9.0.0/16"},
+ {"128.9.0.32/0xff0000FF", NULL},
+ {"128.9.0.32/0x0000ffFF", NULL},
+ {"128.9.0.32/0x00ffFF0000", NULL},
+ {"128.9.0.32/0xffFF", NULL},
+ {"128.9.0.32.27/32", NULL},
+ {"128.9.0k32/32", NULL},
+ {"328.9.0.32/32", NULL},
+ {"128.9..32/32", NULL},
+ {"10/8", "10.0.0.0/8"},
+ {"10.0/8", "10.0.0.0/8"},
+ {"10.0.0/8", "10.0.0.0/8"},
+ {"10.0.1/24", "10.0.1.0/24"},
+ {"_", NULL},
+ {"_/_", NULL},
+ {"1.2.3.1", NULL},
+ {"1.2.3.1/_", NULL},
+ {"1.2.3.1/24._", NULL},
+ {"1.2.3.1/99", NULL},
+ {"localhost/32", "127.0.0.1/32"},
+ {"%default", "0.0.0.0/0"},
+ {NULL, NULL}
+};
+
+void
+regress()
+{
+ struct rtab *r;
+ int status = 0;
+ struct in_addr a;
+ struct in_addr m;
+ char in[100];
+ char buf[100];
+ const char *oops;
+ size_t n;
+
+ for (r = rtab; r->input != NULL; r++) {
+ strcpy(in, r->input);
+ oops = atosubnet(in, 0, &a, &m);
+ if (oops != NULL && r->output == NULL)
+ {} /* okay, error expected */
+ else if (oops != NULL) {
+ printf("`%s' atosubnet failed: %s\n", r->input, oops);
+ status = 1;
+ } else if (r->output == NULL) {
+ printf("`%s' atosubnet succeeded unexpectedly\n",
+ r->input);
+ status = 1;
+ } else {
+ n = subnettoa(a, m, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ printf("`%s' subnettoa failed: need %ld\n",
+ r->input, (long)n);
+ status = 1;
+ } else if (strcmp(r->output, buf) != 0) {
+ printf("`%s' gave `%s', expected `%s'\n",
+ r->input, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* ATOSUBNET_MAIN */
diff --git a/src/libfreeswan/libfreeswan/atoul.3 b/src/libfreeswan/libfreeswan/atoul.3
new file mode 100644
index 000000000..a606fa4a9
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atoul.3
@@ -0,0 +1,161 @@
+.TH IPSEC_ATOUL 3 "11 June 2001"
+.\" RCSID $Id: atoul.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec atoul, ultoa \- convert unsigned-long numbers to and from ASCII
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *atoul(const char *src, size_t srclen,"
+.ti +1c
+.B "int base, unsigned long *n);"
+.br
+.B "size_t ultoa(unsigned long n, int base, char *dst,"
+.ti +1c
+.B "size_t dstlen);"
+.SH DESCRIPTION
+These functions are obsolete; see
+.IR ipsec_ttoul (3)
+for their replacements.
+.PP
+.I Atoul
+converts an ASCII number into a binary
+.B "unsigned long"
+value.
+.I Ultoa
+does the reverse conversion, back to an ASCII version.
+.PP
+Numbers are specified in ASCII as
+decimal (e.g.
+.BR 123 ),
+octal with a leading zero (e.g.
+.BR 012 ,
+which has value 10),
+or hexadecimal with a leading
+.B 0x
+(e.g.
+.BR 0x1f ,
+which has value 31)
+in either upper or lower case.
+.PP
+The
+.I srclen
+parameter of
+.I atoul
+specifies the length of the ASCII string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I base
+parameter of
+.I atoul
+can be
+.BR 8 ,
+.BR 10 ,
+or
+.BR 16 ,
+in which case the number supplied is assumed to be of that form
+(and in the case of
+.BR 16 ,
+to lack any
+.B 0x
+prefix).
+It can also be
+.BR 0 ,
+in which case the number is examined for a leading zero
+or a leading
+.B 0x
+to determine its base,
+or
+.B 13
+(halfway between 10 and 16),
+which has the same effect as
+.B 0
+except that a non-hexadecimal
+number is considered decimal regardless of any leading zero.
+.PP
+The
+.I dstlen
+parameter of
+.I ultoa
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+.PP
+The
+.I base
+parameter of
+.I ultoa
+must be
+.BR 8 ,
+.BR 10 ,
+or
+.BR 16 .
+.PP
+.I Atoul
+returns NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.I Ultoa
+returns the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.SH SEE ALSO
+atol(3), strtoul(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I atoul
+are:
+empty input;
+unknown
+.IR base ;
+non-digit character found;
+number too large for an
+.BR "unsigned long" .
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+There is no provision for reporting an invalid
+.I base
+parameter given to
+.IR ultoa .
+.PP
+The restriction of error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The error-reporting convention lends itself to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = atoul( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/atoul.c b/src/libfreeswan/libfreeswan/atoul.c
new file mode 100644
index 000000000..e32a8cdab
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/atoul.c
@@ -0,0 +1,90 @@
+/*
+ * convert from ASCII form of unsigned long to binary
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: atoul.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - atoul - convert ASCII substring to unsigned long number
+ */
+const char * /* NULL for success, else string literal */
+atoul(src, srclen, base, resultp)
+const char *src;
+size_t srclen; /* 0 means strlen(src) */
+int base; /* 0 means figure it out */
+unsigned long *resultp;
+{
+ const char *stop;
+ static char hex[] = "0123456789abcdef";
+ static char uchex[] = "0123456789ABCDEF";
+ int d;
+ char c;
+ char *p;
+ unsigned long r;
+ unsigned long rlimit;
+ int dlimit;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+
+ if (base == 0 || base == 13) {
+ if (srclen > 2 && *src == '0' && CIEQ(*(src+1), 'x'))
+ return atoul(src+2, srclen-2, 16, resultp);
+ if (srclen > 1 && *src == '0' && base != 13)
+ return atoul(src+1, srclen-1, 8, resultp);
+ return atoul(src, srclen, 10, resultp);
+ }
+ if (base != 8 && base != 10 && base != 16)
+ return "unsupported number base";
+
+ r = 0;
+ stop = src + srclen;
+ if (base == 16) {
+ while (src < stop) {
+ c = *src++;
+ p = strchr(hex, c);
+ if (p != NULL)
+ d = p - hex;
+ else {
+ p = strchr(uchex, c);
+ if (p == NULL)
+ return "non-hex-digit in hex number";
+ d = p - uchex;
+ }
+ r = (r << 4) | d;
+ }
+ /* defer length check to catch invalid digits first */
+ if (srclen > sizeof(unsigned long) * 2)
+ return "hex number too long";
+ } else {
+ rlimit = ULONG_MAX / base;
+ dlimit = (int)(ULONG_MAX - rlimit*base);
+ while (src < stop) {
+ c = *src++;
+ d = c - '0';
+ if (d < 0 || d >= base)
+ return "non-digit in number";
+ if (r > rlimit || (r == rlimit && d > dlimit))
+ return "unsigned-long overflow";
+ r = r*base + d;
+ }
+ }
+
+ *resultp = r;
+ return NULL;
+}
diff --git a/src/libfreeswan/libfreeswan/copyright.c b/src/libfreeswan/libfreeswan/copyright.c
new file mode 100644
index 000000000..0e836f6c2
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/copyright.c
@@ -0,0 +1,56 @@
+/*
+ * return IPsec copyright notice
+ * Copyright (C) 2001, 2002 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: copyright.c,v 1.6 2005/11/02 21:51:13 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static const char *co[] = {
+ "Copyright (C) 1999-2005 Henry Spencer, Richard Guy Briggs,",
+ " D. Hugh Redelmeier, Sandy Harris, Claudia Schmeing,",
+ " Michael Richardson, Angelos D. Keromytis, John Ioannidis,",
+ "",
+ " Ken Bantoft, Stephen J. Bevan, JuanJo Ciarlante, Mathieu Lafon,",
+ " Stephane Laroche, Kai Martius, Tuomo Soini, Herbert Xu,",
+ "",
+ " Andreas Steffen, Martin Berner, Marco Bertossa, David Buechi,",
+ " Ueli Galizzi, Christoph Gysin, Andreas Hess, Patric Lichtsteiner,",
+ " Michael Meier, Andreas Schleiss, Ariane Seiler,",
+ " Mario Strasser, Lukas Suter, Roger Wegmann, Simon Zwahlen,",
+ " Zuercher Hochschule Winterthur (Switzerland).",
+ "",
+ " Jan Hutter, Martin Willi, Andreas Steffen,",
+ " Hochschule fuer Technik Rapperswil (Switzerland).",
+ "",
+ "This program is free software; you can redistribute it and/or modify it",
+ "under the terms of the GNU General Public License as published by the",
+ "Free Software Foundation; either version 2 of the License, or (at your",
+ "option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.",
+ "",
+ "This program is distributed in the hope that it will be useful, but",
+ "WITHOUT ANY WARRANTY; without even the implied warranty of",
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General",
+ "Public License (file COPYING in the distribution) for more details.",
+ NULL
+};
+
+/*
+ - ipsec_copyright_notice - return copyright notice, as a vector of strings
+ */
+const char **
+ipsec_copyright_notice()
+{
+ return co;
+}
diff --git a/src/libfreeswan/libfreeswan/datatot.c b/src/libfreeswan/libfreeswan/datatot.c
new file mode 100644
index 000000000..fbeb35fa9
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/datatot.c
@@ -0,0 +1,233 @@
+/*
+ * convert from binary data (e.g. key) to text form
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: datatot.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static void convert(const char *src, size_t nreal, int format, char *out);
+
+/*
+ - datatot - convert data bytes to text
+ */
+size_t /* true length (with NUL) for success */
+datatot(src, srclen, format, dst, dstlen)
+const char *src;
+size_t srclen;
+int format; /* character indicating what format */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ size_t inblocksize; /* process this many bytes at a time */
+ size_t outblocksize; /* producing this many */
+ size_t breakevery; /* add a _ every this many (0 means don't) */
+ size_t sincebreak; /* output bytes since last _ */
+ char breakchar; /* character used to break between groups */
+ char inblock[10]; /* enough for any format */
+ char outblock[10]; /* enough for any format */
+ char fake[1]; /* fake output area for dstlen == 0 */
+ size_t needed; /* return value */
+ char *stop; /* where the terminating NUL will go */
+ size_t ntodo; /* remaining input */
+ size_t nreal;
+ char *out;
+ char *prefix;
+
+ breakevery = 0;
+ breakchar = '_';
+
+ switch (format) {
+ case 0:
+ case 'h':
+ format = 'x';
+ breakevery = 8;
+ /* FALLTHROUGH */
+ case 'x':
+ inblocksize = 1;
+ outblocksize = 2;
+ prefix = "0x";
+ break;
+ case ':':
+ format = 'x';
+ breakevery = 2;
+ breakchar = ':';
+ /* FALLTHROUGH */
+ case 16:
+ inblocksize = 1;
+ outblocksize = 2;
+ prefix = "";
+ format = 'x';
+ break;
+ case 's':
+ inblocksize = 3;
+ outblocksize = 4;
+ prefix = "0s";
+ break;
+ case 64: /* beware, equals ' ' */
+ inblocksize = 3;
+ outblocksize = 4;
+ prefix = "";
+ format = 's';
+ break;
+ default:
+ return 0;
+ break;
+ }
+ assert(inblocksize < sizeof(inblock));
+ assert(outblocksize < sizeof(outblock));
+ assert(breakevery % outblocksize == 0);
+
+ if (srclen == 0)
+ return 0;
+ ntodo = srclen;
+
+ if (dstlen == 0) { /* dispose of awkward special case */
+ dst = fake;
+ dstlen = 1;
+ }
+ stop = dst + dstlen - 1;
+
+ nreal = strlen(prefix);
+ needed = nreal; /* for starters */
+ if (dstlen <= nreal) { /* prefix won't fit */
+ strncpy(dst, prefix, dstlen - 1);
+ dst += dstlen - 1;
+ } else {
+ strcpy(dst, prefix);
+ dst += nreal;
+ }
+ assert(dst <= stop);
+ sincebreak = 0;
+
+ while (ntodo > 0) {
+ if (ntodo < inblocksize) { /* incomplete input */
+ memset(inblock, 0, sizeof(inblock));
+ memcpy(inblock, src, ntodo);
+ src = inblock;
+ nreal = ntodo;
+ ntodo = inblocksize;
+ } else
+ nreal = inblocksize;
+ out = (outblocksize > stop - dst) ? outblock : dst;
+
+ convert(src, nreal, format, out);
+ needed += outblocksize;
+ sincebreak += outblocksize;
+ if (dst < stop) {
+ if (out != dst) {
+ assert(outblocksize > stop - dst);
+ memcpy(dst, out, stop - dst);
+ dst = stop;
+ } else
+ dst += outblocksize;
+ }
+
+ src += inblocksize;
+ ntodo -= inblocksize;
+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
+ if (dst < stop)
+ *dst++ = breakchar;
+ needed++;
+ sincebreak = 0;
+ }
+ }
+
+ assert(dst <= stop);
+ *dst++ = '\0';
+ needed++;
+
+ return needed;
+}
+
+/*
+ - convert - convert one input block to one output block
+ */
+static void
+convert(src, nreal, format, out)
+const char *src;
+size_t nreal; /* how much of the input block is real */
+int format;
+char *out;
+{
+ static char hex[] = "0123456789abcdef";
+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ unsigned char c;
+ unsigned char c1, c2, c3;
+
+ assert(nreal > 0);
+ switch (format) {
+ case 'x':
+ assert(nreal == 1);
+ c = (unsigned char)*src;
+ *out++ = hex[c >> 4];
+ *out++ = hex[c & 0xf];
+ break;
+ case 's':
+ c1 = (unsigned char)*src++;
+ c2 = (unsigned char)*src++;
+ c3 = (unsigned char)*src++;
+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
+ c |= c2 >> 4; /* ...top 4 of c2 */
+ *out++ = base64[c];
+ if (nreal == 1)
+ *out++ = '=';
+ else {
+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
+ c |= c3 >> 6; /* ...top 2 of c3 */
+ *out++ = base64[c];
+ }
+ if (nreal <= 2)
+ *out++ = '=';
+ else
+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
+ break;
+ default:
+ assert(nreal == 0); /* unknown format */
+ break;
+ }
+}
+
+/*
+ - datatoa - convert data to ASCII
+ * backward-compatibility synonym for datatot
+ */
+size_t /* true length (with NUL) for success */
+datatoa(src, srclen, format, dst, dstlen)
+const char *src;
+size_t srclen;
+int format; /* character indicating what format */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ return datatot(src, srclen, format, dst, dstlen);
+}
+
+/*
+ - bytestoa - convert data bytes to ASCII
+ * backward-compatibility synonym for datatot
+ */
+size_t /* true length (with NUL) for success */
+bytestoa(src, srclen, format, dst, dstlen)
+const char *src;
+size_t srclen;
+int format; /* character indicating what format */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ return datatot(src, srclen, format, dst, dstlen);
+}
diff --git a/src/libfreeswan/libfreeswan/goodmask.3 b/src/libfreeswan/libfreeswan/goodmask.3
new file mode 100644
index 000000000..4a573e51e
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/goodmask.3
@@ -0,0 +1,57 @@
+.TH IPSEC_GOODMASK 3 "11 June 2001"
+.\" RCSID $Id: goodmask.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec goodmask \- is this Internet subnet mask a valid one?
+.br
+ipsec masktobits \- convert Internet subnet mask to bit count
+.br
+ipsec bitstomask \- convert bit count to Internet subnet mask
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "int goodmask(struct in_addr mask);"
+.br
+.B "int masktobits(struct in_addr mask);"
+.br
+.B "struct in_addr bitstomask(int n);"
+.SH DESCRIPTION
+These functions are obsolete;
+see
+.IR ipsec_masktocount (3)
+for a partial replacement.
+.PP
+.I Goodmask
+reports whether the subnet
+.I mask
+is a valid one,
+i.e. consists of a (possibly empty) sequence of
+.BR 1 s
+followed by a (possibly empty) sequence of
+.BR 0 s.
+.I Masktobits
+takes a (valid) subnet mask and returns the number of
+.B 1
+bits in it.
+.I Bitstomask
+reverses this,
+returning the subnet mask corresponding to bit count
+.IR n .
+.PP
+All masks are in network byte order.
+.SH SEE ALSO
+inet(3), ipsec_atosubnet(3)
+.SH DIAGNOSTICS
+.I Masktobits
+returns
+.B \-1
+for an invalid mask.
+.I Bitstomask
+returns an all-zeros mask for a negative or out-of-range
+.IR n .
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The error-reporting convention of
+.I bitstomask
+is less than ideal;
+zero is sometimes a legitimate mask.
diff --git a/src/libfreeswan/libfreeswan/goodmask.c b/src/libfreeswan/libfreeswan/goodmask.c
new file mode 100644
index 000000000..fe7a42335
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/goodmask.c
@@ -0,0 +1,97 @@
+/*
+ * minor utilities for subnet-mask manipulation
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: goodmask.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - goodmask - is this a good (^1*0*$) subnet mask?
+ * You are not expected to understand this. See Henry S. Warren Jr,
+ * "Functions realizable with word-parallel logical and two's-complement
+ * addition instructions", CACM 20.6 (June 1977), p.439.
+ */
+int /* predicate */
+goodmask(mask)
+struct in_addr mask;
+{
+ unsigned long x = ntohl(mask.s_addr);
+ /* clear rightmost contiguous string of 1-bits */
+# define CRCS1B(x) (((x|(x-1))+1)&x)
+# define TOPBIT (1UL << 31)
+
+ /* either zero, or has one string of 1-bits which is left-justified */
+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
+ return 1;
+ return 0;
+}
+
+/*
+ - masktobits - how many bits in this mask?
+ * The algorithm is essentially a binary search, but highly optimized
+ * for this particular task.
+ */
+int /* -1 means !goodmask() */
+masktobits(mask)
+struct in_addr mask;
+{
+ unsigned long m = ntohl(mask.s_addr);
+ int masklen;
+
+ if (!goodmask(mask))
+ return -1;
+
+ if (m&0x00000001UL)
+ return 32;
+ masklen = 0;
+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
+ masklen |= 0x10;
+ m <<= 16;
+ }
+ if (m&(0x00ff0000UL<<1)) {
+ masklen |= 0x08;
+ m <<= 8;
+ }
+ if (m&(0x0f000000UL<<1)) {
+ masklen |= 0x04;
+ m <<= 4;
+ }
+ if (m&(0x30000000UL<<1)) {
+ masklen |= 0x02;
+ m <<= 2;
+ }
+ if (m&(0x40000000UL<<1))
+ masklen |= 0x01;
+
+ return masklen;
+}
+
+/*
+ - bitstomask - return a mask with this many high bits on
+ */
+struct in_addr
+bitstomask(n)
+int n;
+{
+ struct in_addr result;
+
+ if (n > 0 && n <= ABITS)
+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
+ else if (n == 0)
+ result.s_addr = 0;
+ else
+ result.s_addr = 0; /* best error report we can do */
+ return result;
+}
diff --git a/src/libfreeswan/libfreeswan/initaddr.3 b/src/libfreeswan/libfreeswan/initaddr.3
new file mode 100644
index 000000000..b963f21cc
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/initaddr.3
@@ -0,0 +1,129 @@
+.TH IPSEC_INITADDR 3 "11 Sept 2000"
+.\" RCSID $Id: initaddr.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec initaddr \- initialize an ip_address
+.br
+ipsec addrtypeof \- get address type of an ip_address
+.br
+ipsec addrlenof \- get length of address within an ip_address
+.br
+ipsec addrbytesof \- get copy of address within an ip_address
+.br
+ipsec addrbytesptr \- get pointer to address within an ip_address
+.SH SYNOPSIS
+.B "#include <freeswan.h>"
+.sp
+.B "const char *initaddr(const char *src, size_t srclen,"
+.ti +1c
+.B "int af, ip_address *dst);"
+.br
+.B "int addrtypeof(const ip_address *src);"
+.br
+.B "size_t addrlenof(const ip_address *src);"
+.br
+.B "size_t addrbytesof(const ip_address *src,"
+.ti +1c
+.B "unsigned char *dst, size_t dstlen);"
+.br
+.B "size_t addrbytesptr(const ip_address *src,"
+.ti +1c
+.B "const unsigned char **dst);"
+.SH DESCRIPTION
+The
+.B <freeswan.h>
+library uses an internal type
+.I ip_address
+to contain one of the (currently two) types of IP address.
+These functions provide basic tools for creating and examining this type.
+.PP
+.I Initaddr
+initializes a variable
+.I *dst
+of type
+.I ip_address
+from an address
+(in network byte order,
+indicated by a pointer
+.I src
+and a length
+.IR srclen )
+and an address family
+.I af
+(typically
+.B AF_INET
+or
+.BR AF_INET6 ).
+The length must be consistent with the address family.
+.PP
+.I Addrtypeof
+returns the address type of an address,
+normally
+.B AF_INET
+or
+.BR AF_INET6 .
+(The
+.B <freeswan.h>
+header file arranges to include the necessary headers for these
+names to be known.)
+.PP
+.I Addrlenof
+returns the size (in bytes) of the address within an
+.IR ip_address ,
+to permit storage allocation etc.
+.PP
+.I Addrbytesof
+copies the address within the
+.I ip_address
+.I src
+to the buffer indicated by the pointer
+.I dst
+and the length
+.IR dstlen ,
+and returns the address length (in bytes).
+If the address will not fit,
+as many bytes as will fit are copied;
+the returned length is still the full length.
+It is the caller's responsibility to check the
+returned value to ensure that there was enough room.
+.PP
+.I Addrbytesptr
+sets
+.I *dst
+to a pointer to the internal address within the
+.IR ip_address ,
+and returns the address length (in bytes).
+If
+.I dst
+is
+.BR NULL ,
+it just returns the address length.
+The pointer points to
+.B const
+to discourage misuse.
+.PP
+.I Initaddr
+returns
+.B NULL
+for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.PP
+The functions which return
+.I size_t
+return
+.B 0
+for a failure.
+.SH SEE ALSO
+inet(3), ipsec_ttoaddr(3)
+.SH DIAGNOSTICS
+An unknown address family is a fatal error for any of these functions
+except
+.IR addrtypeof .
+An address-size mismatch is a fatal error for
+.IR initaddr .
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+.I Addrtypeof
+should probably have been named
+.IR addrfamilyof .
diff --git a/src/libfreeswan/libfreeswan/initaddr.c b/src/libfreeswan/libfreeswan/initaddr.c
new file mode 100644
index 000000000..c215f6bdf
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/initaddr.c
@@ -0,0 +1,51 @@
+/*
+ * initialize address structure
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: initaddr.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - initaddr - initialize ip_address from bytes
+ */
+err_t /* NULL for success, else string literal */
+initaddr(src, srclen, af, dst)
+const unsigned char *src;
+size_t srclen;
+int af; /* address family */
+ip_address *dst;
+{
+ switch (af) {
+ case AF_INET:
+ if (srclen != 4)
+ return "IPv4 address must be exactly 4 bytes";
+ dst->u.v4.sin_family = af;
+ dst->u.v4.sin_port = 0; /* unused */
+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
+ break;
+ case AF_INET6:
+ if (srclen != 16)
+ return "IPv6 address must be exactly 16 bytes";
+ dst->u.v6.sin6_family = af;
+ dst->u.v6.sin6_flowinfo = 0; /* unused */
+ dst->u.v6.sin6_port = 0; /* unused */
+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
+ break;
+ default:
+ return "unknown address family in initaddr";
+ break;
+ }
+ return NULL;
+}
diff --git a/src/libfreeswan/libfreeswan/initsaid.c b/src/libfreeswan/libfreeswan/initsaid.c
new file mode 100644
index 000000000..4790f6981
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/initsaid.c
@@ -0,0 +1,33 @@
+/*
+ * initialize SA ID structure
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: initsaid.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - initsaid - initialize SA ID from bits
+ */
+void
+initsaid(addr, spi, proto, dst)
+const ip_address *addr;
+ipsec_spi_t spi;
+int proto;
+ip_said *dst;
+{
+ dst->dst = *addr;
+ dst->spi = spi;
+ dst->proto = proto;
+}
diff --git a/src/libfreeswan/libfreeswan/initsubnet.3 b/src/libfreeswan/libfreeswan/initsubnet.3
new file mode 100644
index 000000000..670f71778
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/initsubnet.3
@@ -0,0 +1,137 @@
+.TH IPSEC_INITSUBNET 3 "12 March 2002"
+.\" RCSID $Id: initsubnet.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec initsubnet \- initialize an ip_subnet
+.br
+ipsec addrtosubnet \- initialize a singleton ip_subnet
+.br
+ipsec subnettypeof \- get address type of an ip_subnet
+.br
+ipsec masktocount \- convert subnet mask to bit count
+.br
+ipsec networkof \- get base address of an ip_subnet
+.br
+ipsec maskof \- get subnet mask of an ip_subnet
+.SH SYNOPSIS
+.B "#include <freeswan.h>"
+.sp
+.B "const char *initsubnet(const ip_address *addr,"
+.ti +1c
+.B "int maskbits, int clash, ip_subnet *dst);"
+.br
+.B "const char *addrtosubnet(const ip_address *addr,"
+.ti +1c
+.B "ip_subnet *dst);"
+.sp
+.B "int subnettypeof(const ip_subnet *src);"
+.br
+.B "int masktocount(const ip_address *src);"
+.br
+.B "void networkof(const ip_subnet *src, ip_address *dst);"
+.br
+.B "void maskof(const ip_subnet *src, ip_address *dst);"
+.SH DESCRIPTION
+The
+.B <freeswan.h>
+library uses an internal type
+.I ip_subnet
+to contain a description of an IP subnet
+(base address plus mask).
+These functions provide basic tools for creating and examining this type.
+.PP
+.I Initsubnet
+initializes a variable
+.I *dst
+of type
+.I ip_subnet
+from a base address and
+a count of mask bits.
+The
+.I clash
+parameter specifies what to do if the base address includes
+.B 1
+bits outside the prefix specified by the mask
+(that is, in the ``host number'' part of the address):
+.RS
+.IP '0' 5
+zero out host-number bits
+.IP 'x'
+non-zero host-number bits are an error
+.RE
+.PP
+.I Initsubnet
+returns
+.B NULL
+for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.PP
+.I Addrtosubnet
+initializes an
+.I ip_subnet
+variable
+.I *dst
+to a ``singleton subnet'' containing the single address
+.IR *addr .
+It returns
+.B NULL
+for success and
+a pointer to a string-literal error message for failure.
+.PP
+.I Subnettypeof
+returns the address type of a subnet,
+normally
+.B AF_INET
+or
+.BR AF_INET6 .
+(The
+.B <freeswan.h>
+header file arranges to include the necessary headers for these
+names to be known.)
+.PP
+.I Masktocount
+converts a subnet mask, expressed as an address, to a bit count
+suitable for use with
+.IR initsubnet .
+It returns
+.B \-1
+for error; see DIAGNOSTICS.
+.PP
+.I Networkof
+fills in
+.I *dst
+with the base address of subnet
+.IR src .
+.PP
+.I Maskof
+fills in
+.I *dst
+with the subnet mask of subnet
+.IR src ,
+expressed as an address.
+.SH SEE ALSO
+inet(3), ipsec_ttosubnet(3), ipsec_rangetosubnet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I initsubnet
+are:
+unknown address family;
+unknown
+.I clash
+value;
+impossible mask bit count;
+non-zero host-number bits and
+.I clash
+is
+.BR 'x' .
+Fatal errors in
+.I addrtosubnet
+are:
+unknown address family.
+Fatal errors in
+.I masktocount
+are:
+unknown address family;
+mask bits not contiguous.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/libfreeswan/initsubnet.c b/src/libfreeswan/libfreeswan/initsubnet.c
new file mode 100644
index 000000000..75ca72f36
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/initsubnet.c
@@ -0,0 +1,95 @@
+/*
+ * initialize subnet structure
+ * Copyright (C) 2000, 2002 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: initsubnet.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - initsubnet - initialize ip_subnet from address and count
+ *
+ * The only hard part is checking for host-part bits turned on.
+ */
+err_t /* NULL for success, else string literal */
+initsubnet(addr, count, clash, dst)
+const ip_address *addr;
+int count;
+int clash; /* '0' zero host-part bits, 'x' die on them */
+ip_subnet *dst;
+{
+ unsigned char *p;
+ int n;
+ int c;
+ unsigned m;
+ int die;
+
+ dst->addr = *addr;
+ n = addrbytesptr(&dst->addr, (const unsigned char **)&p);
+ if (n == 0)
+ return "unknown address family";
+
+ switch (clash) {
+ case '0':
+ die = 0;
+ break;
+ case 'x':
+ die = 1;
+ break;
+ default:
+ return "unknown clash-control value in initsubnet";
+ break;
+ }
+
+ c = count / 8;
+ if (c > n)
+ return "impossible mask count";
+ p += c;
+ n -= c;
+
+ m = 0xff;
+ c = count % 8;
+ if (n > 0 && c != 0) /* partial byte */
+ m >>= c;
+ for (; n > 0; n--) {
+ if ((*p & m) != 0) {
+ if (die)
+ return "improper subnet, host-part bits on";
+ *p &= ~m;
+ }
+ m = 0xff;
+ p++;
+ }
+
+ dst->maskbits = count;
+ return NULL;
+}
+
+/*
+ - addrtosubnet - initialize ip_subnet from a single address
+ */
+err_t /* NULL for success, else string literal */
+addrtosubnet(addr, dst)
+const ip_address *addr;
+ip_subnet *dst;
+{
+ int n;
+
+ dst->addr = *addr;
+ n = addrbytesptr(&dst->addr, (const unsigned char **)NULL);
+ if (n == 0)
+ return "unknown address family";
+ dst->maskbits = n*8;
+ return NULL;
+}
diff --git a/src/libfreeswan/libfreeswan/internal.h b/src/libfreeswan/libfreeswan/internal.h
new file mode 100644
index 000000000..16ad78da0
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/internal.h
@@ -0,0 +1,81 @@
+/*
+ * internal definitions for use within the library; do not export!
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: internal.h,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+
+#ifndef ABITS
+#define ABITS 32 /* bits in an IPv4 address */
+#endif
+
+/* case-independent ASCII character equality comparison */
+#define CIEQ(c1, c2) ( ((c1)&~040) == ((c2)&~040) )
+
+/* syntax for passthrough SA */
+#ifndef PASSTHROUGHNAME
+#define PASSTHROUGHNAME "%passthrough"
+#define PASSTHROUGH4NAME "%passthrough4"
+#define PASSTHROUGH6NAME "%passthrough6"
+#define PASSTHROUGHIS "tun0@0.0.0.0"
+#define PASSTHROUGH4IS "tun0@0.0.0.0"
+#define PASSTHROUGH6IS "tun0@::"
+#define PASSTHROUGHTYPE "tun"
+#define PASSTHROUGHSPI 0
+#define PASSTHROUGHDST 0
+#endif
+
+/*
+ * Headers, greatly complicated by stupid and unnecessary inconsistencies
+ * between the user environment and the kernel environment. These are done
+ * here so that this mess need exist in only one place.
+ *
+ * It may seem like a -I or two could avoid most of this, but on closer
+ * inspection it is not quite that easy.
+ */
+
+/* things that need to come from one place or the other, depending */
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#define assert(foo) /* nothing */
+#else
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#endif
+
+/* things that exist only in userland */
+#ifndef __KERNEL__
+
+/* You'd think this would be okay in the kernel too -- it's just a */
+/* bunch of constants -- but no, in RH5.1 it screws up other things. */
+/* (Credit: Mike Warfield tracked this problem down. Thanks Mike!) */
+/* Fortunately, we don't need it in the kernel subset of the library. */
+#include <limits.h>
+
+/* header files for things that should never be called in kernel */
+#include <netdb.h>
+
+/* memory allocation, currently user-only, macro-ized just in case */
+#include <stdlib.h>
+#define MALLOC(n) malloc(n)
+#define FREE(p) free(p)
+
+#endif /* __KERNEL__ */
+
diff --git a/src/libfreeswan/libfreeswan/keyblobtoid.3 b/src/libfreeswan/libfreeswan/keyblobtoid.3
new file mode 100644
index 000000000..be381531a
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/keyblobtoid.3
@@ -0,0 +1,103 @@
+.TH IPSEC_KEYBLOBTOID 3 "25 March 2002"
+.\" RCSID $Id: keyblobtoid.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec keyblobtoid, splitkeytoid \- generate key IDs from RSA keys
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "size_t keyblobtoid(const unsigned char *blob,"
+.ti +1c
+.B "size_t bloblen, char *dst, size_t dstlen);"
+.br
+.B "size_t splitkeytoid(const unsigned char *e, size_t elen,"
+.ti +1c
+.B "const unsigned char *m, size_t mlen, char *dst,
+.ti +1c
+.B "size_t dstlen);"
+.SH DESCRIPTION
+.I Keyblobtoid
+and
+.I splitkeytoid
+generate
+key IDs
+from RSA keys,
+for use in messages and reporting,
+writing the result to
+.IR dst .
+A
+.I key ID
+is a short ASCII string identifying a key;
+currently it is just the first nine characters of the base64
+encoding of the RFC 2537/3110 ``byte blob'' representation of the key.
+(Beware that no finite key ID can be collision-proof:
+there is always some small chance of two random keys having the
+same ID.)
+.PP
+.I Keyblobtoid
+generates a key ID from a key which is already in the form of an
+RFC 2537/3110 binary key
+.I blob
+(encoded exponent length, exponent, modulus).
+.PP
+.I Splitkeytoid
+generates a key ID from a key given in the form of a separate
+(binary) exponent
+.I e
+and modulus
+.IR m .
+.PP
+The
+.I dstlen
+parameter of either
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.I freeswan.h
+header file defines a constant
+.B KEYID_BUF
+which is the size of a buffer large enough for worst-case results.
+.PP
+Both functions return
+.B 0
+for a failure, and otherwise
+always return the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.P
+With keys generated by
+.IR ipsec_rsasigkey (3),
+the first two base64 digits are always the same,
+and the third carries only about one bit of information.
+It's worse with keys using longer fixed exponents,
+e.g. the 24-bit exponent that's common in X.509 certificates.
+However, being able to relate key IDs to the full
+base64 text form of keys by eye is sufficiently useful that this
+waste of space seems justifiable.
+The choice of nine digits is a compromise between bulk and
+probability of collision.
+.SH SEE ALSO
+RFC 3110,
+\fIRSA/SHA-1 SIGs and RSA KEYs in the Domain Name System (DNS)\fR,
+Eastlake, 2001
+(superseding the older but better-known RFC 2537).
+.SH DIAGNOSTICS
+Fatal errors are:
+key too short to supply enough bits to construct a complete key ID
+(almost certainly indicating a garbage key);
+exponent too long for its length to be representable.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/libfreeswan/keyblobtoid.c b/src/libfreeswan/libfreeswan/keyblobtoid.c
new file mode 100644
index 000000000..7798601cf
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/keyblobtoid.c
@@ -0,0 +1,148 @@
+/*
+ * generate printable key IDs
+ * Copyright (C) 2002 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: keyblobtoid.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - keyblobtoid - generate a printable key ID from an RFC 2537/3110 key blob
+ * Current algorithm is just to use first nine base64 digits.
+ */
+size_t
+keyblobtoid(src, srclen, dst, dstlen)
+const unsigned char *src;
+size_t srclen;
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ char buf[KEYID_BUF];
+ size_t ret;
+# define NDIG 9
+
+ if (srclen < (NDIG*6 + 7)/8) {
+ strcpy(buf, "?len= ?");
+ buf[5] = '0' + srclen;
+ ret = 0;
+ } else {
+ (void) datatot(src, srclen, 64, buf, NDIG+1);
+ ret = NDIG+1;
+ }
+
+ if (dstlen > 0) {
+ if (strlen(buf)+1 > dstlen)
+ *(buf + dstlen - 1) = '\0';
+ strcpy(dst, buf);
+ }
+ return ret;
+}
+
+/*
+ - splitkeytoid - generate a printable key ID from exponent/modulus pair
+ * Just constructs the beginnings of a key blob and calls keyblobtoid().
+ */
+size_t
+splitkeytoid(e, elen, m, mlen, dst, dstlen)
+const unsigned char *e;
+size_t elen;
+const unsigned char *m;
+size_t mlen;
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ unsigned char buf[KEYID_BUF]; /* ample room */
+ unsigned char *bufend = buf + sizeof(buf);
+ unsigned char *p;
+ size_t n;
+
+ p = buf;
+ if (elen <= 255)
+ *p++ = elen;
+ else if ((elen &~ 0xffff) == 0) {
+ *p++ = 0;
+ *p++ = (elen>>8) & 0xff;
+ *p++ = elen & 0xff;
+ } else
+ return 0; /* unrepresentable exponent length */
+
+ n = bufend - p;
+ if (elen < n)
+ n = elen;
+ memcpy(p, e, n);
+ p += n;
+
+ n = bufend - p;
+ if (n > 0) {
+ if (mlen < n)
+ n = mlen;
+ memcpy(p, m, n);
+ p += n;
+ }
+
+ return keyblobtoid(buf, p - buf, dst, dstlen);
+}
+
+
+
+#ifdef KEYBLOBTOID_MAIN
+
+#include <stdio.h>
+
+void regress();
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ typedef unsigned char uc;
+ uc hexblob[] = "\x01\x03\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52";
+ uc hexe[] = "\x03";
+ uc hexm[] = "\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52\xef\x85";
+ char b64nine[] = "AQOF8tZ2m";
+ char b64six[] = "AQOF8t";
+ char buf[100];
+ size_t n;
+ char *b = b64nine;
+ size_t bl = strlen(b) + 1;
+ int st = 0;
+
+ n = keyblobtoid(hexblob, strlen(hexblob), buf, sizeof(buf));
+ if (n != bl) {
+ fprintf(stderr, "%s: keyblobtoid returned %d not %d\n",
+ argv[0], n, bl);
+ st = 1;
+ }
+ if (strcmp(buf, b) != 0) {
+ fprintf(stderr, "%s: keyblobtoid generated `%s' not `%s'\n",
+ argv[0], buf, b);
+ st = 1;
+ }
+ n = splitkeytoid(hexe, strlen(hexe), hexm, strlen(hexm), buf,
+ sizeof(buf));
+ if (n != bl) {
+ fprintf(stderr, "%s: splitkeytoid returned %d not %d\n",
+ argv[0], n, bl);
+ st = 1;
+ }
+ if (strcmp(buf, b) != 0) {
+ fprintf(stderr, "%s: splitkeytoid generated `%s' not `%s'\n",
+ argv[0], buf, b);
+ st = 1;
+ }
+ exit(st);
+}
+
+#endif /* KEYBLOBTOID_MAIN */
diff --git a/src/libfreeswan/libfreeswan/optionsfrom.3 b/src/libfreeswan/libfreeswan/optionsfrom.3
new file mode 100644
index 000000000..e270475bd
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/optionsfrom.3
@@ -0,0 +1,182 @@
+.TH IPSEC_OPTIONSFROM 3 "16 Oct 1998"
+.\" RCSID $Id: optionsfrom.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec optionsfrom \- read additional ``command-line'' options from file
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *optionsfrom(char *filename, int *argcp,"
+.ti +1c
+.B "char ***argvp, int optind, FILE *errsto);"
+.SH DESCRIPTION
+.I Optionsfrom
+is called from within a
+.IR getopt_long (3)
+scan,
+as the result of the appearance of an option (preferably
+.BR \-\-optionsfrom )
+to insert additional ``command-line'' arguments
+into the scan immediately after
+the option.
+Typically this would be done to pick up options which are
+security-sensitive and should not be visible to
+.IR ps (1)
+and similar commands,
+and hence cannot be supplied as part
+of the actual command line or the environment.
+.PP
+.I Optionsfrom
+reads the additional arguments from the specified
+.IR filename ,
+allocates a new argument vector to hold pointers to the existing
+arguments plus the new ones,
+and amends
+.I argc
+and
+.I argv
+(via the pointers
+.I argcp
+and
+.IR argvp ,
+which must point to the
+.I argc
+and
+.I argv
+being supplied to
+.IR getopt_long (3))
+accordingly.
+.I Optind
+must be the index, in the original argument vector,
+of the next argument.
+.PP
+If
+.I errsto
+is NULL,
+.I optionsfrom
+returns NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+If
+.I errsto
+is non-NULL and an error occurs,
+.I optionsfrom
+prints a suitable complaint onto the
+.I errsto
+descriptor and invokes
+.I exit
+with an exit status of 2;
+this is a convenience for cases where more sophisticated
+responses are not required.
+.PP
+The text of existing arguments is not disturbed by
+.IR optionsfrom ,
+so pointers to them and into them remain valid.
+.PP
+The file of additional arguments is an ASCII text file.
+Lines consisting solely of white space,
+and lines beginning with
+.BR # ,
+are comments and are ignored.
+Otherwise, a line which does not begin with
+.BR \-
+is taken to be a single argument;
+if it both begins and ends with double-quote ("),
+those quotes are stripped off (note, no other processing is done within
+the line!).
+A line beginning with
+.B \-
+is considered to contain multiple arguments separated by white space.
+.PP
+Because
+.I optionsfrom
+reads its entire file before the
+.IR getopt_long (3)
+scan is resumed, an
+.I optionsfrom
+file can contain another
+.B \-\-optionsfrom
+option.
+Obviously, infinite loops are possible here.
+If
+.I errsto
+is non-NULL,
+.I optionsfrom
+considers it an error to be called more than 100 times.
+If
+.I errsto
+is NULL,
+loop detection is up to the caller
+(and the internal loop counter is zeroed out).
+.SH EXAMPLE
+A reasonable way to invoke
+.I optionsfrom
+would be like so:
+.PP
+.nf
+.ft B
+#include <getopt.h>
+
+struct option opts[] = {
+ /* ... */
+ "optionsfrom", 1, NULL, '+',
+ /* ... */
+};
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int opt;
+ extern char *optarg;
+ extern int optind;
+
+ while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
+ switch (opt) {
+ /* ... */
+ case '+': /* optionsfrom */
+ optionsfrom(optarg, &argc, &argv, optind, stderr);
+ /* does not return on error */
+ break;
+ /* ... */
+ }
+ /* ... */
+.ft
+.fi
+.SH SEE ALSO
+getopt_long(3)
+.SH DIAGNOSTICS
+Errors in
+.I optionsfrom
+are:
+unable to open file;
+attempt to allocate temporary storage for argument or
+argument vector failed;
+read error in file;
+line too long.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The double-quote convention is rather simplistic.
+.PP
+Line length is currently limited to 1023 bytes,
+and there is no continuation convention.
+.PP
+The restriction of error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+.PP
+There is a certain element of unwarranted chumminess with
+the insides of
+.IR getopt_long (3)
+here.
+No non-public interfaces are actually used, but
+.IR optionsfrom
+does rely on
+.IR getopt_long (3)
+being well-behaved in certain ways that are not actually
+promised by the specs.
diff --git a/src/libfreeswan/libfreeswan/optionsfrom.c b/src/libfreeswan/libfreeswan/optionsfrom.c
new file mode 100644
index 000000000..d96a3124d
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/optionsfrom.c
@@ -0,0 +1,301 @@
+/*
+ * pick up more options from a file, in the middle of an option scan
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: optionsfrom.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+#include <stdio.h>
+
+#define MAX 100 /* loop-detection limit */
+
+/* internal work area */
+struct work {
+# define LOTS 1024
+ char buf[LOTS];
+ char *line;
+ char *pending;
+};
+
+static const char *dowork(const char *, int *, char ***, int);
+static const char *getanarg(FILE *, struct work *, char **);
+static char *getline(FILE *, char *, size_t);
+
+/*
+ - optionsfrom - add some options, taken from a file, to argc/argv
+ * If errsto is non-NULL, does not return in event of error.
+ */
+const char * /* NULL for success, else string literal */
+optionsfrom(filename, argcp, argvp, optind, errsto)
+const char *filename;
+int *argcp; /* pointer to argc */
+char ***argvp; /* pointer to argv */
+int optind; /* current optind, number of next argument */
+FILE *errsto; /* where to report errors (NULL means return) */
+{
+ const char *e;
+ static int nuses = 0;
+
+ if (errsto != NULL) {
+ nuses++;
+ if (nuses >= MAX) {
+ fprintf(errsto,
+ "%s: optionsfrom called %d times, looping?\n",
+ (*argvp)[0], nuses);
+ exit(2);
+ }
+ } else
+ nuses = 0;
+
+ e = dowork(filename, argcp, argvp, optind);
+ if (e != NULL && errsto != NULL) {
+ fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e);
+ exit(2);
+ }
+ return e;
+}
+
+/*
+ - dowork - do all the real work of optionsfrom
+ * Does not alter the existing arguments, but does relocate and alter
+ * the argv pointer vector.
+ */
+static const char * /* NULL for success, else string literal */
+dowork(filename, argcp, argvp, optind)
+const char *filename;
+int *argcp; /* pointer to argc */
+char ***argvp; /* pointer to argv */
+int optind; /* current optind, number of next argument */
+{
+ char **newargv;
+ char **tmp;
+ int newargc;
+ int next; /* place for next argument */
+ int room; /* how many more new arguments we can hold */
+# define SOME 10 /* first guess at how many we'll need */
+ FILE *f;
+ int i;
+ const char *p;
+ struct work wa; /* for getanarg() */
+
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return "unable to open file";
+
+ newargc = *argcp + SOME;
+ newargv = malloc((newargc+1) * sizeof(char *));
+ if (newargv == NULL)
+ return "unable to allocate memory";
+ memcpy(newargv, *argvp, optind * sizeof(char *));
+ room = SOME;
+ next = optind;
+
+ newargv[next] = NULL;
+ wa.pending = NULL;
+ while ((p = getanarg(f, &wa, &newargv[next])) == NULL) {
+ if (room == 0) {
+ newargc += SOME;
+ tmp = realloc(newargv, (newargc+1) * sizeof(char *));
+ if (tmp == NULL) {
+ p = "out of space for new argv";
+ break; /* NOTE BREAK OUT */
+ }
+ newargv = tmp;
+ room += SOME;
+ }
+ next++;
+ room--;
+ }
+ if (p != NULL && !feof(f)) { /* error of some kind */
+ for (i = optind+1; i <= next; i++)
+ if (newargv[i] != NULL)
+ free(newargv[i]);
+ free(newargv);
+ fclose(f);
+ return p;
+ }
+
+ fclose(f);
+ memcpy(newargv + next, *argvp + optind,
+ (*argcp+1-optind) * sizeof(char *));
+ *argcp += next - optind;
+ *argvp = newargv;
+ return NULL;
+}
+
+/*
+ - getanarg - get a malloced argument from the file
+ */
+static const char * /* NULL for success, else string literal */
+getanarg(f, w, linep)
+FILE *f;
+struct work *w;
+char **linep; /* where to store pointer if successful */
+{
+ size_t len;
+ char *p;
+ char *endp;
+
+ while (w->pending == NULL) { /* no pending line */
+ if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL)
+ return "error in line read"; /* caller checks EOF */
+ if (w->line[0] != '#' &&
+ *(w->line + strspn(w->line, " \t")) != '\0')
+ w->pending = w->line;
+ }
+
+ if (w->pending == w->line && w->line[0] != '-') {
+ /* fresh plain line */
+ w->pending = NULL;
+ p = w->line;
+ endp = p + strlen(p);
+ if (*p == '"' && endp > p+1 && *(endp-1) == '"') {
+ p++;
+ endp--;
+ *endp = '\0';
+ }
+ if (w->line == w->buf) {
+ *linep = malloc(endp - p + 1);
+ if (*linep == NULL)
+ return "out of memory for new line";
+ strcpy(*linep, p);
+ } else /* getline already malloced it */
+ *linep = p;
+ return NULL;
+ }
+
+ /* chip off a piece of a pending line */
+ p = w->pending;
+ p += strspn(p, " \t");
+ endp = p + strcspn(p, " \t");
+ len = endp - p;
+ if (*endp != '\0') {
+ *endp++ = '\0';
+ endp += strspn(endp, " \t");
+ }
+ /* endp now points to next real character, or to line-end NUL */
+ *linep = malloc(len + 1);
+ if (*linep == NULL) {
+ if (w->line != w->buf)
+ free(w->line);
+ return "out of memory for new argument";
+ }
+ strcpy(*linep, p);
+ if (*endp == '\0') {
+ w->pending = NULL;
+ if (w->line != w->buf)
+ free(w->line);
+ } else
+ w->pending = endp;
+ return NULL;
+}
+
+/*
+ - getline - read a line from the file, trim newline off
+ */
+static char * /* pointer to line, NULL for eof/error */
+getline(f, buf, bufsize)
+FILE *f;
+char *buf; /* buffer to use, if convenient */
+size_t bufsize; /* size of buf */
+{
+ size_t len;
+
+ if (fgets(buf, bufsize, f) == NULL)
+ return NULL;
+ len = strlen(buf);
+
+ if (len < bufsize-1 || buf[bufsize-1] == '\n') {
+ /* it fit */
+ buf[len-1] = '\0';
+ return buf;
+ }
+
+ /* oh crud, buffer overflow */
+ /* for now, to hell with it */
+ return NULL;
+}
+
+
+
+#ifdef TEST
+
+#include <getopt.h>
+
+char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ...";
+struct option opts[] = {
+ "foo", 0, NULL, 'f',
+ "bar", 0, NULL, 'b',
+ "builtin", 0, NULL, 'B',
+ "optionsfrom", 1, NULL, '+',
+ "help", 0, NULL, 'h',
+ "version", 0, NULL, 'v',
+ 0, 0, NULL, 0,
+};
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ int opt;
+ extern char *optarg;
+ extern int optind;
+ int errflg = 0;
+ const char *p;
+ int i;
+ FILE *errs = NULL;
+
+ while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF)
+ switch (opt) {
+ case 'f':
+ case 'b':
+ break;
+ case 'B':
+ errs = stderr;
+ break;
+ case '+': /* optionsfrom */
+ p = optionsfrom(optarg, &argc, &argv, optind, errs);
+ if (p != NULL) {
+ fprintf(stderr, "%s: optionsfrom error: %s\n",
+ argv[0], p);
+ exit(1);
+ }
+ break;
+ case 'h': /* help */
+ printf("%s\n", usage);
+ exit(0);
+ break;
+ case 'v': /* version */
+ printf("1\n");
+ exit(0);
+ break;
+ case '?':
+ default:
+ errflg = 1;
+ break;
+ }
+ if (errflg) {
+ fprintf(stderr, "%s\n", usage);
+ exit(2);
+ }
+
+ for (i = 1; i < argc; i++)
+ printf("%d: `%s'\n", i, argv[i]);
+ exit(0);
+}
+
+
+#endif /* TEST */
diff --git a/src/libfreeswan/libfreeswan/pfkey_v2_build.c b/src/libfreeswan/libfreeswan/pfkey_v2_build.c
new file mode 100644
index 000000000..be58c552f
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/pfkey_v2_build.c
@@ -0,0 +1,1438 @@
+/*
+ * RFC2367 PF_KEYv2 Key management API message parser
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: pfkey_v2_build.c,v 1.4 2005/04/07 19:43:52 as Exp $
+ */
+
+/*
+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
+ */
+
+char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.4 2005/04/07 19:43:52 as Exp $";
+
+/*
+ * Some ugly stuff to allow consistent debugging code for use in the
+ * kernel and in user space
+*/
+
+#ifdef __KERNEL__
+
+# include <linux/kernel.h> /* for printk */
+
+# include "freeswan/ipsec_kversion.h" /* for malloc switch */
+# ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+# else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+# endif /* MALLOC_SLAB */
+# include <linux/errno.h> /* error codes */
+# include <linux/types.h> /* size_t */
+# include <linux/interrupt.h> /* mark_bh */
+
+# include <linux/netdevice.h> /* struct device, and other headers */
+# include <linux/etherdevice.h> /* eth_type_trans */
+# include <linux/ip.h> /* struct iphdr */
+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+# include <linux/ipv6.h> /* struct ipv6hdr */
+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+
+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
+# define FREE(obj) kfree(obj)
+# include <freeswan.h>
+#else /* __KERNEL__ */
+
+# include <sys/types.h>
+# include <linux/types.h>
+# include <linux/errno.h>
+# include <malloc.h>
+# include <string.h> /* memset */
+
+# include <freeswan.h>
+unsigned int pfkey_lib_debug = 0;
+
+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
+
+/* #define PLUTO */
+
+#define DEBUGGING(args...) if(pfkey_lib_debug) { \
+ if(pfkey_debug_func != NULL) { \
+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
+ } else { \
+ printf("pfkey_lib_debug:" args); \
+ } }
+# define MALLOC(size) malloc(size)
+# define FREE(obj) free(obj)
+#endif /* __KERNEL__ */
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#ifdef __KERNEL__
+
+#include "freeswan/radij.h" /* rd_nodes */
+#include "freeswan/ipsec_encap.h" /* sockaddr_encap */
+
+# define DEBUGGING(args...) \
+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
+#endif /* __KERNEL__ */
+
+#include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
+
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
+
+void
+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
+{
+ int i;
+
+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
+ extensions[i] = NULL;
+ }
+}
+
+void
+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
+{
+ int i;
+
+ if (!extensions) {
+ return;
+ }
+
+ if (extensions[0]) {
+ memset(extensions[0], 0, sizeof(struct sadb_msg));
+ FREE(extensions[0]);
+ extensions[0] = NULL;
+ }
+
+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
+ if(extensions[i]) {
+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
+ FREE(extensions[i]);
+ extensions[i] = NULL;
+ }
+ }
+}
+
+void
+pfkey_msg_free(struct sadb_msg **pfkey_msg)
+{
+ if (*pfkey_msg) {
+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
+ FREE(*pfkey_msg);
+ *pfkey_msg = NULL;
+ }
+}
+
+/* Default extension builders taken from the KLIPS code */
+
+int
+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
+ uint8_t msg_type,
+ uint8_t satype,
+ uint8_t msg_errno,
+ uint32_t seq,
+ uint32_t pid)
+{
+ int error = 0;
+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_msg_hdr_build:\n");
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
+ &pfkey_ext,
+ pfkey_ext,
+ *pfkey_ext);
+ /* sanity checks... */
+ if (pfkey_msg) {
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "why is pfkey_msg already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (!msg_type) {
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "msg type not set, must be non-zero..\n");
+ SENDERR(EINVAL);
+ }
+
+ if (msg_type > SADB_MAX) {
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "msg type too large:%d.\n",
+ msg_type);
+ SENDERR(EINVAL);
+ }
+
+ if (satype > SADB_SATYPE_MAX) {
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "satype %d > max %d\n",
+ satype, SADB_SATYPE_MAX);
+ SENDERR(EINVAL);
+ }
+
+ pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
+ *pfkey_ext = (struct sadb_ext*)pfkey_msg;
+
+ if (pfkey_msg == NULL) {
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
+
+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_msg->sadb_msg_type = msg_type;
+ pfkey_msg->sadb_msg_satype = satype;
+
+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
+ pfkey_msg->sadb_msg_errno = msg_errno;
+ pfkey_msg->sadb_msg_reserved = 0;
+ pfkey_msg->sadb_msg_seq = seq;
+ pfkey_msg->sadb_msg_pid = pid;
+ DEBUGGING(
+ "pfkey_msg_hdr_build: "
+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
+ &pfkey_ext,
+ pfkey_ext,
+ *pfkey_ext);
+errlab:
+ return error;
+}
+
+int
+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
+ uint16_t exttype,
+ uint32_t spi,
+ uint8_t replay_window,
+ uint8_t sa_state,
+ uint8_t auth,
+ uint8_t encrypt,
+ uint32_t flags,
+ uint32_t/*IPsecSAref_t*/ ref)
+{
+ int error = 0;
+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
+ ntohl(spi), /* in network order */
+ replay_window,
+ sa_state,
+ auth,
+ encrypt,
+ flags);
+ /* sanity checks... */
+ if (pfkey_sa) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "why is pfkey_sa already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (exttype != SADB_EXT_SA
+ && exttype != SADB_X_EXT_SA2) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "invalid exttype=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ if (replay_window > 64) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "replay window size: %d -- must be 0 <= size <= 64\n",
+ replay_window);
+ SENDERR(EINVAL);
+ }
+
+ if (auth > SADB_AALG_MAX) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "auth=%d > SADB_AALG_MAX=%d.\n",
+ auth,
+ SADB_AALG_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if (encrypt > SADB_EALG_MAX) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
+ encrypt,
+ SADB_EALG_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if (sa_state > SADB_SASTATE_MAX) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "sa_state=%d exceeds MAX=%d.\n",
+ sa_state,
+ SADB_SASTATE_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if (sa_state == SADB_SASTATE_DEAD) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "sa_state=%d is DEAD=%d is not allowed.\n",
+ sa_state,
+ SADB_SASTATE_DEAD);
+ SENDERR(EINVAL);
+ }
+
+ if ((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
+ ref,
+ IPSEC_SAREF_NULL,
+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
+ SENDERR(EINVAL);
+ }
+
+ pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
+ *pfkey_ext = (struct sadb_ext*)pfkey_sa;
+
+ if (pfkey_sa == NULL) {
+ DEBUGGING(
+ "pfkey_sa_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
+
+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
+ pfkey_sa->sadb_sa_exttype = exttype;
+ pfkey_sa->sadb_sa_spi = spi;
+ pfkey_sa->sadb_sa_replay = replay_window;
+ pfkey_sa->sadb_sa_state = sa_state;
+ pfkey_sa->sadb_sa_auth = auth;
+ pfkey_sa->sadb_sa_encrypt = encrypt;
+ pfkey_sa->sadb_sa_flags = flags;
+ pfkey_sa->sadb_x_sa_ref = ref;
+
+errlab:
+ return error;
+}
+
+int
+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
+ uint16_t exttype,
+ uint32_t spi,
+ uint8_t replay_window,
+ uint8_t sa_state,
+ uint8_t auth,
+ uint8_t encrypt,
+ uint32_t flags)
+{
+ return pfkey_sa_ref_build(pfkey_ext,
+ exttype,
+ spi,
+ replay_window,
+ sa_state,
+ auth,
+ encrypt,
+ flags,
+ IPSEC_SAREF_NULL);
+}
+
+int
+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
+ uint16_t exttype,
+ uint32_t allocations,
+ uint64_t bytes,
+ uint64_t addtime,
+ uint64_t usetime,
+ uint32_t packets)
+{
+ int error = 0;
+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_lifetime_build:\n");
+ /* sanity checks... */
+ if (pfkey_lifetime) {
+ DEBUGGING(
+ "pfkey_lifetime_build: "
+ "why is pfkey_lifetime already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (exttype != SADB_EXT_LIFETIME_CURRENT
+ && exttype != SADB_EXT_LIFETIME_HARD
+ && exttype != SADB_EXT_LIFETIME_SOFT) {
+ DEBUGGING(
+ "pfkey_lifetime_build: "
+ "invalid exttype=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
+ *pfkey_ext = (struct sadb_ext*)pfkey_lifetime;
+
+ if (pfkey_lifetime == NULL) {
+ DEBUGGING(
+ "pfkey_lifetime_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
+
+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
+
+errlab:
+ return error;
+}
+
+int
+pfkey_address_build(struct sadb_ext** pfkey_ext,
+ uint16_t exttype,
+ uint8_t proto,
+ uint8_t prefixlen,
+ struct sockaddr* address)
+{
+ int error = 0;
+ int saddr_len = 0;
+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_address_build: "
+ "exttype=%d proto=%d prefixlen=%d\n",
+ exttype,
+ proto,
+ prefixlen);
+ /* sanity checks... */
+ if (pfkey_address) {
+ DEBUGGING(
+ "pfkey_address_build: "
+ "why is pfkey_address already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (!address) {
+ DEBUGGING("pfkey_address_build: "
+ "address is NULL\n");
+ SENDERR(EINVAL);
+ }
+
+ switch(exttype) {
+ case SADB_EXT_ADDRESS_SRC:
+ case SADB_EXT_ADDRESS_DST:
+ case SADB_EXT_ADDRESS_PROXY:
+ case SADB_X_EXT_ADDRESS_DST2:
+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
+ case SADB_X_EXT_ADDRESS_DST_FLOW:
+ case SADB_X_EXT_ADDRESS_SRC_MASK:
+ case SADB_X_EXT_ADDRESS_DST_MASK:
+#ifdef NAT_TRAVERSAL
+ case SADB_X_EXT_NAT_T_OA:
+#endif
+ break;
+ default:
+ DEBUGGING(
+ "pfkey_address_build: "
+ "unrecognised ext_type=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ switch (address->sa_family) {
+ case AF_INET:
+ DEBUGGING(
+ "pfkey_address_build: "
+ "found address family AF_INET.\n");
+ saddr_len = sizeof(struct sockaddr_in);
+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
+ , ntohs(((struct sockaddr_in*)address)->sin_port));
+ break;
+ case AF_INET6:
+ DEBUGGING(
+ "pfkey_address_build: "
+ "found address family AF_INET6.\n");
+ saddr_len = sizeof(struct sockaddr_in6);
+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
+ break;
+ default:
+ DEBUGGING(
+ "pfkey_address_build: "
+ "address->sa_family=%d not supported.\n",
+ address->sa_family);
+ SENDERR(EPFNOSUPPORT);
+ }
+
+ DEBUGGING(
+ "pfkey_address_build: "
+ "found address=%s.\n",
+ ipaddr_txt);
+ if (prefixlen != 0) {
+ DEBUGGING(
+ "pfkey_address_build: "
+ "address prefixes not supported yet.\n");
+ SENDERR(EAFNOSUPPORT); /* not supported yet */
+ }
+
+ pfkey_address = (struct sadb_address*)
+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
+
+ if (pfkey_address == NULL) {
+ DEBUGGING(
+ "pfkey_lifetime_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_address,
+ 0,
+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
+ IPSEC_PFKEYv2_ALIGN));
+
+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
+ IPSEC_PFKEYv2_ALIGN);
+
+ pfkey_address->sadb_address_exttype = exttype;
+ pfkey_address->sadb_address_proto = proto;
+ pfkey_address->sadb_address_prefixlen = prefixlen;
+ pfkey_address->sadb_address_reserved = 0;
+
+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
+ address,
+ saddr_len);
+
+#if 0
+ for (i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
+ pfkey_address_s_ska.sin_zero[i] = 0;
+ }
+#endif
+ DEBUGGING(
+ "pfkey_address_build: "
+ "successful.\n");
+
+ errlab:
+ return error;
+}
+
+int
+pfkey_key_build(struct sadb_ext** pfkey_ext,
+ uint16_t exttype,
+ uint16_t key_bits,
+ char* key)
+{
+ int error = 0;
+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_key_build:\n");
+ /* sanity checks... */
+ if (pfkey_key) {
+ DEBUGGING(
+ "pfkey_key_build: "
+ "why is pfkey_key already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (!key_bits) {
+ DEBUGGING(
+ "pfkey_key_build: "
+ "key_bits is zero, it must be non-zero.\n");
+ SENDERR(EINVAL);
+ }
+
+ if ( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
+ DEBUGGING(
+ "pfkey_key_build: "
+ "unsupported extension type=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ pfkey_key = (struct sadb_key*)
+ MALLOC(sizeof(struct sadb_key) +
+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
+ *pfkey_ext = (struct sadb_ext*)pfkey_key;
+
+ if (pfkey_key == NULL) {
+ DEBUGGING(
+ "pfkey_key_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_key,
+ 0,
+ sizeof(struct sadb_key) +
+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
+
+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
+ 64);
+ pfkey_key->sadb_key_exttype = exttype;
+ pfkey_key->sadb_key_bits = key_bits;
+ pfkey_key->sadb_key_reserved = 0;
+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
+ key,
+ DIVUP(key_bits, 8));
+
+errlab:
+ return error;
+}
+
+int
+pfkey_ident_build(struct sadb_ext** pfkey_ext,
+ uint16_t exttype,
+ uint16_t ident_type,
+ uint64_t ident_id,
+ uint8_t ident_len,
+ char* ident_string)
+{
+ int error = 0;
+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
+
+ DEBUGGING(
+ "pfkey_ident_build:\n");
+ /* sanity checks... */
+ if (pfkey_ident) {
+ DEBUGGING(
+ "pfkey_ident_build: "
+ "why is pfkey_ident already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if ( !((exttype == SADB_EXT_IDENTITY_SRC) ||
+ (exttype == SADB_EXT_IDENTITY_DST))) {
+ DEBUGGING(
+ "pfkey_ident_build: "
+ "unsupported extension type=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ if (ident_type == SADB_IDENTTYPE_RESERVED) {
+ DEBUGGING(
+ "pfkey_ident_build: "
+ "ident_type must be non-zero.\n");
+ SENDERR(EINVAL);
+ }
+
+ if (ident_type > SADB_IDENTTYPE_MAX) {
+ DEBUGGING(
+ "pfkey_ident_build: "
+ "identtype=%d out of range.\n",
+ ident_type);
+ SENDERR(EINVAL);
+ }
+
+ if ((ident_type == SADB_IDENTTYPE_PREFIX ||
+ ident_type == SADB_IDENTTYPE_FQDN) &&
+ !ident_string) {
+ DEBUGGING(
+ "pfkey_ident_build: "
+ "string required to allocate size of extension.\n");
+ SENDERR(EINVAL);
+ }
+
+#if 0
+ if (ident_type == SADB_IDENTTYPE_USERFQDN) {
+ }
+#endif
+
+ pfkey_ident = (struct sadb_ident*)
+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
+ *pfkey_ext = (struct sadb_ext*)pfkey_ident;
+
+ if (pfkey_ident == NULL) {
+ DEBUGGING(
+ "pfkey_ident_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
+
+ pfkey_ident->sadb_ident_len = ident_len;
+ pfkey_ident->sadb_ident_exttype = exttype;
+ pfkey_ident->sadb_ident_type = ident_type;
+ pfkey_ident->sadb_ident_reserved = 0;
+ pfkey_ident->sadb_ident_id = ident_id;
+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
+ ident_string,
+ data_len);
+
+errlab:
+ return error;
+}
+
+int
+pfkey_sens_build(struct sadb_ext** pfkey_ext,
+ uint32_t dpd,
+ uint8_t sens_level,
+ uint8_t sens_len,
+ uint64_t* sens_bitmap,
+ uint8_t integ_level,
+ uint8_t integ_len,
+ uint64_t* integ_bitmap)
+{
+ int error = 0;
+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
+ int i;
+ uint64_t* bitmap;
+
+ DEBUGGING(
+ "pfkey_sens_build:\n");
+ /* sanity checks... */
+ if (pfkey_sens) {
+ DEBUGGING(
+ "pfkey_sens_build: "
+ "why is pfkey_sens already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(
+ "pfkey_sens_build: "
+ "Sorry, I can't build exttype=%d yet.\n",
+ (*pfkey_ext)->sadb_ext_type);
+ SENDERR(EINVAL); /* don't process these yet */
+
+ pfkey_sens = (struct sadb_sens*)
+ MALLOC(sizeof(struct sadb_sens) +
+ (sens_len + integ_len) * sizeof(uint64_t));
+ *pfkey_ext = (struct sadb_ext*)pfkey_sens;
+
+ if (pfkey_sens == NULL) {
+ DEBUGGING(
+ "pfkey_sens_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_sens,
+ 0,
+ sizeof(struct sadb_sens) +
+ (sens_len + integ_len) * sizeof(uint64_t));
+
+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
+ pfkey_sens->sadb_sens_dpd = dpd;
+ pfkey_sens->sadb_sens_sens_level = sens_level;
+ pfkey_sens->sadb_sens_sens_len = sens_len;
+ pfkey_sens->sadb_sens_integ_level = integ_level;
+ pfkey_sens->sadb_sens_integ_len = integ_len;
+ pfkey_sens->sadb_sens_reserved = 0;
+
+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
+ for (i = 0; i < sens_len; i++) {
+ *bitmap = sens_bitmap[i];
+ bitmap++;
+ }
+ for (i = 0; i < integ_len; i++) {
+ *bitmap = integ_bitmap[i];
+ bitmap++;
+ }
+
+errlab:
+ return error;
+}
+
+int
+pfkey_prop_build(struct sadb_ext** pfkey_ext,
+ uint8_t replay,
+ unsigned int comb_num,
+ struct sadb_comb* comb)
+{
+ int error = 0;
+ int i;
+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
+ struct sadb_comb *combp;
+
+ DEBUGGING(
+ "pfkey_prop_build:\n");
+ /* sanity checks... */
+ if (pfkey_prop) {
+ DEBUGGING(
+ "pfkey_prop_build: "
+ "why is pfkey_prop already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ pfkey_prop = (struct sadb_prop*)
+ MALLOC(sizeof(struct sadb_prop) +
+ comb_num * sizeof(struct sadb_comb));
+
+ *pfkey_ext = (struct sadb_ext*)pfkey_prop;
+
+ if (pfkey_prop == NULL) {
+ DEBUGGING(
+ "pfkey_prop_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_prop,
+ 0,
+ sizeof(struct sadb_prop) +
+ comb_num * sizeof(struct sadb_comb));
+
+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
+ pfkey_prop->sadb_prop_replay = replay;
+
+ for (i=0; i<3; i++) {
+ pfkey_prop->sadb_prop_reserved[i] = 0;
+ }
+
+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
+ for (i = 0; i < comb_num; i++) {
+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
+ combp++;
+ }
+
+#if 0
+ uint8_t sadb_comb_auth;
+ uint8_t sadb_comb_encrypt;
+ uint16_t sadb_comb_flags;
+ uint16_t sadb_comb_auth_minbits;
+ uint16_t sadb_comb_auth_maxbits;
+ uint16_t sadb_comb_encrypt_minbits;
+ uint16_t sadb_comb_encrypt_maxbits;
+ uint32_t sadb_comb_reserved;
+ uint32_t sadb_comb_soft_allocations;
+ uint32_t sadb_comb_hard_allocations;
+ uint64_t sadb_comb_soft_bytes;
+ uint64_t sadb_comb_hard_bytes;
+ uint64_t sadb_comb_soft_addtime;
+ uint64_t sadb_comb_hard_addtime;
+ uint64_t sadb_comb_soft_usetime;
+ uint64_t sadb_comb_hard_usetime;
+ uint32_t sadb_comb_soft_packets;
+ uint32_t sadb_comb_hard_packets;
+#endif
+errlab:
+ return error;
+}
+
+int
+pfkey_supported_build(struct sadb_ext** pfkey_ext,
+ uint16_t exttype,
+ unsigned int alg_num,
+ struct sadb_alg* alg)
+{
+ int error = 0;
+ unsigned int i;
+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
+ struct sadb_alg *pfkey_alg;
+
+ /* sanity checks... */
+ if (pfkey_supported) {
+ DEBUGGING(
+ "pfkey_supported_build: "
+ "why is pfkey_supported already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if ( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
+ DEBUGGING(
+ "pfkey_supported_build: "
+ "unsupported extension type=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ pfkey_supported = (struct sadb_supported*)
+ MALLOC(sizeof(struct sadb_supported) +
+ alg_num * sizeof(struct sadb_alg));
+
+ *pfkey_ext = (struct sadb_ext*)pfkey_supported;
+
+ if (pfkey_supported == NULL) {
+ DEBUGGING(
+ "pfkey_supported_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_supported,
+ 0,
+ sizeof(struct sadb_supported) +
+ alg_num *
+ sizeof(struct sadb_alg));
+
+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
+ alg_num *
+ sizeof(struct sadb_alg)) /
+ IPSEC_PFKEYv2_ALIGN;
+ pfkey_supported->sadb_supported_exttype = exttype;
+ pfkey_supported->sadb_supported_reserved = 0;
+
+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
+ for(i = 0; i < alg_num; i++) {
+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
+ pfkey_alg->sadb_alg_reserved = 0;
+ pfkey_alg++;
+ }
+
+#if 0
+ DEBUGGING(
+ "pfkey_supported_build: "
+ "Sorry, I can't build exttype=%d yet.\n",
+ (*pfkey_ext)->sadb_ext_type);
+ SENDERR(EINVAL); /* don't process these yet */
+
+ uint8_t sadb_alg_id;
+ uint8_t sadb_alg_ivlen;
+ uint16_t sadb_alg_minbits;
+ uint16_t sadb_alg_maxbits;
+ uint16_t sadb_alg_reserved;
+#endif
+errlab:
+ return error;
+}
+
+int
+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
+ uint16_t exttype,
+ uint32_t min, /* in network order */
+ uint32_t max) /* in network order */
+{
+ int error = 0;
+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
+
+ /* sanity checks... */
+ if (pfkey_spirange) {
+ DEBUGGING(
+ "pfkey_spirange_build: "
+ "why is pfkey_spirange already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (ntohl(max) < ntohl(min)) {
+ DEBUGGING(
+ "pfkey_spirange_build: "
+ "minspi=%08x must be < maxspi=%08x.\n",
+ ntohl(min),
+ ntohl(max));
+ SENDERR(EINVAL);
+ }
+
+ if (ntohl(min) <= 255) {
+ DEBUGGING(
+ "pfkey_spirange_build: "
+ "minspi=%08x must be > 255.\n",
+ ntohl(min));
+ SENDERR(EEXIST);
+ }
+
+ pfkey_spirange = (struct sadb_spirange*)
+ MALLOC(sizeof(struct sadb_spirange));
+ *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
+
+ if (pfkey_spirange == NULL) {
+ DEBUGGING(
+ "pfkey_spirange_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_spirange,
+ 0,
+ sizeof(struct sadb_spirange));
+
+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
+ pfkey_spirange->sadb_spirange_min = min;
+ pfkey_spirange->sadb_spirange_max = max;
+ pfkey_spirange->sadb_spirange_reserved = 0;
+ errlab:
+ return error;
+}
+
+int
+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
+{
+ int error = 0;
+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
+
+ /* sanity checks... */
+ if (pfkey_x_kmprivate) {
+ DEBUGGING(
+ "pfkey_x_kmprivate_build: "
+ "why is pfkey_x_kmprivate already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
+
+ DEBUGGING(
+ "pfkey_x_kmprivate_build: "
+ "Sorry, I can't build exttype=%d yet.\n",
+ (*pfkey_ext)->sadb_ext_type);
+ SENDERR(EINVAL); /* don't process these yet */
+
+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
+ MALLOC(sizeof(struct sadb_x_kmprivate));
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
+
+ if (pfkey_x_kmprivate == NULL) {
+ DEBUGGING(
+ "pfkey_x_kmprivate_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_x_kmprivate,
+ 0,
+ sizeof(struct sadb_x_kmprivate));
+
+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
+errlab:
+ return error;
+}
+
+int
+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
+ uint8_t satype)
+{
+ int error = 0;
+ int i;
+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_x_satype_build:\n");
+ /* sanity checks... */
+ if (pfkey_x_satype) {
+ DEBUGGING(
+ "pfkey_x_satype_build: "
+ "why is pfkey_x_satype already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ if (!satype) {
+ DEBUGGING(
+ "pfkey_x_satype_build: "
+ "SA type not set, must be non-zero.\n");
+ SENDERR(EINVAL);
+ }
+
+ if (satype > SADB_SATYPE_MAX) {
+ DEBUGGING(
+ "pfkey_x_satype_build: "
+ "satype %d > max %d\n",
+ satype, SADB_SATYPE_MAX);
+ SENDERR(EINVAL);
+ }
+
+ pfkey_x_satype = (struct sadb_x_satype*)
+ MALLOC(sizeof(struct sadb_x_satype));
+
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
+
+ if (pfkey_x_satype == NULL) {
+ DEBUGGING(
+ "pfkey_x_satype_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ memset(pfkey_x_satype,
+ 0,
+ sizeof(struct sadb_x_satype));
+
+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
+ pfkey_x_satype->sadb_x_satype_satype = satype;
+ for (i=0; i<3; i++) {
+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
+ }
+
+errlab:
+ return error;
+}
+
+int
+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
+ uint32_t tunnel,
+ uint32_t netlink,
+ uint32_t xform,
+ uint32_t eroute,
+ uint32_t spi,
+ uint32_t radij,
+ uint32_t esp,
+ uint32_t ah,
+ uint32_t rcv,
+ uint32_t pfkey,
+ uint32_t ipcomp,
+ uint32_t verbose)
+{
+ int error = 0;
+ int i;
+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_x_debug_build:\n");
+ /* sanity checks... */
+ if (pfkey_x_debug) {
+ DEBUGGING(
+ "pfkey_x_debug_build: "
+ "why is pfkey_x_debug already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(
+ "pfkey_x_debug_build: "
+ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
+
+ pfkey_x_debug = (struct sadb_x_debug*)
+ MALLOC(sizeof(struct sadb_x_debug));
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
+
+ if (pfkey_x_debug == NULL) {
+ DEBUGGING(
+ "pfkey_x_debug_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+#if 0
+ memset(pfkey_x_debug,
+ 0,
+ sizeof(struct sadb_x_debug));
+#endif
+
+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
+
+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
+ pfkey_x_debug->sadb_x_debug_xform = xform;
+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
+ pfkey_x_debug->sadb_x_debug_spi = spi;
+ pfkey_x_debug->sadb_x_debug_radij = radij;
+ pfkey_x_debug->sadb_x_debug_esp = esp;
+ pfkey_x_debug->sadb_x_debug_ah = ah;
+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
+
+ for (i=0; i<4; i++) {
+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
+ }
+
+errlab:
+ return error;
+}
+
+#ifdef NAT_TRAVERSAL
+int
+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
+ uint8_t type)
+{
+ int error = 0;
+ int i;
+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_x_nat_t_type_build:\n");
+ /* sanity checks... */
+ if (pfkey_x_nat_t_type) {
+ DEBUGGING(
+ "pfkey_x_nat_t_type_build: "
+ "why is pfkey_x_nat_t_type already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(
+ "pfkey_x_nat_t_type_build: "
+ "type=%d\n", type);
+
+ pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
+ MALLOC(sizeof(struct sadb_x_nat_t_type));
+
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
+ if (pfkey_x_nat_t_type == NULL) {
+ DEBUGGING(
+ "pfkey_x_nat_t_type_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
+ for (i=0; i<3; i++) {
+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
+ }
+
+errlab:
+ return error;
+}
+int
+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
+ uint16_t exttype,
+ uint16_t port)
+{
+ int error = 0;
+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
+
+ DEBUGGING(
+ "pfkey_x_nat_t_port_build:\n");
+ /* sanity checks... */
+ if (pfkey_x_nat_t_port) {
+ DEBUGGING(
+ "pfkey_x_nat_t_port_build: "
+ "why is pfkey_x_nat_t_port already pointing to something?\n");
+ SENDERR(EINVAL);
+ }
+
+ switch (exttype) {
+ case SADB_X_EXT_NAT_T_SPORT:
+ case SADB_X_EXT_NAT_T_DPORT:
+ break;
+ default:
+ DEBUGGING(
+ "pfkey_nat_t_port_build: "
+ "unrecognised ext_type=%d.\n",
+ exttype);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(
+ "pfkey_x_nat_t_port_build: "
+ "ext=%d, port=%d\n", exttype, port);
+
+ pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
+ MALLOC(sizeof(struct sadb_x_nat_t_port));
+ *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
+
+ if (pfkey_x_nat_t_port == NULL) {
+ DEBUGGING(
+ "pfkey_x_nat_t_port_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
+
+errlab:
+ return error;
+}
+#endif
+
+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
+ uint8_t protocol)
+{
+ int error = 0;
+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
+ DEBUGGING("pfkey_x_protocol_build: protocol=%u\n", protocol);
+ /* sanity checks... */
+ if (p != 0) {
+ DEBUGGING("pfkey_x_protocol_build: bogus protocol pointer\n");
+ SENDERR(EINVAL);
+ }
+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
+ DEBUGGING("pfkey_build: memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+ *pfkey_ext = (struct sadb_ext *)p;
+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+ p->sadb_protocol_proto = protocol;
+ p->sadb_protocol_flags = 0;
+ p->sadb_protocol_reserved2 = 0;
+ errlab:
+ return error;
+}
+
+
+#if I_DONT_THINK_THIS_WILL_BE_USEFUL
+int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
+ =
+{
+ NULL, /* pfkey_msg_build, */
+ pfkey_sa_build,
+ pfkey_lifetime_build,
+ pfkey_lifetime_build,
+ pfkey_lifetime_build,
+ pfkey_address_build,
+ pfkey_address_build,
+ pfkey_address_build,
+ pfkey_key_build,
+ pfkey_key_build,
+ pfkey_ident_build,
+ pfkey_ident_build,
+ pfkey_sens_build,
+ pfkey_prop_build,
+ pfkey_supported_build,
+ pfkey_supported_build,
+ pfkey_spirange_build,
+ pfkey_x_kmprivate_build,
+ pfkey_x_satype_build,
+ pfkey_sa_build,
+ pfkey_address_build,
+ pfkey_address_build,
+ pfkey_address_build,
+ pfkey_address_build,
+ pfkey_address_build,
+ pfkey_x_ext_debug_build
+};
+#endif
+
+int
+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
+{
+ int error = 0;
+ unsigned ext;
+ unsigned total_size;
+ struct sadb_ext *pfkey_ext;
+ int extensions_seen = 0;
+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
+
+ if (!extensions[0]) {
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "extensions[0] must be specified (struct sadb_msg).\n");
+ SENDERR(EINVAL);
+ }
+
+ total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
+ for (ext = 1; ext <= SADB_EXT_MAX; ext++) {
+ if(extensions[ext]) {
+ total_size += (extensions[ext])->sadb_ext_len;
+ }
+ }
+
+ if (!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) {
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "memory allocation failed\n");
+ SENDERR(ENOMEM);
+ }
+
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
+ *pfkey_msg,
+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
+ &(extensions[0]));
+ memcpy(*pfkey_msg,
+ extensions[0],
+ sizeof(struct sadb_msg));
+ (*pfkey_msg)->sadb_msg_len = total_size;
+ (*pfkey_msg)->sadb_msg_reserved = 0;
+ extensions_seen = 1 ;
+
+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
+
+ for (ext = 1; ext <= SADB_EXT_MAX; ext++) {
+ /* copy from extension[ext] to buffer */
+ if (extensions[ext]) {
+ /* Is this type of extension permitted for this type of message? */
+ if (!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
+ 1<<ext)) {
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
+ ext,
+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
+ 1<<ext);
+ SENDERR(EINVAL);
+ }
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "copying %lu bytes from extensions[%u]=0p%p to=0p%p\n",
+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
+ ext,
+ extensions[ext],
+ pfkey_ext);
+ memcpy(pfkey_ext,
+ extensions[ext],
+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
+ {
+ char *pfkey_ext_c = (char *)pfkey_ext;
+
+ pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
+ pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
+ }
+ /* Mark that we have seen this extension and remember the header location */
+ extensions_seen |= ( 1 << ext );
+ }
+ }
+
+ /* check required extensions */
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
+ extensions_seen,
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
+
+ if ((extensions_seen &
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "required extensions missing:%08x.\n",
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
+ (extensions_seen &
+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
+ SENDERR(EINVAL);
+ }
+
+ error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir);
+ if (error) {
+ DEBUGGING(
+ "pfkey_msg_build: "
+ "Trouble parsing newly built pfkey message, error=%d.\n",
+ error);
+ SENDERR(-error);
+ }
+
+errlab:
+
+ return error;
+}
diff --git a/src/libfreeswan/libfreeswan/pfkey_v2_debug.c b/src/libfreeswan/libfreeswan/pfkey_v2_debug.c
new file mode 100644
index 000000000..2f2ddd3b1
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/pfkey_v2_debug.c
@@ -0,0 +1,179 @@
+/*
+ * @(#) pfkey version 2 debugging messages
+ *
+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
+ * and Michael Richardson <mcr@freeswan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: pfkey_v2_debug.c,v 1.2 2004/03/22 21:53:18 as Exp $
+ *
+ */
+
+#ifdef __KERNEL__
+
+# include <linux/kernel.h> /* for printk */
+
+# include "freeswan/ipsec_kversion.h" /* for malloc switch */
+# ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+# else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+# endif /* MALLOC_SLAB */
+# include <linux/errno.h> /* error codes */
+# include <linux/types.h> /* size_t */
+# include <linux/interrupt.h> /* mark_bh */
+
+# include <linux/netdevice.h> /* struct device, and other headers */
+# include <linux/etherdevice.h> /* eth_type_trans */
+extern int debug_pfkey;
+
+#else /* __KERNEL__ */
+
+# include <sys/types.h>
+# include <linux/types.h>
+# include <linux/errno.h>
+
+#endif /* __KERNEL__ */
+
+#include "freeswan.h"
+#include "pfkeyv2.h"
+#include "pfkey.h"
+
+/*
+ * This file provides ASCII translations of PF_KEY magic numbers.
+ *
+ */
+
+static char *pfkey_sadb_ext_strings[]={
+ "reserved", /* SADB_EXT_RESERVED 0 */
+ "security-association", /* SADB_EXT_SA 1 */
+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
+ "proposal", /* SADB_EXT_PROPOSAL 13 */
+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
+ "X-security-association", /* SADB_X_EXT_SA2 19 */
+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
+#ifdef NAT_TRAVERSAL
+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
+#endif
+};
+
+const char *
+pfkey_v2_sadb_ext_string(int ext)
+{
+ if(ext <= SADB_EXT_MAX) {
+ return pfkey_sadb_ext_strings[ext];
+ } else {
+ return "unknown-ext";
+ }
+}
+
+
+static char *pfkey_sadb_type_strings[]={
+ "reserved", /* SADB_RESERVED */
+ "getspi", /* SADB_GETSPI */
+ "update", /* SADB_UPDATE */
+ "add", /* SADB_ADD */
+ "delete", /* SADB_DELETE */
+ "get", /* SADB_GET */
+ "acquire", /* SADB_ACQUIRE */
+ "register", /* SADB_REGISTER */
+ "expire", /* SADB_EXPIRE */
+ "flush", /* SADB_FLUSH */
+ "dump", /* SADB_DUMP */
+ "x-promisc", /* SADB_X_PROMISC */
+ "x-pchange", /* SADB_X_PCHANGE */
+ "x-groupsa", /* SADB_X_GRPSA */
+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
+ "x-debug", /* SADB_X_DEBUG */
+};
+
+const char *
+pfkey_v2_sadb_type_string(int sadb_type)
+{
+ if(sadb_type <= SADB_MAX) {
+ return pfkey_sadb_type_strings[sadb_type];
+ } else {
+ return "unknown-sadb-type";
+ }
+}
+
+
+
+
+/*
+ * $Log: pfkey_v2_debug.c,v $
+ * Revision 1.2 2004/03/22 21:53:18 as
+ * merged alg-0.8.1 branch with HEAD
+ *
+ * Revision 1.1.2.1 2004/03/15 22:30:06 as
+ * nat-0.6c patch merged
+ *
+ * Revision 1.1 2004/03/15 20:35:26 as
+ * added files from freeswan-2.04-x509-1.5.3
+ *
+ * Revision 1.7 2002/09/20 05:01:26 rgb
+ * Fixed limit inclusion error in both type and ext string conversion.
+ *
+ * Revision 1.6 2002/04/24 07:55:32 mcr
+ * #include patches and Makefiles for post-reorg compilation.
+ *
+ * Revision 1.5 2002/04/24 07:36:40 mcr
+ * Moved from ./lib/pfkey_v2_debug.c,v
+ *
+ * Revision 1.4 2002/01/29 22:25:36 rgb
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
+ *
+ * Revision 1.3 2002/01/29 01:59:09 mcr
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
+ * updating of IPv6 structures to match latest in6.h version.
+ * removed dead code from freeswan.h that also duplicated kversions.h
+ * code.
+ *
+ * Revision 1.2 2002/01/20 20:34:50 mcr
+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
+ *
+ * Revision 1.1 2001/11/27 05:30:06 mcr
+ * initial set of debug strings for pfkey debugging.
+ * this will eventually only be included for debug builds.
+ *
+ * Revision 1.1 2001/09/21 04:12:03 mcr
+ * first compilable version.
+ *
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff --git a/src/libfreeswan/libfreeswan/pfkey_v2_ext_bits.c b/src/libfreeswan/libfreeswan/pfkey_v2_ext_bits.c
new file mode 100644
index 000000000..fe3f45306
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/pfkey_v2_ext_bits.c
@@ -0,0 +1,803 @@
+/*
+ * RFC2367 PF_KEYv2 Key management API message parser
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: pfkey_v2_ext_bits.c,v 1.2 2004/03/22 21:53:18 as Exp $
+ */
+
+/*
+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
+ */
+
+char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.2 2004/03/22 21:53:18 as Exp $";
+
+/*
+ * Some ugly stuff to allow consistent debugging code for use in the
+ * kernel and in user space
+*/
+
+#ifdef __KERNEL__
+
+# include <linux/kernel.h> /* for printk */
+
+# include "freeswan/ipsec_kversion.h" /* for malloc switch */
+# ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+# else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+# endif /* MALLOC_SLAB */
+# include <linux/errno.h> /* error codes */
+# include <linux/types.h> /* size_t */
+# include <linux/interrupt.h> /* mark_bh */
+
+# include <linux/netdevice.h> /* struct device, and other headers */
+# include <linux/etherdevice.h> /* eth_type_trans */
+# include <linux/ip.h> /* struct iphdr */
+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+# include <linux/ipv6.h>
+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+
+#else /* __KERNEL__ */
+
+# include <sys/types.h>
+# include <linux/types.h>
+# include <linux/errno.h>
+#endif
+
+#include <freeswan.h>
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = {
+
+/* INBOUND EXTENSIONS */
+{
+
+/* PERMITTED IN */
+{
+/* SADB_RESERVED */
+0
+,
+/* SADB_GETSPI */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_SPIRANGE
+,
+/* SADB_UPDATE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+#ifdef NAT_TRAVERSAL
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+#endif
+,
+/* SADB_ADD */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+#ifdef NAT_TRAVERSAL
+| 1<<SADB_X_EXT_NAT_T_TYPE
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+| 1<<SADB_X_EXT_NAT_T_OA
+#endif
+,
+/* SADB_DELETE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_GET */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_ACQUIRE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+,
+/* SADB_REGISTER */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_EXPIRE */
+0
+,
+/* SADB_FLUSH */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_DUMP */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_X_PROMISC */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_PCHANGE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_GRPSA */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_ADDFLOW */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_X_EXT_PROTOCOL
+,
+/* SADB_X_DELFLOW */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_X_EXT_PROTOCOL
+,
+/* SADB_X_DEBUG */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_X_EXT_DEBUG
+#ifdef NAT_TRAVERSAL
+,
+/* SADB_X_NAT_T_NEW_MAPPING */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+#endif
+},
+
+/* REQUIRED IN */
+{
+/* SADB_RESERVED */
+0
+,
+/* SADB_GETSPI */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_SPIRANGE
+,
+/* SADB_UPDATE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+/*| 1<<SADB_EXT_KEY_AUTH*/
+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
+,
+/* SADB_ADD */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+/*| 1<<SADB_EXT_KEY_AUTH*/
+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
+,
+/* SADB_DELETE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_GET */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_ACQUIRE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_PROPOSAL
+,
+/* SADB_REGISTER */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_EXPIRE */
+0
+,
+/* SADB_FLUSH */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_DUMP */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_X_PROMISC */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_PCHANGE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_GRPSA */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_DST
+/*| 1<<SADB_X_EXT_SATYPE2*/
+/*| 1<<SADB_X_EXT_SA2*/
+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
+,
+/* SADB_X_ADDFLOW */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+,
+/* SADB_X_DELFLOW */
+1<<SADB_EXT_RESERVED
+/*| 1<<SADB_EXT_SA*/
+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+#endif
+,
+/* SADB_X_DEBUG */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_X_EXT_DEBUG
+#ifdef NAT_TRAVERSAL
+,
+/* SADB_X_NAT_T_NEW_MAPPING */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+#endif
+}
+
+},
+
+/* OUTBOUND EXTENSIONS */
+{
+
+/* PERMITTED OUT */
+{
+/* SADB_RESERVED */
+0
+,
+/* SADB_GETSPI */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_UPDATE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+,
+/* SADB_ADD */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+#ifdef NAT_TRAVERSAL
+| 1<<SADB_X_EXT_NAT_T_TYPE
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+| 1<<SADB_X_EXT_NAT_T_OA
+#endif
+,
+/* SADB_DELETE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_GET */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+,
+/* SADB_ACQUIRE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+,
+/* SADB_REGISTER */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+,
+/* SADB_EXPIRE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_FLUSH */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_DUMP */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+,
+/* SADB_X_PROMISC */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_PCHANGE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_GRPSA */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_ADDFLOW */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+| 1<<SADB_X_EXT_PROTOCOL
+,
+/* SADB_X_DELFLOW */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+| 1<<SADB_X_EXT_PROTOCOL
+,
+/* SADB_X_DEBUG */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_X_EXT_DEBUG
+#ifdef NAT_TRAVERSAL
+,
+/* SADB_X_NAT_T_NEW_MAPPING */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+#endif
+},
+
+/* REQUIRED OUT */
+{
+/* SADB_RESERVED */
+0
+,
+/* SADB_GETSPI */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_UPDATE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_ADD */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_DELETE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_GET */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+/* | 1<<SADB_EXT_KEY_AUTH */
+/* | 1<<SADB_EXT_KEY_ENCRYPT */
+,
+/* SADB_ACQUIRE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_PROPOSAL
+,
+/* SADB_REGISTER */
+1<<SADB_EXT_RESERVED
+/* | 1<<SADB_EXT_SUPPORTED_AUTH
+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
+,
+/* SADB_EXPIRE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+/* | 1<<SADB_EXT_LIFETIME_HARD
+ | 1<<SADB_EXT_LIFETIME_SOFT */
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_FLUSH */
+1<<SADB_EXT_RESERVED
+,
+/* SADB_DUMP */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+,
+/* SADB_X_PROMISC */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_PCHANGE */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_LIFETIME_CURRENT
+| 1<<SADB_EXT_LIFETIME_HARD
+| 1<<SADB_EXT_LIFETIME_SOFT
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_EXT_ADDRESS_PROXY
+| 1<<SADB_EXT_KEY_AUTH
+| 1<<SADB_EXT_KEY_ENCRYPT
+| 1<<SADB_EXT_IDENTITY_SRC
+| 1<<SADB_EXT_IDENTITY_DST
+| 1<<SADB_EXT_SENSITIVITY
+| 1<<SADB_EXT_PROPOSAL
+| 1<<SADB_EXT_SUPPORTED_AUTH
+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
+| 1<<SADB_EXT_SPIRANGE
+| 1<<SADB_X_EXT_KMPRIVATE
+| 1<<SADB_X_EXT_SATYPE2
+| 1<<SADB_X_EXT_SA2
+| 1<<SADB_X_EXT_ADDRESS_DST2
+,
+/* SADB_X_GRPSA */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_DST
+,
+/* SADB_X_ADDFLOW */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+,
+/* SADB_X_DELFLOW */
+1<<SADB_EXT_RESERVED
+/*| 1<<SADB_EXT_SA*/
+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
+,
+/* SADB_X_DEBUG */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_X_EXT_DEBUG
+#ifdef NAT_TRAVERSAL
+,
+/* SADB_X_NAT_T_NEW_MAPPING */
+1<<SADB_EXT_RESERVED
+| 1<<SADB_EXT_SA
+| 1<<SADB_EXT_ADDRESS_SRC
+| 1<<SADB_EXT_ADDRESS_DST
+| 1<<SADB_X_EXT_NAT_T_SPORT
+| 1<<SADB_X_EXT_NAT_T_DPORT
+#endif
+}
+}
+};
+
+/*
+ * $Log: pfkey_v2_ext_bits.c,v $
+ * Revision 1.2 2004/03/22 21:53:18 as
+ * merged alg-0.8.1 branch with HEAD
+ *
+ * Revision 1.1.2.1 2004/03/15 22:30:06 as
+ * nat-0.6c patch merged
+ *
+ * Revision 1.1 2004/03/15 20:35:26 as
+ * added files from freeswan-2.04-x509-1.5.3
+ *
+ * Revision 1.15 2002/04/24 07:55:32 mcr
+ * #include patches and Makefiles for post-reorg compilation.
+ *
+ * Revision 1.14 2002/04/24 07:36:40 mcr
+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
+ *
+ * Revision 1.13 2002/01/29 22:25:36 rgb
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
+ *
+ * Revision 1.12 2002/01/29 01:59:10 mcr
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
+ * updating of IPv6 structures to match latest in6.h version.
+ * removed dead code from freeswan.h that also duplicated kversions.h
+ * code.
+ *
+ * Revision 1.11 2001/10/18 04:45:24 rgb
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
+ * lib/freeswan.h version macros moved to lib/kversions.h.
+ * Other compiler directive cleanups.
+ *
+ * Revision 1.10 2001/09/08 21:13:35 rgb
+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
+ *
+ * Revision 1.9 2001/06/14 19:35:16 rgb
+ * Update copyright date.
+ *
+ * Revision 1.8 2001/03/26 23:07:36 rgb
+ * Remove requirement for auth and enc key from UPDATE.
+ *
+ * Revision 1.7 2000/09/12 22:35:37 rgb
+ * Restructured to remove unused extensions from CLEARFLOW messages.
+ *
+ * Revision 1.6 2000/09/09 06:39:01 rgb
+ * Added comments for clarity.
+ *
+ * Revision 1.5 2000/06/02 22:54:14 rgb
+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
+ *
+ * Revision 1.4 2000/01/21 06:27:56 rgb
+ * Added address cases for eroute flows.
+ * Added comments for each message type.
+ * Added klipsdebug switching capability.
+ * Fixed GRPSA bitfields.
+ *
+ * Revision 1.3 1999/12/01 22:20:27 rgb
+ * Remove requirement for a proxy address in an incoming getspi message.
+ *
+ * Revision 1.2 1999/11/27 11:57:06 rgb
+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
+ * Add CVS log entry to bottom of file.
+ * Cleaned out unused bits.
+ *
+ */
diff --git a/src/libfreeswan/libfreeswan/pfkey_v2_parse.c b/src/libfreeswan/libfreeswan/pfkey_v2_parse.c
new file mode 100644
index 000000000..5d1f5a3d8
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/pfkey_v2_parse.c
@@ -0,0 +1,1832 @@
+/*
+ * RFC2367 PF_KEYv2 Key management API message parser
+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: pfkey_v2_parse.c,v 1.4 2004/06/13 20:35:07 as Exp $
+ */
+
+/*
+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
+ */
+
+char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.4 2004/06/13 20:35:07 as Exp $";
+
+/*
+ * Some ugly stuff to allow consistent debugging code for use in the
+ * kernel and in user space
+*/
+
+#ifdef __KERNEL__
+
+# include <linux/kernel.h> /* for printk */
+
+#include "freeswan/ipsec_kversion.h" /* for malloc switch */
+
+# ifdef MALLOC_SLAB
+# include <linux/slab.h> /* kmalloc() */
+# else /* MALLOC_SLAB */
+# include <linux/malloc.h> /* kmalloc() */
+# endif /* MALLOC_SLAB */
+# include <linux/errno.h> /* error codes */
+# include <linux/types.h> /* size_t */
+# include <linux/interrupt.h> /* mark_bh */
+
+# include <linux/netdevice.h> /* struct device, and other headers */
+# include <linux/etherdevice.h> /* eth_type_trans */
+# include <linux/ip.h> /* struct iphdr */
+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+# include <linux/ipv6.h> /* struct ipv6hdr */
+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
+extern int debug_pfkey;
+
+# include <freeswan.h>
+
+#include "freeswan/ipsec_encap.h"
+
+#else /* __KERNEL__ */
+
+# include <sys/types.h>
+# include <linux/types.h>
+# include <linux/errno.h>
+
+# include <freeswan.h>
+# include "src/pluto/constants.h"
+# include "src/pluto/defs.h" /* for PRINTF_LIKE */
+# include "src/pluto/log.h" /* for debugging and DBG_log */
+
+/* #define PLUTO */
+
+# ifdef PLUTO
+# define DEBUGGING(level, args...) { DBG_log("pfkey_lib_debug:" args); }
+# else
+# define DEBUGGING(level, args...) if(pfkey_lib_debug & level) { printf("pfkey_lib_debug:" args); } else { ; }
+# endif
+
+#endif /* __KERNEL__ */
+
+
+#include <pfkeyv2.h>
+#include <pfkey.h>
+
+#ifdef __KERNEL__
+extern int sysctl_ipsec_debug_verbose;
+# define DEBUGGING(level, args...) \
+ KLIPS_PRINT( \
+ ((debug_pfkey & level & (PF_KEY_DEBUG_PARSE_STRUCT | PF_KEY_DEBUG_PARSE_PROBLEM)) \
+ || (sysctl_ipsec_debug_verbose && (debug_pfkey & level & PF_KEY_DEBUG_PARSE_FLOW))) \
+ , "klips_debug:" args)
+#endif /* __KERNEL__ */
+#include "freeswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
+
+
+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
+
+struct satype_tbl {
+ uint8_t proto;
+ uint8_t satype;
+ char* name;
+} static satype_tbl[] = {
+#ifdef __KERNEL__
+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
+#ifdef CONFIG_IPSEC_IPCOMP
+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
+#endif /* CONFIG_IPSEC_IPCOMP */
+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
+#else /* __KERNEL__ */
+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
+ { SA_AH, SADB_SATYPE_AH, "AH" },
+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
+#endif /* __KERNEL__ */
+ { 0, 0, "UNKNOWN" }
+};
+
+uint8_t
+satype2proto(uint8_t satype)
+{
+ int i =0;
+
+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
+ i++;
+ }
+ return satype_tbl[i].proto;
+}
+
+uint8_t
+proto2satype(uint8_t proto)
+{
+ int i = 0;
+
+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
+ i++;
+ }
+ return satype_tbl[i].satype;
+}
+
+char*
+satype2name(uint8_t satype)
+{
+ int i = 0;
+
+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
+ i++;
+ }
+ return satype_tbl[i].name;
+}
+
+char*
+proto2name(uint8_t proto)
+{
+ int i = 0;
+
+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
+ i++;
+ }
+ return satype_tbl[i].name;
+}
+
+/* Default extension parsers taken from the KLIPS code */
+
+DEBUG_NO_STATIC int
+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
+#if 0
+ struct sadb_sa sav2;
+#endif
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_sa_parse: entry\n");
+ /* sanity checks... */
+ if(!pfkey_sa) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "NULL pointer passed in.\n");
+ SENDERR(EINVAL);
+ }
+
+#if 0
+ /* check if this structure is short, and if so, fix it up.
+ * XXX this is NOT the way to do things.
+ */
+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
+
+ /* yes, so clear out a temporary structure, and copy first */
+ memset(&sav2, 0, sizeof(sav2));
+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
+ sav2.sadb_x_sa_ref=-1;
+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_sa = &sav2;
+ }
+#endif
+
+
+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
+ pfkey_sa->sadb_sa_len,
+ (int)sizeof(struct sadb_sa));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
+ pfkey_sa->sadb_sa_encrypt,
+ SADB_EALG_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
+ pfkey_sa->sadb_sa_auth,
+ SADB_AALG_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "state=%d exceeds MAX=%d.\n",
+ pfkey_sa->sadb_sa_state,
+ SADB_SASTATE_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "state=%d is DEAD=%d.\n",
+ pfkey_sa->sadb_sa_state,
+ SADB_SASTATE_DEAD);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_sa->sadb_sa_replay > 64) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "replay window size: %d -- must be 0 <= size <= 64\n",
+ pfkey_sa->sadb_sa_replay);
+ SENDERR(EINVAL);
+ }
+
+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
+ {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
+ pfkey_sa->sadb_sa_exttype,
+ SADB_EXT_SA,
+ SADB_X_EXT_SA2);
+ SENDERR(EINVAL);
+ }
+
+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sa_parse: "
+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
+ pfkey_sa->sadb_x_sa_ref,
+ IPSEC_SAREF_NULL,
+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_sa_parse: "
+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
+ pfkey_sa->sadb_sa_len,
+ pfkey_sa->sadb_sa_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
+ pfkey_sa->sadb_sa_replay,
+ pfkey_sa->sadb_sa_state,
+ pfkey_sa->sadb_sa_auth,
+ pfkey_sa->sadb_sa_encrypt,
+ pfkey_sa->sadb_sa_flags,
+ pfkey_sa->sadb_x_sa_ref);
+
+ errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_lifetime_parse:enter\n");
+ /* sanity checks... */
+ if(!pfkey_lifetime) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_lifetime_parse: "
+ "NULL pointer passed in.\n");
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_lifetime->sadb_lifetime_len !=
+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_lifetime_parse: "
+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
+ pfkey_lifetime->sadb_lifetime_len,
+ (int)sizeof(struct sadb_lifetime));
+ SENDERR(EINVAL);
+ }
+
+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_lifetime_parse: "
+ "unexpected ext_type=%d.\n",
+ pfkey_lifetime->sadb_lifetime_exttype);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_lifetime_parse: "
+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
+ pfkey_lifetime->sadb_lifetime_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
+ pfkey_lifetime->sadb_lifetime_allocations,
+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
+ pfkey_lifetime->sadb_x_lifetime_packets);
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_address_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ int saddr_len = 0;
+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
+ char ipaddr_txt[ADDRTOT_BUF];
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_address_parse:enter\n");
+ /* sanity checks... */
+ if(!pfkey_address) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "NULL pointer passed in.\n");
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_address->sadb_address_len <
+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
+ IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
+ pfkey_address->sadb_address_len,
+ (int)sizeof(struct sadb_address),
+ (int)sizeof(struct sockaddr));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_address->sadb_address_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "res=%d, must be zero.\n",
+ pfkey_address->sadb_address_reserved);
+ SENDERR(EINVAL);
+ }
+
+ switch(pfkey_address->sadb_address_exttype) {
+ case SADB_EXT_ADDRESS_SRC:
+ case SADB_EXT_ADDRESS_DST:
+ case SADB_EXT_ADDRESS_PROXY:
+ case SADB_X_EXT_ADDRESS_DST2:
+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
+ case SADB_X_EXT_ADDRESS_DST_FLOW:
+ case SADB_X_EXT_ADDRESS_SRC_MASK:
+ case SADB_X_EXT_ADDRESS_DST_MASK:
+#ifdef NAT_TRAVERSAL
+ case SADB_X_EXT_NAT_T_OA:
+#endif
+ break;
+ default:
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "unexpected ext_type=%d.\n",
+ pfkey_address->sadb_address_exttype);
+ SENDERR(EINVAL);
+ }
+
+ switch(s->sa_family) {
+ case AF_INET:
+ saddr_len = sizeof(struct sockaddr_in);
+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_address_parse: "
+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
+ pfkey_address->sadb_address_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
+ s->sa_family,
+ ipaddr_txt,
+ pfkey_address->sadb_address_proto,
+ ntohs(((struct sockaddr_in*)s)->sin_port));
+ break;
+ case AF_INET6:
+ saddr_len = sizeof(struct sockaddr_in6);
+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_address_parse: "
+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
+ pfkey_address->sadb_address_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
+ s->sa_family,
+ ipaddr_txt,
+ pfkey_address->sadb_address_proto,
+ ((struct sockaddr_in6*)s)->sin6_port);
+ break;
+ default:
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "s->sa_family=%d not supported.\n",
+ s->sa_family);
+ SENDERR(EPFNOSUPPORT);
+ }
+
+ if(pfkey_address->sadb_address_len !=
+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
+ pfkey_address->sadb_address_len,
+ (int)sizeof(struct sadb_address),
+ saddr_len);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_address->sadb_address_prefixlen != 0) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_address_parse: "
+ "address prefixes not supported yet.\n");
+ SENDERR(EAFNOSUPPORT); /* not supported yet */
+ }
+
+ /* XXX check if port!=0 */
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_address_parse: successful.\n");
+ errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_key_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_key_parse:enter\n");
+ /* sanity checks... */
+
+ if(!pfkey_key) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "NULL pointer passed in.\n");
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_key->sadb_key_len,
+ (int)sizeof(struct sadb_key));
+ SENDERR(EINVAL);
+ }
+
+ if(!pfkey_key->sadb_key_bits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "key length set to zero, must be non-zero.\n");
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_key->sadb_key_len !=
+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
+ PFKEYBITS)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "key length=%d does not agree with extension length=%d.\n",
+ pfkey_key->sadb_key_bits,
+ pfkey_key->sadb_key_len);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_key->sadb_key_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "res=%d, must be zero.\n",
+ pfkey_key->sadb_key_reserved);
+ SENDERR(EINVAL);
+ }
+
+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
+ pfkey_key->sadb_key_exttype);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_key_parse: "
+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
+ pfkey_key->sadb_key_len,
+ pfkey_key->sadb_key_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
+ pfkey_key->sadb_key_bits,
+ pfkey_key->sadb_key_reserved);
+
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
+
+ /* sanity checks... */
+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_ident_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_ident->sadb_ident_len,
+ (int)sizeof(struct sadb_ident));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_ident_parse: "
+ "ident_type=%d out of range, must be less than %d.\n",
+ pfkey_ident->sadb_ident_type,
+ SADB_IDENTTYPE_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_ident->sadb_ident_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_ident_parse: "
+ "res=%d, must be zero.\n",
+ pfkey_ident->sadb_ident_reserved);
+ SENDERR(EINVAL);
+ }
+
+ /* string terminator/padding must be zero */
+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_ident_parse: "
+ "string padding must be zero, last is 0x%02x.\n",
+ *((char*)pfkey_ident +
+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
+ SENDERR(EINVAL);
+ }
+ }
+
+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_key_parse: "
+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
+ pfkey_ident->sadb_ident_exttype);
+ SENDERR(EINVAL);
+ }
+
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
+
+ /* sanity checks... */
+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sens_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_sens->sadb_sens_len,
+ (int)sizeof(struct sadb_sens));
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_sens_parse: "
+ "Sorry, I can't parse exttype=%d yet.\n",
+ pfkey_ext->sadb_ext_type);
+#if 0
+ SENDERR(EINVAL); /* don't process these yet */
+#endif
+
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ int i, num_comb;
+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
+
+ /* sanity checks... */
+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
+ pfkey_prop->sadb_prop_len,
+ (int)sizeof(struct sadb_prop),
+ (int)sizeof(struct sadb_comb));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_prop->sadb_prop_replay > 64) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "replay window size: %d -- must be 0 <= size <= 64\n",
+ pfkey_prop->sadb_prop_replay);
+ SENDERR(EINVAL);
+ }
+
+ for(i=0; i<3; i++) {
+ if(pfkey_prop->sadb_prop_reserved[i]) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "res[%d]=%d, must be zero.\n",
+ i, pfkey_prop->sadb_prop_reserved[i]);
+ SENDERR(EINVAL);
+ }
+ }
+
+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
+
+ for(i = 0; i < num_comb; i++) {
+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
+ i,
+ pfkey_comb->sadb_comb_auth,
+ SADB_AALG_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_comb_auth) {
+ if(!pfkey_comb->sadb_comb_auth_minbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
+ i);
+ SENDERR(EINVAL);
+ }
+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
+ i);
+ SENDERR(EINVAL);
+ }
+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_auth_minbits,
+ pfkey_comb->sadb_comb_auth_maxbits);
+ SENDERR(EINVAL);
+ }
+ } else {
+ if(pfkey_comb->sadb_comb_auth_minbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_auth_minbits);
+ SENDERR(EINVAL);
+ }
+ if(pfkey_comb->sadb_comb_auth_maxbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_auth_maxbits);
+ SENDERR(EINVAL);
+ }
+ }
+
+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_comb_parse: "
+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
+ i,
+ pfkey_comb->sadb_comb_encrypt,
+ SADB_EALG_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_comb_encrypt) {
+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
+ i);
+ SENDERR(EINVAL);
+ }
+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
+ i);
+ SENDERR(EINVAL);
+ }
+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_encrypt_minbits,
+ pfkey_comb->sadb_comb_encrypt_maxbits);
+ SENDERR(EINVAL);
+ }
+ } else {
+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_encrypt_minbits);
+ SENDERR(EINVAL);
+ }
+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_encrypt_maxbits);
+ SENDERR(EINVAL);
+ }
+ }
+
+ /* XXX do sanity check on flags */
+
+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
+ i,
+ pfkey_comb->sadb_comb_soft_allocations,
+ pfkey_comb->sadb_comb_hard_allocations);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
+ i,
+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
+ i,
+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
+ i,
+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
+ i,
+ pfkey_comb->sadb_x_comb_soft_packets,
+ pfkey_comb->sadb_x_comb_hard_packets);
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_comb->sadb_comb_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_prop_parse: "
+ "comb[%d].res=%d, must be zero.\n",
+ i,
+ pfkey_comb->sadb_comb_reserved);
+ SENDERR(EINVAL);
+ }
+ pfkey_comb++;
+ }
+
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ unsigned int i, num_alg;
+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
+
+ /* sanity checks... */
+ if((pfkey_supported->sadb_supported_len <
+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_supported_parse: "
+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
+ pfkey_supported->sadb_supported_len,
+ (int)sizeof(struct sadb_supported),
+ (int)sizeof(struct sadb_alg));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_supported->sadb_supported_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_supported_parse: "
+ "res=%d, must be zero.\n",
+ pfkey_supported->sadb_supported_reserved);
+ SENDERR(EINVAL);
+ }
+
+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
+
+ for(i = 0; i < num_alg; i++) {
+ /* process algo description */
+ if(pfkey_alg->sadb_alg_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_supported_parse: "
+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
+ i,
+ pfkey_alg->sadb_alg_id,
+ pfkey_alg->sadb_alg_ivlen,
+ pfkey_alg->sadb_alg_minbits,
+ pfkey_alg->sadb_alg_maxbits,
+ pfkey_alg->sadb_alg_reserved);
+ SENDERR(EINVAL);
+ }
+
+ /* XXX can alg_id auth/enc be determined from info given?
+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
+ rgb, 2000-04-06 */
+
+ switch(pfkey_supported->sadb_supported_exttype) {
+ case SADB_EXT_SUPPORTED_AUTH:
+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_supported_parse: "
+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
+ i,
+ pfkey_alg->sadb_alg_id,
+ SADB_AALG_MAX);
+ SENDERR(EINVAL);
+ }
+ break;
+ case SADB_EXT_SUPPORTED_ENCRYPT:
+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_supported_parse: "
+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
+ i,
+ pfkey_alg->sadb_alg_id,
+ SADB_EALG_MAX);
+ SENDERR(EINVAL);
+ }
+ break;
+ default:
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_supported_parse: "
+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
+ i,
+ pfkey_alg->sadb_alg_id,
+ SADB_EALG_MAX);
+ SENDERR(EINVAL);
+ }
+ pfkey_alg++;
+ }
+
+ errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
+
+ /* sanity checks... */
+ if(pfkey_spirange->sadb_spirange_len !=
+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_spirange_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_spirange->sadb_spirange_len,
+ (int)sizeof(struct sadb_spirange));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_spirange->sadb_spirange_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_spirange_parse: "
+ "reserved=%d must be set to zero.\n",
+ pfkey_spirange->sadb_spirange_reserved);
+ SENDERR(EINVAL);
+ }
+
+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_spirange_parse: "
+ "minspi=%08x must be < maxspi=%08x.\n",
+ ntohl(pfkey_spirange->sadb_spirange_min),
+ ntohl(pfkey_spirange->sadb_spirange_max));
+ SENDERR(EINVAL);
+ }
+
+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_spirange_parse: "
+ "minspi=%08x must be > 255.\n",
+ ntohl(pfkey_spirange->sadb_spirange_min));
+ SENDERR(EEXIST);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_spirange_parse: "
+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
+ pfkey_spirange->sadb_spirange_len,
+ pfkey_spirange->sadb_spirange_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
+ pfkey_spirange->sadb_spirange_min,
+ pfkey_spirange->sadb_spirange_max,
+ pfkey_spirange->sadb_spirange_reserved);
+ errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
+
+ /* sanity checks... */
+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_kmprivate_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
+ (int)sizeof(struct sadb_x_kmprivate));
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_kmprivate_parse: "
+ "reserved=%d must be set to zero.\n",
+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_kmprivate_parse: "
+ "Sorry, I can't parse exttype=%d yet.\n",
+ pfkey_ext->sadb_ext_type);
+ SENDERR(EINVAL); /* don't process these yet */
+
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ int i;
+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_x_satype_parse: enter\n");
+ /* sanity checks... */
+ if(pfkey_x_satype->sadb_x_satype_len !=
+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_satype_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_x_satype->sadb_x_satype_len,
+ (int)sizeof(struct sadb_x_satype));
+ SENDERR(EINVAL);
+ }
+
+ if(!pfkey_x_satype->sadb_x_satype_satype) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_satype_parse: "
+ "satype is zero, must be non-zero.\n");
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_satype_parse: "
+ "satype %d > max %d, invalid.\n",
+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
+ SENDERR(EINVAL);
+ }
+
+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_satype_parse: "
+ "proto lookup from satype=%d failed.\n",
+ pfkey_x_satype->sadb_x_satype_satype);
+ SENDERR(EINVAL);
+ }
+
+ for(i = 0; i < 3; i++) {
+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_satype_parse: "
+ "reserved[%d]=%d must be set to zero.\n",
+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
+ SENDERR(EINVAL);
+ }
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_x_satype_parse: "
+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
+ pfkey_x_satype->sadb_x_satype_len,
+ pfkey_x_satype->sadb_x_satype_exttype,
+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
+ pfkey_x_satype->sadb_x_satype_satype,
+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
+ pfkey_x_satype->sadb_x_satype_reserved[0],
+ pfkey_x_satype->sadb_x_satype_reserved[1],
+ pfkey_x_satype->sadb_x_satype_reserved[2]);
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ int i;
+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_x_debug_parse: enter\n");
+ /* sanity checks... */
+ if(pfkey_x_debug->sadb_x_debug_len !=
+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_debug_parse: "
+ "size wrong ext_len=%d, key_ext_len=%d.\n",
+ pfkey_x_debug->sadb_x_debug_len,
+ (int)sizeof(struct sadb_x_debug));
+ SENDERR(EINVAL);
+ }
+
+ for(i = 0; i < 4; i++) {
+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_debug_parse: "
+ "reserved[%d]=%d must be set to zero.\n",
+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
+ SENDERR(EINVAL);
+ }
+ }
+
+errlab:
+ return error;
+}
+
+DEBUG_NO_STATIC int
+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
+{
+ int error = 0;
+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
+ /* sanity checks... */
+
+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
+ p->sadb_protocol_len, (int)sizeof(*p));
+ SENDERR(EINVAL);
+ }
+
+ if (p->sadb_protocol_reserved2 != 0) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_protocol_parse: res=%d, must be zero.\n",
+ p->sadb_protocol_reserved2);
+ SENDERR(EINVAL);
+ }
+
+ errlab:
+ return error;
+}
+
+#ifdef NAT_TRAVERSAL
+DEBUG_NO_STATIC int
+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
+{
+ return 0;
+}
+DEBUG_NO_STATIC int
+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
+{
+ return 0;
+}
+#endif
+
+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
+
+DEFINEPARSER(pfkey_sa_parse);
+DEFINEPARSER(pfkey_lifetime_parse);
+DEFINEPARSER(pfkey_address_parse);
+DEFINEPARSER(pfkey_key_parse);
+DEFINEPARSER(pfkey_ident_parse);
+DEFINEPARSER(pfkey_sens_parse);
+DEFINEPARSER(pfkey_prop_parse);
+DEFINEPARSER(pfkey_supported_parse);
+DEFINEPARSER(pfkey_spirange_parse);
+DEFINEPARSER(pfkey_x_kmprivate_parse);
+DEFINEPARSER(pfkey_x_satype_parse);
+DEFINEPARSER(pfkey_x_ext_debug_parse);
+DEFINEPARSER(pfkey_x_ext_protocol_parse);
+#ifdef NAT_TRAVERSAL
+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
+#endif
+
+struct pf_key_ext_parsers_def *ext_default_parsers[]=
+{
+ NULL, /* pfkey_msg_parse, */
+ &pfkey_sa_parse_def,
+ &pfkey_lifetime_parse_def,
+ &pfkey_lifetime_parse_def,
+ &pfkey_lifetime_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_key_parse_def,
+ &pfkey_key_parse_def,
+ &pfkey_ident_parse_def,
+ &pfkey_ident_parse_def,
+ &pfkey_sens_parse_def,
+ &pfkey_prop_parse_def,
+ &pfkey_supported_parse_def,
+ &pfkey_supported_parse_def,
+ &pfkey_spirange_parse_def,
+ &pfkey_x_kmprivate_parse_def,
+ &pfkey_x_satype_parse_def,
+ &pfkey_sa_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_address_parse_def,
+ &pfkey_x_ext_debug_parse_def,
+ &pfkey_x_ext_protocol_parse_def
+#ifdef NAT_TRAVERSAL
+ ,
+ &pfkey_x_ext_nat_t_type_parse_def,
+ &pfkey_x_ext_nat_t_port_parse_def,
+ &pfkey_x_ext_nat_t_port_parse_def,
+ &pfkey_address_parse_def
+#endif
+};
+
+int
+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
+ struct pf_key_ext_parsers_def *ext_parsers[],
+ struct sadb_ext *extensions[],
+ int dir)
+{
+ int error = 0;
+ int remain;
+ struct sadb_ext *pfkey_ext;
+ int extensions_seen = 0;
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_msg_parse: "
+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
+ pfkey_msg->sadb_msg_version,
+ pfkey_msg->sadb_msg_type,
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
+ pfkey_msg->sadb_msg_errno,
+ pfkey_msg->sadb_msg_satype,
+ satype2name(pfkey_msg->sadb_msg_satype),
+ pfkey_msg->sadb_msg_len,
+ pfkey_msg->sadb_msg_reserved,
+ pfkey_msg->sadb_msg_seq,
+ pfkey_msg->sadb_msg_pid);
+
+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
+
+ pfkey_extensions_init(extensions);
+
+ remain = pfkey_msg->sadb_msg_len;
+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
+
+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
+ sizeof(struct sadb_msg));
+
+ extensions[0] = (struct sadb_ext *) pfkey_msg;
+
+
+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
+ pfkey_msg->sadb_msg_version,
+ PF_KEY_V2);
+ SENDERR(EINVAL);
+ }
+
+ if(!pfkey_msg->sadb_msg_type) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "msg type not set, must be non-zero..\n");
+ SENDERR(EINVAL);
+ }
+
+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "msg type=%d > max=%d.\n",
+ pfkey_msg->sadb_msg_type,
+ SADB_MAX);
+ SENDERR(EINVAL);
+ }
+
+ switch(pfkey_msg->sadb_msg_type) {
+ case SADB_GETSPI:
+ case SADB_UPDATE:
+ case SADB_ADD:
+ case SADB_DELETE:
+ case SADB_GET:
+ case SADB_X_GRPSA:
+ case SADB_X_ADDFLOW:
+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
+ pfkey_msg->sadb_msg_satype,
+ pfkey_msg->sadb_msg_type,
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
+ SENDERR(EINVAL);
+ } else {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
+ pfkey_msg->sadb_msg_satype,
+ satype2name(pfkey_msg->sadb_msg_satype),
+ satype2proto(pfkey_msg->sadb_msg_satype),
+ pfkey_msg->sadb_msg_type,
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
+ }
+ case SADB_ACQUIRE:
+ case SADB_REGISTER:
+ case SADB_EXPIRE:
+ if(!pfkey_msg->sadb_msg_satype) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
+ pfkey_msg->sadb_msg_type,
+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
+ SENDERR(EINVAL);
+ }
+ default:
+ break;
+ }
+
+ /* errno must not be set in downward messages */
+ /* this is not entirely true... a response to an ACQUIRE could return an error */
+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "errno set to %d.\n",
+ pfkey_msg->sadb_msg_errno);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_msg_parse: "
+ "remain=%d, ext_type=%d(%s), ext_len=%d.\n",
+ remain,
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
+ pfkey_ext->sadb_ext_len);
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_msg_parse: "
+ "extensions permitted=%08x, required=%08x.\n",
+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
+
+ extensions_seen = 1;
+
+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
+ /* Is there enough message left to support another extension header? */
+ if(remain < pfkey_ext->sadb_ext_len) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "remain %d less than ext len %d.\n",
+ remain, pfkey_ext->sadb_ext_len);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_msg_parse: "
+ "parsing ext type=%d(%s) remain=%d.\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
+ remain);
+
+ /* Is the extension header type valid? */
+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
+ SADB_EXT_MAX);
+ SENDERR(EINVAL);
+ }
+
+ /* Have we already seen this type of extension? */
+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
+ {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "ext type %d(%s) already seen.\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
+ SENDERR(EINVAL);
+ }
+
+ /* Do I even know about this type of extension? */
+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "ext type %d(%s) unknown, ignoring.\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
+ goto next_ext;
+ }
+
+ /* Is this type of extension permitted for this type of message? */
+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
+ 1<<pfkey_ext->sadb_ext_type)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
+ 1<<pfkey_ext->sadb_ext_type);
+ SENDERR(EINVAL);
+ }
+
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_msg_parse: "
+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
+ remain,
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
+ pfkey_ext->sadb_ext_len,
+ pfkey_ext,
+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
+
+ /* Parse the extension */
+ if((error =
+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "extension parsing for type %d(%s) failed with error %d.\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
+ error);
+ SENDERR(-error);
+ }
+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
+ "pfkey_msg_parse: "
+ "Extension %d(%s) parsed.\n",
+ pfkey_ext->sadb_ext_type,
+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
+
+ /* Mark that we have seen this extension and remember the header location */
+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
+
+ next_ext:
+ /* Calculate how much message remains */
+ remain -= pfkey_ext->sadb_ext_len;
+
+ if(!remain) {
+ break;
+ }
+ /* Find the next extension header */
+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
+ }
+
+ if(remain) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "unexpected remainder of %d.\n",
+ remain);
+ /* why is there still something remaining? */
+ SENDERR(EINVAL);
+ }
+
+ /* check required extensions */
+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
+ "pfkey_msg_parse: "
+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
+ extensions_seen,
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
+
+ /* don't check further if it is an error return message since it
+ may not have a body */
+ if(pfkey_msg->sadb_msg_errno) {
+ SENDERR(-error);
+ }
+
+ if((extensions_seen &
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "required extensions missing:%08x.\n",
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
+ (extensions_seen &
+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
+ SENDERR(EINVAL);
+ }
+
+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
+ != SADB_X_EXT_ADDRESS_DELFLOW)
+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
+ & SADB_X_SAFLAGS_CLEARFLOW)
+ != SADB_X_SAFLAGS_CLEARFLOW))) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
+ SADB_X_EXT_ADDRESS_DELFLOW
+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
+ SENDERR(EINVAL);
+ }
+
+ switch(pfkey_msg->sadb_msg_type) {
+ case SADB_ADD:
+ case SADB_UPDATE:
+ /* check maturity */
+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
+ SADB_SASTATE_MATURE) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "state=%d for add or update should be MATURE=%d.\n",
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
+ SADB_SASTATE_MATURE);
+ SENDERR(EINVAL);
+ }
+
+ /* check AH and ESP */
+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
+ case SADB_SATYPE_AH:
+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
+ SADB_AALG_NONE)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "auth alg is zero, must be non-zero for AH SAs.\n");
+ SENDERR(EINVAL);
+ }
+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
+ SADB_EALG_NONE) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "AH handed encalg=%d, must be zero.\n",
+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
+ SENDERR(EINVAL);
+ }
+ break;
+ case SADB_SATYPE_ESP:
+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
+ SADB_EALG_NONE)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
+ SENDERR(EINVAL);
+ }
+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
+ SADB_EALG_NULL) &&
+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
+ SADB_AALG_NONE) ) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "ESP handed encNULL+authNONE, illegal combination.\n");
+ SENDERR(EINVAL);
+ }
+ break;
+ case SADB_X_SATYPE_COMP:
+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
+ SADB_EALG_NONE)) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
+ SENDERR(EINVAL);
+ }
+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
+ SADB_AALG_NONE) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "COMP handed auth=%d, must be zero.\n",
+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
+ SENDERR(EINVAL);
+ }
+ break;
+ default:
+ break;
+ }
+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
+ "pfkey_msg_parse: "
+ "spi=%08x must be > 255.\n",
+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
+ SENDERR(EINVAL);
+ }
+ default:
+ break;
+ }
+errlab:
+
+ return error;
+}
+
+/*
+ * $Log: pfkey_v2_parse.c,v $
+ * Revision 1.4 2004/06/13 20:35:07 as
+ * removed references to ipsec_netlink.h
+ *
+ * Revision 1.3 2004/03/30 10:00:17 as
+ * 64 bit issues
+ *
+ * Revision 1.2 2004/03/22 21:53:18 as
+ * merged alg-0.8.1 branch with HEAD
+ *
+ * Revision 1.1.2.1 2004/03/15 22:30:06 as
+ * nat-0.6c patch merged
+ *
+ * Revision 1.1 2004/03/15 20:35:26 as
+ * added files from freeswan-2.04-x509-1.5.3
+ *
+ * Revision 1.53 2003/01/30 02:32:09 rgb
+ *
+ * Rename SAref table macro names for clarity.
+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
+ *
+ * Revision 1.52 2002/12/30 06:53:07 mcr
+ * deal with short SA structures... #if 0 out for now. Probably
+ * not quite the right way.
+ *
+ * Revision 1.51 2002/12/13 18:16:02 mcr
+ * restored sa_ref code
+ *
+ * Revision 1.50 2002/12/13 18:06:52 mcr
+ * temporarily removed sadb_x_sa_ref reference for 2.xx
+ *
+ * Revision 1.49 2002/10/05 05:02:58 dhr
+ *
+ * C labels go on statements
+ *
+ * Revision 1.48 2002/09/20 15:40:45 rgb
+ * Added sadb_x_sa_ref to struct sadb_sa.
+ *
+ * Revision 1.47 2002/09/20 05:01:31 rgb
+ * Fixed usage of pfkey_lib_debug.
+ * Format for function declaration style consistency.
+ * Added text labels to elucidate numeric values presented.
+ * Re-organised debug output to reduce noise in output.
+ *
+ * Revision 1.46 2002/07/24 18:44:54 rgb
+ * Type fiddling to tame ia64 compiler.
+ *
+ * Revision 1.45 2002/05/23 07:14:11 rgb
+ * Cleaned up %p variants to 0p%p for test suite cleanup.
+ *
+ * Revision 1.44 2002/04/24 07:55:32 mcr
+ * #include patches and Makefiles for post-reorg compilation.
+ *
+ * Revision 1.43 2002/04/24 07:36:40 mcr
+ * Moved from ./lib/pfkey_v2_parse.c,v
+ *
+ * Revision 1.42 2002/01/29 22:25:36 rgb
+ * Re-add ipsec_kversion.h to keep MALLOC happy.
+ *
+ * Revision 1.41 2002/01/29 01:59:10 mcr
+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
+ * updating of IPv6 structures to match latest in6.h version.
+ * removed dead code from freeswan.h that also duplicated kversions.h
+ * code.
+ *
+ * Revision 1.40 2002/01/20 20:34:50 mcr
+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
+ *
+ * Revision 1.39 2001/11/27 05:29:22 mcr
+ * pfkey parses are now maintained by a structure
+ * that includes their name for debug purposes.
+ * DEBUGGING() macro changed so that it takes a debug
+ * level so that pf_key() can use this to decode the
+ * structures without innundanting humans.
+ * Also uses pfkey_v2_sadb_ext_string() in messages.
+ *
+ * Revision 1.38 2001/11/06 19:47:47 rgb
+ * Added packet parameter to lifetime and comb structures.
+ *
+ * Revision 1.37 2001/10/18 04:45:24 rgb
+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
+ * lib/freeswan.h version macros moved to lib/kversions.h.
+ * Other compiler directive cleanups.
+ *
+ * Revision 1.36 2001/06/14 19:35:16 rgb
+ * Update copyright date.
+ *
+ * Revision 1.35 2001/05/03 19:44:51 rgb
+ * Standardise on SENDERR() macro.
+ *
+ * Revision 1.34 2001/03/16 07:41:51 rgb
+ * Put freeswan.h include before pluto includes.
+ *
+ * Revision 1.33 2001/02/27 07:13:51 rgb
+ * Added satype2name() function.
+ * Added text to default satype_tbl entry.
+ * Added satype2name() conversions for most satype debug output.
+ *
+ * Revision 1.32 2001/02/26 20:01:09 rgb
+ * Added internal IP protocol 61 for magic SAs.
+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
+ * Re-formatted debug output (split lines, consistent spacing).
+ * Removed acquire, register and expire requirements for a known satype.
+ * Changed message type checking to a switch structure.
+ * Verify expected NULL auth for IPCOMP.
+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
+ * appropriate message types.
+ *
+ * Revision 1.31 2000/12/01 07:09:00 rgb
+ * Added ipcomp sanity check to require encalgo is set.
+ *
+ * Revision 1.30 2000/11/17 18:10:30 rgb
+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
+ * network byte order since this is the way PF_KEYv2 stored spis.
+ *
+ * Revision 1.29 2000/10/12 00:02:39 rgb
+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
+ *
+ * Revision 1.28 2000/09/20 16:23:04 rgb
+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
+ *
+ * Revision 1.27 2000/09/20 04:04:21 rgb
+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
+ * oopsen.
+ *
+ * Revision 1.26 2000/09/15 11:37:02 rgb
+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
+ * IPCOMP zlib deflate code.
+ *
+ * Revision 1.25 2000/09/12 22:35:37 rgb
+ * Restructured to remove unused extensions from CLEARFLOW messages.
+ *
+ * Revision 1.24 2000/09/12 18:59:54 rgb
+ * Added Gerhard's IPv6 support to pfkey parts of libfreeswan.
+ *
+ * Revision 1.23 2000/09/12 03:27:00 rgb
+ * Moved DEBUGGING definition to compile kernel with debug off.
+ *
+ * Revision 1.22 2000/09/09 06:39:27 rgb
+ * Restrict pfkey errno check to downward messages only.
+ *
+ * Revision 1.21 2000/09/08 19:22:34 rgb
+ * Enabled pfkey_sens_parse().
+ * Added check for errno on downward acquire messages only.
+ *
+ * Revision 1.20 2000/09/01 18:48:23 rgb
+ * Fixed reserved check bug and added debug output in
+ * pfkey_supported_parse().
+ * Fixed debug output label bug in pfkey_ident_parse().
+ *
+ * Revision 1.19 2000/08/27 01:55:26 rgb
+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
+ *
+ * Revision 1.18 2000/08/24 17:00:36 rgb
+ * Ignore unknown extensions instead of failing.
+ *
+ * Revision 1.17 2000/06/02 22:54:14 rgb
+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
+ *
+ * Revision 1.16 2000/05/10 19:25:11 rgb
+ * Fleshed out proposal and supported extensions.
+ *
+ * Revision 1.15 2000/01/24 21:15:31 rgb
+ * Added disabled pluto pfkey lib debug flag.
+ * Added algo debugging reporting.
+ *
+ * Revision 1.14 2000/01/22 23:24:29 rgb
+ * Added new functions proto2satype() and satype2proto() and lookup
+ * table satype_tbl. Also added proto2name() since it was easy.
+ *
+ * Revision 1.13 2000/01/21 09:43:59 rgb
+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
+ *
+ * Revision 1.12 2000/01/21 06:28:19 rgb
+ * Added address cases for eroute flows.
+ * Indented compiler directives for readability.
+ * Added klipsdebug switching capability.
+ *
+ * Revision 1.11 1999/12/29 21:14:59 rgb
+ * Fixed debug text cut and paste typo.
+ *
+ * Revision 1.10 1999/12/10 17:45:24 rgb
+ * Added address debugging.
+ *
+ * Revision 1.9 1999/12/09 23:11:42 rgb
+ * Ditched <string.h> include since we no longer use memset().
+ * Use new pfkey_extensions_init() instead of memset().
+ * Added check for SATYPE in pfkey_msg_build().
+ * Tidy up comments and debugging comments.
+ *
+ * Revision 1.8 1999/12/07 19:55:26 rgb
+ * Removed unused first argument from extension parsers.
+ * Removed static pluto debug flag.
+ * Moved message type and state checking to pfkey_msg_parse().
+ * Changed print[fk] type from lx to x to quiet compiler.
+ * Removed redundant remain check.
+ * Changed __u* types to uint* to avoid use of asm/types.h and
+ * sys/types.h in userspace code.
+ *
+ * Revision 1.7 1999/12/01 22:20:51 rgb
+ * Moved pfkey_lib_debug variable into the library.
+ * Added pfkey version check into header parsing.
+ * Added check for SATYPE only for those extensions that require a
+ * non-zero value.
+ *
+ * Revision 1.6 1999/11/27 11:58:05 rgb
+ * Added ipv6 headers.
+ * Moved sadb_satype2proto protocol lookup table from
+ * klips/net/ipsec/pfkey_v2_parser.c.
+ * Enable lifetime_current checking.
+ * Debugging error messages added.
+ * Add argument to pfkey_msg_parse() for direction.
+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
+ * Add CVS log entry to bottom of file.
+ * Moved auth and enc alg check to pfkey_msg_parse().
+ * Enable accidentally disabled spirange parsing.
+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
+ *
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ *
+ */
diff --git a/src/libfreeswan/libfreeswan/portof.3 b/src/libfreeswan/libfreeswan/portof.3
new file mode 100644
index 000000000..fac0d8bc3
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/portof.3
@@ -0,0 +1,70 @@
+.TH IPSEC_PORTOF 3 "8 Sept 2000"
+.\" RCSID $Id: portof.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec portof \- get port field of an ip_address
+.br
+ipsec setportof \- set port field of an ip_address
+.br
+ipsec sockaddrof \- get pointer to internal sockaddr of an ip_address
+.br
+ipsec sockaddrlenof \- get length of internal sockaddr of an ip_address
+.SH SYNOPSIS
+.B "#include <freeswan.h>"
+.sp
+.B "int portof(const ip_address *src);"
+.br
+.B "void setportof(int port, ip_address *dst);"
+.br
+.B "struct sockaddr *sockaddrof(ip_address *src);"
+.br
+.B "size_t sockaddrlenof(const ip_address *src);"
+.SH DESCRIPTION
+The
+.B <freeswan.h>
+internal type
+.I ip_address
+contains one of the
+.I sockaddr
+types internally.
+\fIReliance on this feature is discouraged\fR,
+but it may occasionally be necessary.
+These functions provide low-level tools for this purpose.
+.PP
+.I Portof
+and
+.I setportof
+respectively read and write the port-number field of the internal
+.IR sockaddr .
+The values are in network byte order.
+.PP
+.I Sockaddrof
+returns a pointer to the internal
+.IR sockaddr ,
+for passing to other functions.
+.PP
+.I Sockaddrlenof
+reports the size of the internal
+.IR sockaddr ,
+for use in storage allocation.
+.SH SEE ALSO
+inet(3), ipsec_initaddr(3)
+.SH DIAGNOSTICS
+.I Portof
+returns
+.BR \-1 ,
+.I sockaddrof
+returns
+.BR NULL ,
+and
+.I sockaddrlenof
+returns
+.B 0
+if an unknown address family is found within the
+.IR ip_address .
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+These functions all depend on low-level details of the
+.I ip_address
+type, which are in principle subject to change.
+Avoid using them unless really necessary.
diff --git a/src/libfreeswan/libfreeswan/portof.c b/src/libfreeswan/libfreeswan/portof.c
new file mode 100644
index 000000000..d028ea034
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/portof.c
@@ -0,0 +1,96 @@
+/*
+ * low-level ip_address ugliness
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: portof.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - portof - get the port field of an ip_address
+ */
+int /* network order */
+portof(src)
+const ip_address *src;
+{
+ switch (src->u.v4.sin_family) {
+ case AF_INET:
+ return src->u.v4.sin_port;
+ break;
+ case AF_INET6:
+ return src->u.v6.sin6_port;
+ break;
+ default:
+ return -1; /* "can't happen" */
+ break;
+ }
+}
+
+/*
+ - setportof - set the port field of an ip_address
+ */
+void
+setportof(port, dst)
+int port; /* network order */
+ip_address *dst;
+{
+ switch (dst->u.v4.sin_family) {
+ case AF_INET:
+ dst->u.v4.sin_port = port;
+ break;
+ case AF_INET6:
+ dst->u.v6.sin6_port = port;
+ break;
+ }
+}
+
+/*
+ - sockaddrof - get a pointer to the sockaddr hiding inside an ip_address
+ */
+struct sockaddr *
+sockaddrof(src)
+ip_address *src;
+{
+ switch (src->u.v4.sin_family) {
+ case AF_INET:
+ return (struct sockaddr *)&src->u.v4;
+ break;
+ case AF_INET6:
+ return (struct sockaddr *)&src->u.v6;
+ break;
+ default:
+ return NULL; /* "can't happen" */
+ break;
+ }
+}
+
+/*
+ - sockaddrlenof - get length of the sockaddr hiding inside an ip_address
+ */
+size_t /* 0 for error */
+sockaddrlenof(src)
+const ip_address *src;
+{
+ switch (src->u.v4.sin_family) {
+ case AF_INET:
+ return sizeof(src->u.v4);
+ break;
+ case AF_INET6:
+ return sizeof(src->u.v6);
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
diff --git a/src/libfreeswan/libfreeswan/prng.3 b/src/libfreeswan/libfreeswan/prng.3
new file mode 100644
index 000000000..51f19364f
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/prng.3
@@ -0,0 +1,121 @@
+.TH IPSEC_PRNG 3 "1 April 2002"
+.\" RCSID $Id: prng.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec prng_init \- initialize IPsec pseudorandom-number generator
+.br
+ipsec prng_bytes \- get bytes from IPsec pseudorandom-number generator
+.br
+ipsec prng_final \- close down IPsec pseudorandom-number generator
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "void prng_init(struct prng *prng,"
+.ti +1c
+.B "const unsigned char *key, size_t keylen);"
+.br
+.B "void prng_bytes(struct prng *prng, char *dst,"
+.ti +1c
+.B "size_t dstlen);"
+.br
+.B "unsigned long prng_count(struct prng *prng);"
+.br
+.B "void prng_final(struct prng *prng);"
+.SH DESCRIPTION
+.I Prng_init
+initializes a crypto-quality pseudo-random-number generator from a key;
+.I prng_bytes
+obtains pseudo-random bytes from it;
+.I prng_count
+reports the number of bytes extracted from it to date;
+.I prng_final
+closes it down.
+It is the user's responsibility to initialize a PRNG before using it,
+and not to use it again after it is closed down.
+.PP
+.I Prng_init
+initializes,
+or re-initializes,
+the specified
+.I prng
+from the
+.IR key ,
+whose length is given by
+.IR keylen .
+The user must allocate the
+.B "struct prng"
+pointed to by
+.IR prng .
+There is no particular constraint on the length of the key,
+although a key longer than 256 bytes is unnecessary because
+only the first 256 would be used.
+Initialization requires on the order of 3000 integer operations,
+independent of key length.
+.PP
+.I Prng_bytes
+obtains
+.I dstlen
+pseudo-random bytes from the PRNG and puts them in
+.IR buf .
+This is quite fast,
+on the order of 10 integer operations per byte.
+.PP
+.I Prng_count
+reports the number of bytes obtained from the PRNG
+since it was (last) initialized.
+.PP
+.I Prng_final
+closes down a PRNG by
+zeroing its internal memory,
+obliterating all trace of the state used to generate its previous output.
+This requires on the order of 250 integer operations.
+.PP
+The
+.B <freeswan.h>
+header file supplies the definition of the
+.B prng
+structure.
+Examination of its innards is discouraged, as they may change.
+.PP
+The PRNG algorithm
+used by these functions is currently identical to that of RC4(TM).
+This algorithm is cryptographically strong,
+sufficiently unpredictable that even a hostile observer will
+have difficulty determining the next byte of output from past history,
+provided it is initialized from a reasonably large key composed of
+highly random bytes (see
+.IR random (4)).
+The usual run of software pseudo-random-number generators
+(e.g.
+.IR random (3))
+are
+.I not
+cryptographically strong.
+.PP
+The well-known attacks against RC4(TM),
+e.g. as found in 802.11b's WEP encryption system,
+apply only if multiple PRNGs are initialized with closely-related keys
+(e.g., using a counter appended to a base key).
+If such keys are used, the first few hundred pseudo-random bytes
+from each PRNG should be discarded,
+to give the PRNGs a chance to randomize their innards properly.
+No useful attacks are known if the key is well randomized to begin with.
+.SH SEE ALSO
+random(3), random(4)
+.br
+Bruce Schneier,
+\fIApplied Cryptography\fR, 2nd ed., 1996, ISBN 0-471-11709-9,
+pp. 397-8.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+If an attempt is made to obtain more than 4e9 bytes
+between initializations,
+the PRNG will continue to work but
+.IR prng_count 's
+output will stick at
+.BR 4000000000 .
+Fixing this would require a longer integer type and does
+not seem worth the trouble,
+since you should probably re-initialize before then anyway...
+.PP
+``RC4'' is a trademark of RSA Data Security, Inc.
diff --git a/src/libfreeswan/libfreeswan/prng.c b/src/libfreeswan/libfreeswan/prng.c
new file mode 100644
index 000000000..e31836783
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/prng.c
@@ -0,0 +1,202 @@
+/*
+ * crypto-class pseudorandom number generator
+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
+ * Copyright (C) 2002 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: prng.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - prng_init - initialize PRNG from a key
+ */
+void
+prng_init(prng, key, keylen)
+struct prng *prng;
+const unsigned char *key;
+size_t keylen;
+{
+ unsigned char k[256];
+ int i, j;
+ unsigned const char *p;
+ unsigned const char *keyend = key + keylen;
+ unsigned char t;
+
+ for (i = 0; i <= 255; i++)
+ prng->sbox[i] = i;
+ p = key;
+ for (i = 0; i <= 255; i++) {
+ k[i] = *p++;
+ if (p >= keyend)
+ p = key;
+ }
+ j = 0;
+ for (i = 0; i <= 255; i++) {
+ j = (j + prng->sbox[i] + k[i]) & 0xff;
+ t = prng->sbox[i];
+ prng->sbox[i] = prng->sbox[j];
+ prng->sbox[j] = t;
+ k[i] = 0; /* clear out key memory */
+ }
+ prng->i = 0;
+ prng->j = 0;
+ prng->count = 0;
+}
+
+/*
+ - prng_bytes - get some pseudorandom bytes from PRNG
+ */
+void
+prng_bytes(prng, dst, dstlen)
+struct prng *prng;
+unsigned char *dst;
+size_t dstlen;
+{
+ int i, j, t;
+ unsigned char *p = dst;
+ size_t remain = dstlen;
+# define MAX 4000000000ul
+
+ while (remain > 0) {
+ i = (prng->i + 1) & 0xff;
+ prng->i = i;
+ j = (prng->j + prng->sbox[i]) & 0xff;
+ prng->j = j;
+ t = prng->sbox[i];
+ prng->sbox[i] = prng->sbox[j];
+ prng->sbox[j] = t;
+ t = (t + prng->sbox[i]) & 0xff;
+ *p++ = prng->sbox[t];
+ remain--;
+ }
+ if (prng->count < MAX - dstlen)
+ prng->count += dstlen;
+ else
+ prng->count = MAX;
+}
+
+/*
+ - prnt_count - how many bytes have been extracted from PRNG so far?
+ */
+unsigned long
+prng_count(prng)
+struct prng *prng;
+{
+ return prng->count;
+}
+
+/*
+ - prng_final - clear out PRNG to ensure nothing left in memory
+ */
+void
+prng_final(prng)
+struct prng *prng;
+{
+ int i;
+
+ for (i = 0; i <= 255; i++)
+ prng->sbox[i] = 0;
+ prng->i = 0;
+ prng->j = 0;
+ prng->count = 0; /* just for good measure */
+}
+
+
+
+#ifdef PRNG_MAIN
+
+#include <stdio.h>
+
+void regress();
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ struct prng pr;
+ unsigned char buf[100];
+ unsigned char *p;
+ size_t n;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ prng_init(&pr, argv[1], strlen(argv[1]));
+ prng_bytes(&pr, buf, 32);
+ printf("0x");
+ for (p = buf, n = 32; n > 0; p++, n--)
+ printf("%02x", *p);
+ printf("\n%lu bytes\n", prng_count(&pr));
+ prng_final(&pr);
+ exit(0);
+}
+
+void
+regress()
+{
+ struct prng pr;
+ unsigned char buf[100];
+ unsigned char *p;
+ size_t n;
+ /* somewhat non-random sample key */
+ unsigned char key[] = "here we go gathering nuts in May";
+ /* first thirty bytes of output from that key */
+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
+ int nzero, none;
+ int show = 0;
+
+ prng_init(&pr, key, strlen(key));
+ prng_bytes(&pr, buf, sizeof(buf));
+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
+ if (*p == 0)
+ nzero++;
+ if (*p == 255)
+ none++;
+ }
+ if (nzero > 3 || none > 3) {
+ fprintf(stderr, "suspiciously non-random output!\n");
+ show = 1;
+ }
+ if (memcmp(buf, good, strlen(good)) != 0) {
+ fprintf(stderr, "incorrect output!\n");
+ show = 1;
+ }
+ if (show) {
+ fprintf(stderr, "0x");
+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
+ fprintf(stderr, "%02x", *p);
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+ if (prng_count(&pr) != sizeof(buf)) {
+ fprintf(stderr, "got %u bytes, but count is %lu\n",
+ sizeof(buf), prng_count(&pr));
+ exit(1);
+ }
+ prng_final(&pr);
+ exit(0);
+}
+
+#endif /* PRNG_MAIN */
diff --git a/src/libfreeswan/libfreeswan/rangetoa.c b/src/libfreeswan/libfreeswan/rangetoa.c
new file mode 100644
index 000000000..e63b432f8
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/rangetoa.c
@@ -0,0 +1,61 @@
+/*
+ * convert binary form of address range to ASCII
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: rangetoa.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - rangetoa - convert address range to ASCII
+ */
+size_t /* space needed for full conversion */
+rangetoa(addrs, format, dst, dstlen)
+struct in_addr addrs[2];
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ size_t len;
+ size_t rest;
+ int n;
+ char *p;
+
+ switch (format) {
+ case 0:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ len = addrtoa(addrs[0], 0, dst, dstlen);
+ if (len < dstlen)
+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
+ p++, len++, n--)
+ *p = '.';
+ else
+ p = NULL;
+ if (len < dstlen)
+ rest = dstlen - len;
+ else {
+ if (dstlen > 0)
+ *(dst + dstlen - 1) = '\0';
+ rest = 0;
+ }
+
+ len += addrtoa(addrs[1], 0, p, rest);
+
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/rangetosubnet.3 b/src/libfreeswan/libfreeswan/rangetosubnet.3
new file mode 100644
index 000000000..7d707545e
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/rangetosubnet.3
@@ -0,0 +1,59 @@
+.TH IPSEC_RANGETOSUBNET 3 "8 Sept 2000"
+.\" RCSID $Id: rangetosubnet.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec rangetosubnet \- convert address range to subnet
+.SH SYNOPSIS
+.B "#include <freeswan.h>"
+.sp
+.B "const char *rangetosubnet(const ip_address *start,"
+.ti +1c
+.B "const ip_address *stop, ip_subnet *dst);"
+.SH DESCRIPTION
+.I Rangetosubnet
+accepts two IP addresses which define an address range,
+from
+.I start
+to
+.I stop
+inclusive,
+and converts this to a subnet if possible.
+The addresses must both be IPv4 or both be IPv6,
+and the address family of the resulting subnet is the same.
+.PP
+.I Rangetosubnet
+returns NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.SH SEE ALSO
+ipsec_initsubnet(3), ipsec_ttosubnet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I rangetosubnet
+are:
+mixed address families;
+unknown address family;
+.I start
+and
+.I stop
+do not define a subnet.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The restriction of error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = rangetosubnet( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/rangetosubnet.c b/src/libfreeswan/libfreeswan/rangetosubnet.c
new file mode 100644
index 000000000..048b10556
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/rangetosubnet.c
@@ -0,0 +1,226 @@
+/*
+ * express an address range as a subnet (if possible)
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: rangetosubnet.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - rangetosubnet - turn an address range into a subnet, if possible
+ *
+ * A range which is a valid subnet will have a network part which is the
+ * same in the from value and the to value, followed by a host part which
+ * is all 0 in the from value and all 1 in the to value.
+ */
+err_t
+rangetosubnet(from, to, dst)
+const ip_address *from;
+const ip_address *to;
+ip_subnet *dst;
+{
+ unsigned const char *fp;
+ unsigned const char *tp;
+ unsigned fb;
+ unsigned tb;
+ unsigned const char *f;
+ unsigned const char *t;
+ size_t n;
+ size_t n2;
+ int i;
+ int nnet;
+ unsigned m;
+
+ if (addrtypeof(from) != addrtypeof(to))
+ return "mismatched address types";
+ n = addrbytesptr(from, &fp);
+ if (n == 0)
+ return "unknown address type";
+ n2 = addrbytesptr(to, &tp);
+ if (n != n2)
+ return "internal size mismatch in rangetosubnet";
+
+ f = fp;
+ t = tp;
+ nnet = 0;
+ for (i = n; i > 0 && *f == *t; i--, f++, t++)
+ nnet += 8;
+ if (i > 0 && !(*f == 0x00 && *t == 0xff)) { /* mid-byte bdry. */
+ fb = *f++;
+ tb = *t++;
+ i--;
+ m = 0x80;
+ while ((fb&m) == (tb&m)) {
+ fb &= ~m;
+ tb |= m;
+ m >>= 1;
+ nnet++;
+ }
+ if (fb != 0x00 || tb != 0xff)
+ return "not a valid subnet";
+ }
+ for (; i > 0 && *f == 0x00 && *t == 0xff; i--, f++, t++)
+ continue;
+
+ if (i != 0)
+ return "invalid subnet";
+
+ return initsubnet(from, nnet, 'x', dst);
+}
+
+
+
+#ifdef RANGETOSUBNET_MAIN
+
+#include <stdio.h>
+
+void regress(void);
+
+int
+main(int argc, char *argv[])
+{
+ ip_address start;
+ ip_address stop;
+ ip_subnet sub;
+ char buf[100];
+ const char *oops;
+ size_t n;
+ int af;
+ int i;
+
+ if (argc == 2 && strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s [-6] start stop\n", argv[0]);
+ fprintf(stderr, " or: %s -r\n", argv[0]);
+ exit(2);
+ }
+
+ af = AF_INET;
+ i = 1;
+ if (strcmp(argv[i], "-6") == 0) {
+ af = AF_INET6;
+ i++;
+ }
+
+ oops = ttoaddr(argv[i], 0, af, &start);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: start conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ oops = ttoaddr(argv[i+1], 0, af, &stop);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: stop conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ oops = rangetosubnet(&start, &stop, &sub);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: rangetosubnet failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ n = subnettot(&sub, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ fprintf(stderr, "%s: reverse conversion", argv[0]);
+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
+ (long)n, (long)sizeof(buf));
+ exit(1);
+ }
+ printf("%s\n", buf);
+
+ exit(0);
+}
+
+struct rtab {
+ int family;
+ char *start;
+ char *stop;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {4, "1.2.3.0", "1.2.3.255", "1.2.3.0/24"},
+ {4, "1.2.3.0", "1.2.3.7", "1.2.3.0/29"},
+ {4, "1.2.3.240", "1.2.3.255", "1.2.3.240/28"},
+ {4, "0.0.0.0", "255.255.255.255", "0.0.0.0/0"},
+ {4, "1.2.3.4", "1.2.3.4", "1.2.3.4/32"},
+ {4, "1.2.3.0", "1.2.3.254", NULL},
+ {4, "1.2.3.0", "1.2.3.126", NULL},
+ {4, "1.2.3.0", "1.2.3.125", NULL},
+ {4, "1.2.0.0", "1.2.255.255", "1.2.0.0/16"},
+ {4, "1.2.0.0", "1.2.0.255", "1.2.0.0/24"},
+ {4, "1.2.255.0", "1.2.255.255", "1.2.255.0/24"},
+ {4, "1.2.255.0", "1.2.254.255", NULL},
+ {4, "1.2.255.1", "1.2.255.255", NULL},
+ {4, "1.2.0.1", "1.2.255.255", NULL},
+ {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"},
+ {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"},
+ {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"},
+ {4, NULL, NULL, NULL},
+};
+
+void
+regress()
+{
+ struct rtab *r;
+ int status = 0;
+ ip_address start;
+ ip_address stop;
+ ip_subnet sub;
+ char buf[100];
+ const char *oops;
+ size_t n;
+ int af;
+
+ for (r = rtab; r->start != NULL; r++) {
+ af = (r->family == 4) ? AF_INET : AF_INET6;
+ oops = ttoaddr(r->start, 0, af, &start);
+ if (oops != NULL) {
+ printf("surprise failure converting `%s'\n", r->start);
+ exit(1);
+ }
+ oops = ttoaddr(r->stop, 0, af, &stop);
+ if (oops != NULL) {
+ printf("surprise failure converting `%s'\n", r->stop);
+ exit(1);
+ }
+ oops = rangetosubnet(&start, &stop, &sub);
+ if (oops != NULL && r->output == NULL)
+ {} /* okay, error expected */
+ else if (oops != NULL) {
+ printf("`%s'-`%s' rangetosubnet failed: %s\n",
+ r->start, r->stop, oops);
+ status = 1;
+ } else if (r->output == NULL) {
+ printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n",
+ r->start, r->stop);
+ status = 1;
+ } else {
+ n = subnettot(&sub, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ printf("`%s'-`%s' subnettot failed: need %ld\n",
+ r->start, r->stop, (long)n);
+ status = 1;
+ } else if (strcmp(r->output, buf) != 0) {
+ printf("`%s'-`%s' gave `%s', expected `%s'\n",
+ r->start, r->stop, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* RANGETOSUBNET_MAIN */
diff --git a/src/libfreeswan/libfreeswan/sameaddr.3 b/src/libfreeswan/libfreeswan/sameaddr.3
new file mode 100644
index 000000000..71be10761
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/sameaddr.3
@@ -0,0 +1,165 @@
+.TH IPSEC_ANYADDR 3 "28 Nov 2000"
+.\" RCSID $Id: sameaddr.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec sameaddr \- are two addresses the same?
+.br
+ipsec addrcmp \- ordered comparison of addresses
+.br
+ipsec samesubnet \- are two subnets the same?
+.br
+ipsec addrinsubnet \- is an address within a subnet?
+.br
+ipsec subnetinsubnet \- is a subnet within another subnet?
+.br
+ipsec subnetishost \- is a subnet a single host?
+.br
+ipsec samesaid \- are two SA IDs the same?
+.br
+ipsec sameaddrtype \- are two addresses of the same address family?
+.br
+ipsec samesubnettype \- are two subnets of the same address family?
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "int sameaddr(const ip_address *a, const ip_address *b);"
+.br
+.B "int addrcmp(const ip_address *a, const ip_address *b);"
+.br
+.B "int samesubnet(const ip_subnet *a, const ip_subnet *b);"
+.br
+.B "int addrinsubnet(const ip_address *a, const ip_subnet *s);"
+.br
+.B "int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);"
+.br
+.B "int subnetishost(const ip_subnet *s);"
+.br
+.B "int samesaid(const ip_said *a, const ip_said *b);"
+.br
+.B "int sameaddrtype(const ip_address *a, const ip_address *b);"
+.br
+.B "int samesubnettype(const ip_subnet *a, const ip_subnet *b);"
+.SH DESCRIPTION
+These functions do various comparisons and tests on the
+.I ip_address
+type and
+.I ip_subnet
+types.
+.PP
+.I Sameaddr
+returns
+non-zero
+if addresses
+.I a
+and
+.IR b
+are identical,
+and
+.B 0
+otherwise.
+Addresses of different families are never identical.
+.PP
+.I Addrcmp
+returns
+.BR \-1 ,
+.BR 0 ,
+or
+.BR 1
+respectively
+if address
+.I a
+is less than, equal to, or greater than
+.IR b .
+If they are not of the same address family,
+they are never equal;
+the ordering reported in this case is arbitrary
+(and probably not useful) but consistent.
+.PP
+.I Samesubnet
+returns
+non-zero
+if subnets
+.I a
+and
+.IR b
+are identical,
+and
+.B 0
+otherwise.
+Subnets of different address families are never identical.
+.PP
+.I Addrinsubnet
+returns
+non-zero
+if address
+.I a
+is within subnet
+.IR s
+and
+.B 0
+otherwise.
+An address is never within a
+subnet of a different address family.
+.PP
+.I Subnetinsubnet
+returns
+non-zero
+if subnet
+.I a
+is a subset of subnet
+.IR b
+and
+.B 0
+otherwise.
+A subnet is deemed to be a subset of itself.
+A subnet is never a subset of another
+subnet if their address families differ.
+.PP
+.I Subnetishost
+returns
+non-zero
+if subnet
+.I s
+is in fact only a single host,
+and
+.B 0
+otherwise.
+.PP
+.I Samesaid
+returns
+non-zero
+if SA IDs
+.I a
+and
+.IR b
+are identical,
+and
+.B 0
+otherwise.
+.PP
+.I Sameaddrtype
+returns
+non-zero
+if addresses
+.I a
+and
+.IR b
+are of the same address family,
+and
+.B 0
+otherwise.
+.PP
+.I Samesubnettype
+returns
+non-zero
+if subnets
+.I a
+and
+.IR b
+are of the same address family,
+and
+.B 0
+otherwise.
+.SH SEE ALSO
+inet(3), ipsec_initaddr(3)
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/libfreeswan/sameaddr.c b/src/libfreeswan/libfreeswan/sameaddr.c
new file mode 100644
index 000000000..efc40796e
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/sameaddr.c
@@ -0,0 +1,190 @@
+/*
+ * comparisons
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: sameaddr.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static int samenbits(const ip_address *a, const ip_address *b, int n);
+
+/*
+ - addrcmp - compare two addresses
+ * Caution, the order of the tests is subtle: doing type test before
+ * size test can yield cases where a<b, b<c, but a>c.
+ */
+int /* like memcmp */
+addrcmp(a, b)
+const ip_address *a;
+const ip_address *b;
+{
+ int at = addrtypeof(a);
+ int bt = addrtypeof(b);
+ const unsigned char *ap;
+ const unsigned char *bp;
+ size_t as = addrbytesptr(a, &ap);
+ size_t bs = addrbytesptr(b, &bp);
+ size_t n = (as < bs) ? as : bs; /* min(as, bs) */
+ int c = memcmp(ap, bp, n);
+
+ if (c != 0) /* bytes differ */
+ return (c < 0) ? -1 : 1;
+ if (as != bs) /* comparison incomplete: lexical order */
+ return (as < bs) ? -1 : 1;
+ if (at != bt) /* bytes same but not same type: break tie */
+ return (at < bt) ? -1 : 1;
+ return 0;
+}
+
+/*
+ - sameaddr - are two addresses the same?
+ */
+int
+sameaddr(a, b)
+const ip_address *a;
+const ip_address *b;
+{
+ return (addrcmp(a, b) == 0) ? 1 : 0;
+}
+
+/*
+ - samesubnet - are two subnets the same?
+ */
+int
+samesubnet(a, b)
+const ip_subnet *a;
+const ip_subnet *b;
+{
+ if (!sameaddr(&a->addr, &b->addr)) /* also does type check */
+ return 0;
+ if (a->maskbits != b->maskbits)
+ return 0;
+ return 1;
+}
+
+/*
+ - subnetishost - is a subnet in fact a single host?
+ */
+int
+subnetishost(a)
+const ip_subnet *a;
+{
+ return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0;
+}
+
+/*
+ - samesaid - are two SA IDs the same?
+ */
+int
+samesaid(a, b)
+const ip_said *a;
+const ip_said *b;
+{
+ if (a->spi != b->spi) /* test first, most likely to be different */
+ return 0;
+ if (!sameaddr(&a->dst, &b->dst))
+ return 0;
+ if (a->proto != b->proto)
+ return 0;
+ return 1;
+}
+
+/*
+ - sameaddrtype - do two addresses have the same type?
+ */
+int
+sameaddrtype(a, b)
+const ip_address *a;
+const ip_address *b;
+{
+ return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0;
+}
+
+/*
+ - samesubnettype - do two subnets have the same type?
+ */
+int
+samesubnettype(a, b)
+const ip_subnet *a;
+const ip_subnet *b;
+{
+ return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0;
+}
+
+/*
+ - addrinsubnet - is this address in this subnet?
+ */
+int
+addrinsubnet(a, s)
+const ip_address *a;
+const ip_subnet *s;
+{
+ if (addrtypeof(a) != subnettypeof(s))
+ return 0;
+ if (!samenbits(a, &s->addr, s->maskbits))
+ return 0;
+ return 1;
+}
+
+/*
+ - subnetinsubnet - is one subnet within another?
+ */
+int
+subnetinsubnet(a, b)
+const ip_subnet *a;
+const ip_subnet *b;
+{
+ if (subnettypeof(a) != subnettypeof(b))
+ return 0;
+ if (a->maskbits < b->maskbits) /* a is bigger than b */
+ return 0;
+ if (!samenbits(&a->addr, &b->addr, b->maskbits))
+ return 0;
+ return 1;
+}
+
+/*
+ - samenbits - do two addresses have the same first n bits?
+ */
+static int
+samenbits(a, b, nbits)
+const ip_address *a;
+const ip_address *b;
+int nbits;
+{
+ const unsigned char *ap;
+ const unsigned char *bp;
+ size_t n;
+ int m;
+
+ if (addrtypeof(a) != addrtypeof(b))
+ return 0; /* arbitrary */
+ n = addrbytesptr(a, &ap);
+ if (n == 0)
+ return 0; /* arbitrary */
+ (void) addrbytesptr(b, &bp);
+ if (nbits > n*8)
+ return 0; /* "can't happen" */
+
+ for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++)
+ continue;
+ if (nbits >= 8)
+ return 0;
+ if (nbits > 0) { /* partial byte */
+ m = ~(0xff >> nbits);
+ if ((*ap & m) != (*bp & m))
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/libfreeswan/libfreeswan/satoa.c b/src/libfreeswan/libfreeswan/satoa.c
new file mode 100644
index 000000000..410fb8437
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/satoa.c
@@ -0,0 +1,102 @@
+/*
+ * convert from binary form of SA ID to ASCII
+ * Copyright (C) 1998, 1999, 2001 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: satoa.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static struct typename {
+ char type;
+ char *name;
+} typenames[] = {
+ { SA_AH, "ah" },
+ { SA_ESP, "esp" },
+ { SA_IPIP, "tun" },
+ { SA_COMP, "comp" },
+ { SA_INT, "int" },
+ { 0, NULL }
+};
+
+/*
+ - satoa - convert SA to ASCII "ah507@1.2.3.4"
+ */
+size_t /* space needed for full conversion */
+satoa(sa, format, dst, dstlen)
+struct sa_id sa;
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ size_t len = 0; /* 0 means not handled yet */
+ int base;
+ struct typename *tn;
+ char buf[30+ADDRTOA_BUF];
+
+ switch (format) {
+ case 0:
+ base = 16; /* temporarily at least */
+ break;
+ case 'd':
+ base = 10;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ for (tn = typenames; tn->name != NULL; tn++)
+ if (sa.proto == tn->type)
+ break;
+ if (tn->name == NULL)
+ return 0;
+
+ if (strcmp(tn->name, PASSTHROUGHTYPE) == 0 &&
+ sa.spi == PASSTHROUGHSPI &&
+ sa.dst.s_addr == PASSTHROUGHDST) {
+ strcpy(buf, PASSTHROUGHNAME);
+ len = strlen(buf);
+ } else if (sa.proto == SA_INT && sa.dst.s_addr == 0) {
+ char *p;
+
+ switch (ntohl(sa.spi)) {
+ case SPI_PASS: p = "%pass"; break;
+ case SPI_DROP: p = "%drop"; break;
+ case SPI_REJECT: p = "%reject"; break;
+ case SPI_HOLD: p = "%hold"; break;
+ case SPI_TRAP: p = "%trap"; break;
+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
+ default: p = NULL; break;
+ }
+ if (p != NULL) {
+ strcpy(buf, p);
+ len = strlen(buf);
+ }
+ }
+
+ if (len == 0) {
+ strcpy(buf, tn->name);
+ len = strlen(buf);
+ len += ultoa(ntohl(sa.spi), base, buf+len, sizeof(buf)-len);
+ *(buf+len-1) = '@';
+ len += addrtoa(sa.dst, 0, buf+len, sizeof(buf)-len);
+ }
+
+ if (dst != NULL) {
+ if (len > dstlen)
+ *(buf+dstlen-1) = '\0';
+ strcpy(dst, buf);
+ }
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/satot.c b/src/libfreeswan/libfreeswan/satot.c
new file mode 100644
index 000000000..927f4ca1f
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/satot.c
@@ -0,0 +1,132 @@
+/*
+ * convert from binary form of SA ID to text
+ * Copyright (C) 2000, 2001 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: satot.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static struct typename {
+ char type;
+ char *name;
+} typenames[] = {
+ { SA_AH, "ah" },
+ { SA_ESP, "esp" },
+ { SA_IPIP, "tun" },
+ { SA_COMP, "comp" },
+ { SA_INT, "int" },
+ { 0, NULL }
+};
+
+/*
+ - satot - convert SA to text "ah507@1.2.3.4"
+ */
+size_t /* space needed for full conversion */
+satot(sa, format, dst, dstlen)
+const ip_said *sa;
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ size_t len = 0; /* 0 means "not recognized yet" */
+ int base;
+ int showversion; /* use delimiter to show IP version? */
+ struct typename *tn;
+ char *p;
+ char *pre;
+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
+ char unk[10];
+
+ switch (format) {
+ case 0:
+ base = 16;
+ showversion = 1;
+ break;
+ case 'f':
+ base = 17;
+ showversion = 1;
+ break;
+ case 'x':
+ base = 'x';
+ showversion = 0;
+ break;
+ case 'd':
+ base = 10;
+ showversion = 0;
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ pre = NULL;
+ for (tn = typenames; tn->name != NULL; tn++)
+ if (sa->proto == tn->type) {
+ pre = tn->name;
+ break; /* NOTE BREAK OUT */
+ }
+ if (pre == NULL) { /* unknown protocol */
+ strcpy(unk, "unk");
+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
+ sizeof(unk)-strlen(unk));
+ pre = unk;
+ }
+
+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
+ sa->spi == PASSTHROUGHSPI &&
+ isunspecaddr(&sa->dst)) {
+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
+ PASSTHROUGH4NAME :
+ PASSTHROUGH6NAME);
+ len = strlen(buf);
+ }
+
+ if (sa->proto == SA_INT && addrtypeof(&sa->dst) == AF_INET &&
+ isunspecaddr(&sa->dst)) {
+ switch (ntohl(sa->spi)) {
+ case SPI_PASS: p = "%pass"; break;
+ case SPI_DROP: p = "%drop"; break;
+ case SPI_REJECT: p = "%reject"; break;
+ case SPI_HOLD: p = "%hold"; break;
+ case SPI_TRAP: p = "%trap"; break;
+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
+ default: p = NULL; break;
+ }
+ if (p != NULL) {
+ strcpy(buf, p);
+ len = strlen(buf);
+ }
+ }
+
+ if (len == 0) { /* general case needed */
+ strcpy(buf, pre);
+ len = strlen(buf);
+ if (showversion) {
+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
+ ':';
+ len++;
+ *(buf+len) = '\0';
+ }
+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
+ *(buf+len-1) = '@';
+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
+ }
+
+ if (dst != NULL) {
+ if (len > dstlen)
+ *(buf+dstlen-1) = '\0';
+ strcpy(dst, buf);
+ }
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/subnetof.3 b/src/libfreeswan/libfreeswan/subnetof.3
new file mode 100644
index 000000000..1911e499f
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/subnetof.3
@@ -0,0 +1,47 @@
+.TH IPSEC_SUBNETOF 3 "11 June 2001"
+.\" RCSID $Id: subnetof.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec subnetof \- given Internet address and subnet mask, return subnet number
+.br
+ipsec hostof \- given Internet address and subnet mask, return host part
+.br
+ipsec broadcastof \- given Internet address and subnet mask, return broadcast address
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "struct in_addr subnetof(struct in_addr addr,"
+.ti +1c
+.B "struct in_addr mask);"
+.br
+.B "struct in_addr hostof(struct in_addr addr,"
+.ti +1c
+.B "struct in_addr mask);"
+.br
+.B "struct in_addr broadcastof(struct in_addr addr,"
+.ti +1c
+.B "struct in_addr mask);"
+.SH DESCRIPTION
+These functions are obsolete; see
+.IR ipsec_networkof (3)
+for their replacements.
+.PP
+.I Subnetof
+takes an Internet
+.I address
+and a subnet
+.I mask
+and returns the network part of the address
+(all in network byte order).
+.I Hostof
+similarly returns the host part, and
+.I broadcastof
+returns the broadcast address (all-1s convention) for the network.
+.PP
+These functions are provided to hide the Internet bit-munging inside
+an API, in hopes of easing the eventual transition to IPv6.
+.SH SEE ALSO
+inet(3), ipsec_atosubnet(3)
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+Calling functions for this is more costly than doing it yourself.
diff --git a/src/libfreeswan/libfreeswan/subnetof.c b/src/libfreeswan/libfreeswan/subnetof.c
new file mode 100644
index 000000000..1b288c591
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/subnetof.c
@@ -0,0 +1,60 @@
+/*
+ * minor network-address manipulation utilities
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: subnetof.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - subnetof - given address and mask, return subnet part
+ */
+struct in_addr
+subnetof(addr, mask)
+struct in_addr addr;
+struct in_addr mask;
+{
+ struct in_addr result;
+
+ result.s_addr = addr.s_addr & mask.s_addr;
+ return result;
+}
+
+/*
+ - hostof - given address and mask, return host part
+ */
+struct in_addr
+hostof(addr, mask)
+struct in_addr addr;
+struct in_addr mask;
+{
+ struct in_addr result;
+
+ result.s_addr = addr.s_addr & ~mask.s_addr;
+ return result;
+}
+
+/*
+ - broadcastof - given (network) address and mask, return broadcast address
+ */
+struct in_addr
+broadcastof(addr, mask)
+struct in_addr addr;
+struct in_addr mask;
+{
+ struct in_addr result;
+
+ result.s_addr = addr.s_addr | ~mask.s_addr;
+ return result;
+}
diff --git a/src/libfreeswan/libfreeswan/subnettoa.c b/src/libfreeswan/libfreeswan/subnettoa.c
new file mode 100644
index 000000000..36cad8b88
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/subnettoa.c
@@ -0,0 +1,62 @@
+/*
+ * convert binary form of subnet description to ASCII
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: subnettoa.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - subnettoa - convert address and mask to ASCII "addr/mask"
+ * Output expresses the mask as a bit count if possible, else dotted decimal.
+ */
+size_t /* space needed for full conversion */
+subnettoa(addr, mask, format, dst, dstlen)
+struct in_addr addr;
+struct in_addr mask;
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ size_t len;
+ size_t rest;
+ int n;
+ char *p;
+
+ switch (format) {
+ case 0:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ len = addrtoa(addr, 0, dst, dstlen);
+ if (len < dstlen) {
+ dst[len - 1] = '/';
+ p = dst + len;
+ rest = dstlen - len;
+ } else {
+ p = NULL;
+ rest = 0;
+ }
+
+ n = masktobits(mask);
+ if (n >= 0)
+ len += ultoa((unsigned long)n, 10, p, rest);
+ else
+ len += addrtoa(mask, 0, p, rest);
+
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/subnettot.c b/src/libfreeswan/libfreeswan/subnettot.c
new file mode 100644
index 000000000..0385d25e5
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/subnettot.c
@@ -0,0 +1,56 @@
+/*
+ * convert binary form of subnet description to text
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: subnettot.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - subnettot - convert subnet to text "addr/bitcount"
+ */
+size_t /* space needed for full conversion */
+subnettot(sub, format, dst, dstlen)
+const ip_subnet *sub;
+int format; /* character */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ size_t len;
+ size_t rest;
+ char *p;
+
+ switch (format) {
+ case 0:
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ len = addrtot(&sub->addr, format, dst, dstlen);
+ if (len < dstlen) {
+ dst[len - 1] = '/';
+ p = dst + len;
+ rest = dstlen - len;
+ } else {
+ p = NULL;
+ rest = 0;
+ }
+
+
+ len += ultoa((unsigned long)sub->maskbits, 10, p, rest);
+
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/subnettypeof.c b/src/libfreeswan/libfreeswan/subnettypeof.c
new file mode 100644
index 000000000..6f44b2e4b
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/subnettypeof.c
@@ -0,0 +1,109 @@
+/*
+ * extract parts of an ip_subnet, and related
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: subnettypeof.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - subnettypeof - get the address type of an ip_subnet
+ */
+int
+subnettypeof(src)
+const ip_subnet *src;
+{
+ return src->addr.u.v4.sin_family;
+}
+
+/*
+ - networkof - get the network address of a subnet
+ */
+void
+networkof(src, dst)
+const ip_subnet *src;
+ip_address *dst;
+{
+ *dst = src->addr;
+}
+
+/*
+ - maskof - get the mask of a subnet, as an address
+ */
+void
+maskof(src, dst)
+const ip_subnet *src;
+ip_address *dst;
+{
+ int b;
+ unsigned char buf[16];
+ size_t n = addrlenof(&src->addr);
+ unsigned char *p;
+
+ if (src->maskbits > n*8 || n > sizeof(buf))
+ return; /* "can't happen" */
+
+ p = buf;
+ for (b = src->maskbits; b >= 8; b -= 8)
+ *p++ = 0xff;
+ if (b != 0)
+ *p++ = (0xff << (8 - b)) & 0xff;
+ while (p - buf < n)
+ *p++ = 0;
+
+ (void) initaddr(buf, n, addrtypeof(&src->addr), dst);
+}
+
+/*
+ - masktocount - convert a mask, expressed as an address, to a bit count
+ */
+int /* -1 if not valid mask */
+masktocount(src)
+const ip_address *src;
+{
+ int b;
+ unsigned const char *bp;
+ size_t n;
+ unsigned const char *p;
+ unsigned const char *stop;
+
+ n = addrbytesptr(src, &bp);
+ if (n == 0)
+ return -1;
+
+ p = bp;
+ stop = bp + n;
+
+ n = 0;
+ while (p < stop && *p == 0xff) {
+ p++;
+ n += 8;
+ }
+ if (p < stop && *p != 0) { /* boundary in mid-byte */
+ b = *p++;
+ while (b&0x80) {
+ b <<= 1;
+ n++;
+ }
+ if ((b&0xff) != 0)
+ return -1; /* bits not contiguous */
+ }
+ while (p < stop && *p == 0)
+ p++;
+
+ if (p != stop)
+ return -1;
+
+ return n;
+}
diff --git a/src/libfreeswan/libfreeswan/ttoaddr.3 b/src/libfreeswan/libfreeswan/ttoaddr.3
new file mode 100644
index 000000000..5bf48d4b2
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttoaddr.3
@@ -0,0 +1,377 @@
+.TH IPSEC_TTOADDR 3 "28 Sept 2001"
+.\" RCSID $Id: ttoaddr.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec ttoaddr, tnatoaddr, addrtot \- convert Internet addresses to and from text
+.br
+ipsec ttosubnet, subnettot \- convert subnet/mask text form to and from addresses
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *ttoaddr(const char *src, size_t srclen,"
+.ti +1c
+.B "int af, ip_address *addr);"
+.br
+.B "const char *tnatoaddr(const char *src, size_t srclen,"
+.ti +1c
+.B "int af, ip_address *addr);"
+.br
+.B "size_t addrtot(const ip_address *addr, int format,"
+.ti +1c
+.B "char *dst, size_t dstlen);"
+.sp
+.B "const char *ttosubnet(const char *src, size_t srclen,"
+.ti +1c
+.B "int af, ip_subnet *dst);"
+.br
+.B "size_t subnettot(const ip_subnet *sub, int format,"
+.ti +1c
+.B "char *dst, size_t dstlen);"
+.SH DESCRIPTION
+.I Ttoaddr
+converts a text-string name or numeric address into a binary address
+(in network byte order).
+.I Tnatoaddr
+does the same conversion,
+but the only text forms it accepts are
+the ``official'' forms of
+numeric address (dotted-decimal for IPv4, colon-hex for IPv6).
+.I Addrtot
+does the reverse conversion, from binary address back to a text form.
+.I Ttosubnet
+and
+.I subnettot
+do likewise for the ``address/mask'' form used to write a
+specification of a subnet.
+.PP
+An IPv4 address is specified in text as a
+dotted-decimal address (e.g.
+.BR 1.2.3.4 ),
+an eight-digit network-order hexadecimal number with the usual C prefix (e.g.
+.BR 0x01020304 ,
+which is synonymous with
+.BR 1.2.3.4 ),
+an eight-digit host-order hexadecimal number with a
+.B 0h
+prefix (e.g.
+.BR 0h01020304 ,
+which is synonymous with
+.B 1.2.3.4
+on a big-endian host and
+.B 4.3.2.1
+on a little-endian host),
+a DNS name to be looked up via
+.IR gethostbyname (3),
+or an old-style network name to be looked up via
+.IR getnetbyname (3).
+.PP
+A dotted-decimal address may be incomplete, in which case
+text-to-binary conversion implicitly appends
+as many instances of
+.B .0
+as necessary to bring it up to four components.
+The components of a dotted-decimal address are always taken as
+decimal, and leading zeros are ignored.
+For example,
+.B 10
+is synonymous with
+.BR 10.0.0.0 ,
+and
+.B 128.009.000.032
+is synonymous with
+.BR 128.9.0.32
+(the latter example is verbatim from RFC 1166).
+The result of applying
+.I addrtot
+to an IPv4 address is always complete and does not contain leading zeros.
+.PP
+Use of hexadecimal addresses is
+.B strongly
+.BR discouraged ;
+they are included only to save hassles when dealing with
+the handful of perverted programs which already print
+network addresses in hexadecimal.
+.PP
+An IPv6 address is specified in text with
+colon-hex notation (e.g.
+.BR 0:56:78ab:22:33:44:55:66 ),
+colon-hex with
+.B ::
+abbreviating at most one subsequence of multiple zeros (e.g.
+.BR 99:ab::54:068 ,
+which is synonymous with
+.BR 99:ab:0:0:0:0:54:68 ),
+or a DNS name to be looked up via
+.IR gethostbyname (3).
+The result of applying
+.I addrtot
+to an IPv6 address will use
+.B ::
+abbreviation if possible,
+and will not contain leading zeros.
+.PP
+The letters in hexadecimal
+may be uppercase or lowercase or any mixture thereof.
+.PP
+DNS names may be complete (optionally terminated with a ``.'')
+or incomplete, and are looked up as specified by local system configuration
+(see
+.IR resolver (5)).
+The
+.I h_addr
+value returned by
+.IR gethostbyname2 (3)
+is used,
+so with current DNS implementations,
+the result when the name corresponds to more than one address is
+difficult to predict.
+IPv4 name lookup resorts to
+.IR getnetbyname (3)
+only if
+.IR gethostbyname2 (3)
+fails.
+.PP
+A subnet specification is of the form \fInetwork\fB/\fImask\fR.
+The
+.I network
+and
+.I mask
+can be any form acceptable to
+.IR ttoaddr .
+In addition, and preferably, the
+.I mask
+can be a decimal integer (leading zeros ignored) giving a bit count,
+in which case
+it stands for a mask with that number of high bits on and all others off
+(e.g.,
+.B 24
+in IPv4 means
+.BR 255.255.255.0 ).
+In any case, the mask must be contiguous
+(a sequence of high bits on and all remaining low bits off).
+As a special case, the subnet specification
+.B %default
+is a synonym for
+.B 0.0.0.0/0
+or
+.B ::/0
+in IPv4 or IPv6 respectively.
+.PP
+.I Ttosubnet
+ANDs the mask with the address before returning,
+so that any non-network bits in the address are turned off
+(e.g.,
+.B 10.1.2.3/24
+is synonymous with
+.BR 10.1.2.0/24 ).
+.I Subnettot
+always generates the decimal-integer-bit-count
+form of the mask,
+with no leading zeros.
+.PP
+The
+.I srclen
+parameter of
+.I ttoaddr
+and
+.I ttosubnet
+specifies the length of the text string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I af
+parameter of
+.I ttoaddr
+and
+.I ttosubnet
+specifies the address family of interest.
+It should be either
+.B AF_INET
+or
+.BR AF_INET6 .
+.PP
+The
+.I dstlen
+parameter of
+.I addrtot
+and
+.I subnettot
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.I freeswan.h
+header file defines constants,
+.B ADDRTOT_BUF
+and
+.BR SUBNETTOT_BUF ,
+which are the sizes of buffers just large enough for worst-case results.
+.PP
+The
+.I format
+parameter of
+.I addrtot
+and
+.I subnettot
+specifies what format is to be used for the conversion.
+The value
+.B 0
+(not the character
+.BR '0' ,
+but a zero value)
+specifies a reasonable default,
+and is in fact the only format currently available in
+.IR subnettot .
+.I Addrtot
+also accepts format values
+.B 'r'
+(signifying a text form suitable for DNS reverse lookups,
+e.g.
+.B 4.3.2.1.IN-ADDR.ARPA.
+for IPv4 and
+RFC 2874 format for IPv6),
+and
+.B 'R'
+(signifying an alternate reverse-lookup form,
+an error for IPv4 and RFC 1886 format for IPv6).
+Reverse-lookup names always end with a ``.''.
+.PP
+The text-to-binary functions return NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+The binary-to-text functions return
+.B 0
+for a failure, and otherwise
+always return the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.SH SEE ALSO
+inet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I ttoaddr
+are:
+empty input;
+unknown address family;
+attempt to allocate temporary storage for a very long name failed;
+name lookup failed;
+syntax error in dotted-decimal or colon-hex form;
+dotted-decimal or colon-hex component too large.
+.PP
+Fatal errors in
+.I ttosubnet
+are:
+no
+.B /
+in
+.IR src ;
+.I ttoaddr
+error in conversion of
+.I network
+or
+.IR mask ;
+bit-count mask too big;
+mask non-contiguous.
+.PP
+Fatal errors in
+.I addrtot
+and
+.I subnettot
+are:
+unknown format.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The interpretation of incomplete dotted-decimal addresses
+(e.g.
+.B 10/24
+means
+.BR 10.0.0.0/24 )
+differs from that of some older conversion
+functions, e.g. those of
+.IR inet (3).
+The behavior of the older functions has never been
+particularly consistent or particularly useful.
+.PP
+Ignoring leading zeros in dotted-decimal components and bit counts
+is arguably the most useful behavior in this application,
+but it might occasionally cause confusion with the historical use of leading
+zeros to denote octal numbers.
+.PP
+.I Ttoaddr
+does not support the mixed colon-hex-dotted-decimal
+convention used to embed an IPv4 address in an IPv6 address.
+.PP
+.I Addrtot
+always uses the
+.B ::
+abbreviation (which can appear only once in an address) for the
+.I first
+sequence of multiple zeros in an IPv6 address.
+One can construct addresses (unlikely ones) in which this is suboptimal.
+.PP
+.I Addrtot
+.B 'r'
+conversion of an IPv6 address uses lowercase hexadecimal,
+not the uppercase used in RFC 2874's examples.
+It takes careful reading of RFCs 2874, 2673, and 2234 to realize
+that lowercase is technically legitimate here,
+and there may be software which botches this
+and hence would have trouble with lowercase hex.
+.PP
+Possibly
+.I subnettot
+ought to recognize the
+.B %default
+case and generate that string as its output.
+Currently it doesn't.
+.PP
+It is barely possible that somebody, somewhere,
+might have a legitimate use for non-contiguous subnet masks.
+.PP
+.IR Getnetbyname (3)
+is a historical dreg.
+.PP
+.I Tnatoaddr
+probably should enforce completeness of dotted-decimal addresses.
+.PP
+The restriction of text-to-binary error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The text-to-binary error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = ttoaddr( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/ttoaddr.c b/src/libfreeswan/libfreeswan/ttoaddr.c
new file mode 100644
index 000000000..efcb33e9f
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttoaddr.c
@@ -0,0 +1,426 @@
+/*
+ * conversion from text forms of addresses to internal ones
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ttoaddr.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ * Legal ASCII characters in a domain name. Underscore technically is not,
+ * but is a common misunderstanding. Non-ASCII characters are simply
+ * exempted from checking at the moment, to allow for UTF-8 encoded stuff;
+ * the purpose of this check is merely to catch blatant errors.
+ */
+static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_.";
+#define ISASCII(c) (((c) & 0x80) == 0)
+
+static err_t tryname(const char *, size_t, int, int, ip_address *);
+static err_t tryhex(const char *, size_t, int, ip_address *);
+static err_t trydotted(const char *, size_t, ip_address *);
+static err_t getbyte(const char **, const char *, int *);
+static err_t colon(const char *, size_t, ip_address *);
+static err_t getpiece(const char **, const char *, unsigned *);
+
+/*
+ - ttoaddr - convert text name or dotted-decimal address to binary address
+ */
+err_t /* NULL for success, else string literal */
+ttoaddr(src, srclen, af, dst)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+int af; /* address family */
+ip_address *dst;
+{
+ err_t oops;
+# define HEXLEN 10 /* strlen("0x11223344") */
+ int nultermd;
+
+ if (srclen == 0) {
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+ nultermd = 1;
+ } else
+ nultermd = 0; /* at least, not *known* to be terminated */
+
+ switch (af) {
+ case AF_INET:
+ case AF_INET6:
+ case 0: /* guess */
+ break;
+
+ default:
+ return "invalid address family";
+ }
+
+ if (af == AF_INET && srclen == HEXLEN && *src == '0') {
+ if (*(src+1) == 'x' || *(src+1) == 'X')
+ return tryhex(src+2, srclen-2, 'x', dst);
+ if (*(src+1) == 'h' || *(src+1) == 'H')
+ return tryhex(src+2, srclen-2, 'h', dst);
+ }
+
+ if (memchr(src, ':', srclen) != NULL) {
+ if(af == 0)
+ {
+ af = AF_INET6;
+ }
+
+ if (af != AF_INET6)
+ return "non-ipv6 address may not contain `:'";
+ return colon(src, srclen, dst);
+ }
+
+ if (af == 0 || af == AF_INET) {
+ oops = trydotted(src, srclen, dst);
+ if (oops == NULL)
+ return NULL; /* it worked */
+ if (*oops != '?')
+ return oops; /* probably meant as d-d */
+ }
+
+ return tryname(src, srclen, nultermd, af, dst);
+}
+
+/*
+ - tnatoaddr - convert text numeric address (only) to binary address
+ */
+err_t /* NULL for success, else string literal */
+tnatoaddr(src, srclen, af, dst)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+int af; /* address family */
+ip_address *dst;
+{
+ err_t oops;
+
+ if (srclen == 0) {
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+ }
+
+ switch (af) {
+ case 0: /* guess */
+ oops = colon(src, srclen, dst);
+ if(oops == NULL)
+ {
+ return NULL;
+ }
+ oops = trydotted(src, srclen, dst);
+ if(oops == NULL)
+ {
+ return NULL;
+ }
+ return "does not appear to be either IPv4 or IPv6 numeric address";
+ break;
+
+ case AF_INET6:
+ return colon(src, srclen, dst);
+ break;
+ case AF_INET:
+ oops = trydotted(src, srclen, dst);
+ if (oops == NULL)
+ return NULL; /* it worked */
+ if (*oops != '?')
+ return oops; /* probably meant as d-d */
+ return "does not appear to be numeric address";
+ break;
+ default:
+ return "unknown address family in tnatoaddr";
+ break;
+ }
+}
+
+/*
+ - tryname - try it as a name
+ * Slightly complicated by lack of reliable NUL termination in source.
+ */
+static err_t
+tryname(src, srclen, nultermd, af, dst)
+const char *src;
+size_t srclen;
+int nultermd; /* is it known to be NUL-terminated? */
+int af;
+ip_address *dst;
+{
+ struct hostent *h;
+ struct netent *ne = NULL;
+ char namebuf[100]; /* enough for most DNS names */
+ const char *cp;
+ char *p = namebuf;
+ size_t n;
+
+ for (cp = src, n = srclen; n > 0; cp++, n--)
+ if (ISASCII(*cp) && strchr(namechars, *cp) == NULL)
+ return "illegal (non-DNS-name) character in name";
+
+ if (nultermd)
+ cp = src;
+ else {
+ if (srclen+1 > sizeof(namebuf)) {
+ p = (char *) MALLOC(srclen+1);
+ if (p == NULL)
+ return "unable to get temporary space for name";
+ }
+ p[0] = '\0'; /* strncpy semantics are wrong */
+ strncat(p, src, srclen);
+ cp = (const char *)p;
+ }
+
+ h = gethostbyname2(cp, af);
+ if (h == NULL && af == AF_INET)
+ ne = getnetbyname(cp);
+ if (p != namebuf)
+ FREE(p);
+ if (h == NULL && ne == NULL)
+ return "does not look numeric and name lookup failed";
+
+ if (h != NULL) {
+ if (h->h_addrtype != af)
+ return "address-type mismatch from gethostbyname2!!!";
+ return initaddr((unsigned char *)h->h_addr, h->h_length, af, dst);
+ } else {
+ if (ne->n_addrtype != af)
+ return "address-type mismatch from getnetbyname!!!";
+ ne->n_net = htonl(ne->n_net);
+ return initaddr((unsigned char *)&ne->n_net, sizeof(ne->n_net),
+ af, dst);
+ }
+}
+
+/*
+ - tryhex - try conversion as an eight-digit hex number (AF_INET only)
+ */
+static err_t
+tryhex(src, srclen, flavor, dst)
+const char *src;
+size_t srclen; /* should be 8 */
+int flavor; /* 'x' for network order, 'h' for host order */
+ip_address *dst;
+{
+ err_t oops;
+ unsigned long ul;
+ union {
+ uint32_t addr;
+ unsigned char buf[4];
+ } u;
+
+ if (srclen != 8)
+ return "internal error, tryhex called with bad length";
+
+ oops = ttoul(src, srclen, 16, &ul);
+ if (oops != NULL)
+ return oops;
+
+ u.addr = (flavor == 'h') ? ul : htonl(ul);
+ return initaddr(u.buf, sizeof(u.buf), AF_INET, dst);
+}
+
+/*
+ - trydotted - try conversion as dotted decimal (AF_INET only)
+ *
+ * If the first char of a complaint is '?', that means "didn't look like
+ * dotted decimal at all".
+ */
+static err_t
+trydotted(src, srclen, dst)
+const char *src;
+size_t srclen;
+ip_address *dst;
+{
+ const char *stop = src + srclen; /* just past end */
+ int byte;
+ err_t oops;
+# define NBYTES 4
+ unsigned char buf[NBYTES];
+ int i;
+
+ memset(buf, 0, sizeof(buf));
+ for (i = 0; i < NBYTES && src < stop; i++) {
+ oops = getbyte(&src, stop, &byte);
+ if (oops != NULL) {
+ if (*oops != '?')
+ return oops; /* bad number */
+ if (i > 1)
+ return oops+1; /* failed number */
+ return oops; /* with leading '?' */
+ }
+ buf[i] = byte;
+ if (i < 3 && src < stop && *src++ != '.') {
+ if (i == 0)
+ return "?syntax error in dotted-decimal address";
+ else
+ return "syntax error in dotted-decimal address";
+ }
+ }
+ if (src != stop)
+ return "extra garbage on end of dotted-decimal address";
+
+ return initaddr(buf, sizeof(buf), AF_INET, dst);
+}
+
+/*
+ - getbyte - try to scan a byte in dotted decimal
+ * A subtlety here is that all this arithmetic on ASCII digits really is
+ * highly portable -- ANSI C guarantees that digits 0-9 are contiguous.
+ * It's easier to just do it ourselves than set up for a call to ttoul().
+ *
+ * If the first char of a complaint is '?', that means "didn't look like a
+ * number at all".
+ */
+err_t
+getbyte(srcp, stop, retp)
+const char **srcp; /* *srcp is updated */
+const char *stop; /* first untouchable char */
+int *retp; /* return-value pointer */
+{
+ char c;
+ const char *p;
+ int no;
+
+ if (*srcp >= stop)
+ return "?empty number in dotted-decimal address";
+
+ no = 0;
+ p = *srcp;
+ while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') {
+ no = no*10 + (c - '0');
+ p++;
+ }
+ if (p == *srcp)
+ return "?non-numeric component in dotted-decimal address";
+ *srcp = p;
+ if (no > 255)
+ return "byte overflow in dotted-decimal address";
+ *retp = no;
+ return NULL;
+}
+
+/*
+ - colon - convert IPv6 "numeric" address
+ */
+static err_t
+colon(src, srclen, dst)
+const char *src;
+size_t srclen; /* known to be >0 */
+ip_address *dst;
+{
+ const char *stop = src + srclen; /* just past end */
+ unsigned piece;
+ int gapat; /* where was empty piece seen */
+ err_t oops;
+# define NPIECES 8
+ unsigned char buf[NPIECES*2]; /* short may have wrong byte order */
+ int i;
+ int j;
+# define IT "IPv6 numeric address"
+ int naftergap;
+
+ /* leading or trailing :: becomes single empty field */
+ if (*src == ':') { /* legal only if leading :: */
+ if (srclen == 1 || *(src+1) != ':')
+ return "illegal leading `:' in " IT;
+ if (srclen == 2) {
+ unspecaddr(AF_INET6, dst);
+ return NULL;
+ }
+ src++; /* past first but not second */
+ srclen--;
+ }
+ if (*(stop-1) == ':') { /* legal only if trailing :: */
+ if (srclen == 1 || *(stop-2) != ':')
+ return "illegal trailing `:' in " IT;
+ srclen--; /* leave one */
+ }
+
+ gapat = -1;
+ for (i = 0; i < NPIECES && src < stop; i++) {
+ oops = getpiece(&src, stop, &piece);
+ if (oops != NULL && *oops == ':') { /* empty field */
+ if (gapat >= 0)
+ return "more than one :: in " IT;
+ gapat = i;
+ } else if (oops != NULL)
+ return oops;
+ buf[2*i] = piece >> 8;
+ buf[2*i + 1] = piece & 0xff;
+ if (i < NPIECES-1) { /* there should be more input */
+ if (src == stop && gapat < 0)
+ return IT " ends prematurely";
+ if (src != stop && *src++ != ':')
+ return "syntax error in " IT;
+ }
+ }
+ if (src != stop)
+ return "extra garbage on end of " IT;
+
+ if (gapat < 0 && i < NPIECES) /* should have been caught earlier */
+ return "incomplete " IT " (internal error)";
+ if (gapat >= 0 && i == NPIECES)
+ return "non-abbreviating empty field in " IT;
+ if (gapat >= 0) {
+ naftergap = i - (gapat + 1);
+ for (i--, j = NPIECES-1; naftergap > 0; i--, j--, naftergap--) {
+ buf[2*j] = buf[2*i];
+ buf[2*j + 1] = buf[2*i + 1];
+ }
+ for (; j >= gapat; j--)
+ buf[2*j] = buf[2*j + 1] = 0;
+ }
+
+ return initaddr(buf, sizeof(buf), AF_INET6, dst);
+}
+
+/*
+ - getpiece - try to scan one 16-bit piece of an IPv6 address
+ */
+err_t /* ":" means "empty field seen" */
+getpiece(srcp, stop, retp)
+const char **srcp; /* *srcp is updated */
+const char *stop; /* first untouchable char */
+unsigned *retp; /* return-value pointer */
+{
+ const char *p;
+# define NDIG 4
+ int d;
+ unsigned long ret;
+ err_t oops;
+
+ if (*srcp >= stop || **srcp == ':') { /* empty field */
+ *retp = 0;
+ return ":";
+ }
+
+ p = *srcp;
+ d = 0;
+ while (p < stop && d < NDIG && isxdigit(*p)) {
+ p++;
+ d++;
+ }
+ if (d == 0)
+ return "non-hex field in IPv6 numeric address";
+ if (p < stop && d == NDIG && isxdigit(*p))
+ return "field in IPv6 numeric address longer than 4 hex digits";
+
+ oops = ttoul(*srcp, d, 16, &ret);
+ if (oops != NULL) /* shouldn't happen, really... */
+ return oops;
+
+ *srcp = p;
+ *retp = ret;
+ return NULL;
+}
diff --git a/src/libfreeswan/libfreeswan/ttodata.3 b/src/libfreeswan/libfreeswan/ttodata.3
new file mode 100644
index 000000000..98bbe4ab3
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttodata.3
@@ -0,0 +1,281 @@
+.TH IPSEC_TTODATA 3 "16 August 2003"
+.\" RCSID $Id: ttodata.3,v 1.2 2005/07/18 20:13:42 as Exp $
+.SH NAME
+ipsec ttodata, datatot \- convert binary data bytes from and to text formats
+.SH SYNOPSIS
+.B "#include <freeswan.h>"
+.sp
+.B "const char *ttodata(const char *src, size_t srclen,"
+.ti +1c
+.B "int base, char *dst, size_t dstlen, size_t *lenp);"
+.br
+.B "const char *ttodatav(const char *src, size_t srclen,"
+.ti +1c
+.B "int base, char *dst, size_t dstlen, size_t *lenp,"
+.ti +1c
+.B "char *errp, size_t errlen, int flags);"
+.br
+.B "size_t datatot(const char *src, size_t srclen,"
+.ti +1c
+.B "int format, char *dst, size_t dstlen);"
+.SH DESCRIPTION
+.IR Ttodata ,
+.IR ttodatav ,
+and
+.I datatot
+convert arbitrary binary data (e.g. encryption or authentication keys)
+from and to more-or-less human-readable text formats.
+.PP
+Currently supported formats are hexadecimal, base64, and characters.
+.PP
+A hexadecimal text value begins with a
+.B 0x
+(or
+.BR 0X )
+prefix and continues with two-digit groups
+of hexadecimal digits (0-9, and a-f or A-F),
+each group encoding the value of one binary byte, high-order digit first.
+A single
+.B _
+(underscore)
+between consecutive groups is ignored, permitting punctuation to improve
+readability; doing this every eight digits seems about right.
+.PP
+A base64 text value begins with a
+.B 0s
+(or
+.BR 0S )
+prefix
+and continues with four-digit groups of base64 digits (A-Z, a-z, 0-9, +, and /),
+each group encoding the value of three binary bytes as described in
+section 6.8 of RFC 2045.
+If
+.B flags
+has the
+.B TTODATAV_IGNORESPACE
+bit on, blanks are ignore (after the prefix).
+Note that the last one or two digits of a base64 group can be
+.B =
+to indicate that fewer than three binary bytes are encoded.
+.PP
+A character text value begins with a
+.B 0t
+(or
+.BR 0T )
+prefix
+and continues with text characters, each being the value of one binary byte.
+.PP
+All these functions basically copy data from
+.I src
+(whose size is specified by
+.IR srclen )
+to
+.I dst
+(whose size is specified by
+.IR dstlen ),
+doing the conversion en route.
+If the result will not fit in
+.IR dst ,
+it is truncated;
+under no circumstances are more than
+.I dstlen
+bytes of result written to
+.IR dst .
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result bytes are written at all.
+.PP
+The
+.I base
+parameter of
+.I ttodata
+and
+.I ttodatav
+specifies what format the input is in;
+normally it should be
+.B 0
+to signify that this gets figured out from the prefix.
+Values of
+.BR 16 ,
+.BR 64 ,
+and
+.BR 256
+respectively signify hexadecimal, base64, and character-text formats
+without prefixes.
+.PP
+The
+.I format
+parameter of
+.IR datatot ,
+a single character used as a type code,
+specifies which text format is wanted.
+The value
+.B 0
+(not ASCII
+.BR '0' ,
+but a zero value) specifies a reasonable default.
+Other currently-supported values are:
+.RS 2
+.TP 4
+.B 'x'
+continuous lower-case hexadecimal with a
+.B 0x
+prefix
+.TP
+.B 'h'
+lower-case hexadecimal with a
+.B 0x
+prefix and a
+.B _
+every eight digits
+.TP
+.B ':'
+lower-case hexadecimal with no prefix and a
+.B :
+(colon) every two digits
+.TP
+.B 16
+lower-case hexadecimal with no prefix or
+.B _
+.TP
+.B 's'
+continuous base64 with a
+.B 0s
+prefix
+.TP
+.B 64
+continuous base64 with no prefix
+.RE
+.PP
+The default format is currently
+.BR 'h' .
+.PP
+.I Ttodata
+returns NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+On success,
+if and only if
+.I lenp
+is non-NULL,
+.B *lenp
+is set to the number of bytes required to contain the full untruncated result.
+It is the caller's responsibility to check this against
+.I dstlen
+to determine whether he has obtained a complete result.
+The
+.B *lenp
+value is correct even if
+.I dstlen
+is zero, which offers a way to determine how much space would be needed
+before having to allocate any.
+.PP
+.I Ttodatav
+is just like
+.I ttodata
+except that in certain cases,
+if
+.I errp
+is non-NULL,
+the buffer pointed to by
+.I errp
+(whose length is given by
+.IR errlen )
+is used to hold a more detailed error message.
+The return value is NULL for success,
+and is either
+.I errp
+or a pointer to a string literal for failure.
+If the size of the error-message buffer is
+inadequate for the desired message,
+.I ttodatav
+will fall back on returning a pointer to a literal string instead.
+The
+.I freeswan.h
+header file defines a constant
+.B TTODATAV_BUF
+which is the size of a buffer large enough for worst-case results.
+.PP
+The normal return value of
+.IR datatot
+is the number of bytes required
+to contain the full untruncated result.
+It is the caller's responsibility to check this against
+.I dstlen
+to determine whether he has obtained a complete result.
+The return value is correct even if
+.I dstlen
+is zero, which offers a way to determine how much space would be needed
+before having to allocate any.
+A return value of
+.B 0
+signals a fatal error of some kind
+(see DIAGNOSTICS).
+.PP
+A zero value for
+.I srclen
+in
+.I ttodata
+(but not
+.IR datatot !)
+is synonymous with
+.BR strlen(src) .
+A non-zero
+.I srclen
+in
+.I ttodata
+must not include the terminating NUL.
+.PP
+Unless
+.I dstlen
+is zero,
+the result supplied by
+.I datatot
+is always NUL-terminated,
+and its needed-size return value includes space for the terminating NUL.
+.PP
+Several obsolete variants of these functions
+.RI ( atodata ,
+.IR datatoa ,
+.IR atobytes ,
+and
+.IR bytestoa )
+are temporarily also supported.
+.SH SEE ALSO
+sprintf(3), ipsec_atoaddr(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I ttodata
+and
+.I ttodatav
+are:
+unknown characters in the input;
+unknown or missing prefix;
+unknown base;
+incomplete digit group;
+non-zero padding in a base64 less-than-three-bytes digit group;
+zero-length input.
+.PP
+Fatal errors in
+.I datatot
+are:
+unknown format code;
+zero-length input.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+.I Datatot
+should have a format code to produce character-text output.
+.PP
+The
+.B 0s
+and
+.B 0t
+prefixes are the author's inventions and are not a standard
+of any kind.
+They have been chosen to avoid collisions with existing practice
+(some C implementations use
+.B 0b
+for binary)
+and possible confusion with unprefixed hexadecimal.
diff --git a/src/libfreeswan/libfreeswan/ttodata.c b/src/libfreeswan/libfreeswan/ttodata.c
new file mode 100644
index 000000000..e1bf7606a
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttodata.c
@@ -0,0 +1,722 @@
+/*
+ * convert from text form of arbitrary data (e.g., keys) to binary
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ttodata.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/* converters and misc */
+static int unhex(const char *, char *, size_t);
+static int unb64(const char *, char *, size_t);
+static int untext(const char *, char *, size_t);
+static const char *badch(const char *, int, char *, size_t);
+
+/* internal error codes for converters */
+#define SHORT (-2) /* internal buffer too short */
+#define BADPAD (-3) /* bad base64 padding */
+#define BADCH0 (-4) /* invalid character 0 */
+#define BADCH1 (-5) /* invalid character 1 */
+#define BADCH2 (-6) /* invalid character 2 */
+#define BADCH3 (-7) /* invalid character 3 */
+#define BADOFF(code) (BADCH0-(code))
+
+/*
+ - ttodatav - convert text to data, with verbose error reports
+ * If some of this looks slightly odd, it's because it has changed
+ * repeatedly (from the original atodata()) without a major rewrite.
+ */
+const char * /* NULL on success, else literal or errp */
+ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen, flags)
+const char *src;
+size_t srclen; /* 0 means apply strlen() */
+int base; /* 0 means figure it out */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+size_t *lenp; /* where to record length (NULL is nowhere) */
+char *errp; /* error buffer */
+size_t errlen;
+unsigned int flags;
+{
+ size_t ingroup; /* number of input bytes converted at once */
+ char buf[4]; /* output from conversion */
+ int nbytes; /* size of output */
+ int (*decode)(const char *, char *, size_t);
+ char *stop;
+ int ndone;
+ int i;
+ int underscoreok;
+ int skipSpace = 0;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (dstlen == 0)
+ dst = buf; /* point it somewhere valid */
+ stop = dst + dstlen;
+
+ if (base == 0) {
+ if (srclen < 2)
+ return "input too short to be valid";
+ if (*src++ != '0')
+ return "input does not begin with format prefix";
+ switch (*src++) {
+ case 'x':
+ case 'X':
+ base = 16;
+ break;
+ case 's':
+ case 'S':
+ base = 64;
+ break;
+ case 't':
+ case 'T':
+ base = 256;
+ break;
+ default:
+ return "unknown format prefix";
+ }
+ srclen -= 2;
+ }
+ switch (base) {
+ case 16:
+ decode = unhex;
+ underscoreok = 1;
+ ingroup = 2;
+ break;
+ case 64:
+ decode = unb64;
+ underscoreok = 0;
+ ingroup = 4;
+ if(flags & TTODATAV_IGNORESPACE) {
+ skipSpace = 1;
+ }
+ break;
+
+ case 256:
+ decode = untext;
+ ingroup = 1;
+ underscoreok = 0;
+ break;
+ default:
+ return "unknown base";
+ }
+
+ /* proceed */
+ ndone = 0;
+ while (srclen > 0) {
+ char stage[4]; /* staging area for group */
+ size_t sl = 0;
+
+ /* Grab ingroup characters into stage,
+ * squeezing out blanks if we are supposed to ignore them.
+ */
+ for (sl = 0; sl < ingroup; src++, srclen--) {
+ if (srclen == 0)
+ return "input ends in mid-byte, perhaps truncated";
+ else if (!(skipSpace && (*src == ' ' || *src == '\t')))
+ stage[sl++] = *src;
+ }
+
+ nbytes = (*decode)(stage, buf, sizeof(buf));
+ switch (nbytes) {
+ case BADCH0:
+ case BADCH1:
+ case BADCH2:
+ case BADCH3:
+ return badch(stage, nbytes, errp, errlen);
+ case SHORT:
+ return "internal buffer too short (\"can't happen\")";
+ case BADPAD:
+ return "bad (non-zero) padding at end of base64 input";
+ }
+ if (nbytes <= 0)
+ return "unknown internal error";
+ for (i = 0; i < nbytes; i++) {
+ if (dst < stop)
+ *dst++ = buf[i];
+ ndone++;
+ }
+ while (srclen >= 1 && skipSpace && (*src == ' ' || *src == '\t')){
+ src++;
+ srclen--;
+ }
+ if (underscoreok && srclen > 1 && *src == '_') {
+ /* srclen > 1 means not last character */
+ src++;
+ srclen--;
+ }
+ }
+
+ if (ndone == 0)
+ return "no data bytes specified by input";
+ if (lenp != NULL)
+ *lenp = ndone;
+ return NULL;
+}
+
+/*
+ - ttodata - convert text to data
+ */
+const char * /* NULL on success, else literal */
+ttodata(src, srclen, base, dst, dstlen, lenp)
+const char *src;
+size_t srclen; /* 0 means apply strlen() */
+int base; /* 0 means figure it out */
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+size_t *lenp; /* where to record length (NULL is nowhere) */
+{
+ return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL,
+ (size_t)0, TTODATAV_SPACECOUNTS);
+}
+
+/*
+ - atodata - convert ASCII to data
+ * backward-compatibility interface
+ */
+size_t /* 0 for failure, true length for success */
+atodata(src, srclen, dst, dstlen)
+const char *src;
+size_t srclen;
+char *dst;
+size_t dstlen;
+{
+ size_t len;
+ const char *err;
+
+ err = ttodata(src, srclen, 0, dst, dstlen, &len);
+ if (err != NULL)
+ return 0;
+ return len;
+}
+
+/*
+ - atobytes - convert ASCII to data bytes
+ * another backward-compatibility interface
+ */
+const char *
+atobytes(src, srclen, dst, dstlen, lenp)
+const char *src;
+size_t srclen;
+char *dst;
+size_t dstlen;
+size_t *lenp;
+{
+ return ttodata(src, srclen, 0, dst, dstlen, lenp);
+}
+
+/*
+ - unhex - convert two ASCII hex digits to byte
+ */
+static int /* number of result bytes, or error code */
+unhex(src, dst, dstlen)
+const char *src; /* known to be full length */
+char *dst;
+size_t dstlen; /* not large enough is a failure */
+{
+ char *p;
+ unsigned byte;
+ static char hex[] = "0123456789abcdef";
+
+ if (dstlen < 1)
+ return SHORT;
+
+ p = strchr(hex, *src);
+ if (p == NULL)
+ p = strchr(hex, tolower(*src));
+ if (p == NULL)
+ return BADCH0;
+ byte = (p - hex) << 4;
+ src++;
+
+ p = strchr(hex, *src);
+ if (p == NULL)
+ p = strchr(hex, tolower(*src));
+ if (p == NULL)
+ return BADCH1;
+ byte |= (p - hex);
+
+ *dst = byte;
+ return 1;
+}
+
+/*
+ - unb64 - convert four ASCII base64 digits to three bytes
+ * Note that a base64 digit group is padded out with '=' if it represents
+ * less than three bytes: one byte is dd==, two is ddd=, three is dddd.
+ */
+static int /* number of result bytes, or error code */
+unb64(src, dst, dstlen)
+const char *src; /* known to be full length */
+char *dst;
+size_t dstlen;
+{
+ char *p;
+ unsigned byte1;
+ unsigned byte2;
+ static char base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ if (dstlen < 3)
+ return SHORT;
+
+ p = strchr(base64, *src++);
+
+ if (p == NULL)
+ return BADCH0;
+ byte1 = (p - base64) << 2; /* first six bits */
+
+ p = strchr(base64, *src++);
+ if (p == NULL) {
+ return BADCH1;
+ }
+
+ byte2 = p - base64; /* next six: two plus four */
+ *dst++ = byte1 | (byte2 >> 4);
+ byte1 = (byte2 & 0xf) << 4;
+
+ p = strchr(base64, *src++);
+ if (p == NULL) {
+ if (*(src-1) == '=' && *src == '=') {
+ if (byte1 != 0) /* bad padding */
+ return BADPAD;
+ return 1;
+ }
+ return BADCH2;
+ }
+
+ byte2 = p - base64; /* next six: four plus two */
+ *dst++ = byte1 | (byte2 >> 2);
+ byte1 = (byte2 & 0x3) << 6;
+
+ p = strchr(base64, *src++);
+ if (p == NULL) {
+ if (*(src-1) == '=') {
+ if (byte1 != 0) /* bad padding */
+ return BADPAD;
+ return 2;
+ }
+ return BADCH3;
+ }
+ byte2 = p - base64; /* last six */
+ *dst++ = byte1 | byte2;
+
+ return 3;
+}
+
+/*
+ - untext - convert one ASCII character to byte
+ */
+static int /* number of result bytes, or error code */
+untext(src, dst, dstlen)
+const char *src; /* known to be full length */
+char *dst;
+size_t dstlen; /* not large enough is a failure */
+{
+ if (dstlen < 1)
+ return SHORT;
+
+ *dst = *src;
+ return 1;
+}
+
+/*
+ - badch - produce a nice complaint about an unknown character
+ *
+ * If the compiler complains that the array bigenough[] has a negative
+ * size, that means the TTODATAV_BUF constant has been set too small.
+ */
+static const char * /* literal or errp */
+badch(src, errcode, errp, errlen)
+const char *src;
+int errcode;
+char *errp; /* might be NULL */
+size_t errlen;
+{
+ static const char pre[] = "unknown character (`";
+ static const char suf[] = "') in input";
+ char buf[5];
+# define REQD (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
+ struct sizecheck {
+ char bigenough[TTODATAV_BUF - REQD]; /* see above */
+ };
+ char ch;
+
+ if (errp == NULL || errlen < REQD)
+ return "unknown character in input";
+ strcpy(errp, pre);
+ ch = *(src + BADOFF(errcode));
+ if (isprint(ch)) {
+ buf[0] = ch;
+ buf[1] = '\0';
+ } else {
+ buf[0] = '\\';
+ buf[1] = ((ch & 0700) >> 6) + '0';
+ buf[2] = ((ch & 0070) >> 3) + '0';
+ buf[3] = ((ch & 0007) >> 0) + '0';
+ buf[4] = '\0';
+ }
+ strcat(errp, buf);
+ strcat(errp, suf);
+ return (const char *)errp;
+}
+
+
+
+#ifdef TTODATA_MAIN
+
+#include <stdio.h>
+
+struct artab;
+static void check(struct artab *r, char *buf, size_t n, err_t oops, int *status);
+static void regress(char *pgm);
+static void hexout(const char *s, size_t len, FILE *f);
+
+/*
+ - main - convert first argument to hex, or run regression
+ */
+int
+main(int argc, char *argv[])
+{
+ char buf[1024];
+ char buf2[1024];
+ char err[512];
+ size_t n;
+ size_t i;
+ char *p = buf;
+ char *p2 = buf2;
+ char *pgm = argv[0];
+ const char *oops;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {0x<hex>|0s<base64>|-r}\n", pgm);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress(pgm); /* should not return */
+ fprintf(stderr, "%s: regress() returned?!?\n", pgm);
+ exit(1);
+ }
+
+ oops = ttodatav(argv[1], 0, 0, buf, sizeof(buf), &n,
+ err, sizeof(err), TTODATAV_IGNORESPACE);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm,
+ oops, argv[1]);
+ exit(1);
+ }
+
+ if (n > sizeof(buf)) {
+ p = (char *)malloc((size_t)n);
+ if (p == NULL) {
+ fprintf(stderr,
+ "%s: unable to malloc %d bytes for result\n",
+ pgm, n);
+ exit(1);
+ }
+ oops = ttodata(argv[1], 0, 0, p, n, &n);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n",
+ pgm, oops);
+ exit(1);
+ }
+ }
+
+ hexout(p, n, stdout);
+ printf("\n");
+
+ i = datatot(buf, n, 'h', buf2, sizeof(buf2));
+ if (i == 0) {
+ fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm,
+ argv[1]);
+ exit(1);
+ }
+
+ if (i > sizeof(buf2)) {
+ p2 = (char *)malloc((size_t)i);
+ if (p == NULL) {
+ fprintf(stderr,
+ "%s: unable to malloc %d bytes for result\n",
+ pgm, i);
+ exit(1);
+ }
+ i = datatot(buf, n, 'h', p2, i);
+ if (i == 0) {
+ fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm);
+ exit(1);
+ }
+ }
+
+ printf("%s\n", p2);
+
+ exit(0);
+}
+
+/*
+ - hexout - output an arbitrary-length string in hex
+ */
+static void
+hexout(s, len, f)
+const char *s;
+size_t len;
+FILE *f;
+{
+ size_t i;
+
+ fprintf(f, "0x");
+ for (i = 0; i < len; i++)
+ fprintf(f, "%02x", (unsigned char)s[i]);
+}
+
+struct artab {
+ int base;
+# define IGNORESPACE_BIAS 1000
+ char *ascii; /* NULL for end */
+ char *data; /* NULL for error expected */
+} atodatatab[] = {
+ { 0, "", NULL, },
+ { 0, "0", NULL, },
+ { 0, "0x", NULL, },
+ { 0, "0xa", NULL, },
+ { 0, "0xab", "\xab", },
+ { 0, "0xabc", NULL, },
+ { 0, "0xabcd", "\xab\xcd", },
+ { 0, "0x0123456789", "\x01\x23\x45\x67\x89", },
+ { 0, "0x01x", NULL, },
+ { 0, "0xabcdef", "\xab\xcd\xef", },
+ { 0, "0xABCDEF", "\xab\xcd\xef", },
+ { 0, "0XaBc0eEd81f", "\xab\xc0\xee\xd8\x1f", },
+ { 0, "0XaBc0_eEd8", "\xab\xc0\xee\xd8", },
+ { 0, "0XaBc0_", NULL, },
+ { 0, "0X_aBc0", NULL, },
+ { 0, "0Xa_Bc0", NULL, },
+ { 16, "aBc0eEd8", "\xab\xc0\xee\xd8", },
+ { 0, "0s", NULL, },
+ { 0, "0sA", NULL, },
+ { 0, "0sBA", NULL, },
+ { 0, "0sCBA", NULL, },
+ { 0, "0sDCBA", "\x0c\x20\x40", },
+ { 0, "0SDCBA", "\x0c\x20\x40", },
+ { 0, "0sDA==", "\x0c", },
+ { 0, "0sDC==", NULL, },
+ { 0, "0sDCA=", "\x0c\x20", },
+ { 0, "0sDCB=", NULL, },
+ { 0, "0sDCAZ", "\x0c\x20\x19", },
+ { 0, "0sDCAa", "\x0c\x20\x1a", },
+ { 0, "0sDCAz", "\x0c\x20\x33", },
+ { 0, "0sDCA0", "\x0c\x20\x34", },
+ { 0, "0sDCA9", "\x0c\x20\x3d", },
+ { 0, "0sDCA+", "\x0c\x20\x3e", },
+ { 0, "0sDCA/", "\x0c\x20\x3f", },
+ { 0, "0sAbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0s AbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sA braCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAb raCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbr aCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbra Cadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraC adabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCa dabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCad abra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCada bra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCadab ra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCadabr a+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCadabra +", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { IGNORESPACE_BIAS + 0, "0sAbraCadabra+ ", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", },
+ { 0, "0t", NULL, },
+ { 0, "0tabc_xyz", "abc_xyz", },
+ { 256, "abc_xyz", "abc_xyz", },
+ { 0, NULL, NULL, },
+};
+
+struct drtab {
+ char *data; /* input; NULL for end */
+ char format;
+ int buflen; /* -1 means big buffer */
+ int outlen; /* -1 means strlen(ascii)+1 */
+ char *ascii; /* NULL for error expected */
+} datatoatab[] = {
+ { "", 'x', -1, -1, NULL, },
+ { "", 'X', -1, -1, NULL, },
+ { "", 'n', -1, -1, NULL, },
+ { "0", 'x', -1, -1, "0x30", },
+ { "0", 'x', 0, 5, "---", },
+ { "0", 'x', 1, 5, "", },
+ { "0", 'x', 2, 5, "0", },
+ { "0", 'x', 3, 5, "0x", },
+ { "0", 'x', 4, 5, "0x3", },
+ { "0", 'x', 5, 5, "0x30", },
+ { "0", 'x', 6, 5, "0x30", },
+ { "\xab\xcd", 'x', -1, -1, "0xabcd", },
+ { "\x01\x23\x45\x67\x89", 'x', -1, -1, "0x0123456789", },
+ { "\xab\xcd\xef", 'x', -1, -1, "0xabcdef", },
+ { "\xab\xc0\xee\xd8\x1f", 'x', -1, -1, "0xabc0eed81f", },
+ { "\x01\x02", 'h', -1, -1, "0x0102", },
+ { "\x01\x02\x03\x04\x05\x06", 'h', -1, -1, "0x01020304_0506", },
+ { "\xab\xc0\xee\xd8\x1f", 16, -1, -1, "abc0eed81f", },
+ { "\x0c\x20\x40", 's', -1, -1, "0sDCBA", },
+ { "\x0c\x20\x40", 's', 0, 7, "---", },
+ { "\x0c\x20\x40", 's', 1, 7, "", },
+ { "\x0c\x20\x40", 's', 2, 7, "0", },
+ { "\x0c\x20\x40", 's', 3, 7, "0s", },
+ { "\x0c\x20\x40", 's', 4, 7, "0sD", },
+ { "\x0c\x20\x40", 's', 5, 7, "0sDC", },
+ { "\x0c\x20\x40", 's', 6, 7, "0sDCB", },
+ { "\x0c\x20\x40", 's', 7, 7, "0sDCBA", },
+ { "\x0c\x20\x40", 's', 8, 7, "0sDCBA", },
+ { "\x0c", 's', -1, -1, "0sDA==", },
+ { "\x0c\x20", 's', -1, -1, "0sDCA=", },
+ { "\x0c\x20\x19", 's', -1, -1, "0sDCAZ", },
+ { "\x0c\x20\x1a", 's', -1, -1, "0sDCAa", },
+ { "\x0c\x20\x33", 's', -1, -1, "0sDCAz", },
+ { "\x0c\x20\x34", 's', -1, -1, "0sDCA0", },
+ { "\x0c\x20\x3d", 's', -1, -1, "0sDCA9", },
+ { "\x0c\x20\x3e", 's', -1, -1, "0sDCA+", },
+ { "\x0c\x20\x3f", 's', -1, -1, "0sDCA/", },
+ { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+", },
+ { "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+", },
+ { NULL, 'x', -1, -1, NULL, },
+};
+
+/*
+ - regress - regression-test ttodata() and datatot()
+ */
+static void
+check(r, buf, n, oops, status)
+struct artab *r;
+char *buf;
+size_t n;
+err_t oops;
+int *status;
+{
+ if (oops != NULL && r->data == NULL)
+ {} /* error expected */
+ else if (oops != NULL) {
+ printf("`%s' gave error `%s', expecting %d `", r->ascii,
+ oops, strlen(r->data));
+ hexout(r->data, strlen(r->data), stdout);
+ printf("'\n");
+ *status = 1;
+ } else if (r->data == NULL) {
+ printf("`%s' gave %d `", r->ascii, n);
+ hexout(buf, n, stdout);
+ printf("', expecting error\n");
+ *status = 1;
+ } else if (n != strlen(r->data)) {
+ printf("length wrong in `%s': got %d `", r->ascii, n);
+ hexout(buf, n, stdout);
+ printf("', expecting %d `", strlen(r->data));
+ hexout(r->data, strlen(r->data), stdout);
+ printf("'\n");
+ *status = 1;
+ } else if (memcmp(buf, r->data, n) != 0) {
+ printf("`%s' gave %d `", r->ascii, n);
+ hexout(buf, n, stdout);
+ printf("', expecting %d `", strlen(r->data));
+ hexout(r->data, strlen(r->data), stdout);
+ printf("'\n");
+ *status = 1;
+ }
+ fflush(stdout);
+}
+
+static void /* should not return at all, in fact */
+regress(pgm)
+char *pgm;
+{
+ struct artab *r;
+ struct drtab *dr;
+ char buf[100];
+ size_t n;
+ int status = 0;
+
+ for (r = atodatatab; r->ascii != NULL; r++) {
+ int base = r->base;
+ int xbase = 0;
+
+ if ((base == 0 || base == IGNORESPACE_BIAS + 0) && r->ascii[0] == '0') {
+ switch (r->ascii[1]) {
+ case 'x':
+ case 'X':
+ xbase = 16;
+ break;
+ case 's':
+ case 'S':
+ xbase = 64;
+ break;
+ case 't':
+ case 'T':
+ xbase = 256;
+ break;
+ }
+ }
+
+ if (base >= IGNORESPACE_BIAS) {
+ base = base - IGNORESPACE_BIAS;
+ check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
+ if (xbase != 0)
+ check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
+ } else {
+ check(r, buf, n, ttodata(r->ascii, 0, base, buf, sizeof(buf), &n), &status);
+ if (base == 64 || xbase == 64)
+ check(r, buf, n, ttodatav(r->ascii, 0, base, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
+ if (xbase != 0) {
+ check(r, buf, n, ttodata(r->ascii+2, 0, xbase, buf, sizeof(buf), &n), &status);
+ if (base == 64 || xbase == 64)
+ check(r, buf, n, ttodatav(r->ascii+2, 0, xbase, buf, sizeof(buf), &n, NULL, 0, TTODATAV_IGNORESPACE), &status);
+ }
+ }
+ }
+ for (dr = datatoatab; dr->data != NULL; dr++) {
+ size_t should;
+
+ strcpy(buf, "---");
+ n = datatot(dr->data, strlen(dr->data), dr->format, buf,
+ (dr->buflen == -1) ? sizeof(buf) : dr->buflen);
+ should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1;
+ if (dr->outlen != -1)
+ should = dr->outlen;
+ if (n == 0 && dr->ascii == NULL)
+ {} /* error expected */
+ else if (n == 0) {
+ printf("`");
+ hexout(dr->data, strlen(dr->data), stdout);
+ printf("' %c gave error, expecting %d `%s'\n",
+ dr->format, should, dr->ascii);
+ status = 1;
+ } else if (dr->ascii == NULL) {
+ printf("`");
+ hexout(dr->data, strlen(dr->data), stdout);
+ printf("' %c gave %d `%.*s', expecting error\n",
+ dr->format, n, (int)n, buf);
+ status = 1;
+ } else if (n != should) {
+ printf("length wrong in `");
+ hexout(dr->data, strlen(dr->data), stdout);
+ printf("': got %d `%s'", n, buf);
+ printf(", expecting %d `%s'\n", should, dr->ascii);
+ status = 1;
+ } else if (strcmp(buf, dr->ascii) != 0) {
+ printf("`");
+ hexout(dr->data, strlen(dr->data), stdout);
+ printf("' gave %d `%s'", n, buf);
+ printf(", expecting %d `%s'\n", should, dr->ascii);
+ status = 1;
+ }
+ fflush(stdout);
+ }
+ exit(status);
+}
+
+#endif /* TTODATA_MAIN */
diff --git a/src/libfreeswan/libfreeswan/ttoprotoport.c b/src/libfreeswan/libfreeswan/ttoprotoport.c
new file mode 100644
index 000000000..46321838c
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttoprotoport.c
@@ -0,0 +1,103 @@
+/*
+ * conversion from protocol/port string to protocol and port
+ * Copyright (C) 2002 Mario Strasser <mast@gmx.net>,
+ * Zuercher Hochschule Winterthur,
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: ttoprotoport.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ * ttoprotoport - converts from protocol/port string to protocol and port
+ */
+err_t
+ttoprotoport(src, src_len, proto, port, has_port_wildcard)
+char *src; /* input string */
+size_t src_len; /* length of input string, use strlen() if 0 */
+u_int8_t *proto; /* extracted protocol number */
+u_int16_t *port; /* extracted port number if it exists */
+int *has_port_wildcard; /* set if port is %any */
+{
+ char *end, *service_name;
+ char proto_name[16];
+ int proto_len;
+ long int l;
+ struct protoent *protocol;
+ struct servent *service;
+
+ /* get the length of the string */
+ if (!src_len) src_len = strlen(src);
+
+ /* locate delimiter '/' between protocol and port */
+ end = strchr(src, '/');
+ if (end != NULL) {
+ proto_len = end - src;
+ service_name = end + 1;
+ } else {
+ proto_len = src_len;
+ service_name = src + src_len;
+ }
+
+ /* copy protocol name*/
+ memset(proto_name, '\0', sizeof(proto_name));
+ memcpy(proto_name, src, proto_len);
+
+ /* extract protocol by trying to resolve it by name */
+ protocol = getprotobyname(proto_name);
+ if (protocol != NULL) {
+ *proto = protocol->p_proto;
+ }
+ else /* failed, now try it by number */
+ {
+ l = strtol(proto_name, &end, 0);
+
+ if (*proto_name && *end)
+ return "<protocol> is neither a number nor a valid name";
+
+ if (l < 0 || l > 0xff)
+ return "<protocol> must be between 0 and 255";
+
+ *proto = (u_int8_t)l;
+ }
+
+ /* is there a port wildcard? */
+ *has_port_wildcard = (strcmp(service_name, "%any") == 0);
+
+ if (*has_port_wildcard)
+ {
+ *port = 0;
+ return NULL;
+ }
+
+ /* extract port by trying to resolve it by name */
+ service = getservbyname(service_name, NULL);
+ if (service != NULL) {
+ *port = ntohs(service->s_port);
+ }
+ else /* failed, now try it by number */
+ {
+ l = strtol(service_name, &end, 0);
+
+ if (*service_name && *end)
+ return "<port> is neither a number nor a valid name";
+
+ if (l < 0 || l > 0xffff)
+ return "<port> must be between 0 and 65535";
+
+ *port = (u_int16_t)l;
+ }
+ return NULL;
+}
+
diff --git a/src/libfreeswan/libfreeswan/ttosa.3 b/src/libfreeswan/libfreeswan/ttosa.3
new file mode 100644
index 000000000..bf918e108
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttosa.3
@@ -0,0 +1,288 @@
+.TH IPSEC_TTOSA 3 "26 Nov 2001"
+.\" RCSID $Id: ttosa.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec ttosa, satot \- convert IPsec Security Association IDs to and from text
+.br
+ipsec initsaid \- initialize an SA ID
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "typedef struct {"
+.ti +1c
+.B "ip_address dst;"
+.ti +1c
+.B "ipsec_spi_t spi;"
+.ti +1c
+.B "int proto;"
+.br
+.B "} ip_said;"
+.sp
+.B "const char *ttosa(const char *src, size_t srclen,"
+.ti +1c
+.B "ip_said *sa);
+.br
+.B "size_t satot(const ip_said *sa, int format,"
+.ti +1c
+.B "char *dst, size_t dstlen);"
+.br
+.B "void initsaid(const ip_address *addr, ipsec_spi_t spi,"
+.ti +1c
+.B "int proto, ip_said *dst);"
+.SH DESCRIPTION
+.I Ttosa
+converts an ASCII Security Association (SA) specifier into an
+.B ip_said
+structure (containing
+a destination-host address
+in network byte order,
+an SPI number in network byte order, and
+a protocol code).
+.I Satot
+does the reverse conversion, back to a text SA specifier.
+.I Initsaid
+initializes an
+.B ip_said
+from separate items of information.
+.PP
+An SA is specified in text with a mail-like syntax, e.g.
+.BR esp.5a7@1.2.3.4 .
+An SA specifier contains
+a protocol prefix (currently
+.BR ah ,
+.BR esp ,
+.BR tun ,
+.BR comp ,
+or
+.BR int ),
+a single character indicating the address family
+.RB ( .
+for IPv4,
+.B :
+for IPv6),
+an unsigned integer SPI number in hexadecimal (with no
+.B 0x
+prefix),
+and an IP address.
+The IP address can be any form accepted by
+.IR ipsec_ttoaddr (3),
+e.g. dotted-decimal IPv4 address,
+colon-hex IPv6 address,
+or DNS name.
+.PP
+As a special case, the SA specifier
+.B %passthrough4
+or
+.B %passthrough6
+signifies the special SA used to indicate that packets should be
+passed through unaltered.
+(At present, these are synonyms for
+.B tun.0@0.0.0.0
+and
+.B tun:0@::
+respectively,
+but that is subject to change without notice.)
+.B %passthrough
+is a historical synonym for
+.BR %passthrough4 .
+These forms are known to both
+.I ttosa
+and
+.IR satot ,
+so the internal representation is never visible.
+.PP
+Similarly, the SA specifiers
+.BR %pass ,
+.BR %drop ,
+.BR %reject ,
+.BR %hold ,
+.BR %trap ,
+and
+.BR %trapsubnet
+signify special ``magic'' SAs used to indicate that packets should be
+passed, dropped, rejected (dropped with ICMP notification),
+held,
+and trapped (sent up to
+.IR ipsec_pluto (8),
+with either of two forms of
+.B %hold
+automatically installed)
+respectively.
+These forms too are known to both routines,
+so the internal representation of the magic SAs should never be visible.
+.PP
+The
+.B <freeswan.h>
+header file supplies the
+.B ip_said
+structure, as well as a data type
+.B ipsec_spi_t
+which is an unsigned 32-bit integer.
+(There is no consistency between kernel and user on what such a type
+is called, hence the header hides the differences.)
+.PP
+The protocol code uses the same numbers that IP does.
+For user convenience, given the difficulty in acquiring the exact set of
+protocol names used by the kernel,
+.B <freeswan.h>
+defines the names
+.BR SA_ESP ,
+.BR SA_AH ,
+.BR SA_IPIP ,
+and
+.BR SA_COMP
+to have the same values as the kernel names
+.BR IPPROTO_ESP ,
+.BR IPPROTO_AH ,
+.BR IPPROTO_IPIP ,
+and
+.BR IPPROTO_COMP .
+.PP
+.B <freeswan.h>
+also defines
+.BR SA_INT
+to have the value
+.BR 61
+(reserved by IANA for ``any host internal protocol'')
+and
+.BR SPI_PASS ,
+.BR SPI_DROP ,
+.BR SPI_REJECT ,
+.BR SPI_HOLD ,
+and
+.B SPI_TRAP
+to have the values 256-260 (in \fIhost\fR byte order) respectively.
+These are used in constructing the magic SAs
+(which always have address
+.BR 0.0.0.0 ).
+.PP
+If
+.I satot
+encounters an unknown protocol code, e.g. 77,
+it yields output using a prefix
+showing the code numerically, e.g. ``unk77''.
+This form is
+.I not
+recognized by
+.IR ttosa .
+.PP
+The
+.I srclen
+parameter of
+.I ttosa
+specifies the length of the string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I dstlen
+parameter of
+.I satot
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.B <freeswan.h>
+header file defines a constant,
+.BR SATOT_BUF ,
+which is the size of a buffer just large enough for worst-case results.
+.PP
+The
+.I format
+parameter of
+.I satot
+specifies what format is to be used for the conversion.
+The value
+.B 0
+(not the ASCII character
+.BR '0' ,
+but a zero value)
+specifies a reasonable default
+(currently
+lowercase protocol prefix, lowercase hexadecimal SPI,
+dotted-decimal or colon-hex address).
+The value
+.B 'f'
+is similar except that the SPI is padded with
+.BR 0 s
+to a fixed 32-bit width, to ease aligning displayed tables.
+.PP
+.I Ttosa
+returns
+.B NULL
+for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.I Satot
+returns
+.B 0
+for a failure, and otherwise
+always returns the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL;
+it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred.
+.PP
+There is also, temporarily, support for some obsolete
+forms of SA specifier which lack the address-family indicator.
+.SH SEE ALSO
+ipsec_ttoul(3), ipsec_ttoaddr(3), ipsec_samesaid(3), inet(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I ttosa
+are:
+empty input;
+input too small to be a legal SA specifier;
+no
+.B @
+in input;
+unknown protocol prefix;
+conversion error in
+.I ttoul
+or
+.IR ttoaddr .
+.PP
+Fatal errors in
+.I satot
+are:
+unknown format.
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+The restriction of text-to-binary error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The text-to-binary error-reporting convention lends itself
+to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = ttosa( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/ttosa.c b/src/libfreeswan/libfreeswan/ttosa.c
new file mode 100644
index 000000000..aa2283694
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttosa.c
@@ -0,0 +1,280 @@
+/*
+ * convert from text form of SA ID to binary
+ * Copyright (C) 2000, 2001 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ttosa.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+static struct satype {
+ char *prefix;
+ size_t prelen; /* strlen(prefix) */
+ int proto;
+} satypes[] = {
+ { "ah", 2, SA_AH },
+ { "esp", 3, SA_ESP },
+ { "tun", 3, SA_IPIP },
+ { "comp", 4, SA_COMP },
+ { "int", 3, SA_INT },
+ { NULL, 0, 0, }
+};
+
+static struct magic {
+ char *name;
+ char *really;
+} magic[] = {
+ { PASSTHROUGHNAME, PASSTHROUGH4IS },
+ { PASSTHROUGH4NAME, PASSTHROUGH4IS },
+ { PASSTHROUGH6NAME, PASSTHROUGH6IS },
+ { "%pass", "int256@0.0.0.0" },
+ { "%drop", "int257@0.0.0.0" },
+ { "%reject", "int258@0.0.0.0" },
+ { "%hold", "int259@0.0.0.0" },
+ { "%trap", "int260@0.0.0.0" },
+ { "%trapsubnet", "int261@0.0.0.0" },
+ { NULL, NULL }
+};
+
+/*
+ - ttosa - convert text "ah507@10.0.0.1" to SA identifier
+ */
+err_t /* NULL for success, else string literal */
+ttosa(src, srclen, sa)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+ip_said *sa;
+{
+ const char *at;
+ const char *addr;
+ size_t alen;
+ const char *spi = NULL;
+ struct satype *sat;
+ unsigned long ul;
+ const char *oops;
+ struct magic *mp;
+ size_t nlen;
+# define MINLEN 5 /* ah0@0 is as short as it can get */
+ int af;
+ int base;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+ if (srclen < MINLEN)
+ return "string too short to be SA identifier";
+ if (*src == '%') {
+ for (mp = magic; mp->name != NULL; mp++) {
+ nlen = strlen(mp->name);
+ if (srclen == nlen && memcmp(src, mp->name, nlen) == 0)
+ break;
+ }
+ if (mp->name == NULL)
+ return "unknown % keyword";
+ src = mp->really;
+ srclen = strlen(src);
+ }
+
+ at = memchr(src, '@', srclen);
+ if (at == NULL)
+ return "no @ in SA specifier";
+
+ for (sat = satypes; sat->prefix != NULL; sat++)
+ if (sat->prelen < srclen &&
+ strncmp(src, sat->prefix, sat->prelen) == 0) {
+ sa->proto = sat->proto;
+ spi = src + sat->prelen;
+ break; /* NOTE BREAK OUT */
+ }
+ if (sat->prefix == NULL)
+ return "SA specifier lacks valid protocol prefix";
+
+ if (spi >= at)
+ return "no SPI in SA specifier";
+ switch (*spi) {
+ case '.':
+ af = AF_INET;
+ spi++;
+ base = 16;
+ break;
+ case ':':
+ af = AF_INET6;
+ spi++;
+ base = 16;
+ break;
+ default:
+ af = AF_UNSPEC; /* not known yet */
+ base = 0;
+ break;
+ }
+ if (spi >= at)
+ return "no SPI found in SA specifier";
+ oops = ttoul(spi, at - spi, base, &ul);
+ if (oops != NULL)
+ return oops;
+ sa->spi = htonl(ul);
+
+ addr = at + 1;
+ alen = srclen - (addr - src);
+ if (af == AF_UNSPEC)
+ af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET;
+ oops = ttoaddr(addr, alen, af, &sa->dst);
+ if (oops != NULL)
+ return oops;
+
+ return NULL;
+}
+
+
+
+#ifdef TTOSA_MAIN
+
+#include <stdio.h>
+
+void regress(void);
+
+int
+main(int argc, char *argv[])
+{
+ ip_said sa;
+ char buf[100];
+ char buf2[100];
+ const char *oops;
+ size_t n;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ oops = ttosa(argv[1], 0, &sa);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ n = satot(&sa, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto);
+ fprintf(stderr, "%lx@", (long unsigned int)sa.spi);
+ (void) addrtot(&sa.dst, 0, buf2, sizeof(buf2));
+ fprintf(stderr, "%s", buf2);
+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
+ (long)n, (long)sizeof(buf));
+ exit(1);
+ }
+ printf("%s\n", buf);
+
+ exit(0);
+}
+
+struct rtab {
+ int format;
+# define FUDGE 0x1000
+ char *input;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {0, "esp257@1.2.3.0", "esp.101@1.2.3.0"},
+ {0, "ah0x20@1.2.3.4", "ah.20@1.2.3.4"},
+ {0, "tun20@1.2.3.4", "tun.14@1.2.3.4"},
+ {0, "comp20@1.2.3.4", "comp.14@1.2.3.4"},
+ {0, "esp257@::1", "esp:101@::1"},
+ {0, "esp257@0bc:12de::1", "esp:101@bc:12de::1"},
+ {0, "esp78@1049:1::8007:2040", "esp:4e@1049:1::8007:2040"},
+ {0, "esp0x78@1049:1::8007:2040", "esp:78@1049:1::8007:2040"},
+ {0, "ah78@1049:1::8007:2040", "ah:4e@1049:1::8007:2040"},
+ {0, "ah0x78@1049:1::8007:2040", "ah:78@1049:1::8007:2040"},
+ {0, "tun78@1049:1::8007:2040", "tun:4e@1049:1::8007:2040"},
+ {0, "tun0x78@1049:1::8007:2040", "tun:78@1049:1::8007:2040"},
+ {0, "duk99@3ffe:370:400:ff::9001:3001", NULL},
+ {0, "esp78x@1049:1::8007:2040", NULL},
+ {0, "esp0x78@1049:1:0xfff::8007:2040", NULL},
+ {0, "es78@1049:1::8007:2040", NULL},
+ {0, "", NULL},
+ {0, "_", NULL},
+ {0, "ah2.2", NULL},
+ {0, "goo2@1.2.3.4", NULL},
+ {0, "esp9@1.2.3.4", "esp.9@1.2.3.4"},
+ {'f', "esp0xa9@1.2.3.4", "esp.000000a9@1.2.3.4"},
+ {0, "espp9@1.2.3.4", NULL},
+ {0, "es9@1.2.3.4", NULL},
+ {0, "ah@1.2.3.4", NULL},
+ {0, "esp7x7@1.2.3.4", NULL},
+ {0, "esp77@1.0x2.3.4", NULL},
+ {0, PASSTHROUGHNAME, PASSTHROUGH4NAME},
+ {0, PASSTHROUGH6NAME, PASSTHROUGH6NAME},
+ {0, "%pass", "%pass"},
+ {0, "int256@0.0.0.0", "%pass"},
+ {0, "%drop", "%drop"},
+ {0, "int257@0.0.0.0", "%drop"},
+ {0, "%reject", "%reject"},
+ {0, "int258@0.0.0.0", "%reject"},
+ {0, "%hold", "%hold"},
+ {0, "int259@0.0.0.0", "%hold"},
+ {0, "%trap", "%trap"},
+ {0, "int260@0.0.0.0", "%trap"},
+ {0, "%trapsubnet", "%trapsubnet"},
+ {0, "int261@0.0.0.0", "%trapsubnet"},
+ {0, "int262@0.0.0.0", "int.106@0.0.0.0"},
+ {FUDGE, "esp9@1.2.3.4", "unk77.9@1.2.3.4"},
+ {0, NULL, NULL}
+};
+
+void
+regress(void)
+{
+ struct rtab *r;
+ int status = 0;
+ ip_said sa;
+ char in[100];
+ char buf[100];
+ const char *oops;
+ size_t n;
+
+ for (r = rtab; r->input != NULL; r++) {
+ strcpy(in, r->input);
+ oops = ttosa(in, 0, &sa);
+ if (oops != NULL && r->output == NULL)
+ {} /* okay, error expected */
+ else if (oops != NULL) {
+ printf("`%s' ttosa failed: %s\n", r->input, oops);
+ status = 1;
+ } else if (r->output == NULL) {
+ printf("`%s' ttosa succeeded unexpectedly\n",
+ r->input);
+ status = 1;
+ } else {
+ if (r->format&FUDGE)
+ sa.proto = 77;
+ n = satot(&sa, (char)r->format, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ printf("`%s' satot failed: need %ld\n",
+ r->input, (long)n);
+ status = 1;
+ } else if (strcmp(r->output, buf) != 0) {
+ printf("`%s' gave `%s', expected `%s'\n",
+ r->input, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* TTOSA_MAIN */
diff --git a/src/libfreeswan/libfreeswan/ttosubnet.c b/src/libfreeswan/libfreeswan/ttosubnet.c
new file mode 100644
index 000000000..7f5cddb82
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttosubnet.c
@@ -0,0 +1,296 @@
+/*
+ * convert from text form of subnet specification to binary
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ttosubnet.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+#ifndef DEFAULTSUBNET
+#define DEFAULTSUBNET "%default"
+#endif
+
+/*
+ - ttosubnet - convert text "addr/mask" to address and mask
+ * Mask can be integer bit count.
+ */
+err_t
+ttosubnet(src, srclen, af, dst)
+const char *src;
+size_t srclen; /* 0 means "apply strlen" */
+int af; /* AF_INET or AF_INET6 */
+ip_subnet *dst;
+{
+ const char *slash;
+ const char *colon;
+ const char *mask;
+ size_t mlen;
+ const char *oops;
+ unsigned long bc;
+ static char def[] = DEFAULTSUBNET;
+# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */
+ static char defis4[] = "0/0";
+# define DEFIS4LEN (sizeof(defis4) - 1)
+ static char defis6[] = "::/0";
+# define DEFIS6LEN (sizeof(defis6) - 1)
+ ip_address addrtmp;
+ ip_address masktmp;
+ int nbits;
+ int i;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+
+ switch (af) {
+ case AF_INET:
+ nbits = 32;
+ break;
+ case AF_INET6:
+ nbits = 128;
+ break;
+ default:
+ return "unknown address family in ttosubnet";
+ break;
+ }
+
+ if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) {
+ src = (af == AF_INET) ? defis4 : defis6;
+ srclen = (af == AF_INET) ? DEFIS4LEN : DEFIS6LEN;
+ }
+
+ slash = memchr(src, '/', srclen);
+ if (slash == NULL)
+ return "no / in subnet specification";
+ mask = slash + 1;
+ mlen = srclen - (mask - src);
+
+ oops = ttoaddr(src, slash-src, af, &addrtmp);
+ if (oops != NULL)
+ return oops;
+
+ /* extract port */
+ colon = memchr(mask, ':', mlen);
+ if (colon == 0)
+ {
+ setportof(0, &addrtmp);
+ }
+ else
+ {
+ long port;
+
+ oops = ttoul(colon+1, mlen-(colon-mask+1), 10, &port);
+ if (oops != NULL)
+ return oops;
+ setportof(htons(port), &addrtmp);
+ mlen = colon - mask;
+ }
+
+ /*extract mask */
+ oops = ttoul(mask, mlen, 10, &bc);
+ if (oops == NULL) {
+ /* ttoul succeeded, it's a bit-count mask */
+ if (bc > nbits)
+ return "subnet mask bit count too large";
+ i = bc;
+ } else {
+ oops = ttoaddr(mask, mlen, af, &masktmp);
+ if (oops != NULL)
+ return oops;
+ i = masktocount(&masktmp);
+ if (i < 0)
+ return "non-contiguous or otherwise erroneous mask";
+ }
+
+ return initsubnet(&addrtmp, i, '0', dst);
+}
+
+
+
+#ifdef TTOSUBNET_MAIN
+
+#include <stdio.h>
+
+void regress(void);
+
+int main(int argc, char *argv[])
+{
+ ip_subnet s;
+ char buf[100];
+ char buf2[100];
+ const char *oops;
+ size_t n;
+ int af;
+ char *p;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s [-6] addr/mask\n", argv[0]);
+ fprintf(stderr, " or: %s -r\n", argv[0]);
+ exit(2);
+ }
+
+ if (strcmp(argv[1], "-r") == 0) {
+ regress();
+ fprintf(stderr, "regress() returned?!?\n");
+ exit(1);
+ }
+
+ af = AF_INET;
+ p = argv[1];
+ if (strcmp(argv[1], "-6") == 0) {
+ af = AF_INET6;
+ p = argv[2];
+ } else if (strchr(argv[1], ':') != NULL)
+ af = AF_INET6;
+
+ oops = ttosubnet(p, 0, af, &s);
+ if (oops != NULL) {
+ fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops);
+ exit(1);
+ }
+ n = subnettot(&s, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ fprintf(stderr, "%s: reverse conversion of ", argv[0]);
+ (void) addrtot(&s.addr, 0, buf2, sizeof(buf2));
+ fprintf(stderr, "%s/", buf2);
+ fprintf(stderr, "%d", s.maskbits);
+ fprintf(stderr, " failed: need %ld bytes, have only %ld\n",
+ (long)n, (long)sizeof(buf));
+ exit(1);
+ }
+ printf("%s\n", buf);
+
+ exit(0);
+}
+
+struct rtab {
+ int family;
+ char *input;
+ char *output; /* NULL means error expected */
+} rtab[] = {
+ {4, "1.2.3.0/255.255.255.0", "1.2.3.0/24"},
+ {4, "1.2.3.0/24", "1.2.3.0/24"},
+ {4, "1.2.3.0/24:10", "1.2.3.0/24:10"},
+ {4, "1.2.3.0/24:-1", NULL},
+ {4, "1.2.3.0/24:none", NULL},
+ {4, "1.2.3.0/24:", NULL},
+ {4, "1.2.3.0/24:0x10", "1.2.3.0/24:16"},
+ {4, "1.2.3.0/24:0X10", "1.2.3.0/24:16"},
+ {4, "1.2.3.0/24:010", "1.2.3.0/24:8"},
+ {4, "1.2.3.1/255.255.255.240", "1.2.3.0/28"},
+ {4, "1.2.3.1/32", "1.2.3.1/32"},
+ {4, "1.2.3.1/0", "0.0.0.0/0"},
+/* {4, "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0"}, */
+ {4, "1.2.3.1/255.255.127.0", NULL},
+ {4, "128.009.000.032/32", "128.9.0.32/32"},
+ {4, "128.0x9.0.32/32", NULL},
+ {4, "0x80090020/32", "128.9.0.32/32"},
+ {4, "0x800x0020/32", NULL},
+ {4, "128.9.0.32/0xffFF0000", "128.9.0.0/16"},
+ {4, "128.9.0.32/0xff0000FF", NULL},
+ {4, "128.9.0.32/0x0000ffFF", NULL},
+ {4, "128.9.0.32/0x00ffFF0000", NULL},
+ {4, "128.9.0.32/0xffFF", NULL},
+ {4, "128.9.0.32.27/32", NULL},
+ {4, "128.9.0k32/32", NULL},
+ {4, "328.9.0.32/32", NULL},
+ {4, "128.9..32/32", NULL},
+ {4, "10/8", "10.0.0.0/8"},
+ {4, "10.0/8", "10.0.0.0/8"},
+ {4, "10.0.0/8", "10.0.0.0/8"},
+ {4, "10.0.1/24", "10.0.1.0/24"},
+ {4, "_", NULL},
+ {4, "_/_", NULL},
+ {4, "1.2.3.1", NULL},
+ {4, "1.2.3.1/_", NULL},
+ {4, "1.2.3.1/24._", NULL},
+ {4, "1.2.3.1/99", NULL},
+ {4, "localhost/32", "127.0.0.1/32"},
+ {4, "%default", "0.0.0.0/0"},
+ {6, "3049:1::8007:2040/0", "::/0"},
+ {6, "3049:1::8007:2040/128", "3049:1::8007:2040/128"},
+ {6, "3049:1::192.168.0.1/128", NULL}, /*"3049:1::c0a8:1/128",*/
+ {6, "3049:1::8007::2040/128", NULL},
+ {6, "3049:1::8007:2040/ffff::0", "3049::/16"},
+ {6, "3049:1::8007:2040/64", "3049:1::/64"},
+ {6, "3049:1::8007:2040/ffff::", "3049::/16"},
+ {6, "3049:1::8007:2040/0000:ffff::0", NULL},
+ {6, "3049:1::8007:2040/ff1f::0", NULL},
+ {6, "3049:1::8007:x:2040/128", NULL},
+ {6, "3049:1t::8007:2040/128", NULL},
+ {6, "3049:1::80071:2040/128", NULL},
+ {6, "::/21", "::/21"},
+ {6, "::1/128", "::1/128"},
+ {6, "1::/21", "1::/21"},
+ {6, "1::2/128", "1::2/128"},
+ {6, "1:0:0:0:0:0:0:2/128", "1::2/128"},
+ {6, "1:0:0:0:3:0:0:2/128", "1::3:0:0:2/128"},
+ {6, "1:0:0:3:0:0:0:2/128", "1::3:0:0:0:2/128"},
+ {6, "1:0:3:0:0:0:0:2/128", "1:0:3::2/128"},
+ {6, "abcd:ef01:2345:6789:0:00a:000:20/128", "abcd:ef01:2345:6789:0:a:0:20/128"},
+ {6, "3049:1::8007:2040/ffff:ffff:", NULL},
+ {6, "3049:1::8007:2040/ffff:88::", NULL},
+ {6, "3049:12::9000:3200/ffff:fff0::", "3049:10::/28"},
+ {6, "3049:12::9000:3200/28", "3049:10::/28"},
+ {6, "3049:12::9000:3200/ff00:::", NULL},
+ {6, "3049:12::9000:3200/ffff:::", NULL},
+ {6, "3049:12::9000:3200/128_", NULL},
+ {6, "3049:12::9000:3200/", NULL},
+ {6, "%default", "::/0"},
+ {4, NULL, NULL}
+};
+
+void
+regress(void)
+{
+ struct rtab *r;
+ int status = 0;
+ ip_subnet s;
+ char in[100];
+ char buf[100];
+ const char *oops;
+ size_t n;
+ int af;
+
+ for (r = rtab; r->input != NULL; r++) {
+ af = (r->family == 4) ? AF_INET : AF_INET6;
+ strcpy(in, r->input);
+ oops = ttosubnet(in, 0, af, &s);
+ if (oops != NULL && r->output == NULL)
+ {} /* okay, error expected */
+ else if (oops != NULL) {
+ printf("`%s' ttosubnet failed: %s\n", r->input, oops);
+ status = 1;
+ } else if (r->output == NULL) {
+ printf("`%s' ttosubnet succeeded unexpectedly\n",
+ r->input);
+ status = 1;
+ } else {
+ n = subnettot(&s, 0, buf, sizeof(buf));
+ if (n > sizeof(buf)) {
+ printf("`%s' subnettot failed: need %ld\n",
+ r->input, (long)n);
+ status = 1;
+ } else if (strcmp(r->output, buf) != 0) {
+ printf("`%s' gave `%s', expected `%s'\n",
+ r->input, buf, r->output);
+ status = 1;
+ }
+ }
+ }
+ exit(status);
+}
+
+#endif /* TTOSUBNET_MAIN */
diff --git a/src/libfreeswan/libfreeswan/ttoul.3 b/src/libfreeswan/libfreeswan/ttoul.3
new file mode 100644
index 000000000..67d4bd34f
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttoul.3
@@ -0,0 +1,192 @@
+.TH IPSEC_TTOUL 3 "16 Aug 2000"
+.\" RCSID $Id: ttoul.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec ttoul, ultot \- convert unsigned-long numbers to and from text
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *ttoul(const char *src, size_t srclen,"
+.ti +1c
+.B "int base, unsigned long *n);"
+.br
+.B "size_t ultot(unsigned long n, int format, char *dst,"
+.ti +1c
+.B "size_t dstlen);"
+.SH DESCRIPTION
+.I Ttoul
+converts a text-string number into a binary
+.B "unsigned long"
+value.
+.I Ultot
+does the reverse conversion, back to a text version.
+.PP
+Numbers are specified in text as
+decimal (e.g.
+.BR 123 ),
+octal with a leading zero (e.g.
+.BR 012 ,
+which has value 10),
+or hexadecimal with a leading
+.B 0x
+(e.g.
+.BR 0x1f ,
+which has value 31)
+in either upper or lower case.
+.PP
+The
+.I srclen
+parameter of
+.I ttoul
+specifies the length of the string pointed to by
+.IR src ;
+it is an error for there to be anything else
+(e.g., a terminating NUL) within that length.
+As a convenience for cases where an entire NUL-terminated string is
+to be converted,
+a
+.I srclen
+value of
+.B 0
+is taken to mean
+.BR strlen(src) .
+.PP
+The
+.I base
+parameter of
+.I ttoul
+can be
+.BR 8 ,
+.BR 10 ,
+or
+.BR 16 ,
+in which case the number supplied is assumed to be of that form
+(and in the case of
+.BR 16 ,
+to lack any
+.B 0x
+prefix).
+It can also be
+.BR 0 ,
+in which case the number is examined for a leading zero
+or a leading
+.B 0x
+to determine its base.
+.PP
+The
+.I dstlen
+parameter of
+.I ultot
+specifies the size of the
+.I dst
+parameter;
+under no circumstances are more than
+.I dstlen
+bytes written to
+.IR dst .
+A result which will not fit is truncated.
+.I Dstlen
+can be zero, in which case
+.I dst
+need not be valid and no result is written,
+but the return value is unaffected;
+in all other cases, the (possibly truncated) result is NUL-terminated.
+The
+.I freeswan.h
+header file defines a constant,
+.BR ULTOT_BUF ,
+which is the size of a buffer just large enough for worst-case results.
+.PP
+The
+.I format
+parameter of
+.I ultot
+must be one of:
+.RS
+.IP \fB'o'\fR 4
+octal conversion with leading
+.B 0
+.IP \fB\ 8\fR
+octal conversion with no leading
+.B 0
+.IP \fB'd'\fR
+decimal conversion
+.IP \fB10\fR
+same as
+.B d
+.IP \fB'x'\fR
+hexadecimal conversion, including leading
+.B 0x
+.IP \fB16\fR
+hexadecimal conversion with no leading
+.B 0x
+.IP \fB17\fR
+like
+.B 16
+except padded on left with
+.BR 0 s
+to eight digits (full width of a 32-bit number)
+.RE
+.PP
+.I Ttoul
+returns NULL for success and
+a pointer to a string-literal error message for failure;
+see DIAGNOSTICS.
+.I Ultot
+returns
+.B 0
+for a failure, and otherwise
+returns the size of buffer which would
+be needed to
+accommodate the full conversion result, including terminating NUL
+(it is the caller's responsibility to check this against the size of
+the provided buffer to determine whether truncation has occurred).
+.SH SEE ALSO
+atol(3), strtoul(3)
+.SH DIAGNOSTICS
+Fatal errors in
+.I ttoul
+are:
+empty input;
+unknown
+.IR base ;
+non-digit character found;
+number too large for an
+.BR "unsigned long" .
+.PP
+Fatal errors in
+.I ultot
+are:
+unknown
+.IR format .
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
+.SH BUGS
+Conversion of
+.B 0
+with format
+.B o
+yields
+.BR 00 .
+.PP
+.I Ultot
+format
+.B 17
+is a bit of a kludge.
+.PP
+The restriction of error reports to literal strings
+(so that callers don't need to worry about freeing them or copying them)
+does limit the precision of error reporting.
+.PP
+The error-reporting convention lends itself to slightly obscure code,
+because many readers will not think of NULL as signifying success.
+A good way to make it clearer is to write something like:
+.PP
+.RS
+.nf
+.B "const char *error;"
+.sp
+.B "error = ttoul( /* ... */ );"
+.B "if (error != NULL) {"
+.B " /* something went wrong */"
+.fi
+.RE
diff --git a/src/libfreeswan/libfreeswan/ttoul.c b/src/libfreeswan/libfreeswan/ttoul.c
new file mode 100644
index 000000000..9c6193c68
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ttoul.c
@@ -0,0 +1,91 @@
+/*
+ * convert from text form of unsigned long to binary
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ttoul.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - ttoul - convert text substring to unsigned long number
+ */
+const char * /* NULL for success, else string literal */
+ttoul(src, srclen, base, resultp)
+const char *src;
+size_t srclen; /* 0 means strlen(src) */
+int base; /* 0 means figure it out */
+unsigned long *resultp;
+{
+ const char *stop;
+ static char hex[] = "0123456789abcdef";
+ static char uchex[] = "0123456789ABCDEF";
+ int d;
+ char c;
+ char *p;
+ unsigned long r;
+ unsigned long rlimit;
+ int dlimit;
+
+ if (srclen == 0)
+ srclen = strlen(src);
+ if (srclen == 0)
+ return "empty string";
+
+ if (base == 0) {
+ if (srclen > 2 && *src == '0' &&
+ (*(src+1) == 'x' || *(src+1) == 'X'))
+ return ttoul(src+2, srclen-2, 16, resultp);
+ if (srclen > 1 && *src == '0')
+ return ttoul(src+1, srclen-1, 8, resultp);
+ return ttoul(src, srclen, 10, resultp);
+ }
+ if (base != 8 && base != 10 && base != 16)
+ return "unsupported number base";
+
+ r = 0;
+ stop = src + srclen;
+ if (base == 16) {
+ while (src < stop) {
+ c = *src++;
+ p = strchr(hex, c);
+ if (p != NULL)
+ d = p - hex;
+ else {
+ p = strchr(uchex, c);
+ if (p == NULL)
+ return "non-hex digit in hex number";
+ d = p - uchex;
+ }
+ r = (r << 4) | d;
+ }
+ /* defer length check to catch invalid digits first */
+ if (srclen > sizeof(unsigned long) * 2)
+ return "hex number too long";
+ } else {
+ rlimit = ULONG_MAX / base;
+ dlimit = (int)(ULONG_MAX - rlimit*base);
+ while (src < stop) {
+ c = *src++;
+ d = c - '0';
+ if (d < 0 || d >= base)
+ return "non-digit in number";
+ if (r > rlimit || (r == rlimit && d > dlimit))
+ return "unsigned-long overflow";
+ r = r*base + d;
+ }
+ }
+
+ *resultp = r;
+ return NULL;
+}
diff --git a/src/libfreeswan/libfreeswan/ultoa.c b/src/libfreeswan/libfreeswan/ultoa.c
new file mode 100644
index 000000000..2c2644826
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ultoa.c
@@ -0,0 +1,67 @@
+/*
+ * convert unsigned long to ASCII
+ * Copyright (C) 1998, 1999 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ultoa.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - ultoa - convert unsigned long to decimal ASCII
+ */
+size_t /* length required for full conversion */
+ultoa(n, base, dst, dstlen)
+unsigned long n;
+int base;
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ char buf[3*sizeof(unsigned long) + 1];
+ char *bufend = buf + sizeof(buf);
+ size_t len;
+ char *p;
+ static char hex[] = "0123456789abcdef";
+
+ p = bufend;
+ *--p = '\0';
+ if (base == 10) {
+ do {
+ *--p = n%10 + '0';
+ n /= 10;
+ } while (n != 0);
+ } else if (base == 16) {
+ do {
+ *--p = hex[n&0xf];
+ n >>= 4;
+ } while (n != 0);
+ *--p = 'x';
+ *--p = '0';
+ } else if (base == 8) {
+ do {
+ *--p = (n&07) + '0';
+ n >>= 3;
+ } while (n != 0);
+ *--p = '0';
+ } else
+ *--p = '?';
+
+ len = bufend - p;
+
+ if (dstlen > 0) {
+ if (len > dstlen)
+ *(p + dstlen - 1) = '\0';
+ strcpy(dst, p);
+ }
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/ultot.c b/src/libfreeswan/libfreeswan/ultot.c
new file mode 100644
index 000000000..edffa4a2d
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/ultot.c
@@ -0,0 +1,83 @@
+/*
+ * convert unsigned long to text
+ * Copyright (C) 2000 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: ultot.c,v 1.1 2004/03/15 20:35:26 as Exp $
+ */
+#include "internal.h"
+#include "freeswan.h"
+
+/*
+ - ultot - convert unsigned long to text
+ */
+size_t /* length required for full conversion */
+ultot(n, base, dst, dstlen)
+unsigned long n;
+int base;
+char *dst; /* need not be valid if dstlen is 0 */
+size_t dstlen;
+{
+ char buf[3*sizeof(unsigned long) + 1];
+ char *bufend = buf + sizeof(buf);
+ size_t len;
+ char *p;
+ static char hex[] = "0123456789abcdef";
+# define HEX32 (32/4)
+
+ p = bufend;
+ *--p = '\0';
+ switch (base) {
+ case 10:
+ case 'd':
+ do {
+ *--p = n%10 + '0';
+ n /= 10;
+ } while (n != 0);
+ break;
+ case 16:
+ case 17:
+ case 'x':
+ do {
+ *--p = hex[n&0xf];
+ n >>= 4;
+ } while (n != 0);
+ if (base == 17)
+ while (bufend - p < HEX32 + 1)
+ *--p = '0';
+ if (base == 'x') {
+ *--p = 'x';
+ *--p = '0';
+ }
+ break;
+ case 8:
+ case 'o':
+ do {
+ *--p = (n&07) + '0';
+ n >>= 3;
+ } while (n != 0);
+ if (base == 'o')
+ *--p = '0';
+ break;
+ default:
+ return 0;
+ break;
+ }
+
+ len = bufend - p;
+ if (dstlen > 0) {
+ if (len > dstlen)
+ *(p + dstlen - 1) = '\0';
+ strcpy(dst, p);
+ }
+ return len;
+}
diff --git a/src/libfreeswan/libfreeswan/version.3 b/src/libfreeswan/libfreeswan/version.3
new file mode 100644
index 000000000..06c5f01e3
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/version.3
@@ -0,0 +1,44 @@
+.TH IPSEC_VERSION 3 "21 Nov 2001"
+.\" RCSID $Id: version.3,v 1.1 2004/03/15 20:35:26 as Exp $
+.SH NAME
+ipsec ipsec_version_code \- get IPsec version code
+.br
+ipsec ipsec_version_string \- get full IPsec version string
+.br
+ipsec ipsec_copyright_notice \- get IPsec copyright notice
+.SH SYNOPSIS
+.B "#include <freeswan.h>
+.sp
+.B "const char *ipsec_version_code(void);"
+.br
+.B "const char *ipsec_version_string(void);"
+.br
+.B "const char **ipsec_copyright_notice(void);"
+.SH DESCRIPTION
+These functions provide information on version numbering and copyright
+of the Linux FreeS/WAN IPsec implementation.
+.PP
+.I Ipsec_version_code
+returns a pointer to a string constant
+containing the current IPsec version code,
+such as ``1.92'' or ``snap2001Nov19b''.
+.PP
+.I Ipsec_version_string
+returns a pointer to a string constant giving a full version identification,
+consisting of the version code preceded by a prefix identifying the software,
+e.g. ``Linux FreeS/WAN 1.92''.
+.PP
+.I Ipsec_copyright_notice
+returns a pointer to a vector of pointers,
+terminated by a
+.BR NULL ,
+which is the text of a suitable copyright notice.
+Each pointer points to a string constant (possibly empty) which is one line
+of the somewhat-verbose copyright notice.
+The strings are NUL-terminated and do not contain a newline;
+supplying suitable line termination for the output device is
+the caller's responsibility.
+.SH SEE ALSO
+ipsec(8)
+.SH HISTORY
+Written for the FreeS/WAN project by Henry Spencer.
diff --git a/src/libfreeswan/libfreeswan/version.in.c b/src/libfreeswan/libfreeswan/version.in.c
new file mode 100644
index 000000000..b3556f721
--- /dev/null
+++ b/src/libfreeswan/libfreeswan/version.in.c
@@ -0,0 +1,44 @@
+/*
+ * return IPsec version information
+ * Copyright (C) 2001 Henry Spencer.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: version.in.c,v 1.2 2004/03/16 12:26:32 as Exp $
+ */
+
+#ifdef __KERNEL__
+#include <linux/netdevice.h>
+#endif
+
+#include "freeswan.h"
+
+#define V "xxx" /* substituted in by Makefile */
+static const char strongswan_number[] = V;
+static const char strongswan_string[] = "Linux strongSwan " V;
+
+/*
+ - ipsec_version_code - return IPsec version number/code, as string
+ */
+const char *
+ipsec_version_code()
+{
+ return strongswan_number;
+}
+
+/*
+ - ipsec_version_string - return full version string
+ */
+const char *
+ipsec_version_string()
+{
+ return strongswan_string;
+}
diff --git a/src/libfreeswan/libipsecpolicy/.cvsignore b/src/libfreeswan/libipsecpolicy/.cvsignore
new file mode 100644
index 000000000..17435c875
--- /dev/null
+++ b/src/libfreeswan/libipsecpolicy/.cvsignore
@@ -0,0 +1 @@
+version.c
diff --git a/src/libfreeswan/libipsecpolicy/Makefile b/src/libfreeswan/libipsecpolicy/Makefile
new file mode 100644
index 000000000..a23fa5d04
--- /dev/null
+++ b/src/libfreeswan/libipsecpolicy/Makefile
@@ -0,0 +1,96 @@
+# FreeS/WAN library
+# Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: Makefile,v 1.1 2004/03/15 20:35:24 as Exp $
+
+
+FREESWANSRCDIR=../..
+
+include ${FREESWANSRCDIR}/Makefile.inc
+include ${FREESWANSRCDIR}/Makefile.ver
+
+
+MANDIR=$(MANTREE)/man3
+
+SRCS=policyquery.c cgipolicy.c
+
+OBJS=${SRCS:.c=.o} version.o
+
+KLIPSD=${FREESWANSRCDIR}/linux/include
+
+LIB=libipsecpolicy.a
+# Original flags
+CFLAGS=-I. -I${KLIPSD} -I${FREESWANSRCDIR} $(USERCOMPILE)
+CFLAGS+= -Wall
+CFLAGS+= -Wpointer-arith
+CFLAGS+= -Wcast-qual
+CFLAGS+= -Wstrict-prototypes
+CFLAGS+= -Wbad-function-cast
+
+MANS=
+
+.PHONY: all install clean l t lt tar check depend checkprograms
+
+all: $(LIB)
+programs: $(LIB)
+
+install:
+ @mkdir -p $(MANDIR)
+ @for f in $(MANS) ; \
+ do \
+ $(INSTALL) $(INSTMANFLAGS) $(SRCDIR)/$$f $(MANDIR)/ipsec_$$f || exit 1 ; \
+ done
+ @$(FREESWANSRCDIR)/packaging/utils/manlink $(foreach man, $(MANS), ${SRCDIR}/$(man)) | \
+ while read from to; \
+ do \
+ ln -s -f ipsec_$$from $(MANDIR)/$$to; \
+ done
+
+
+install_file_list:
+ @for f in $(MANS) ; \
+ do \
+ echo $(MANDIR)/ipsec_$$f;\
+ done;
+ @$(FREESWANSRCDIR)/packaging/utils/manlink $(foreach man, $(MANS), ${SRCDIR}/$(man)) | \
+ while read from to; \
+ do \
+ echo $(MANDIR)/$$to; \
+ done
+
+$(LIB): $(OBJS)
+ $(AR) $(ARFLAGS) $(LIB) $(OBJS)
+
+$(OBJS): $(HDRS)
+
+# build version.c using version number from Makefile.ver
+version.c: version.in.c ${FREESWANSRCDIR}/Makefile.ver
+ sed '/"/s/xxx/$(IPSECVERSION)/' version.in.c >$@
+
+clean:
+ rm -f $(LIB) *.o try* core *.core $(EXTHDRS) $(EXTLIBS) version.c
+
+
+tar: clean
+ tar -cvf /tmp/lib.tar Makefile [a-z]*
+
+check:
+ echo no checks in lib right now.
+
+depend:
+ makedepend -Y -- $(CFLAGS) -- $(SRCS)
+
+checkprograms:
+
+# DO NOT DELETE
+
diff --git a/src/libfreeswan/libipsecpolicy/cgipolicy.c b/src/libfreeswan/libipsecpolicy/cgipolicy.c
new file mode 100644
index 000000000..d28243e85
--- /dev/null
+++ b/src/libfreeswan/libipsecpolicy/cgipolicy.c
@@ -0,0 +1,77 @@
+/* routines that interface with pluto to get policy information
+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: cgipolicy.c,v 1.1 2004/03/15 20:35:24 as Exp $
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <freeswan.h>
+#include <freeswan/ipsec_policy.h>
+
+#include "libipsecpolicy.h"
+
+/*
+ * this version is appropriate for when one is called from a perl CGI,
+ * running under Apache. It extracts the appropriate things out of standard
+ * CGI environment variables, namely:
+ * $SERVER_ADDR us
+ * $REMOTE_ADDR them
+ */
+
+err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result)
+{
+ err_t ret;
+ char *us, *them;
+
+ /* clear it all out */
+ memset(result, 0, sizeof(*result));
+
+ /* setup it up */
+ result->head.ipm_version = IPSEC_POLICY_MSG_REVISION;
+ result->head.ipm_msg_len = sizeof(*result);
+ result->head.ipm_msg_type = IPSEC_CMD_QUERY_HOSTPAIR;
+ result->head.ipm_msg_seq = ipsec_policy_seq();
+
+
+ us = getenv("SERVER_ADDR");
+ them = getenv("REMOTE_ADDR");
+ if(!us || !them) {
+ return "$SERVER_ADDR and $REMOTE_ADDR must be set";
+ }
+
+ ret = ttoaddr(us, 0, AF_INET, &result->query_local);
+ if(ret != NULL) {
+ return ret;
+ }
+
+ ret = ttoaddr(them, 0, AF_INET, &result->query_remote);
+ if(ret != NULL) {
+ return ret;
+ }
+
+ return ipsec_policy_sendrecv((unsigned char *)result, sizeof(*result));
+}
+
diff --git a/src/libfreeswan/libipsecpolicy/libipsecpolicy.h b/src/libfreeswan/libipsecpolicy/libipsecpolicy.h
new file mode 100644
index 000000000..2c4ebdc0c
--- /dev/null
+++ b/src/libfreeswan/libipsecpolicy/libipsecpolicy.h
@@ -0,0 +1,4 @@
+
+extern u_int32_t ipsec_policy_seq(void);
+
+
diff --git a/src/libfreeswan/libipsecpolicy/policyquery.c b/src/libfreeswan/libipsecpolicy/policyquery.c
new file mode 100644
index 000000000..6555bdc08
--- /dev/null
+++ b/src/libfreeswan/libipsecpolicy/policyquery.c
@@ -0,0 +1,167 @@
+/* routines that interface with pluto to get policy information
+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: policyquery.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <wait.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <freeswan.h>
+#include <freeswan/ipsec_policy.h>
+
+#include "libipsecpolicy.h"
+
+static int policy_query_socket = -1;
+static u_int32_t policy_seq = 1;
+
+u_int32_t ipsec_policy_seq(void)
+{
+ return ++policy_seq;
+}
+
+err_t ipsec_policy_init(void)
+{
+ struct sockaddr_un sn;
+
+ if(policy_query_socket != -1) {
+ return NULL;
+ }
+
+ policy_query_socket = socket(PF_UNIX, SOCK_STREAM, 0);
+ if(policy_query_socket == -1) {
+ return "failed to open policy socket";
+ }
+
+ /* now connect it */
+ sn.sun_family = AF_UNIX;
+ strcpy(sn.sun_path, IPSEC_POLICY_SOCKET);
+
+ if(connect(policy_query_socket, (struct sockaddr *)&sn, sizeof(sn)) != 0) {
+ int saveerrno = errno;
+ close(policy_query_socket);
+ policy_query_socket=-1;
+ errno = saveerrno;
+ return "failed to connect policy socket";
+ }
+
+ /* okay, I think we are done */
+ return NULL;
+}
+
+err_t ipsec_policy_final(void)
+{
+ if(policy_query_socket != -1) {
+ close(policy_query_socket);
+ policy_query_socket = -1;
+ }
+
+ return NULL;
+}
+
+err_t ipsec_policy_readmsg(int policysock,
+ unsigned char *buf,
+ size_t buflen)
+{
+ struct ipsec_policy_msg_head ipmh;
+
+ if(read(policysock, &ipmh, sizeof(ipmh))
+ != sizeof(ipmh)) {
+ return "read failed";
+ }
+
+ /* got the header, sanitize it, and find out how much more to read */
+ switch(ipmh.ipm_version) {
+ case IPSEC_POLICY_MSG_REVISION:
+ break;
+
+ default:
+ /* XXX go deal with older versions, error for now */
+ fprintf(stderr, "Bad magic header: %u\n", ipmh.ipm_version);
+ return "bad policy msg version magic";
+ }
+
+ if(ipmh.ipm_msg_len > buflen) {
+ return "buffer too small for this message";
+ }
+
+ buflen = ipmh.ipm_msg_len;
+ memcpy(buf, &ipmh, sizeof(ipmh));
+ buf += sizeof(ipmh);
+ buflen -= sizeof(ipmh);
+
+ if(read(policysock, buf, buflen) != buflen) {
+ return "short read from socket";
+ }
+
+ return NULL;
+}
+
+err_t ipsec_policy_sendrecv(unsigned char *buf,
+ size_t buflen)
+{
+ err_t ret;
+ ipsec_policy_init();
+
+ if(write(policy_query_socket, buf, buflen)
+ != buflen) {
+ return "write failed";
+ }
+
+ ret = ipsec_policy_readmsg(policy_query_socket,
+ buf, buflen);
+
+ ipsec_policy_final();
+
+ return ret;
+}
+
+
+err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result)
+{
+ int len;
+
+ /* clear it out */
+ memset(result, 0, sizeof(*result));
+
+ /* setup it up */
+ result->head.ipm_version = IPSEC_POLICY_MSG_REVISION;
+ result->head.ipm_msg_len = sizeof(*result);
+ result->head.ipm_msg_type = IPSEC_CMD_QUERY_HOSTPAIR;
+ result->head.ipm_msg_seq = ipsec_policy_seq();
+
+ /* suck out the data on the sockets */
+ len = sizeof(result->query_local);
+ if(getsockname(fd, (struct sockaddr *)&result->query_local, &len) != 0) {
+ return "getsockname failed";
+ }
+
+ len = sizeof(result->query_remote);
+ if(getpeername(fd, (struct sockaddr *)&result->query_remote, &len) != 0) {
+ return "getpeername failed";
+ }
+
+ return ipsec_policy_sendrecv((unsigned char *)result, sizeof(*result));
+}
+
diff --git a/src/libfreeswan/libipsecpolicy/version.in.c b/src/libfreeswan/libipsecpolicy/version.in.c
new file mode 100644
index 000000000..304c58c0c
--- /dev/null
+++ b/src/libfreeswan/libipsecpolicy/version.in.c
@@ -0,0 +1,38 @@
+/*
+ * libipsecpolicy version information
+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ * License for more details.
+ *
+ * RCSID $Id: version.in.c,v 1.1 2004/03/15 20:35:25 as Exp $
+ */
+
+#define V "xxx" /* substituted in by Makefile */
+static const char ipsecpolicy_number[] = V;
+static const char ipsecpolicy_string[] = "Linux FreeS/WAN policylib " V;
+
+/*
+ - ipsec_version_code - return IPsec version number/code, as string
+ */
+const char *
+ipsec_version_code(void)
+{
+ return ipsecpolicy_number;
+}
+
+/*
+ - ipsec_version_string - return full version string
+ */
+const char *
+ipsec_version_string(void)
+{
+ return ipsecpolicy_string;
+}
diff --git a/src/libfreeswan/liblwres/Makefile b/src/libfreeswan/liblwres/Makefile
new file mode 100644
index 000000000..84a7713ab
--- /dev/null
+++ b/src/libfreeswan/liblwres/Makefile
@@ -0,0 +1,73 @@
+# Copyright (C) 2000, 2001 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile,v 1.1 2004/03/15 20:35:25 as Exp $
+
+srcdir = .
+VPATH = .
+top_srcdir = .
+
+CINCLUDES = -I${srcdir}/unix/include \
+ -I. -I./include -I${srcdir}/include
+CDEFINES = -g
+CWARNINGS = -Werror
+
+CFLAGS=${CINCLUDES} ${CDEFINES} ${CWARNINGS}
+
+VERSION="@(\#) freeswan-hacking-9.2.1-for-fs2"
+LIBINTERFACE=2
+LIBREVISION=0
+LIBAGE=1
+RANLIB=ranlib
+
+# Alphabetically
+OBJS = async.o context.o gai_strerror.o getaddrinfo.o gethost.o \
+ getipnode.o getnameinfo.o getrrset.o getrrset2.o herror.o \
+ lwbuffer.o lwconfig.o lwpacket.o lwresutil.o \
+ lwres_gabn.o lwres_gnba.o lwres_grbn.o lwres_noop.o \
+ lwinetaton.o lwinetpton.o lwinetntop.o
+
+# Alphabetically
+SRCS = async.c context.c gai_strerror.c getaddrinfo.c gethost.c \
+ getipnode.c getnameinfo.c getrrset.c getrrset2.c herror.c \
+ lwbuffer.c lwconfig.c lwpacket.c lwresutil.c \
+ lwres_gabn.c lwres_gnba.c lwres_grbn.c lwres_noop.c \
+ lwinetaton.c lwinetpton.c lwinetntop.c
+
+programs all: liblwres.a
+
+version.o: version.c
+ ${LIBTOOL} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+liblwres.a: ${OBJS} version.o
+ ${AR} ${ARFLAGS} $@ ${OBJS} version.o
+ ${RANLIB} $@
+
+timestamp: liblwres.a
+ touch timestamp
+
+clean distclean mostlyclean realclean cleanall spotless::
+ rm -f liblwres.a liblwres.la timestamp $(OBJS)
+
+install checkprograms check install_file_list:
+ @true
+
+TAGS: ${SRCS}
+ etags ${SRCS}
diff --git a/src/libfreeswan/liblwres/api b/src/libfreeswan/liblwres/api
new file mode 100644
index 000000000..f86947031
--- /dev/null
+++ b/src/libfreeswan/liblwres/api
@@ -0,0 +1,3 @@
+LIBINTERFACE = 2
+LIBREVISION = 0
+LIBAGE = 1
diff --git a/src/libfreeswan/liblwres/assert_p.h b/src/libfreeswan/liblwres/assert_p.h
new file mode 100644
index 000000000..0c5718290
--- /dev/null
+++ b/src/libfreeswan/liblwres/assert_p.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: assert_p.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_ASSERT_P_H
+#define LWRES_ASSERT_P_H 1
+
+#include <assert.h> /* Required for assert() prototype. */
+
+#define REQUIRE(x) assert(x)
+#define INSIST(x) assert(x)
+
+#define UNUSED(x) ((void)(x))
+
+#define SPACE_OK(b, s) (LWRES_BUFFER_AVAILABLECOUNT(b) >= (s))
+#define SPACE_REMAINING(b, s) (LWRES_BUFFER_REMAINING(b) >= (s))
+
+#endif /* LWRES_ASSERT_P_H */
diff --git a/src/libfreeswan/liblwres/async.c b/src/libfreeswan/liblwres/async.c
new file mode 100644
index 000000000..b23596a70
--- /dev/null
+++ b/src/libfreeswan/liblwres/async.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2003, Michael Richardson <mcr@freeswawn.org>
+ * Derived from code: Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: async.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+#include <lwres/async.h>
+
+#include "assert_p.h"
+#include "context_p.h"
+
+/*
+ * malloc / calloc functions that guarantee to only
+ * return NULL if there is an error, like they used
+ * to before the ANSI C committee broke them.
+ */
+
+static void *
+sane_malloc(size_t size) {
+ if (size == 0)
+ size = 1;
+ return (malloc(size));
+}
+
+static void *
+sane_calloc(size_t number, size_t size) {
+ size_t len = number * size;
+ void *mem = sane_malloc(len);
+ if (mem != NULL)
+ memset(mem, 0, len);
+ return (mem);
+}
+
+int
+lwres_async_init(lwres_context_t **pctx)
+{
+ lwres_result_t lwresult;
+ lwres_context_t *ctx = NULL;
+ int result;
+
+ lwresult = lwres_context_create(&ctx, NULL, NULL, NULL, 0);
+ if (lwresult != LWRES_R_SUCCESS) {
+ result = lwresult_to_result(lwresult);
+ return(result);
+ }
+ (void) lwres_conf_parse(ctx, lwres_resolv_conf);
+
+ *pctx = ctx;
+ return (ERRSET_SUCCESS);
+}
+
+int
+lwres_getrrsetbyname_init(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ lwres_context_t *ctx,
+ struct lwres_async_state *las)
+{
+ lwres_result_t lwresult;
+ unsigned int i;
+ unsigned int lwflags;
+ unsigned int result;
+
+ int ret;
+ lwres_lwpacket_t pkt;
+ lwres_grbnrequest_t request;
+ char target_name[1024];
+ unsigned int target_length;
+
+ int ret2;
+
+ if (rdclass > 0xffff || rdtype > 0xffff) {
+ result = ERRSET_INVAL;
+ return result;
+ }
+
+ /*
+ * Don't allow queries of class or type ANY
+ */
+ if (rdclass == 0xff || rdtype == 0xff) {
+ result = ERRSET_INVAL;
+ return result;
+ }
+
+ /*
+ * If any input flags were defined, lwflags would be set here
+ * based on them
+ */
+ UNUSED(flags);
+ lwflags = 0;
+
+ las->b_in.base = NULL;
+ las->b_out.base = NULL;
+ las->serial = lwres_context_nextserial(ctx);
+ las->opcode = LWRES_OPCODE_GETRDATABYNAME;
+
+ target_length = strlen(hostname);
+ if (target_length >= sizeof(target_name))
+ return (LWRES_R_FAILURE);
+ strcpy(target_name, hostname); /* strcpy is safe */
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.rdclass = rdclass;
+ request.rdtype = rdtype;
+ request.flags = lwflags;
+ request.name = target_name;
+ request.namelen = target_length;
+ pkt.pktflags = 0;
+ pkt.serial = las->serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ /* set up async system */
+ las->next = ctx->pending;
+ ctx->pending = las;
+
+ ret = lwres_grbnrequest_render(ctx, &request, &pkt, &las->b_out);
+
+ return ret;
+}
+
+int
+lwres_getrrsetbyname_xmit(lwres_context_t *ctx,
+ struct lwres_async_state *las)
+{
+ lwres_result_t lwresult;
+ int ret;
+
+ lwresult = lwres_context_send(ctx, las->b_out.base, las->b_out.length);
+
+ return(lwresult_to_result(lwresult));
+}
+
+
+
+unsigned long
+lwres_async_timeout(lwres_context_t *ctx)
+{
+ unsigned long tv_sec;
+
+ /*
+ * Type of tv_sec is long, so make sure the unsigned long timeout
+ * does not overflow it.
+ */
+ if (ctx->timeout <= LONG_MAX)
+ tv_sec = (long)ctx->timeout;
+ else
+ tv_sec = LONG_MAX;
+
+ return tv_sec;
+}
+
+int
+lwres_async_fd(lwres_context_t *ctx)
+{
+ return (ctx->sock);
+}
+
+
+/*
+const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+*/
+
+int
+lwres_getrrsetbyname_read(struct lwres_async_state **plas,
+ lwres_context_t *ctx,
+ struct rrsetinfo **res)
+{
+ lwres_result_t lwresult;
+ lwres_grbnresponse_t *response = NULL;
+ char *buffer;
+ struct rrsetinfo *rrset = NULL;
+ int recvlen;
+ int ret, result, i;
+ lwres_buffer_t b_in;
+ struct lwres_async_state *las;
+ struct lwres_async_state **las_prev;
+ lwres_lwpacket_t pkt;
+
+ buffer = NULL;
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ return ERRSET_NOMEMORY;
+ }
+
+ ret = LWRES_R_SUCCESS;
+ lwresult = lwres_context_recv(ctx, buffer, LWRES_RECVLENGTH, &recvlen);
+ if (lwresult == LWRES_R_RETRY) {
+ ret = LWRES_R_RETRY;
+ goto out;
+ }
+
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * find an appropriate waiting las entry. This is a linear search.
+ * we can do MUCH better, since we control the serial number!
+ * do that later.
+ */
+ las_prev = &ctx->pending;
+ las = ctx->pending;
+ while(las && las->serial != pkt.serial) {
+ las_prev=&las->next;
+ las=las->next;
+ }
+
+ if(las == NULL) {
+ /* no matching serial number! */
+ return(LWRES_R_RETRY);
+ }
+
+ /* okay, remove it from the receive queue */
+ *las_prev = las->next;
+ las->next = NULL;
+
+ *plas = las;
+
+ /*
+ * Free what we've transmitted, long ago.
+ */
+ CTXFREE(las->b_out.base, las->b_out.length);
+ las->b_out.base = NULL;
+ las->b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_grbnresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS) {
+ out:
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_grbnresponse_free(ctx, &response);
+ result = lwresult_to_result(ret);
+ goto fail;
+ }
+
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ lwresult = LWRES_R_SUCCESS;
+
+ rrset = sane_malloc(sizeof(struct rrsetinfo));
+ if (rrset == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ rrset->rri_name = NULL;
+ rrset->rri_rdclass = response->rdclass;
+ rrset->rri_rdtype = response->rdtype;
+ rrset->rri_ttl = response->ttl;
+ rrset->rri_flags = 0;
+ rrset->rri_nrdatas = 0;
+ rrset->rri_rdatas = NULL;
+ rrset->rri_nsigs = 0;
+ rrset->rri_sigs = NULL;
+
+ rrset->rri_name = sane_malloc(response->realnamelen + 1);
+ if (rrset->rri_name == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ strncpy(rrset->rri_name, response->realname, response->realnamelen);
+ rrset->rri_name[response->realnamelen] = 0;
+
+ if ((response->flags & LWRDATA_VALIDATED) != 0)
+ rrset->rri_flags |= RRSET_VALIDATED;
+
+ rrset->rri_nrdatas = response->nrdatas;
+ rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_rdatas == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
+ rrset->rri_rdatas[i].rdi_data =
+ sane_malloc(rrset->rri_rdatas[i].rdi_length);
+ if (rrset->rri_rdatas[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
+ rrset->rri_rdatas[i].rdi_length);
+ }
+ rrset->rri_nsigs = response->nsigs;
+ rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_sigs == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ rrset->rri_sigs[i].rdi_length = response->siglen[i];
+ rrset->rri_sigs[i].rdi_data =
+ sane_malloc(rrset->rri_sigs[i].rdi_length);
+ if (rrset->rri_sigs[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
+ rrset->rri_sigs[i].rdi_length);
+ }
+
+ lwres_grbnresponse_free(ctx, &response);
+
+ *res = rrset;
+ return (ERRSET_SUCCESS);
+ fail:
+ if (rrset != NULL)
+ lwres_freerrset(rrset);
+ if (response != NULL)
+ lwres_grbnresponse_free(ctx, &response);
+ return (result);
+
+}
+
diff --git a/src/libfreeswan/liblwres/config.h b/src/libfreeswan/liblwres/config.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/libfreeswan/liblwres/config.h
diff --git a/src/libfreeswan/liblwres/context.c b/src/libfreeswan/liblwres/context.c
new file mode 100644
index 000000000..40f8f3e3d
--- /dev/null
+++ b/src/libfreeswan/liblwres/context.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: context.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/platform.h>
+
+#ifdef LWRES_PLATFORM_NEEDSYSSELECTH
+#include <sys/select.h>
+#endif
+
+#include "context_p.h"
+#include "assert_p.h"
+
+/*
+ * Some systems define the socket length argument as an int, some as size_t,
+ * some as socklen_t. The last is what the current POSIX standard mandates.
+ * This definition is here so it can be portable but easily changed if needed.
+ */
+#ifndef LWRES_SOCKADDR_LEN_T
+#define LWRES_SOCKADDR_LEN_T unsigned int
+#endif
+
+/*
+ * Make a socket nonblocking.
+ */
+#ifndef MAKE_NONBLOCKING
+#define MAKE_NONBLOCKING(sd, retval) \
+do { \
+ retval = fcntl(sd, F_GETFL, 0); \
+ if (retval != -1) { \
+ retval |= O_NONBLOCK; \
+ retval = fcntl(sd, F_SETFL, retval); \
+ } \
+} while (0)
+#endif
+
+lwres_uint16_t lwres_udp_port = LWRES_UDP_PORT;
+const char *lwres_resolv_conf = LWRES_RESOLV_CONF;
+
+static void *
+lwres_malloc(void *, size_t);
+
+static void
+lwres_free(void *, void *, size_t);
+
+static lwres_result_t
+context_connect(lwres_context_t *);
+
+lwres_result_t
+lwres_context_create(lwres_context_t **contextp, void *arg,
+ lwres_malloc_t malloc_function,
+ lwres_free_t free_function,
+ unsigned int flags)
+{
+ lwres_context_t *ctx;
+
+ REQUIRE(contextp != NULL && *contextp == NULL);
+ UNUSED(flags);
+
+ /*
+ * If we were not given anything special to use, use our own
+ * functions. These are just wrappers around malloc() and free().
+ */
+ if (malloc_function == NULL || free_function == NULL) {
+ REQUIRE(malloc_function == NULL);
+ REQUIRE(free_function == NULL);
+ malloc_function = lwres_malloc;
+ free_function = lwres_free;
+ }
+
+ ctx = malloc_function(arg, sizeof(lwres_context_t));
+ if (ctx == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ /*
+ * Set up the context.
+ */
+ ctx->malloc = malloc_function;
+ ctx->free = free_function;
+ ctx->arg = arg;
+ ctx->sock = -1;
+
+ ctx->timeout = LWRES_DEFAULT_TIMEOUT;
+ ctx->serial = time(NULL); /* XXXMLG or BEW */
+
+ /*
+ * Init resolv.conf bits.
+ */
+ lwres_conf_init(ctx);
+
+ *contextp = ctx;
+ return (LWRES_R_SUCCESS);
+}
+
+void
+lwres_context_destroy(lwres_context_t **contextp) {
+ lwres_context_t *ctx;
+
+ REQUIRE(contextp != NULL && *contextp != NULL);
+
+ ctx = *contextp;
+ *contextp = NULL;
+
+ if (ctx->sock != -1) {
+ close(ctx->sock);
+ ctx->sock = -1;
+ }
+
+ CTXFREE(ctx, sizeof(lwres_context_t));
+}
+
+lwres_uint32_t
+lwres_context_nextserial(lwres_context_t *ctx) {
+ REQUIRE(ctx != NULL);
+
+ return (ctx->serial++);
+}
+
+void
+lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial) {
+ REQUIRE(ctx != NULL);
+
+ ctx->serial = serial;
+}
+
+void
+lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len) {
+ REQUIRE(mem != NULL);
+ REQUIRE(len != 0);
+
+ CTXFREE(mem, len);
+}
+
+void *
+lwres_context_allocmem(lwres_context_t *ctx, size_t len) {
+ REQUIRE(len != 0);
+
+ return (CTXMALLOC(len));
+}
+
+static void *
+lwres_malloc(void *arg, size_t len) {
+ void *mem;
+
+ UNUSED(arg);
+
+ mem = malloc(len);
+ if (mem == NULL)
+ return (NULL);
+
+ memset(mem, 0xe5, len);
+
+ return (mem);
+}
+
+static void
+lwres_free(void *arg, void *mem, size_t len) {
+ UNUSED(arg);
+
+ memset(mem, 0xa9, len);
+ free(mem);
+}
+
+static lwres_result_t
+context_connect(lwres_context_t *ctx) {
+ int s;
+ int ret;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr *sa;
+ LWRES_SOCKADDR_LEN_T salen;
+ int domain;
+
+ if (ctx->confdata.lwnext != 0) {
+ memcpy(&ctx->address, &ctx->confdata.lwservers[0],
+ sizeof(lwres_addr_t));
+ LWRES_LINK_INIT(&ctx->address, link);
+ } else {
+ /* The default is the IPv4 loopback address 127.0.0.1. */
+ memset(&ctx->address, 0, sizeof(ctx->address));
+ ctx->address.family = LWRES_ADDRTYPE_V4;
+ ctx->address.length = 4;
+ ctx->address.address[0] = 127;
+ ctx->address.address[1] = 0;
+ ctx->address.address[2] = 0;
+ ctx->address.address[3] = 1;
+ }
+
+ if (ctx->address.family == LWRES_ADDRTYPE_V4) {
+ memcpy(&sin.sin_addr, ctx->address.address,
+ sizeof(sin.sin_addr));
+ sin.sin_port = htons(lwres_udp_port);
+ sin.sin_family = AF_INET;
+ sa = (struct sockaddr *)&sin;
+ salen = sizeof(sin);
+ domain = PF_INET;
+ } else if (ctx->address.family == LWRES_ADDRTYPE_V6) {
+ memcpy(&sin6.sin6_addr, ctx->address.address,
+ sizeof(sin6.sin6_addr));
+ sin6.sin6_port = htons(lwres_udp_port);
+ sin6.sin6_family = AF_INET6;
+ sa = (struct sockaddr *)&sin6;
+ salen = sizeof(sin6);
+ domain = PF_INET6;
+ } else
+ return (LWRES_R_IOERROR);
+
+ s = socket(domain, SOCK_DGRAM, IPPROTO_UDP);
+ if (s < 0)
+ return (LWRES_R_IOERROR);
+
+ ret = connect(s, sa, salen);
+ if (ret != 0) {
+ close(s);
+ return (LWRES_R_IOERROR);
+ }
+
+ MAKE_NONBLOCKING(s, ret);
+ if (ret < 0)
+ return (LWRES_R_IOERROR);
+
+ ctx->sock = s;
+
+ return (LWRES_R_SUCCESS);
+}
+
+int
+lwres_context_getsocket(lwres_context_t *ctx) {
+ return (ctx->sock);
+}
+
+lwres_result_t
+lwres_context_send(lwres_context_t *ctx,
+ void *sendbase, int sendlen) {
+ int ret;
+ lwres_result_t lwresult;
+
+ if (ctx->sock == -1) {
+ lwresult = context_connect(ctx);
+ if (lwresult != LWRES_R_SUCCESS)
+ return (lwresult);
+ }
+
+ ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0);
+ if (ret < 0)
+ return (LWRES_R_IOERROR);
+ if (ret != sendlen)
+ return (LWRES_R_IOERROR);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_context_recv(lwres_context_t *ctx,
+ void *recvbase, int recvlen,
+ int *recvd_len)
+{
+ LWRES_SOCKADDR_LEN_T fromlen;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr *sa;
+ int ret;
+
+ if (ctx->address.family == LWRES_ADDRTYPE_V4) {
+ sa = (struct sockaddr *)&sin;
+ fromlen = sizeof(sin);
+ } else {
+ sa = (struct sockaddr *)&sin6;
+ fromlen = sizeof(sin6);
+ }
+
+ /*
+ * The address of fromlen is cast to void * to shut up compiler
+ * warnings, namely on systems that have the sixth parameter
+ * prototyped as a signed int when LWRES_SOCKADDR_LEN_T is
+ * defined as unsigned.
+ */
+ ret = recvfrom(ctx->sock, recvbase, recvlen, 0, sa, (void *)&fromlen);
+
+ if (ret < 0)
+ return (LWRES_R_IOERROR);
+
+ if (ret == recvlen)
+ return (LWRES_R_TOOLARGE);
+
+ /*
+ * If we got something other than what we expect, have the caller
+ * wait for another packet. This can happen if an old result
+ * comes in, or if someone is sending us random stuff.
+ */
+ if (ctx->address.family == LWRES_ADDRTYPE_V4) {
+ if (fromlen != sizeof(sin)
+ || memcmp(&sin.sin_addr, ctx->address.address,
+ sizeof(sin.sin_addr)) != 0
+ || sin.sin_port != htons(lwres_udp_port))
+ return (LWRES_R_RETRY);
+ } else {
+ if (fromlen != sizeof(sin6)
+ || memcmp(&sin6.sin6_addr, ctx->address.address,
+ sizeof(sin6.sin6_addr)) != 0
+ || sin6.sin6_port != htons(lwres_udp_port))
+ return (LWRES_R_RETRY);
+ }
+
+ if (recvd_len != NULL)
+ *recvd_len = ret;
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_context_sendrecv(lwres_context_t *ctx,
+ void *sendbase, int sendlen,
+ void *recvbase, int recvlen,
+ int *recvd_len)
+{
+ lwres_result_t result;
+ int ret2;
+ fd_set readfds;
+ struct timeval timeout;
+
+ /*
+ * Type of tv_sec is long, so make sure the unsigned long timeout
+ * does not overflow it.
+ */
+ if (ctx->timeout <= LONG_MAX)
+ timeout.tv_sec = (long)ctx->timeout;
+ else
+ timeout.tv_sec = LONG_MAX;
+
+ timeout.tv_usec = 0;
+
+ result = lwres_context_send(ctx, sendbase, sendlen);
+ if (result != LWRES_R_SUCCESS)
+ return (result);
+ again:
+ FD_ZERO(&readfds);
+ FD_SET(ctx->sock, &readfds);
+ ret2 = select(ctx->sock + 1, &readfds, NULL, NULL, &timeout);
+
+ /*
+ * What happened with select?
+ */
+ if (ret2 < 0)
+ return (LWRES_R_IOERROR);
+ if (ret2 == 0)
+ return (LWRES_R_TIMEOUT);
+
+ result = lwres_context_recv(ctx, recvbase, recvlen, recvd_len);
+ if (result == LWRES_R_RETRY)
+ goto again;
+
+ return (result);
+}
diff --git a/src/libfreeswan/liblwres/context_p.h b/src/libfreeswan/liblwres/context_p.h
new file mode 100644
index 000000000..52dd870e1
--- /dev/null
+++ b/src/libfreeswan/liblwres/context_p.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: context_p.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_CONTEXT_P_H
+#define LWRES_CONTEXT_P_H 1
+
+/*
+ * Helper functions, assuming the context is always called "ctx" in
+ * the scope these functions are called from.
+ */
+#define CTXMALLOC(len) ctx->malloc(ctx->arg, (len))
+#define CTXFREE(addr, len) ctx->free(ctx->arg, (addr), (len))
+
+#define LWRES_DEFAULT_TIMEOUT 120 /* 120 seconds for a reply */
+
+/*
+ * Not all the attributes here are actually settable by the application at
+ * this time.
+ */
+struct lwres_context {
+ unsigned int timeout; /* time to wait for reply */
+ lwres_uint32_t serial; /* serial number state */
+
+ /*
+ * For network I/O.
+ */
+ int sock; /* socket to send on */
+ lwres_addr_t address; /* address to send to */
+
+ /*
+ * Function pointers for allocating memory.
+ */
+ lwres_malloc_t malloc;
+ lwres_free_t free;
+ void *arg;
+
+ /*
+ * resolv.conf-like data
+ */
+ lwres_conf_t confdata;
+
+ /* linked list of outstanding DNS requests */
+ struct lwres_async_state *pending;
+};
+
+#endif /* LWRES_CONTEXT_P_H */
+
+/*
+ * Local Variables:
+ * c-basic-offset: 8
+ * End Variables:
+ */
diff --git a/src/libfreeswan/liblwres/gai_strerror.c b/src/libfreeswan/liblwres/gai_strerror.c
new file mode 100644
index 000000000..913b5139f
--- /dev/null
+++ b/src/libfreeswan/liblwres/gai_strerror.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: gai_strerror.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <lwres/netdb.h>
+
+static const char *gai_messages[] = {
+ "no error",
+ "address family for hostname not supported",
+ "temporary failure in name resolution",
+ "invalid value for ai_flags",
+ "non-recoverable failure in name resolution",
+ "ai_family not supported",
+ "memory allocation failure",
+ "no address associated with hostname",
+ "hostname nor servname provided, or not known",
+ "servname not supported for ai_socktype",
+ "ai_socktype not supported",
+ "system error returned in errno",
+ "bad hints",
+ "bad protocol"
+};
+
+char *
+lwres_gai_strerror(int ecode) {
+ union {
+ const char *const_ptr;
+ char *deconst_ptr;
+ } ptr;
+
+ if ((ecode < 0) ||
+ (ecode >= (int)(sizeof(gai_messages)/sizeof(*gai_messages))))
+ ptr.const_ptr = "invalid error code";
+ else
+ ptr.const_ptr = gai_messages[ecode];
+ return (ptr.deconst_ptr);
+}
diff --git a/src/libfreeswan/liblwres/getaddrinfo.c b/src/libfreeswan/liblwres/getaddrinfo.c
new file mode 100644
index 000000000..06cb39ffc
--- /dev/null
+++ b/src/libfreeswan/liblwres/getaddrinfo.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * This code is derived from software contributed to Internet Software
+ * Consortium by Berkeley Software Design, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM AND
+ * BERKELEY SOFTWARE DESIGN, INC DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE CONSORTIUM OR BERKELEY
+ * SOFTWARE DESIGN, INC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getaddrinfo.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h>
+
+#define SA(addr) ((struct sockaddr *)(addr))
+#define SIN(addr) ((struct sockaddr_in *)(addr))
+#define SIN6(addr) ((struct sockaddr_in6 *)(addr))
+#define SUN(addr) ((struct sockaddr_un *)(addr))
+
+static struct addrinfo
+ *ai_reverse(struct addrinfo *oai),
+ *ai_clone(struct addrinfo *oai, int family),
+ *ai_alloc(int family, int addrlen);
+#ifdef AF_LOCAL
+static int get_local(const char *name, int socktype, struct addrinfo **res);
+#endif
+
+static int add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static int add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port);
+static void set_order(int, int (**)(const char *, int, struct addrinfo **,
+ int, int));
+
+#define FOUND_IPV4 0x1
+#define FOUND_IPV6 0x2
+#define FOUND_MAX 2
+
+#define ISC_AI_MASK (AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST)
+
+int
+lwres_getaddrinfo(const char *hostname, const char *servname,
+ const struct addrinfo *hints, struct addrinfo **res)
+{
+ struct servent *sp;
+ const char *proto;
+ int family, socktype, flags, protocol;
+ struct addrinfo *ai, *ai_list;
+ int port, err, i;
+ int (*net_order[FOUND_MAX+1])(const char *, int, struct addrinfo **,
+ int, int);
+
+ if (hostname == NULL && servname == NULL)
+ return (EAI_NONAME);
+
+ proto = NULL;
+ if (hints != NULL) {
+ if ((hints->ai_flags & ~(ISC_AI_MASK)) != 0)
+ return (EAI_BADFLAGS);
+ if (hints->ai_addrlen || hints->ai_canonname ||
+ hints->ai_addr || hints->ai_next) {
+ errno = EINVAL;
+ return (EAI_SYSTEM);
+ }
+ family = hints->ai_family;
+ socktype = hints->ai_socktype;
+ protocol = hints->ai_protocol;
+ flags = hints->ai_flags;
+ switch (family) {
+ case AF_UNSPEC:
+ switch (hints->ai_socktype) {
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ }
+ break;
+ case AF_INET:
+ case AF_INET6:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ proto = "tcp";
+ break;
+ case SOCK_DGRAM:
+ proto = "udp";
+ break;
+ case SOCK_RAW:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#ifdef AF_LOCAL
+ case AF_LOCAL:
+ switch (hints->ai_socktype) {
+ case 0:
+ break;
+ case SOCK_STREAM:
+ break;
+ case SOCK_DGRAM:
+ break;
+ default:
+ return (EAI_SOCKTYPE);
+ }
+ break;
+#endif
+ default:
+ return (EAI_FAMILY);
+ }
+ } else {
+ protocol = 0;
+ family = 0;
+ socktype = 0;
+ flags = 0;
+ }
+
+#ifdef AF_LOCAL
+ /*
+ * First, deal with AF_LOCAL. If the family was not set,
+ * then assume AF_LOCAL if the first character of the
+ * hostname/servname is '/'.
+ */
+
+ if (hostname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *hostname == '/')))
+ return (get_local(hostname, socktype, res));
+
+ if (servname != NULL &&
+ (family == AF_LOCAL || (family == 0 && *servname == '/')))
+ return (get_local(servname, socktype, res));
+#endif
+
+ /*
+ * Ok, only AF_INET and AF_INET6 left.
+ */
+ ai_list = NULL;
+
+ /*
+ * First, look up the service name (port) if it was
+ * requested. If the socket type wasn't specified, then
+ * try and figure it out.
+ */
+ if (servname != NULL) {
+ char *e;
+
+ port = strtol(servname, &e, 10);
+ if (*e == '\0') {
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+ if (port < 0 || port > 65535)
+ return (EAI_SERVICE);
+ port = htons((unsigned short) port);
+ } else {
+ sp = getservbyname(servname, proto);
+ if (sp == NULL)
+ return (EAI_SERVICE);
+ port = sp->s_port;
+ if (socktype == 0) {
+ if (strcmp(sp->s_proto, "tcp") == 0)
+ socktype = SOCK_STREAM;
+ else if (strcmp(sp->s_proto, "udp") == 0)
+ socktype = SOCK_DGRAM;
+ }
+ }
+ } else
+ port = 0;
+
+ /*
+ * Next, deal with just a service name, and no hostname.
+ * (we verified that one of them was non-null up above).
+ */
+ if (hostname == NULL && (flags & AI_PASSIVE) != 0) {
+ if (family == AF_INET || family == 0) {
+ ai = ai_alloc(AF_INET, sizeof(struct sockaddr_in));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN(ai->ai_addr)->sin_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ if (family == AF_INET6 || family == 0) {
+ ai = ai_alloc(AF_INET6, sizeof(struct sockaddr_in6));
+ if (ai == NULL) {
+ lwres_freeaddrinfo(ai_list);
+ return (EAI_MEMORY);
+ }
+ ai->ai_socktype = socktype;
+ ai->ai_protocol = protocol;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ ai->ai_next = ai_list;
+ ai_list = ai;
+ }
+
+ *res = ai_list;
+ return (0);
+ }
+
+ /*
+ * If the family isn't specified or AI_NUMERICHOST specified,
+ * check first to see if it is a numeric address.
+ * Though the gethostbyname2() routine
+ * will recognize numeric addresses, it will only recognize
+ * the format that it is being called for. Thus, a numeric
+ * AF_INET address will be treated by the AF_INET6 call as
+ * a domain name, and vice versa. Checking for both numerics
+ * here avoids that.
+ */
+ if (hostname != NULL &&
+ (family == 0 || (flags & AI_NUMERICHOST) != 0)) {
+ char abuf[sizeof(struct in6_addr)];
+ char nbuf[NI_MAXHOST];
+ int addrsize, addroff;
+#ifdef LWRES_HAVE_SIN6_SCOPE_ID
+ char *p, *ep;
+ char ntmp[NI_MAXHOST];
+ lwres_uint32_t scopeid;
+#endif
+
+#ifdef LWRES_HAVE_SIN6_SCOPE_ID
+ /*
+ * Scope identifier portion.
+ */
+ ntmp[0] = '\0';
+ if (strchr(hostname, '%') != NULL) {
+ strncpy(ntmp, hostname, sizeof(ntmp) - 1);
+ ntmp[sizeof(ntmp) - 1] = '\0';
+ p = strchr(ntmp, '%');
+ ep = NULL;
+
+ /*
+ * Vendors may want to support non-numeric
+ * scopeid around here.
+ */
+
+ if (p != NULL)
+ scopeid = (lwres_uint32_t)strtoul(p + 1,
+ &ep, 10);
+ if (p != NULL && ep != NULL && ep[0] == '\0')
+ *p = '\0';
+ else {
+ ntmp[0] = '\0';
+ scopeid = 0;
+ }
+ } else
+ scopeid = 0;
+#endif
+
+ if (lwres_net_pton(AF_INET, hostname, (struct in_addr *)abuf)
+ == 1)
+ {
+ if (family == AF_INET6) {
+ /*
+ * Convert to a V4 mapped address.
+ */
+ struct in6_addr *a6 = (struct in6_addr *)abuf;
+ memcpy(&a6->s6_addr[12], &a6->s6_addr[0], 4);
+ memset(&a6->s6_addr[10], 0xff, 2);
+ memset(&a6->s6_addr[0], 0, 10);
+ goto inet6_addr;
+ }
+ addrsize = sizeof(struct in_addr);
+ addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
+ family = AF_INET;
+ goto common;
+#ifdef LWRES_HAVE_SIN6_SCOPE_ID
+ } else if (ntmp[0] != '\0' &&
+ lwres_net_pton(AF_INET6, ntmp, abuf) == 1)
+ {
+ if (family && family != AF_INET6)
+ return (EAI_NONAME);
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+ goto common;
+#endif
+ } else if (lwres_net_pton(AF_INET6, hostname, abuf) == 1) {
+ if (family != 0 && family != AF_INET6)
+ return (EAI_NONAME);
+ inet6_addr:
+ addrsize = sizeof(struct in6_addr);
+ addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ family = AF_INET6;
+
+ common:
+ ai = ai_clone(ai_list, family);
+ if (ai == NULL)
+ return (EAI_MEMORY);
+ ai_list = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy((char *)ai->ai_addr + addroff, abuf, addrsize);
+ if (flags & AI_CANONNAME) {
+#if defined(LWRES_HAVE_SIN6_SCOPE_ID)
+ if (ai->ai_family == AF_INET6)
+ SIN6(ai->ai_addr)->sin6_scope_id =
+ scopeid;
+#endif
+ if (lwres_getnameinfo(ai->ai_addr,
+ ai->ai_addrlen, nbuf, sizeof(nbuf),
+ NULL, 0,
+ NI_NUMERICHOST) == 0) {
+ ai->ai_canonname = strdup(nbuf);
+ if (ai->ai_canonname == NULL)
+ return (EAI_MEMORY);
+ } else {
+ /* XXX raise error? */
+ ai->ai_canonname = NULL;
+ }
+ }
+ goto done;
+ } else if ((flags & AI_NUMERICHOST) != 0) {
+ return (EAI_NONAME);
+ }
+ }
+
+ set_order(family, net_order);
+ for (i = 0; i < FOUND_MAX; i++) {
+ if (net_order[i] == NULL)
+ break;
+ err = (net_order[i])(hostname, flags, &ai_list,
+ socktype, port);
+ if (err != 0)
+ return (err);
+ }
+
+ if (ai_list == NULL)
+ return (EAI_NODATA);
+
+done:
+ ai_list = ai_reverse(ai_list);
+
+ *res = ai_list;
+ return (0);
+}
+
+static char *
+lwres_strsep(char **stringp, const char *delim) {
+ char *string = *stringp;
+ char *s;
+ const char *d;
+ char sc, dc;
+
+ if (string == NULL)
+ return (NULL);
+
+ for (s = string; *s != '\0'; s++) {
+ sc = *s;
+ for (d = delim; (dc = *d) != '\0'; d++)
+ if (sc == dc) {
+ *s++ = '\0';
+ *stringp = s;
+ return (string);
+ }
+ }
+ *stringp = NULL;
+ return (string);
+}
+
+static void
+set_order(int family, int (**net_order)(const char *, int, struct addrinfo **,
+ int, int))
+{
+ char *order, *tok;
+ int found;
+
+ if (family) {
+ switch (family) {
+ case AF_INET:
+ *net_order++ = add_ipv4;
+ break;
+ case AF_INET6:
+ *net_order++ = add_ipv6;
+ break;
+ }
+ } else {
+ order = getenv("NET_ORDER");
+ found = 0;
+ while (order != NULL) {
+ /*
+ * We ignore any unknown names.
+ */
+ tok = lwres_strsep(&order, ":");
+ if (strcasecmp(tok, "inet6") == 0) {
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ found |= FOUND_IPV6;
+ } else if (strcasecmp(tok, "inet") == 0 ||
+ strcasecmp(tok, "inet4") == 0) {
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ found |= FOUND_IPV4;
+ }
+ }
+
+ /*
+ * Add in anything that we didn't find.
+ */
+ if ((found & FOUND_IPV4) == 0)
+ *net_order++ = add_ipv4;
+ if ((found & FOUND_IPV6) == 0)
+ *net_order++ = add_ipv6;
+ }
+ *net_order = NULL;
+ return;
+}
+
+static char v4_loop[4] = { 127, 0, 0, 1 };
+
+/*
+ * The test against 0 is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
+ */
+#define ERR(code) \
+ do { result = (code); \
+ if (result != 0) goto cleanup; \
+ } while (0)
+
+static int
+add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gabnresponse_t *by = NULL;
+ lwres_addr_t *addr;
+ lwres_result_t lwres;
+ int result = 0;
+
+ lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (lwres != LWRES_R_SUCCESS)
+ ERR(EAI_FAIL);
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ ai = ai_clone(*aip, AF_INET);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr, v4_loop, 4);
+ } else {
+ lwres = lwres_getaddrsbyname(lwrctx, hostname,
+ LWRES_ADDRTYPE_V4, &by);
+ if (lwres != LWRES_R_SUCCESS) {
+ if (lwres == LWRES_R_NOTFOUND)
+ goto cleanup;
+ else
+ ERR(EAI_FAIL);
+ }
+ addr = LWRES_LIST_HEAD(by->addrs);
+ while (addr != NULL) {
+ ai = ai_clone(*aip, AF_INET);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN(ai->ai_addr)->sin_port = port;
+ memcpy(&SIN(ai->ai_addr)->sin_addr,
+ addr->address, 4);
+ if (flags & AI_CANONNAME) {
+ ai->ai_canonname = strdup(by->realname);
+ if (ai->ai_canonname == NULL)
+ ERR(EAI_MEMORY);
+ }
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+ }
+ cleanup:
+ if (by != NULL)
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (result);
+}
+
+static char v6_loop[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
+
+static int
+add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
+ int socktype, int port)
+{
+ struct addrinfo *ai;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gabnresponse_t *by = NULL;
+ lwres_addr_t *addr;
+ lwres_result_t lwres;
+ int result = 0;
+
+ lwres = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (lwres != LWRES_R_SUCCESS)
+ ERR(EAI_FAIL);
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+
+ if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
+ ai = ai_clone(*aip, AF_INET6);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr, v6_loop, 16);
+ } else {
+ lwres = lwres_getaddrsbyname(lwrctx, hostname,
+ LWRES_ADDRTYPE_V6, &by);
+ if (lwres != LWRES_R_SUCCESS) {
+ if (lwres == LWRES_R_NOTFOUND)
+ goto cleanup;
+ else
+ ERR(EAI_FAIL);
+ }
+ addr = LWRES_LIST_HEAD(by->addrs);
+ while (addr != NULL) {
+ ai = ai_clone(*aip, AF_INET6);
+ if (ai == NULL) {
+ lwres_freeaddrinfo(*aip);
+ ERR(EAI_MEMORY);
+ }
+ *aip = ai;
+ ai->ai_socktype = socktype;
+ SIN6(ai->ai_addr)->sin6_port = port;
+ memcpy(&SIN6(ai->ai_addr)->sin6_addr,
+ addr->address, 16);
+ if (flags & AI_CANONNAME) {
+ ai->ai_canonname = strdup(by->realname);
+ if (ai->ai_canonname == NULL)
+ ERR(EAI_MEMORY);
+ }
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+ }
+ cleanup:
+ if (by != NULL)
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (result);
+}
+
+void
+lwres_freeaddrinfo(struct addrinfo *ai) {
+ struct addrinfo *ai_next;
+
+ while (ai != NULL) {
+ ai_next = ai->ai_next;
+ if (ai->ai_addr != NULL)
+ free(ai->ai_addr);
+ if (ai->ai_canonname)
+ free(ai->ai_canonname);
+ free(ai);
+ ai = ai_next;
+ }
+}
+
+#ifdef AF_LOCAL
+static int
+get_local(const char *name, int socktype, struct addrinfo **res) {
+ struct addrinfo *ai;
+ struct sockaddr_un *sun;
+
+ if (socktype == 0)
+ return (EAI_SOCKTYPE);
+
+ ai = ai_alloc(AF_LOCAL, sizeof(*sun));
+ if (ai == NULL)
+ return (EAI_MEMORY);
+
+ sun = SUN(ai->ai_addr);
+ strncpy(sun->sun_path, name, sizeof(sun->sun_path));
+
+ ai->ai_socktype = socktype;
+ /*
+ * ai->ai_flags, ai->ai_protocol, ai->ai_canonname,
+ * and ai->ai_next were initialized to zero.
+ */
+
+ *res = ai;
+ return (0);
+}
+#endif
+
+/*
+ * Allocate an addrinfo structure, and a sockaddr structure
+ * of the specificed length. We initialize:
+ * ai_addrlen
+ * ai_family
+ * ai_addr
+ * ai_addr->sa_family
+ * ai_addr->sa_len (LWRES_PLATFORM_HAVESALEN)
+ * and everything else is initialized to zero.
+ */
+static struct addrinfo *
+ai_alloc(int family, int addrlen) {
+ struct addrinfo *ai;
+
+ ai = (struct addrinfo *)calloc(1, sizeof(*ai));
+ if (ai == NULL)
+ return (NULL);
+
+ ai->ai_addr = SA(calloc(1, addrlen));
+ if (ai->ai_addr == NULL) {
+ free(ai);
+ return (NULL);
+ }
+ ai->ai_addrlen = addrlen;
+ ai->ai_family = family;
+ ai->ai_addr->sa_family = family;
+#ifdef LWRES_PLATFORM_HAVESALEN
+ ai->ai_addr->sa_len = addrlen;
+#endif
+ return (ai);
+}
+
+static struct addrinfo *
+ai_clone(struct addrinfo *oai, int family) {
+ struct addrinfo *ai;
+
+ ai = ai_alloc(family, ((family == AF_INET6) ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)));
+
+ if (ai == NULL) {
+ lwres_freeaddrinfo(oai);
+ return (NULL);
+ }
+ if (oai == NULL)
+ return (ai);
+
+ ai->ai_flags = oai->ai_flags;
+ ai->ai_socktype = oai->ai_socktype;
+ ai->ai_protocol = oai->ai_protocol;
+ ai->ai_canonname = NULL;
+ ai->ai_next = oai;
+ return (ai);
+}
+
+static struct addrinfo *
+ai_reverse(struct addrinfo *oai) {
+ struct addrinfo *nai, *tai;
+
+ nai = NULL;
+
+ while (oai != NULL) {
+ /*
+ * Grab one off the old list.
+ */
+ tai = oai;
+ oai = oai->ai_next;
+ /*
+ * Put it on the front of the new list.
+ */
+ tai->ai_next = nai;
+ nai = tai;
+ }
+ return (nai);
+}
diff --git a/src/libfreeswan/liblwres/gethost.c b/src/libfreeswan/liblwres/gethost.c
new file mode 100644
index 000000000..32c8359b4
--- /dev/null
+++ b/src/libfreeswan/liblwres/gethost.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: gethost.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <lwres/net.h>
+#include <lwres/netdb.h>
+
+#include "assert_p.h"
+
+#define LWRES_ALIGNBYTES (sizeof(char *) - 1)
+#define LWRES_ALIGN(p) \
+ (((unsigned long)(p) + LWRES_ALIGNBYTES) &~ LWRES_ALIGNBYTES)
+
+static struct hostent *he = NULL;
+static int copytobuf(struct hostent *, struct hostent *, char *, int);
+
+struct hostent *
+lwres_gethostbyname(const char *name) {
+
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ he = lwres_getipnodebyname(name, AF_INET, 0, &lwres_h_errno);
+ return (he);
+}
+
+struct hostent *
+lwres_gethostbyname2(const char *name, int af) {
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ he = lwres_getipnodebyname(name, af, 0, &lwres_h_errno);
+ return (he);
+}
+
+struct hostent *
+lwres_gethostbyaddr(const char *addr, int len, int type) {
+
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ he = lwres_getipnodebyaddr(addr, len, type, &lwres_h_errno);
+ return (he);
+}
+
+struct hostent *
+lwres_gethostent(void) {
+ if (he != NULL)
+ lwres_freehostent(he);
+
+ return (NULL);
+}
+
+void
+lwres_sethostent(int stayopen) {
+ /*
+ * Empty.
+ */
+ UNUSED(stayopen);
+}
+
+void
+lwres_endhostent(void) {
+ /*
+ * Empty.
+ */
+}
+
+struct hostent *
+lwres_gethostbyname_r(const char *name, struct hostent *resbuf,
+ char *buf, int buflen, int *error)
+{
+ struct hostent *he;
+ int res;
+
+ he = lwres_getipnodebyname(name, AF_INET, 0, error);
+ if (he == NULL)
+ return (NULL);
+ res = copytobuf(he, resbuf, buf, buflen);
+ lwres_freehostent(he);
+ if (res != 0) {
+ errno = ERANGE;
+ return (NULL);
+ }
+ return (resbuf);
+}
+
+struct hostent *
+lwres_gethostbyaddr_r(const char *addr, int len, int type,
+ struct hostent *resbuf, char *buf, int buflen,
+ int *error)
+{
+ struct hostent *he;
+ int res;
+
+ he = lwres_getipnodebyaddr(addr, len, type, error);
+ if (he == NULL)
+ return (NULL);
+ res = copytobuf(he, resbuf, buf, buflen);
+ lwres_freehostent(he);
+ if (res != 0) {
+ errno = ERANGE;
+ return (NULL);
+ }
+ return (resbuf);
+}
+
+struct hostent *
+lwres_gethostent_r(struct hostent *resbuf, char *buf, int buflen, int *error) {
+ UNUSED(resbuf);
+ UNUSED(buf);
+ UNUSED(buflen);
+ *error = 0;
+ return (NULL);
+}
+
+void
+lwres_sethostent_r(int stayopen) {
+ /*
+ * Empty.
+ */
+ UNUSED(stayopen);
+}
+
+void
+lwres_endhostent_r(void) {
+ /*
+ * Empty.
+ */
+}
+
+static int
+copytobuf(struct hostent *he, struct hostent *hptr, char *buf, int buflen) {
+ char *cp;
+ char **ptr;
+ int i, n;
+ int nptr, len;
+
+ /*
+ * Find out the amount of space required to store the answer.
+ */
+ nptr = 2; /* NULL ptrs */
+ len = (char *)LWRES_ALIGN(buf) - buf;
+ for (i = 0; he->h_addr_list[i]; i++, nptr++) {
+ len += he->h_length;
+ }
+ for (i = 0; he->h_aliases[i]; i++, nptr++) {
+ len += strlen(he->h_aliases[i]) + 1;
+ }
+ len += strlen(he->h_name) + 1;
+ len += nptr * sizeof(char*);
+
+ if (len > buflen) {
+ return (-1);
+ }
+
+ /*
+ * Copy address size and type.
+ */
+ hptr->h_addrtype = he->h_addrtype;
+ n = hptr->h_length = he->h_length;
+
+ ptr = (char **)LWRES_ALIGN(buf);
+ cp = (char *)LWRES_ALIGN(buf) + nptr * sizeof(char *);
+
+ /*
+ * Copy address list.
+ */
+ hptr->h_addr_list = ptr;
+ for (i = 0; he->h_addr_list[i]; i++, ptr++) {
+ memcpy(cp, he->h_addr_list[i], n);
+ hptr->h_addr_list[i] = cp;
+ cp += n;
+ }
+ hptr->h_addr_list[i] = NULL;
+ ptr++;
+
+ /*
+ * Copy official name.
+ */
+ n = strlen(he->h_name) + 1;
+ strcpy(cp, he->h_name);
+ hptr->h_name = cp;
+ cp += n;
+
+ /*
+ * Copy aliases.
+ */
+ hptr->h_aliases = ptr;
+ for (i = 0; he->h_aliases[i]; i++) {
+ n = strlen(he->h_aliases[i]) + 1;
+ strcpy(cp, he->h_aliases[i]);
+ hptr->h_aliases[i] = cp;
+ cp += n;
+ }
+ hptr->h_aliases[i] = NULL;
+
+ return (0);
+}
diff --git a/src/libfreeswan/liblwres/getipnode.c b/src/libfreeswan/liblwres/getipnode.c
new file mode 100644
index 000000000..94882cbe4
--- /dev/null
+++ b/src/libfreeswan/liblwres/getipnode.c
@@ -0,0 +1,839 @@
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getipnode.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+
+#include "assert_p.h"
+
+#ifndef INADDRSZ
+#define INADDRSZ 4
+#endif
+#ifndef IN6ADDRSZ
+#define IN6ADDRSZ 16
+#endif
+
+#ifdef LWRES_PLATFORM_NEEDIN6ADDRANY
+LIBLWRES_EXTERNAL_DATA const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+#endif
+
+#ifndef IN6_IS_ADDR_V4COMPAT
+static const unsigned char in6addr_compat[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+#define IN6_IS_ADDR_V4COMPAT(x) (!memcmp((x)->s6_addr, in6addr_compat, 12) && \
+ ((x)->s6_addr[12] != 0 || \
+ (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && \
+ (x)->s6_addr[15] != 1)))
+#endif
+#ifndef IN6_IS_ADDR_V4MAPPED
+#define IN6_IS_ADDR_V4MAPPED(x) (!memcmp((x)->s6_addr, in6addr_mapped, 12))
+#endif
+
+static const unsigned char in6addr_mapped[12] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff
+};
+
+/***
+ *** Forward declarations.
+ ***/
+
+static int
+scan_interfaces(int *, int *);
+
+static struct hostent *
+copyandmerge(struct hostent *, struct hostent *, int, int *);
+
+static struct hostent *
+hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src);
+
+static struct hostent *
+hostfromname(lwres_gabnresponse_t *name, int af);
+
+/***
+ *** Public functions.
+ ***/
+
+/*
+ * AI_V4MAPPED + AF_INET6
+ * If no IPv6 address then a query for IPv4 and map returned values.
+ *
+ * AI_ALL + AI_V4MAPPED + AF_INET6
+ * Return IPv6 and IPv4 mapped.
+ *
+ * AI_ADDRCONFIG
+ * Only return IPv6 / IPv4 address if there is an interface of that
+ * type active.
+ */
+
+struct hostent *
+lwres_getipnodebyname(const char *name, int af, int flags, int *error_num) {
+ int have_v4 = 1, have_v6 = 1;
+ struct in_addr in4;
+ struct in6_addr in6;
+ struct hostent he, *he1 = NULL, *he2 = NULL, *he3 = NULL;
+ int v4 = 0, v6 = 0;
+ int tmp_err;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gabnresponse_t *by = NULL;
+ int n;
+
+ /*
+ * If we care about active interfaces then check.
+ */
+ if ((flags & AI_ADDRCONFIG) != 0)
+ if (scan_interfaces(&have_v4, &have_v6) == -1) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ /* Check for literal address. */
+ if ((v4 = lwres_net_pton(AF_INET, name, &in4)) != 1)
+ v6 = lwres_net_pton(AF_INET6, name, &in6);
+
+ /*
+ * Impossible combination?
+ */
+ if ((af == AF_INET6 && (flags & AI_V4MAPPED) == 0 && v4 == 1) ||
+ (af == AF_INET && v6 == 1) ||
+ (have_v4 == 0 && v4 == 1) ||
+ (have_v6 == 0 && v6 == 1) ||
+ (have_v4 == 0 && af == AF_INET) ||
+ (have_v6 == 0 && af == AF_INET6 &&
+ (((flags & AI_V4MAPPED) != 0 && have_v4) ||
+ (flags & AI_V4MAPPED) == 0))) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+
+ /*
+ * Literal address?
+ */
+ if (v4 == 1 || v6 == 1) {
+ char *addr_list[2];
+ char *aliases[1];
+ union {
+ const char *const_name;
+ char *deconst_name;
+ } u;
+
+ u.const_name = name;
+ he.h_name = u.deconst_name;
+ he.h_addr_list = addr_list;
+ he.h_addr_list[0] = (v4 == 1) ? (char *)&in4 : (char *)&in6;
+ he.h_addr_list[1] = NULL;
+ he.h_aliases = aliases;
+ he.h_aliases[0] = NULL;
+ he.h_length = (v4 == 1) ? INADDRSZ : IN6ADDRSZ;
+ he.h_addrtype = (v4 == 1) ? AF_INET : AF_INET6;
+ return (copyandmerge(&he, NULL, af, error_num));
+ }
+
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n != 0) {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ tmp_err = NO_RECOVERY;
+ if (have_v6 && af == AF_INET6) {
+
+ n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V6, &by);
+ if (n == 0) {
+ he1 = hostfromname(by, AF_INET6);
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (he1 == NULL) {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ } else {
+ tmp_err = HOST_NOT_FOUND;
+ }
+ }
+
+ if (have_v4 &&
+ ((af == AF_INET) ||
+ (af == AF_INET6 && (flags & AI_V4MAPPED) != 0 &&
+ (he1 == NULL || (flags & AI_ALL) != 0)))) {
+ n = lwres_getaddrsbyname(lwrctx, name, LWRES_ADDRTYPE_V4, &by);
+ if (n == 0) {
+ he2 = hostfromname(by, AF_INET);
+ lwres_gabnresponse_free(lwrctx, &by);
+ if (he2 == NULL) {
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ } else if (he1 == NULL) {
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+ goto cleanup;
+ }
+ } else
+ *error_num = tmp_err;
+
+ he3 = copyandmerge(he1, he2, af, error_num);
+
+ cleanup:
+ if (he1 != NULL)
+ lwres_freehostent(he1);
+ if (he2 != NULL)
+ lwres_freehostent(he2);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (he3);
+}
+
+struct hostent *
+lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num) {
+ struct hostent *he1, *he2;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gnbaresponse_t *by = NULL;
+ lwres_result_t n;
+ union {
+ const void *konst;
+ struct in6_addr *in6;
+ } u;
+
+ /*
+ * Sanity checks.
+ */
+ if (src == NULL) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ switch (af) {
+ case AF_INET:
+ if (len != INADDRSZ) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ case AF_INET6:
+ if (len != IN6ADDRSZ) {
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ break;
+ default:
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+
+ /*
+ * The de-"const"-ing game is done because at least one
+ * vendor's system (RedHat 6.0) defines the IN6_IS_ADDR_*
+ * macros in such a way that they discard the const with
+ * internal casting, and gcc ends up complaining. Rather
+ * than replacing their own (possibly optimized) definitions
+ * with our own, cleanly discarding the const is the easiest
+ * thing to do.
+ */
+ u.konst = src;
+
+ /*
+ * Look up IPv4 and IPv4 mapped/compatible addresses.
+ */
+ if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(u.in6)) ||
+ (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(u.in6)) ||
+ (af == AF_INET)) {
+ const unsigned char *cp = src;
+
+ if (af == AF_INET6)
+ cp += 12;
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n == LWRES_R_SUCCESS)
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ if (n == LWRES_R_SUCCESS)
+ n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V4,
+ INADDRSZ, cp, &by);
+ if (n != LWRES_R_SUCCESS) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ if (n == LWRES_R_NOTFOUND)
+ *error_num = HOST_NOT_FOUND;
+ else
+ *error_num = NO_RECOVERY;
+ return (NULL);
+ }
+ he1 = hostfromaddr(by, AF_INET, cp);
+ lwres_gnbaresponse_free(lwrctx, &by);
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ if (af != AF_INET6)
+ return (he1);
+
+ /*
+ * Convert from AF_INET to AF_INET6.
+ */
+ he2 = copyandmerge(he1, NULL, af, error_num);
+ lwres_freehostent(he1);
+ if (he2 == NULL)
+ return (NULL);
+ /*
+ * Restore original address.
+ */
+ memcpy(he2->h_addr, src, len);
+ return (he2);
+ }
+
+ /*
+ * Lookup IPv6 address.
+ */
+ if (memcmp(src, &in6addr_any, IN6ADDRSZ) == 0) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n == LWRES_R_SUCCESS)
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+ if (n == LWRES_R_SUCCESS)
+ n = lwres_getnamebyaddr(lwrctx, LWRES_ADDRTYPE_V6, IN6ADDRSZ,
+ src, &by);
+ if (n != 0) {
+ *error_num = HOST_NOT_FOUND;
+ return (NULL);
+ }
+ he1 = hostfromaddr(by, AF_INET6, src);
+ lwres_gnbaresponse_free(lwrctx, &by);
+ if (he1 == NULL)
+ *error_num = NO_RECOVERY;
+ lwres_context_destroy(&lwrctx);
+ return (he1);
+}
+
+void
+lwres_freehostent(struct hostent *he) {
+ char **cpp;
+ int names = 1;
+ int addresses = 1;
+
+ free(he->h_name);
+
+ cpp = he->h_addr_list;
+ while (*cpp != NULL) {
+ free(*cpp);
+ *cpp = NULL;
+ cpp++;
+ addresses++;
+ }
+
+ cpp = he->h_aliases;
+ while (*cpp != NULL) {
+ free(*cpp);
+ cpp++;
+ names++;
+ }
+
+ free(he->h_aliases);
+ free(he->h_addr_list);
+ free(he);
+}
+
+/*
+ * Private
+ */
+
+/*
+ * Scan the interface table and set have_v4 and have_v6 depending
+ * upon whether there are IPv4 and IPv6 interface addresses.
+ *
+ * Returns:
+ * 0 on success
+ * -1 on failure.
+ */
+
+static int
+scan_interfaces(int *have_v4, int *have_v6) {
+#if 1
+ *have_v4 = *have_v6 = 1;
+ return (0);
+#else
+ struct ifconf ifc;
+ struct ifreq ifreq;
+ struct in_addr in4;
+ struct in6_addr in6;
+ char *buf = NULL, *cp, *cplim;
+ static int bufsiz = 4095;
+ int s, cpsize, n;
+
+ /*
+ * Set to zero. Used as loop terminators below.
+ */
+ *have_v4 = *have_v6 = 0;
+
+ /*
+ * Get interface list from system.
+ */
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+ goto err_ret;
+
+ /*
+ * Grow buffer until large enough to contain all interface
+ * descriptions.
+ */
+ for (;;) {
+ buf = malloc(bufsiz);
+ if (buf == NULL)
+ goto err_ret;
+ ifc.ifc_len = bufsiz;
+ ifc.ifc_buf = buf;
+#ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF
+ /*
+ * This is a fix for IRIX OS in which the call to ioctl with
+ * the flag SIOCGIFCONF may not return an entry for all the
+ * interfaces like most flavors of Unix.
+ */
+ if (emul_ioctl(&ifc) >= 0)
+ break;
+#else
+ if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) {
+ /*
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.ifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (ifc.ifc_len + 2 * sizeof(ifreq) < bufsiz)
+ break;
+ }
+#endif
+ if ((n == -1) && errno != EINVAL)
+ goto err_ret;
+
+ if (bufsiz > 1000000)
+ goto err_ret;
+
+ free(buf);
+ bufsiz += 4096;
+ }
+
+ /*
+ * Parse system's interface list.
+ */
+ cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */
+ for (cp = buf;
+ (*have_v4 == 0 || *have_v6 == 0) && cp < cplim;
+ cp += cpsize) {
+ memcpy(&ifreq, cp, sizeof ifreq);
+#ifdef LWRES_PLATFORM_HAVESALEN
+#ifdef FIX_ZERO_SA_LEN
+ if (ifreq.ifr_addr.sa_len == 0)
+ ifreq.ifr_addr.sa_len = IN6ADDRSZ;
+#endif
+#ifdef HAVE_MINIMUM_IFREQ
+ cpsize = sizeof ifreq;
+ if (ifreq.ifr_addr.sa_len > sizeof (struct sockaddr))
+ cpsize += (int)ifreq.ifr_addr.sa_len -
+ (int)(sizeof(struct sockaddr));
+#else
+ cpsize = sizeof ifreq.ifr_name + ifreq.ifr_addr.sa_len;
+#endif /* HAVE_MINIMUM_IFREQ */
+#elif defined SIOCGIFCONF_ADDR
+ cpsize = sizeof ifreq;
+#else
+ cpsize = sizeof ifreq.ifr_name;
+ /* XXX maybe this should be a hard error? */
+ if (ioctl(s, SIOCGIFADDR, (char *)&ifreq) < 0)
+ continue;
+#endif /* LWRES_PLATFORM_HAVESALEN */
+ switch (ifreq.ifr_addr.sa_family) {
+ case AF_INET:
+ if (*have_v4 == 0) {
+ memcpy(&in4,
+ &((struct sockaddr_in *)
+ &ifreq.ifr_addr)->sin_addr,
+ sizeof(in4));
+ if (in4.s_addr == INADDR_ANY)
+ break;
+ n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq);
+ if (n < 0)
+ break;
+ if ((ifreq.ifr_flags & IFF_UP) == 0)
+ break;
+ *have_v4 = 1;
+ }
+ break;
+ case AF_INET6:
+ if (*have_v6 == 0) {
+ memcpy(&in6,
+ &((struct sockaddr_in6 *)
+ &ifreq.ifr_addr)->sin6_addr,
+ sizeof(in6));
+ if (memcmp(&in6, &in6addr_any,
+ sizeof(in6)) == 0)
+ break;
+ n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq);
+ if (n < 0)
+ break;
+ if ((ifreq.ifr_flags & IFF_UP) == 0)
+ break;
+ *have_v6 = 1;
+ }
+ break;
+ }
+ }
+ if (buf != NULL)
+ free(buf);
+ close(s);
+ return (0);
+ err_ret:
+ if (buf != NULL)
+ free(buf);
+ if (s != -1)
+ close(s);
+ return (-1);
+#endif
+}
+
+static struct hostent *
+copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num)
+{
+ struct hostent *he = NULL;
+ int addresses = 1; /* NULL terminator */
+ int names = 1; /* NULL terminator */
+ int len = 0;
+ char **cpp, **npp;
+
+ /*
+ * Work out array sizes.
+ */
+ if (he1 != NULL) {
+ cpp = he1->h_addr_list;
+ while (*cpp != NULL) {
+ addresses++;
+ cpp++;
+ }
+ cpp = he1->h_aliases;
+ while (*cpp != NULL) {
+ names++;
+ cpp++;
+ }
+ }
+
+ if (he2 != NULL) {
+ cpp = he2->h_addr_list;
+ while (*cpp != NULL) {
+ addresses++;
+ cpp++;
+ }
+ if (he1 == NULL) {
+ cpp = he2->h_aliases;
+ while (*cpp != NULL) {
+ names++;
+ cpp++;
+ }
+ }
+ }
+
+ if (addresses == 1) {
+ *error_num = NO_ADDRESS;
+ return (NULL);
+ }
+
+ he = malloc(sizeof *he);
+ if (he == NULL)
+ goto no_recovery;
+
+ he->h_addr_list = malloc(sizeof(char *) * (addresses));
+ if (he->h_addr_list == NULL)
+ goto cleanup0;
+ memset(he->h_addr_list, 0, sizeof(char *) * (addresses));
+
+ /*
+ * Copy addresses.
+ */
+ npp = he->h_addr_list;
+ if (he1 != NULL) {
+ cpp = he1->h_addr_list;
+ while (*cpp != NULL) {
+ *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ if (*npp == NULL)
+ goto cleanup1;
+ /*
+ * Convert to mapped if required.
+ */
+ if (af == AF_INET6 && he1->h_addrtype == AF_INET) {
+ memcpy(*npp, in6addr_mapped,
+ sizeof in6addr_mapped);
+ memcpy(*npp + sizeof in6addr_mapped, *cpp,
+ INADDRSZ);
+ } else {
+ memcpy(*npp, *cpp,
+ (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ }
+ cpp++;
+ npp++;
+ }
+ }
+
+ if (he2 != NULL) {
+ cpp = he2->h_addr_list;
+ while (*cpp != NULL) {
+ *npp = malloc((af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ if (*npp == NULL)
+ goto cleanup1;
+ /*
+ * Convert to mapped if required.
+ */
+ if (af == AF_INET6 && he2->h_addrtype == AF_INET) {
+ memcpy(*npp, in6addr_mapped,
+ sizeof in6addr_mapped);
+ memcpy(*npp + sizeof in6addr_mapped, *cpp,
+ INADDRSZ);
+ } else {
+ memcpy(*npp, *cpp,
+ (af == AF_INET) ? INADDRSZ : IN6ADDRSZ);
+ }
+ cpp++;
+ npp++;
+ }
+ }
+
+ he->h_aliases = malloc(sizeof(char *) * (names));
+ if (he->h_aliases == NULL)
+ goto cleanup1;
+ memset(he->h_aliases, 0, sizeof(char *) * (names));
+
+ /*
+ * Copy aliases.
+ */
+ npp = he->h_aliases;
+ cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases;
+ while (*cpp != NULL) {
+ len = strlen (*cpp) + 1;
+ *npp = malloc(len);
+ if (*npp == NULL)
+ goto cleanup2;
+ strcpy(*npp, *cpp);
+ npp++;
+ cpp++;
+ }
+
+ /*
+ * Copy hostname.
+ */
+ he->h_name = malloc(strlen((he1 != NULL) ?
+ he1->h_name : he2->h_name) + 1);
+ if (he->h_name == NULL)
+ goto cleanup2;
+ strcpy(he->h_name, (he1 != NULL) ? he1->h_name : he2->h_name);
+
+ /*
+ * Set address type and length.
+ */
+ he->h_addrtype = af;
+ he->h_length = (af == AF_INET) ? INADDRSZ : IN6ADDRSZ;
+ return (he);
+
+ cleanup2:
+ cpp = he->h_aliases;
+ while (*cpp != NULL) {
+ free(*cpp);
+ cpp++;
+ }
+ free(he->h_aliases);
+
+ cleanup1:
+ cpp = he->h_addr_list;
+ while (*cpp != NULL) {
+ free(*cpp);
+ *cpp = NULL;
+ cpp++;
+ }
+ free(he->h_addr_list);
+
+ cleanup0:
+ free(he);
+
+ no_recovery:
+ *error_num = NO_RECOVERY;
+ return (NULL);
+}
+
+static struct hostent *
+hostfromaddr(lwres_gnbaresponse_t *addr, int af, const void *src) {
+ struct hostent *he;
+ int i;
+
+ he = malloc(sizeof *he);
+ if (he == NULL)
+ goto cleanup;
+ memset(he, 0, sizeof(*he));
+
+ /*
+ * Set family and length.
+ */
+ he->h_addrtype = af;
+ switch (af) {
+ case AF_INET:
+ he->h_length = INADDRSZ;
+ break;
+ case AF_INET6:
+ he->h_length = IN6ADDRSZ;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ /*
+ * Copy name.
+ */
+ he->h_name = strdup(addr->realname);
+ if (he->h_name == NULL)
+ goto cleanup;
+
+ /*
+ * Copy aliases.
+ */
+ he->h_aliases = malloc(sizeof(char *) * (addr->naliases + 1));
+ if (he->h_aliases == NULL)
+ goto cleanup;
+ for (i = 0 ; i < addr->naliases; i++) {
+ he->h_aliases[i] = strdup(addr->aliases[i]);
+ if (he->h_aliases[i] == NULL)
+ goto cleanup;
+ }
+ he->h_aliases[i] = NULL;
+
+ /*
+ * Copy address.
+ */
+ he->h_addr_list = malloc(sizeof(char *) * 2);
+ if (he->h_addr_list == NULL)
+ goto cleanup;
+ he->h_addr_list[0] = malloc(he->h_length);
+ if (he->h_addr_list[0] == NULL)
+ goto cleanup;
+ memcpy(he->h_addr_list[0], src, he->h_length);
+ he->h_addr_list[1] = NULL;
+ return (he);
+
+ cleanup:
+ if (he != NULL && he->h_addr_list != NULL) {
+ for (i = 0; he->h_addr_list[i] != NULL; i++)
+ free(he->h_addr_list[i]);
+ free(he->h_addr_list);
+ }
+ if (he != NULL && he->h_aliases != NULL) {
+ for (i = 0; he->h_aliases[i] != NULL; i++)
+ free(he->h_aliases[i]);
+ free(he->h_aliases);
+ }
+ if (he != NULL && he->h_name != NULL)
+ free(he->h_name);
+ if (he != NULL)
+ free(he);
+ return (NULL);
+}
+
+static struct hostent *
+hostfromname(lwres_gabnresponse_t *name, int af) {
+ struct hostent *he;
+ int i;
+ lwres_addr_t *addr;
+
+ he = malloc(sizeof *he);
+ if (he == NULL)
+ goto cleanup;
+ memset(he, 0, sizeof(*he));
+
+ /*
+ * Set family and length.
+ */
+ he->h_addrtype = af;
+ switch (af) {
+ case AF_INET:
+ he->h_length = INADDRSZ;
+ break;
+ case AF_INET6:
+ he->h_length = IN6ADDRSZ;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ /*
+ * Copy name.
+ */
+ he->h_name = strdup(name->realname);
+ if (he->h_name == NULL)
+ goto cleanup;
+
+ /*
+ * Copy aliases.
+ */
+ he->h_aliases = malloc(sizeof(char *) * (name->naliases + 1));
+ for (i = 0 ; i < name->naliases; i++) {
+ he->h_aliases[i] = strdup(name->aliases[i]);
+ if (he->h_aliases[i] == NULL)
+ goto cleanup;
+ }
+ he->h_aliases[i] = NULL;
+
+ /*
+ * Copy addresses.
+ */
+ he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1));
+ addr = LWRES_LIST_HEAD(name->addrs);
+ i = 0;
+ while (addr != NULL) {
+ he->h_addr_list[i] = malloc(he->h_length);
+ if (he->h_addr_list[i] == NULL)
+ goto cleanup;
+ memcpy(he->h_addr_list[i], addr->address, he->h_length);
+ addr = LWRES_LIST_NEXT(addr, link);
+ i++;
+ }
+ he->h_addr_list[i] = NULL;
+ return (he);
+
+ cleanup:
+ if (he != NULL && he->h_addr_list != NULL) {
+ for (i = 0; he->h_addr_list[i] != NULL; i++)
+ free(he->h_addr_list[i]);
+ free(he->h_addr_list);
+ }
+ if (he != NULL && he->h_aliases != NULL) {
+ for (i = 0; he->h_aliases[i] != NULL; i++)
+ free(he->h_aliases[i]);
+ free(he->h_aliases);
+ }
+ if (he != NULL && he->h_name != NULL)
+ free(he->h_name);
+ if (he != NULL)
+ free(he);
+ return (NULL);
+}
diff --git a/src/libfreeswan/liblwres/getnameinfo.c b/src/libfreeswan/liblwres/getnameinfo.c
new file mode 100644
index 000000000..36eea3180
--- /dev/null
+++ b/src/libfreeswan/liblwres/getnameinfo.c
@@ -0,0 +1,289 @@
+/*
+ * Portions Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getnameinfo.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by WIDE Project and
+ * its contributors.
+ * 4. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * XXX
+ * Issues to be discussed:
+ * - Return values. There seems to be no standard for return value (RFC2553)
+ * but INRIA implementation returns EAI_xxx defined for getaddrinfo().
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h>
+
+#include "assert_p.h"
+
+#define SUCCESS 0
+
+static struct afd {
+ int a_af;
+ size_t a_addrlen;
+ size_t a_socklen;
+} afdl [] = {
+ /*
+ * First entry is linked last...
+ */
+ { AF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in) },
+ { AF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6) },
+ {0, 0, 0},
+};
+
+#define ENI_NOSERVNAME 1
+#define ENI_NOHOSTNAME 2
+#define ENI_MEMORY 3
+#define ENI_SYSTEM 4
+#define ENI_FAMILY 5
+#define ENI_SALEN 6
+#define ENI_NOSOCKET 7
+
+/*
+ * The test against 0 is there to keep the Solaris compiler
+ * from complaining about "end-of-loop code not reached".
+ */
+#define ERR(code) \
+ do { result = (code); \
+ if (result != 0) goto cleanup; \
+ } while (0)
+
+int
+lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
+ size_t hostlen, char *serv, size_t servlen, int flags)
+{
+ struct afd *afd;
+ struct servent *sp;
+ unsigned short port;
+#ifdef LWRES_PLATFORM_HAVESALEN
+ size_t len;
+#endif
+ int family, i;
+ const void *addr;
+ char *p;
+#if 0
+ unsigned long v4a;
+ unsigned char pfx;
+#endif
+ char numserv[sizeof("65000")];
+ char numaddr[sizeof("abcd:abcd:abcd:abcd:abcd:abcd:255.255.255.255")
+ + 1 + sizeof("4294967295")];
+ const char *proto;
+ lwres_uint32_t lwf = 0;
+ lwres_context_t *lwrctx = NULL;
+ lwres_gnbaresponse_t *by = NULL;
+ int result = SUCCESS;
+ int n;
+
+ if (sa == NULL)
+ ERR(ENI_NOSOCKET);
+
+#ifdef LWRES_PLATFORM_HAVESALEN
+ len = sa->sa_len;
+ if (len != salen)
+ ERR(ENI_SALEN);
+#endif
+
+ family = sa->sa_family;
+ for (i = 0; afdl[i].a_af; i++)
+ if (afdl[i].a_af == family) {
+ afd = &afdl[i];
+ goto found;
+ }
+ ERR(ENI_FAMILY);
+
+ found:
+ if (salen != afd->a_socklen)
+ ERR(ENI_SALEN);
+
+ switch (family) {
+ case AF_INET:
+ port = ((const struct sockaddr_in *)sa)->sin_port;
+ addr = &((const struct sockaddr_in *)sa)->sin_addr.s_addr;
+ break;
+
+ case AF_INET6:
+ port = ((const struct sockaddr_in6 *)sa)->sin6_port;
+ addr = ((const struct sockaddr_in6 *)sa)->sin6_addr.s6_addr;
+ break;
+
+ default:
+ port = 0;
+ addr = NULL;
+ INSIST(0);
+ }
+ proto = (flags & NI_DGRAM) ? "udp" : "tcp";
+
+ if (serv == NULL || servlen == 0) {
+ /*
+ * Caller does not want service.
+ */
+ } else if ((flags & NI_NUMERICSERV) != 0 ||
+ (sp = getservbyport(port, proto)) == NULL) {
+ sprintf(numserv, "%d", ntohs(port));
+ if ((strlen(numserv) + 1) > servlen)
+ ERR(ENI_MEMORY);
+ strcpy(serv, numserv);
+ } else {
+ if ((strlen(sp->s_name) + 1) > servlen)
+ ERR(ENI_MEMORY);
+ strcpy(serv, sp->s_name);
+ }
+
+#if 0
+ switch (sa->sa_family) {
+ case AF_INET:
+ v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
+ if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
+ flags |= NI_NUMERICHOST;
+ v4a >>= IN_CLASSA_NSHIFT;
+ if (v4a == 0 || v4a == IN_LOOPBACKNET)
+ flags |= NI_NUMERICHOST;
+ break;
+
+ case AF_INET6:
+ pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0];
+ if (pfx == 0 || pfx == 0xfe || pfx == 0xff)
+ flags |= NI_NUMERICHOST;
+ break;
+ }
+#endif
+
+ if (host == NULL || hostlen == 0) {
+ /*
+ * What should we do?
+ */
+ } else if (flags & NI_NUMERICHOST) {
+ if (lwres_net_ntop(afd->a_af, addr, numaddr, sizeof(numaddr))
+ == NULL)
+ ERR(ENI_SYSTEM);
+#if defined(LWRES_HAVE_SIN6_SCOPE_ID)
+ if (afd->a_af == AF_INET6 &&
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
+ char *p = numaddr + strlen(numaddr);
+ const char *stringscope = NULL;
+#if 0
+ if ((flags & NI_NUMERICSCOPE) == 0) {
+ /*
+ * Vendors may want to add support for
+ * non-numeric scope identifier.
+ */
+ stringscope = foo;
+ }
+#endif
+ if (stringscope == NULL) {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%u",
+ ((const struct sockaddr_in6 *)sa)->sin6_scope_id);
+ } else {
+ snprintf(p, sizeof(numaddr) - (p - numaddr),
+ "%%%s", stringscope);
+ }
+ }
+#endif
+ if (strlen(numaddr) + 1 > hostlen)
+ ERR(ENI_MEMORY);
+ strcpy(host, numaddr);
+ } else {
+ switch (family) {
+ case AF_INET:
+ lwf = LWRES_ADDRTYPE_V4;
+ break;
+ case AF_INET6:
+ lwf = LWRES_ADDRTYPE_V6;
+ break;
+ default:
+ INSIST(0);
+ }
+
+ n = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (n == 0)
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+
+ if (n == 0)
+ n = lwres_getnamebyaddr(lwrctx, lwf,
+ (lwres_uint16_t)afd->a_addrlen,
+ addr, &by);
+ if (n == 0) {
+ if (flags & NI_NOFQDN) {
+ p = strchr(by->realname, '.');
+ if (p)
+ *p = '\0';
+ }
+ if ((strlen(by->realname) + 1) > hostlen)
+ ERR(ENI_MEMORY);
+ strcpy(host, by->realname);
+ } else {
+ if (flags & NI_NAMEREQD)
+ ERR(ENI_NOHOSTNAME);
+ if (lwres_net_ntop(afd->a_af, addr, numaddr,
+ sizeof(numaddr))
+ == NULL)
+ ERR(ENI_NOHOSTNAME);
+ if ((strlen(numaddr) + 1) > hostlen)
+ ERR(ENI_MEMORY);
+ strcpy(host, numaddr);
+ }
+ }
+ result = SUCCESS;
+ cleanup:
+ if (by != NULL)
+ lwres_gnbaresponse_free(lwrctx, &by);
+ if (lwrctx != NULL) {
+ lwres_conf_clear(lwrctx);
+ lwres_context_destroy(&lwrctx);
+ }
+ return (result);
+}
diff --git a/src/libfreeswan/liblwres/getrrset.c b/src/libfreeswan/liblwres/getrrset.c
new file mode 100644
index 000000000..cf8359268
--- /dev/null
+++ b/src/libfreeswan/liblwres/getrrset.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getrrset.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+
+#include "assert_p.h"
+
+unsigned int
+lwresult_to_result(lwres_result_t lwresult) {
+ switch (lwresult) {
+ case LWRES_R_SUCCESS: return (ERRSET_SUCCESS);
+ case LWRES_R_NOMEMORY: return (ERRSET_NOMEMORY);
+ case LWRES_R_NOTFOUND: return (ERRSET_NONAME);
+ case LWRES_R_TYPENOTFOUND: return (ERRSET_NODATA);
+ case LWRES_R_RETRY: return (ERRSET_RETRY);
+ default: return (ERRSET_FAIL);
+ }
+}
+
+/*
+ * malloc / calloc functions that guarantee to only
+ * return NULL if there is an error, like they used
+ * to before the ANSI C committee broke them.
+ */
+
+static void *
+sane_malloc(size_t size) {
+ if (size == 0)
+ size = 1;
+ return (malloc(size));
+}
+
+static void *
+sane_calloc(size_t number, size_t size) {
+ size_t len = number * size;
+ void *mem = sane_malloc(len);
+ if (mem != NULL)
+ memset(mem, 0, len);
+ return (mem);
+}
+
+int
+lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ struct rrsetinfo **res)
+{
+ lwres_context_t *lwrctx = NULL;
+ lwres_result_t lwresult;
+ lwres_grbnresponse_t *response = NULL;
+ struct rrsetinfo *rrset = NULL;
+ unsigned int i;
+ unsigned int lwflags;
+ unsigned int result;
+
+ if (rdclass > 0xffff || rdtype > 0xffff) {
+ result = ERRSET_INVAL;
+ goto fail;
+ }
+
+ /*
+ * Don't allow queries of class or type ANY
+ */
+ if (rdclass == 0xff || rdtype == 0xff) {
+ result = ERRSET_INVAL;
+ goto fail;
+ }
+
+ lwresult = lwres_context_create(&lwrctx, NULL, NULL, NULL, 0);
+ if (lwresult != LWRES_R_SUCCESS) {
+ result = lwresult_to_result(lwresult);
+ goto fail;
+ }
+ (void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
+
+ /*
+ * If any input flags were defined, lwflags would be set here
+ * based on them
+ */
+ UNUSED(flags);
+ lwflags = 0;
+
+ lwresult = lwres_getrdatabyname(lwrctx, hostname,
+ (lwres_uint16_t)rdclass,
+ (lwres_uint16_t)rdtype,
+ lwflags, &response);
+ if (lwresult != LWRES_R_SUCCESS) {
+ result = lwresult_to_result(lwresult);
+ goto fail;
+ }
+
+ rrset = sane_malloc(sizeof(struct rrsetinfo));
+ if (rrset == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ rrset->rri_name = NULL;
+ rrset->rri_rdclass = response->rdclass;
+ rrset->rri_rdtype = response->rdtype;
+ rrset->rri_ttl = response->ttl;
+ rrset->rri_flags = 0;
+ rrset->rri_nrdatas = 0;
+ rrset->rri_rdatas = NULL;
+ rrset->rri_nsigs = 0;
+ rrset->rri_sigs = NULL;
+
+ rrset->rri_name = sane_malloc(response->realnamelen + 1);
+ if (rrset->rri_name == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ strncpy(rrset->rri_name, response->realname, response->realnamelen);
+ rrset->rri_name[response->realnamelen] = 0;
+
+ if ((response->flags & LWRDATA_VALIDATED) != 0)
+ rrset->rri_flags |= RRSET_VALIDATED;
+
+ rrset->rri_nrdatas = response->nrdatas;
+ rrset->rri_rdatas = sane_calloc(rrset->rri_nrdatas,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_rdatas == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ rrset->rri_rdatas[i].rdi_length = response->rdatalen[i];
+ rrset->rri_rdatas[i].rdi_data =
+ sane_malloc(rrset->rri_rdatas[i].rdi_length);
+ if (rrset->rri_rdatas[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_rdatas[i].rdi_data, response->rdatas[i],
+ rrset->rri_rdatas[i].rdi_length);
+ }
+ rrset->rri_nsigs = response->nsigs;
+ rrset->rri_sigs = sane_calloc(rrset->rri_nsigs,
+ sizeof(struct rdatainfo));
+ if (rrset->rri_sigs == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ rrset->rri_sigs[i].rdi_length = response->siglen[i];
+ rrset->rri_sigs[i].rdi_data =
+ sane_malloc(rrset->rri_sigs[i].rdi_length);
+ if (rrset->rri_sigs[i].rdi_data == NULL) {
+ result = ERRSET_NOMEMORY;
+ goto fail;
+ }
+ memcpy(rrset->rri_sigs[i].rdi_data, response->sigs[i],
+ rrset->rri_sigs[i].rdi_length);
+ }
+
+ lwres_grbnresponse_free(lwrctx, &response);
+ lwres_context_destroy(&lwrctx);
+ *res = rrset;
+ return (ERRSET_SUCCESS);
+ fail:
+ if (rrset != NULL)
+ lwres_freerrset(rrset);
+ if (response != NULL)
+ lwres_grbnresponse_free(lwrctx, &response);
+ if (lwrctx != NULL)
+ lwres_context_destroy(&lwrctx);
+ return (result);
+
+}
+
+void
+lwres_freerrset(struct rrsetinfo *rrset) {
+ unsigned int i;
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ if (rrset->rri_rdatas[i].rdi_data == NULL)
+ break;
+ free(rrset->rri_rdatas[i].rdi_data);
+ }
+ free(rrset->rri_rdatas);
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ if (rrset->rri_sigs[i].rdi_data == NULL)
+ break;
+ free(rrset->rri_sigs[i].rdi_data);
+ }
+ free(rrset->rri_sigs);
+ free(rrset->rri_name);
+ free(rrset);
+}
+
diff --git a/src/libfreeswan/liblwres/getrrset2.c b/src/libfreeswan/liblwres/getrrset2.c
new file mode 100644
index 000000000..031021e06
--- /dev/null
+++ b/src/libfreeswan/liblwres/getrrset2.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: getrrset2.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/netdb.h> /* XXX #include <netdb.h> */
+
+#include <lwres/async.h>
+
+#include "assert_p.h"
+
+int
+lwres_getrrsetbyname_async(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ struct rrsetinfo **res)
+{
+ int ret, ret2;
+ lwres_context_t *ctx = NULL;
+ struct lwres_async_state las;
+ struct lwres_async_state *plas;
+ struct timeval timeout;
+ fd_set readfds;
+ int sock;
+
+ ret = lwres_async_init(&ctx);
+ if(ret != ERRSET_SUCCESS) {
+ return(ret);
+ }
+
+ ret = lwres_getrrsetbyname_init(hostname, rdclass,
+ rdtype, flags,
+ ctx, &las);
+
+ if(ret != ERRSET_SUCCESS) {
+ return ret;
+ }
+
+ again:
+
+ lwres_getrrsetbyname_xmit(ctx, &las);
+ timeout.tv_sec = lwres_async_timeout(ctx);
+ sock = lwres_async_fd(ctx);
+
+ FD_ZERO(&readfds);
+ FD_SET(sock, &readfds);
+ ret2 = select(sock + 1, &readfds, NULL, NULL, &timeout);
+
+ /*
+ * What happened with select?
+ */
+ if (ret2 < 0) {
+ ret = LWRES_R_IOERROR;
+ goto out3;
+ }
+ if (ret2 == 0) {
+ ret = LWRES_R_TIMEOUT;
+ goto out3;
+ }
+
+ ret = lwres_getrrsetbyname_read(&plas, ctx, res);
+ if(ret == LWRES_R_RETRY) {
+ /* XXX retransmit */
+ goto again;
+ }
+
+ out3:
+ /* clean stuff up */
+
+ out:
+ if (ctx != NULL)
+ lwres_context_destroy(&ctx);
+
+ return ret;
+}
+
diff --git a/src/libfreeswan/liblwres/herror.c b/src/libfreeswan/liblwres/herror.c
new file mode 100644
index 000000000..7a8bcb2bd
--- /dev/null
+++ b/src/libfreeswan/liblwres/herror.c
@@ -0,0 +1,101 @@
+/*
+ * Portions Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
+static const char rcsid[] =
+ "$Id: herror.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <lwres/netdb.h>
+#include <lwres/platform.h>
+
+LIBLWRES_EXTERNAL_DATA int lwres_h_errno;
+
+/*
+ * these have never been declared in any header file so make them static
+ */
+
+static const char *h_errlist[] = {
+ "Resolver Error 0 (no error)",
+ "Unknown host", /* 1 HOST_NOT_FOUND */
+ "Host name lookup failure", /* 2 TRY_AGAIN */
+ "Unknown server error", /* 3 NO_RECOVERY */
+ "No address associated with name", /* 4 NO_ADDRESS */
+};
+
+static int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+
+
+/*
+ * herror --
+ * print the error indicated by the h_errno value.
+ */
+void
+lwres_herror(const char *s) {
+ fprintf(stderr, "%s: %s\n", s, lwres_hstrerror(lwres_h_errno));
+}
+
+/*
+ * hstrerror --
+ * return the string associated with a given "host" errno value.
+ */
+const char *
+lwres_hstrerror(int err) {
+ if (err < 0)
+ return ("Resolver internal error");
+ else if (err < h_nerr)
+ return (h_errlist[err]);
+ return ("Unknown resolver error");
+}
diff --git a/src/libfreeswan/liblwres/include/lwres/async.h b/src/libfreeswan/liblwres/include/lwres/async.h
new file mode 100644
index 000000000..6715afaed
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/async.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003 Michael Richardson
+ * Contributed by Michael Richardson <mcr@freeswan.org> while working
+ * on the Linux FreeS/WAN project in 2003.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: async.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_ASYNC_H
+#define LWRES_ASYNC_H 1
+
+#include <lwres/lwres.h>
+
+/*
+ * support for asynchronous requests to lwres port
+ */
+struct lwres_async_state {
+ struct lwres_async_state *next;
+
+ lwres_buffer_t b_in, b_out;
+ lwres_uint32_t serial;
+ int opcode;
+
+ int (*callback)(void *uctx, struct rrsetinfo *res);
+ void *uctx;
+};
+
+
+
+/*
+ * The calls for asynchronous requests.
+ */
+
+int lwres_async_init(lwres_context_t **pctx);
+
+int lwres_getrrsetbyname_init(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ lwres_context_t *ctx,
+ struct lwres_async_state *las);
+
+int lwres_getrrsetbyname_xmit(lwres_context_t *ctx,
+ struct lwres_async_state *las);
+
+unsigned long lwres_async_timeout(lwres_context_t *ctx);
+
+int lwres_async_fd(lwres_context_t *ctx);
+
+int lwres_getrrsetbyname_read(struct lwres_async_state **plas,
+ lwres_context_t *ctx,
+ struct rrsetinfo **res);
+
+int lwres_getrrsetbyname_async(const char *hostname, unsigned int rdclass,
+ unsigned int rdtype, unsigned int flags,
+ struct rrsetinfo **res);
+
+#endif /* LWRES_ASYNC_H */
+
+
+
+
+
+
+
+
+
diff --git a/src/libfreeswan/liblwres/include/lwres/context.h b/src/libfreeswan/liblwres/include/lwres/context.h
new file mode 100644
index 000000000..55ca3c7fb
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/context.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: context.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_CONTEXT_H
+#define LWRES_CONTEXT_H 1
+
+#include <stddef.h>
+
+#include <lwres/lang.h>
+#include <lwres/int.h>
+#include <lwres/result.h>
+
+/*
+ * Used to set various options such as timeout, authentication, etc
+ */
+typedef struct lwres_context lwres_context_t;
+
+LWRES_LANG_BEGINDECLS
+
+typedef void *(*lwres_malloc_t)(void *arg, size_t length);
+typedef void (*lwres_free_t)(void *arg, void *mem, size_t length);
+
+/*
+ * XXXMLG
+ *
+ * Make the server reload /etc/resolv.conf periodically.
+ *
+ * Make the server do sortlist/searchlist.
+ *
+ * Client side can disable the search/sortlist processing.
+ *
+ * Use an array of addresses/masks and searchlist for client-side, and
+ * if added to the client disable the processing on the server.
+ *
+ * Share /etc/resolv.conf data between contexts.
+ */
+
+/*
+ * _SERVERMODE
+ * Don't allocate and connect a socket to the server, since the
+ * caller _is_ a server.
+ */
+#define LWRES_CONTEXT_SERVERMODE 0x00000001U
+
+lwres_result_t
+lwres_context_create(lwres_context_t **contextp, void *arg,
+ lwres_malloc_t malloc_function,
+ lwres_free_t free_function,
+ unsigned int flags);
+/*
+ * Allocate a lwres context. This is used in all lwres calls.
+ *
+ * Memory management can be replaced here by passing in two functions.
+ * If one is non-NULL, they must both be non-NULL. "arg" is passed to
+ * these functions.
+ *
+ * Contexts are not thread safe. Document at the top of the file.
+ * XXXMLG
+ *
+ * If they are NULL, the standard malloc() and free() will be used.
+ *
+ * Requires:
+ *
+ * contextp != NULL && contextp == NULL.
+ *
+ * Returns:
+ *
+ * Returns 0 on success, non-zero on failure.
+ */
+
+void
+lwres_context_destroy(lwres_context_t **contextp);
+/*
+ * Frees all memory associated with a lwres context.
+ *
+ * Requires:
+ *
+ * contextp != NULL && contextp == NULL.
+ */
+
+lwres_uint32_t
+lwres_context_nextserial(lwres_context_t *ctx);
+/*
+ * XXXMLG Document
+ */
+
+void
+lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial);
+
+void
+lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len);
+
+void *
+lwres_context_allocmem(lwres_context_t *ctx, size_t len);
+
+int
+lwres_context_getsocket(lwres_context_t *ctx);
+
+lwres_result_t
+lwres_context_send(lwres_context_t *ctx,
+ void *sendbase, int sendlen);
+
+lwres_result_t
+lwres_context_recv(lwres_context_t *ctx,
+ void *recvbase, int recvlen,
+ int *recvd_len);
+
+lwres_result_t
+lwres_context_sendrecv(lwres_context_t *ctx,
+ void *sendbase, int sendlen,
+ void *recvbase, int recvlen,
+ int *recvd_len);
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_CONTEXT_H */
+
diff --git a/src/libfreeswan/liblwres/include/lwres/int.h b/src/libfreeswan/liblwres/include/lwres/int.h
new file mode 100644
index 000000000..470372e77
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/int.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: int.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_INT_H
+#define LWRES_INT_H 1
+
+typedef char lwres_int8_t;
+typedef unsigned char lwres_uint8_t;
+typedef short lwres_int16_t;
+typedef unsigned short lwres_uint16_t;
+typedef int lwres_int32_t;
+typedef unsigned int lwres_uint32_t;
+typedef long long lwres_int64_t;
+typedef unsigned long long lwres_uint64_t;
+
+#endif /* LWRES_INT_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/ipv6.h b/src/libfreeswan/liblwres/include/lwres/ipv6.h
new file mode 100644
index 000000000..ee7bc0743
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/ipv6.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ipv6.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_IPV6_H
+#define LWRES_IPV6_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * IPv6 definitions for systems which do not support IPv6.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <lwres/int.h>
+#include <lwres/platform.h>
+
+/***
+ *** Types.
+ ***/
+
+struct in6_addr {
+ union {
+ lwres_uint8_t _S6_u8[16];
+ lwres_uint16_t _S6_u16[8];
+ lwres_uint32_t _S6_u32[4];
+ } _S6_un;
+};
+#define s6_addr _S6_un._S6_u8
+#define s6_addr8 _S6_un._S6_u8
+#define s6_addr16 _S6_un._S6_u16
+#define s6_addr32 _S6_un._S6_u32
+
+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
+
+LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_any;
+LIBLWRES_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback;
+
+struct sockaddr_in6 {
+#ifdef LWRES_PLATFORM_HAVESALEN
+ lwres_uint8_t sin6_len;
+ lwres_uint8_t sin6_family;
+#else
+ lwres_uint16_t sin6_family;
+#endif
+ lwres_uint16_t sin6_port;
+ lwres_uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ lwres_uint32_t sin6_scope_id;
+};
+
+#ifdef LWRES_PLATFORM_HAVESALEN
+#define SIN6_LEN 1
+#endif
+
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /* send/recv interface index */
+};
+
+/*
+ * Unspecified
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == 0))
+
+/*
+ * Loopback
+ */
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == htonl(1)))
+
+/*
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] != 0) && \
+ ((a)->s6_addr32[3] != htonl(1)))
+
+/*
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+
+#endif /* LWRES_IPV6_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/lang.h b/src/libfreeswan/liblwres/include/lwres/lang.h
new file mode 100644
index 000000000..1de35fd91
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/lang.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lang.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LANG_H
+#define LWRES_LANG_H 1
+
+#ifdef __cplusplus
+#define LWRES_LANG_BEGINDECLS extern "C" {
+#define LWRES_LANG_ENDDECLS }
+#else
+#define LWRES_LANG_BEGINDECLS
+#define LWRES_LANG_ENDDECLS
+#endif
+
+#endif /* LWRES_LANG_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/list.h b/src/libfreeswan/liblwres/include/lwres/list.h
new file mode 100644
index 000000000..e90a1b55a
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/list.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: list.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LIST_H
+#define LWRES_LIST_H 1
+
+#define LWRES_LIST(type) struct { type *head, *tail; }
+#define LWRES_LIST_INIT(list) \
+ do { (list).head = NULL; (list).tail = NULL; } while (0)
+
+#define LWRES_LINK(type) struct { type *prev, *next; }
+#define LWRES_LINK_INIT(elt, link) \
+ do { \
+ (elt)->link.prev = (void *)(-1); \
+ (elt)->link.next = (void *)(-1); \
+ } while (0)
+#define LWRES_LINK_LINKED(elt, link) \
+ ((void *)((elt)->link.prev) != (void *)(-1))
+
+#define LWRES_LIST_HEAD(list) ((list).head)
+#define LWRES_LIST_TAIL(list) ((list).tail)
+#define LWRES_LIST_EMPTY(list) LWRES_TF((list).head == NULL)
+
+#define LWRES_LIST_PREPEND(list, elt, link) \
+ do { \
+ if ((list).head != NULL) \
+ (list).head->link.prev = (elt); \
+ else \
+ (list).tail = (elt); \
+ (elt)->link.prev = NULL; \
+ (elt)->link.next = (list).head; \
+ (list).head = (elt); \
+ } while (0)
+
+#define LWRES_LIST_APPEND(list, elt, link) \
+ do { \
+ if ((list).tail != NULL) \
+ (list).tail->link.next = (elt); \
+ else \
+ (list).head = (elt); \
+ (elt)->link.prev = (list).tail; \
+ (elt)->link.next = NULL; \
+ (list).tail = (elt); \
+ } while (0)
+
+#define LWRES_LIST_UNLINK(list, elt, link) \
+ do { \
+ if ((elt)->link.next != NULL) \
+ (elt)->link.next->link.prev = (elt)->link.prev; \
+ else \
+ (list).tail = (elt)->link.prev; \
+ if ((elt)->link.prev != NULL) \
+ (elt)->link.prev->link.next = (elt)->link.next; \
+ else \
+ (list).head = (elt)->link.next; \
+ (elt)->link.prev = (void *)(-1); \
+ (elt)->link.next = (void *)(-1); \
+ } while (0)
+
+#define LWRES_LIST_PREV(elt, link) ((elt)->link.prev)
+#define LWRES_LIST_NEXT(elt, link) ((elt)->link.next)
+
+#define LWRES_LIST_INSERTBEFORE(list, before, elt, link) \
+ do { \
+ if ((before)->link.prev == NULL) \
+ LWRES_LIST_PREPEND(list, elt, link); \
+ else { \
+ (elt)->link.prev = (before)->link.prev; \
+ (before)->link.prev = (elt); \
+ (elt)->link.prev->link.next = (elt); \
+ (elt)->link.next = (before); \
+ } \
+ } while (0)
+
+#define LWRES_LIST_INSERTAFTER(list, after, elt, link) \
+ do { \
+ if ((after)->link.next == NULL) \
+ LWRES_LIST_APPEND(list, elt, link); \
+ else { \
+ (elt)->link.next = (after)->link.next; \
+ (after)->link.next = (elt); \
+ (elt)->link.next->link.prev = (elt); \
+ (elt)->link.prev = (after); \
+ } \
+ } while (0)
+
+#define LWRES_LIST_APPENDLIST(list1, list2, link) \
+ do { \
+ if (LWRES_LIST_EMPTY(list1)) \
+ (list1) = (list2); \
+ else if (!LWRES_LIST_EMPTY(list2)) { \
+ (list1).tail->link.next = (list2).head; \
+ (list2).head->link.prev = (list1).tail; \
+ (list1).tail = (list2).tail; \
+ } \
+ (list2).head = NULL; \
+ (list2).tail = NULL; \
+ } while (0)
+
+#define LWRES_LIST_ENQUEUE(list, elt, link) LWRES_LIST_APPEND(list, elt, link)
+#define LWRES_LIST_DEQUEUE(list, elt, link) LWRES_LIST_UNLINK(list, elt, link)
+
+#endif /* LWRES_LIST_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/lwbuffer.h b/src/libfreeswan/liblwres/include/lwres/lwbuffer.h
new file mode 100644
index 000000000..7486e8bc3
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/lwbuffer.h
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwbuffer.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LWBUFFER_H
+#define LWRES_LWBUFFER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Buffers
+ *
+ * A buffer is a region of memory, together with a set of related subregions.
+ * Buffers are used for parsing and I/O operations.
+ *
+ * The 'used region' and the 'available' region are disjoint, and their
+ * union is the buffer's region. The used region extends from the beginning
+ * of the buffer region to the last used byte. The available region
+ * extends from one byte greater than the last used byte to the end of the
+ * buffer's region. The size of the used region can be changed using various
+ * buffer commands. Initially, the used region is empty.
+ *
+ * The used region is further subdivided into two disjoint regions: the
+ * 'consumed region' and the 'remaining region'. The union of these two
+ * regions is the used region. The consumed region extends from the beginning
+ * of the used region to the byte before the 'current' offset (if any). The
+ * 'remaining' region the current pointer to the end of the used
+ * region. The size of the consumed region can be changed using various
+ * buffer commands. Initially, the consumed region is empty.
+ *
+ * The 'active region' is an (optional) subregion of the remaining region.
+ * It extends from the current offset to an offset in the remaining region
+ * that is selected with lwres_buffer_setactive(). Initially, the active
+ * region is empty. If the current offset advances beyond the chosen offset,
+ * the active region will also be empty.
+ *
+ * /----- used region -----\/-- available --\
+ * +----------------------------------------+
+ * | consumed | remaining | |
+ * +----------------------------------------+
+ * a b c d e
+ *
+ * a == base of buffer.
+ * b == current pointer. Can be anywhere between a and d.
+ * c == active pointer. Meaningful between b and d.
+ * d == used pointer.
+ * e == length of buffer.
+ *
+ * a-e == entire (length) of buffer.
+ * a-d == used region.
+ * a-b == consumed region.
+ * b-d == remaining region.
+ * b-c == optional active region.
+ *
+ * The following invariants are maintained by all routines:
+ *
+ * length > 0
+ *
+ * base is a valid pointer to length bytes of memory
+ *
+ * 0 <= used <= length
+ *
+ * 0 <= current <= used
+ *
+ * 0 <= active <= used
+ * (although active < current implies empty active region)
+ *
+ * MP:
+ * Buffers have no synchronization. Clients must ensure exclusive
+ * access.
+ *
+ * Reliability:
+ * No anticipated impact.
+ *
+ * Resources:
+ * Memory: 1 pointer + 6 unsigned integers per buffer.
+ *
+ * Security:
+ * No anticipated impact.
+ *
+ * Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <lwres/lang.h>
+#include <lwres/int.h>
+
+LWRES_LANG_BEGINDECLS
+
+/***
+ *** Magic numbers
+ ***/
+#define LWRES_BUFFER_MAGIC 0x4275663fU /* Buf?. */
+
+#define LWRES_BUFFER_VALID(b) ((b) != NULL && \
+ (b)->magic == LWRES_BUFFER_MAGIC)
+
+/*
+ * The following macros MUST be used only on valid buffers. It is the
+ * caller's responsibility to ensure this by using the LWRES_BUFFER_VALID
+ * check above, or by calling another lwres_buffer_*() function (rather than
+ * another macro.)
+ */
+
+/*
+ * Get the length of the used region of buffer "b"
+ */
+#define LWRES_BUFFER_USEDCOUNT(b) ((b)->used)
+
+/*
+ * Get the length of the available region of buffer "b"
+ */
+#define LWRES_BUFFER_AVAILABLECOUNT(b) ((b)->length - (b)->used)
+
+#define LWRES_BUFFER_REMAINING(b) ((b)->used - (b)->current)
+
+/*
+ * Note that the buffer structure is public. This is principally so buffer
+ * operations can be implemented using macros. Applications are strongly
+ * discouraged from directly manipulating the structure.
+ */
+
+typedef struct lwres_buffer lwres_buffer_t;
+struct lwres_buffer {
+ unsigned int magic;
+ unsigned char *base;
+ /* The following integers are byte offsets from 'base'. */
+ unsigned int length;
+ unsigned int used;
+ unsigned int current;
+ unsigned int active;
+};
+
+/***
+ *** Functions
+ ***/
+
+void
+lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
+/*
+ * Make 'b' refer to the 'length'-byte region starting at base.
+ *
+ * Requires:
+ *
+ * 'length' > 0
+ *
+ * 'base' is a pointer to a sequence of 'length' bytes.
+ *
+ */
+
+void
+lwres_buffer_invalidate(lwres_buffer_t *b);
+/*
+ * Make 'b' an invalid buffer.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * Ensures:
+ * If assertion checking is enabled, future attempts to use 'b' without
+ * calling lwres_buffer_init() on it will cause an assertion failure.
+ */
+
+void
+lwres_buffer_add(lwres_buffer_t *b, unsigned int n);
+/*
+ * Increase the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * used + n <= length
+ *
+ */
+
+void
+lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
+/*
+ * Decrease the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * used >= n
+ *
+ */
+
+void
+lwres_buffer_clear(lwres_buffer_t *b);
+/*
+ * Make the used region empty.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ * used = 0
+ *
+ */
+
+void
+lwres_buffer_first(lwres_buffer_t *b);
+/*
+ * Make the consumed region empty.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ * current == 0
+ *
+ */
+
+void
+lwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
+/*
+ * Increase the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * current + n <= used
+ *
+ */
+
+void
+lwres_buffer_back(lwres_buffer_t *b, unsigned int n);
+/*
+ * Decrease the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer
+ *
+ * n <= current
+ *
+ */
+
+lwres_uint8_t
+lwres_buffer_getuint8(lwres_buffer_t *b);
+/*
+ * Read an unsigned 8-bit integer from 'b' and return it.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer.
+ *
+ * The length of the available region of 'b' is at least 1.
+ *
+ * Ensures:
+ *
+ * The current pointer in 'b' is advanced by 1.
+ *
+ * Returns:
+ *
+ * A 8-bit unsigned integer.
+ */
+
+void
+lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
+/*
+ * Store an unsigned 8-bit integer from 'val' into 'b'.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 1.
+ *
+ * Ensures:
+ * The used pointer in 'b' is advanced by 1.
+ */
+
+lwres_uint16_t
+lwres_buffer_getuint16(lwres_buffer_t *b);
+/*
+ * Read an unsigned 16-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer.
+ *
+ * The length of the available region of 'b' is at least 2.
+ *
+ * Ensures:
+ *
+ * The current pointer in 'b' is advanced by 2.
+ *
+ * Returns:
+ *
+ * A 16-bit unsigned integer.
+ */
+
+void
+lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
+/*
+ * Store an unsigned 16-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 2.
+ *
+ * Ensures:
+ * The used pointer in 'b' is advanced by 2.
+ */
+
+lwres_uint32_t
+lwres_buffer_getuint32(lwres_buffer_t *b);
+/*
+ * Read an unsigned 32-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ * 'b' is a valid buffer.
+ *
+ * The length of the available region of 'b' is at least 2.
+ *
+ * Ensures:
+ *
+ * The current pointer in 'b' is advanced by 2.
+ *
+ * Returns:
+ *
+ * A 32-bit unsigned integer.
+ */
+
+void
+lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
+/*
+ * Store an unsigned 32-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 4.
+ *
+ * Ensures:
+ * The used pointer in 'b' is advanced by 4.
+ */
+
+void
+lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
+ unsigned int length);
+/*
+ * Copy 'length' bytes of memory at 'base' into 'b'.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * 'base' points to 'length' bytes of valid memory.
+ *
+ */
+
+void
+lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
+ unsigned int length);
+/*
+ * Copy 'length' bytes of memory from 'b' into 'base'.
+ *
+ * Requires:
+ * 'b' is a valid buffer.
+ *
+ * 'base' points to at least 'length' bytes of valid memory.
+ *
+ * 'b' have at least 'length' bytes remaining.
+ */
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_LWBUFFER_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/lwpacket.h b/src/libfreeswan/liblwres/include/lwres/lwpacket.h
new file mode 100644
index 000000000..a0d216e57
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/lwpacket.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwpacket.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LWPACKET_H
+#define LWRES_LWPACKET_H 1
+
+#include <lwres/lang.h>
+#include <lwres/lwbuffer.h>
+#include <lwres/result.h>
+
+typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+
+#define LWRES_LWPACKET_LENGTH (4 * 5 + 2 * 4)
+
+#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
+
+
+#define LWRES_LWPACKETVERSION_0 0
+
+/*
+ * "length" is the overall packet length, including the entire packet header.
+ *
+ * "version" specifies the header format. Currently, there is only one
+ * format, LWRES_LWPACKETVERSION_0.
+ *
+ * "flags" specifies library-defined flags for this packet. None of these
+ * are definable by the caller, but library-defined values can be set by
+ * the caller. For example, one bit in this field indicates if the packet
+ * is a request or a response.
+ *
+ * "serial" is set by the requestor and is returned in all replies. If two
+ * packets from the same source have the same serial number and are from
+ * the same source, they are assumed to be duplicates and the latter ones
+ * may be dropped. (The library does not do this by default on replies, but
+ * does so on requests.)
+ *
+ * "opcode" is application defined. Opcodes between 0x04000000 and 0xffffffff
+ * are application defined. Opcodes between 0x00000000 and 0x03ffffff are
+ * reserved for library use.
+ *
+ * "result" is application defined, and valid only on replies.
+ * Results between 0x04000000 and 0xffffffff are application defined.
+ * Results between 0x00000000 and 0x03ffffff are reserved for library use.
+ * (This is the same reserved range defined in <isc/resultclass.h>, so it
+ * would be trivial to map ISC_R_* result codes into packet result codes
+ * when appropriate.)
+ *
+ * "recvlength" is set to the maximum buffer size that the receiver can
+ * handle on requests, and the size of the buffer needed to satisfy a request
+ * when the buffer is too large for replies.
+ *
+ * "authtype" is the packet level auth type used.
+ * Authtypes between 0x1000 and 0xffff are application defined. Authtypes
+ * between 0x0000 and 0x0fff are reserved for library use. This is currently
+ * unused and MUST be set to zero.
+ *
+ * "authlen" is the length of the authentication data. See the specific
+ * authtypes for more information on what is contained in this field. This
+ * is currently unused, and MUST be set to zero.
+ *
+ * The remainder of the packet consists of two regions, one described by
+ * "authlen" and one of "length - authlen - sizeof(lwres_lwpacket_t)".
+ *
+ * That is:
+ *
+ * pkt header
+ * authlen bytes of auth information
+ * data bytes
+ */
+
+/*
+ * Currently defined opcodes:
+ *
+ * NOOP. Success is always returned, with the packet contents echoed.
+ *
+ * GETADDRSBYNAME. Return all known addresses for a given name.
+ * This may return NIS or /etc/hosts info as well as DNS
+ * information. Flags will be provided to indicate ip4/ip6
+ * addresses are desired.
+ *
+ * GETNAMEBYADDR. Return the hostname for the given address. Once
+ * again, it will return data from multiple sources.
+ */
+
+LWRES_LANG_BEGINDECLS
+
+/* XXXMLG document */
+lwres_result_t
+lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+
+lwres_result_t
+lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_LWPACKET_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/lwres.h b/src/libfreeswan/liblwres/include/lwres/lwres.h
new file mode 100644
index 000000000..e819c8b68
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/lwres.h
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwres.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_LWRES_H
+#define LWRES_LWRES_H 1
+
+#include <stdio.h>
+
+#include <lwres/context.h>
+#include <lwres/lang.h>
+#include <lwres/list.h>
+#include <lwres/lwpacket.h>
+
+/*
+ * Design notes:
+ *
+ * Each opcode has two structures and three functions which operate on each
+ * structure. For example, using the "no operation/ping" opcode as an
+ * example:
+ *
+ * lwres_nooprequest_t:
+ *
+ * lwres_nooprequest_render() takes a lwres_nooprequest_t and
+ * and renders it into wire format, storing the allocated
+ * buffer information in a passed-in buffer. When this buffer
+ * is no longer needed, it must be freed by
+ * lwres_context_freemem(). All other memory used by the
+ * caller must be freed manually, including the
+ * lwres_nooprequest_t passed in.
+ *
+ * lwres_nooprequest_parse() takes a wire format message and
+ * breaks it out into a lwres_nooprequest_t. The structure
+ * must be freed via lwres_nooprequest_free() when it is no longer
+ * needed.
+ *
+ * lwres_nooprequest_free() releases into the lwres_context_t
+ * any space allocated during parsing.
+ *
+ * lwres_noopresponse_t:
+ *
+ * The functions used are similar to the three used for
+ * requests, just with different names.
+ *
+ * Typically, the client will use request_render, response_parse, and
+ * response_free, while the daemon will use request_parse, response_render,
+ * and request_free.
+ *
+ * The basic flow of a typical client is:
+ *
+ * fill in a request_t, and call the render function.
+ *
+ * Transmit the buffer returned to the daemon.
+ *
+ * Wait for a response.
+ *
+ * When a response is received, parse it into a response_t.
+ *
+ * free the request buffer using lwres_context_freemem().
+ *
+ * free the response structure and its associated buffer using
+ * response_free().
+ */
+
+#define LWRES_UDP_PORT 921
+#define LWRES_RECVLENGTH 16384
+#define LWRES_ADDR_MAXLEN 16 /* changing this breaks ABI */
+#define LWRES_RESOLV_CONF "/etc/resolv.conf"
+
+/*
+ * Flags.
+ *
+ * These flags are only relevant to rrset queries.
+ *
+ * TRUSTNOTREQUIRED: DNSSEC is not required (input)
+ * SECUREDATA: The data was crypto-verified with DNSSEC (output)
+ *
+ */
+#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U
+#define LWRES_FLAG_SECUREDATA 0x00000002U
+
+/*
+ * no-op
+ */
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ /* public */
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;
+
+/*
+ * get addresses by name
+ */
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+struct lwres_addr {
+ lwres_uint32_t family;
+ lwres_uint16_t length;
+ unsigned char address[LWRES_ADDR_MAXLEN];
+ LWRES_LINK(lwres_addr_t) link;
+};
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ /* if base != NULL, it will be freed when this structure is freed. */
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+
+/*
+ * get name by address
+ */
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ /* if base != NULL, it will be freed when this structure is freed. */
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;
+
+/*
+ * get rdata by name
+ */
+#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass;
+ lwres_uint16_t rdtype;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_grbnrequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass;
+ lwres_uint16_t rdtype;
+ lwres_uint32_t ttl;
+ lwres_uint16_t nrdatas;
+ lwres_uint16_t nsigs;
+ char *realname;
+ lwres_uint16_t realnamelen;
+ unsigned char **rdatas;
+ lwres_uint16_t *rdatalen;
+ unsigned char **sigs;
+ lwres_uint16_t *siglen;
+ /* if base != NULL, it will be freed when this structure is freed. */
+ void *base;
+ size_t baselen;
+} lwres_grbnresponse_t;
+
+#define LWRDATA_VALIDATED 0x00000001
+
+/*
+ * resolv.conf data
+ */
+
+#define LWRES_CONFMAXNAMESERVERS 3 /* max 3 "nameserver" entries */
+#define LWRES_CONFMAXLWSERVERS 1 /* max 1 "lwserver" entry */
+#define LWRES_CONFMAXSEARCH 8 /* max 8 domains in "search" entry */
+#define LWRES_CONFMAXLINELEN 256 /* max size of a line */
+#define LWRES_CONFMAXSORTLIST 10
+typedef struct {
+ lwres_context_t *lwctx;
+ lwres_addr_t nameservers[LWRES_CONFMAXNAMESERVERS];
+ lwres_uint8_t nsnext; /* index for next free slot */
+
+ lwres_addr_t lwservers[LWRES_CONFMAXLWSERVERS];
+ lwres_uint8_t lwnext; /* index for next free slot */
+
+ char *domainname;
+
+ char *search[LWRES_CONFMAXSEARCH];
+ lwres_uint8_t searchnxt; /* index for next free slot */
+
+ struct {
+ lwres_addr_t addr;
+ /* mask has a non-zero 'family' and 'length' if set */
+ lwres_addr_t mask;
+ } sortlist[LWRES_CONFMAXSORTLIST];
+ lwres_uint8_t sortlistnxt;
+
+ lwres_uint8_t resdebug; /* non-zero if 'options debug' set */
+ lwres_uint8_t ndots; /* set to n in 'options ndots:n' */
+ lwres_uint8_t no_tld_query; /* non-zero if 'options no_tld_query' */
+} lwres_conf_t;
+
+#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
+#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
+
+#define LWRES_MAX_ALIASES 16 /* max # of aliases */
+#define LWRES_MAX_ADDRS 64 /* max # of addrs */
+
+LWRES_LANG_BEGINDECLS
+
+/*
+ * This is in host byte order.
+ */
+extern lwres_uint16_t lwres_udp_port;
+
+extern const char *lwres_resolv_conf;
+
+lwres_result_t
+lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);
+
+lwres_result_t
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_gabnresponse_t **structp);
+
+void
+lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+void
+lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+
+lwres_result_t
+lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);
+
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_gnbaresponse_t **structp);
+
+void
+lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+void
+lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+lwres_result_t
+lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp);
+
+lwres_result_t
+lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_grbnresponse_t **structp);
+
+void
+lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+void
+lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp);
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+lwres_result_t
+lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+/*
+ * Allocate space and render into wire format a noop request packet.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * b != NULL, and points to a lwres_buffer_t. The contents of the
+ * buffer structure will be initialized to contain the wire-format
+ * noop request packet.
+ *
+ * Caller needs to fill in parts of "pkt" before calling:
+ * serial, maxrecv, result.
+ *
+ * Returns:
+ *
+ * Returns 0 on success, non-zero on failure.
+ *
+ * On successful return, *b will contain data about the wire-format
+ * packet. It can be transmitted in any way, including lwres_sendblock().
+ */
+
+lwres_result_t
+lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+
+lwres_result_t
+lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);
+/*
+ * Parse a noop request. Note that to get here, the lwpacket must have
+ * already been parsed and removed by the caller, otherwise it would be
+ * pretty hard for it to know this is the right function to call.
+ *
+ * The function verifies bits of the header, but does not modify it.
+ */
+
+lwres_result_t
+lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt,
+ lwres_noopresponse_t **structp);
+
+void
+lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp);
+
+void
+lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);
+
+/*
+ * Frees any dynamically allocated memory for this structure.
+ *
+ * Requires:
+ *
+ * ctx != NULL, and be a context returned via lwres_contextcreate().
+ *
+ * structp != NULL && *structp != NULL.
+ *
+ * Ensures:
+ *
+ * *structp == NULL.
+ *
+ * All memory allocated by this structure will be returned to the
+ * system via the context's free function.
+ */
+
+lwres_result_t
+lwres_conf_parse(lwres_context_t *ctx, const char *filename);
+/*
+ * parses a resolv.conf-format file and stores the results in the structure
+ * pointed to by *ctx.
+ *
+ * Requires:
+ * ctx != NULL
+ * filename != NULL && strlen(filename) > 0
+ *
+ * Returns:
+ * LWRES_R_SUCCESS on a successful parse.
+ * Anything else on error, although the structure may be partially filled
+ * in.
+ */
+
+lwres_result_t
+lwres_conf_print(lwres_context_t *ctx, FILE *fp);
+/*
+ * Prints a resolv.conf-format of confdata output to fp.
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+void
+lwres_conf_init(lwres_context_t *ctx);
+/*
+ * sets all internal fields to a default state. Used to initialize a new
+ * lwres_conf_t structure (not reset a used on).
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+void
+lwres_conf_clear(lwres_context_t *ctx);
+/*
+ * frees all internally allocated memory in confdata. Uses the memory
+ * routines supplied by ctx.
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+lwres_conf_t *
+lwres_conf_get(lwres_context_t *ctx);
+/*
+ * returns a pointer to the current config structure.
+ * Be extremely cautions in modifying the contents of this structure; it
+ * needs an API to return the various bits of data, walk lists, etc.
+ *
+ * Requires:
+ * ctx != NULL
+ */
+
+/*
+ * Helper functions
+ */
+
+lwres_result_t
+lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len);
+
+lwres_result_t
+lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len);
+
+lwres_result_t
+lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr);
+
+lwres_result_t
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
+ lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
+ lwres_uint16_t addrlen, const unsigned char *addr,
+ lwres_gnbaresponse_t **structp);
+
+lwres_result_t
+lwres_getrdatabyname(lwres_context_t *ctx, const char *name,
+ lwres_uint16_t rdclass, lwres_uint16_t rdtype,
+ lwres_uint32_t flags, lwres_grbnresponse_t **structp);
+
+lwres_result_t
+lwres_getaddrsbyname_setup(lwres_context_t *ctx, const char *name,
+ lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+
+
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_LWRES_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/netdb.h b/src/libfreeswan/liblwres/include/lwres/netdb.h
new file mode 100644
index 000000000..2391d31fb
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/netdb.h
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netdb.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_NETDB_H
+#define LWRES_NETDB_H 1
+
+#include <stddef.h> /* Required on FreeBSD (and others?) for size_t. */
+#include <netdb.h> /* Contractual provision. */
+
+#include <lwres/lang.h>
+
+/*
+ * Define if <netdb.h> does not declare struct addrinfo.
+ */
+#undef ISC_LWRES_NEEDADDRINFO
+
+#ifdef ISC_LWRES_NEEDADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for hostname */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+#endif
+
+/*
+ * Undefine all #defines we are interested in as <netdb.h> may or may not have
+ * defined them.
+ */
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#undef NETDB_INTERNAL
+#undef NETDB_SUCCESS
+#undef HOST_NOT_FOUND
+#undef TRY_AGAIN
+#undef NO_RECOVERY
+#undef NO_DATA
+#undef NO_ADDRESS
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+
+#define AI_PASSIVE 0x00000001
+#define AI_CANONNAME 0x00000002
+#define AI_NUMERICHOST 0x00000004
+
+/*
+ * Flag values for getipnodebyname()
+ */
+#undef AI_V4MAPPED
+#undef AI_ALL
+#undef AI_ADDRCONFIG
+#undef AI_DEFAULT
+
+#define AI_V4MAPPED 0x00000008
+#define AI_ALL 0x00000010
+#define AI_ADDRCONFIG 0x00000020
+#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
+
+/*
+ * Constants for lwres_getnameinfo()
+ */
+#undef NI_MAXHOST
+#undef NI_MAXSERV
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+/*
+ * Flag values for lwres_getnameinfo()
+ */
+#undef NI_NOFQDN
+#undef NI_NUMERICHOST
+#undef NI_NAMEREQD
+#undef NI_NUMERICSERV
+#undef NI_DGRAM
+#undef NI_NUMERICSCOPE
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/
+
+/*
+ * Define if <netdb.h> does not declare struct rrsetinfo.
+ */
+#define ISC_LWRES_NEEDRRSETINFO 1
+
+#ifdef ISC_LWRES_NEEDRRSETINFO
+/*
+ * Structures for getrrsetbyname()
+ */
+struct rdatainfo {
+ unsigned int rdi_length;
+ unsigned char *rdi_data;
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags;
+ int rri_rdclass;
+ int rri_rdtype;
+ unsigned int rri_ttl;
+ unsigned int rri_nrdatas;
+ unsigned int rri_nsigs;
+ char *rri_name;
+ struct rdatainfo *rri_rdatas;
+ struct rdatainfo *rri_sigs;
+};
+
+/*
+ * Flags for getrrsetbyname()
+ */
+#define RRSET_VALIDATED 0x00000001
+ /* Set was dnssec validated */
+
+/*
+ * Return codes for getrrsetbyname()
+ */
+#define ERRSET_SUCCESS 0
+#define ERRSET_NOMEMORY 1
+#define ERRSET_FAIL 2
+#define ERRSET_INVAL 3
+#define ERRSET_NONAME 4
+#define ERRSET_NODATA 5
+#define ERRSET_RETRY 6
+#endif
+
+/*
+ * Define to map into lwres_ namespace.
+ */
+
+#define LWRES_NAMESPACE
+
+#ifdef LWRES_NAMESPACE
+
+/*
+ * Use our versions not the ones from the C library.
+ */
+
+#ifdef getnameinfo
+#undef getnameinfo
+#endif
+#define getnameinfo lwres_getnameinfo
+
+#ifdef getaddrinfo
+#undef getaddrinfo
+#endif
+#define getaddrinfo lwres_getaddrinfo
+
+#ifdef freeaddrinfo
+#undef freeaddrinfo
+#endif
+#define freeaddrinfo lwres_freeaddrinfo
+
+#ifdef gai_strerror
+#undef gai_strerror
+#endif
+#define gai_strerror lwres_gai_strerror
+
+#ifdef herror
+#undef herror
+#endif
+#define herror lwres_herror
+
+#ifdef hstrerror
+#undef hstrerror
+#endif
+#define hstrerror lwres_hstrerror
+
+#ifdef getipnodebyname
+#undef getipnodebyname
+#endif
+#define getipnodebyname lwres_getipnodebyname
+
+#ifdef getipnodebyaddr
+#undef getipnodebyaddr
+#endif
+#define getipnodebyaddr lwres_getipnodebyaddr
+
+#ifdef freehostent
+#undef freehostent
+#endif
+#define freehostent lwres_freehostent
+
+#ifdef gethostbyname
+#undef gethostbyname
+#endif
+#define gethostbyname lwres_gethostbyname
+
+#ifdef gethostbyname2
+#undef gethostbyname2
+#endif
+#define gethostbyname2 lwres_gethostbyname2
+
+#ifdef gethostbyaddr
+#undef gethostbyaddr
+#endif
+#define gethostbyaddr lwres_gethostbyaddr
+
+#ifdef gethostent
+#undef gethostent
+#endif
+#define gethostent lwres_gethostent
+
+#ifdef sethostent
+#undef sethostent
+#endif
+#define sethostent lwres_sethostent
+
+#ifdef endhostent
+#undef endhostent
+#endif
+#define endhostent lwres_endhostent
+
+/* #define sethostfile lwres_sethostfile */
+
+#ifdef gethostbyname_r
+#undef gethostbyname_r
+#endif
+#define gethostbyname_r lwres_gethostbyname_r
+
+#ifdef gethostbyaddr_r
+#undef gethostbyaddr_r
+#endif
+#define gethostbyaddr_r lwres_gethostbyaddr_r
+
+#ifdef gethostent_r
+#undef gethostent_r
+#endif
+#define gethostent_r lwres_gethostent_r
+
+#ifdef sethostent_r
+#undef sethostent_r
+#endif
+#define sethostent_r lwres_sethostent_r
+
+#ifdef endhostent_r
+#undef endhostent_r
+#endif
+#define endhostent_r lwres_endhostent_r
+
+#ifdef getrrsetbyname
+#undef getrrsetbyname
+#endif
+#define getrrsetbyname lwres_getrrsetbyname
+
+#ifdef freerrset
+#undef freerrset
+#endif
+#define freerrset lwres_freerrset
+
+#ifdef notyet
+#define getservbyname lwres_getservbyname
+#define getservbyport lwres_getservbyport
+#define getservent lwres_getservent
+#define setservent lwres_setservent
+#define endservent lwres_endservent
+
+#define getservbyname_r lwres_getservbyname_r
+#define getservbyport_r lwres_getservbyport_r
+#define getservent_r lwres_getservent_r
+#define setservent_r lwres_setservent_r
+#define endservent_r lwres_endservent_r
+
+#define getprotobyname lwres_getprotobyname
+#define getprotobynumber lwres_getprotobynumber
+#define getprotoent lwres_getprotoent
+#define setprotoent lwres_setprotoent
+#define endprotoent lwres_endprotoent
+
+#define getprotobyname_r lwres_getprotobyname_r
+#define getprotobynumber_r lwres_getprotobynumber_r
+#define getprotoent_r lwres_getprotoent_r
+#define setprotoent_r lwres_setprotoent_r
+#define endprotoent_r lwres_endprotoent_r
+
+#ifdef getnetbyname
+#undef getnetbyname
+#endif
+#define getnetbyname lwres_getnetbyname
+
+#ifdef getnetbyaddr
+#undef getnetbyaddr
+#endif
+#define getnetbyaddr lwres_getnetbyaddr
+
+#ifdef getnetent
+#undef getnetent
+#endif
+#define getnetent lwres_getnetent
+
+#ifdef setnetent
+#undef setnetent
+#endif
+#define setnetent lwres_setnetent
+
+#ifdef endnetent
+#undef endnetent
+#endif
+#define endnetent lwres_endnetent
+
+
+#ifdef getnetbyname_r
+#undef getnetbyname_r
+#endif
+#define getnetbyname_r lwres_getnetbyname_r
+
+#ifdef getnetbyaddr_r
+#undef getnetbyaddr_r
+#endif
+#define getnetbyaddr_r lwres_getnetbyaddr_r
+
+#ifdef getnetent_r
+#undef getnetent_r
+#endif
+#define getnetent_r lwres_getnetent_r
+
+#ifdef setnetent_r
+#undef setnetent_r
+#endif
+#define setnetent_r lwres_setnetent_r
+
+#ifdef endnetent_r
+#undef endnetent_r
+#endif
+#define endnetent_r lwres_endnetent_r
+#endif /* notyet */
+
+#ifdef h_errno
+#undef h_errno
+#endif
+#define h_errno lwres_h_errno
+
+#endif /* LWRES_NAMESPACE */
+
+LWRES_LANG_BEGINDECLS
+
+extern int lwres_h_errno;
+
+int lwres_getaddrinfo(const char *, const char *,
+ const struct addrinfo *, struct addrinfo **);
+int lwres_getnameinfo(const struct sockaddr *, size_t, char *,
+ size_t, char *, size_t, int);
+void lwres_freeaddrinfo(struct addrinfo *);
+char *lwres_gai_strerror(int);
+
+struct hostent *lwres_gethostbyaddr(const char *, int, int);
+struct hostent *lwres_gethostbyname(const char *);
+struct hostent *lwres_gethostbyname2(const char *, int);
+struct hostent *lwres_gethostent(void);
+struct hostent *lwres_getipnodebyname(const char *, int, int, int *);
+struct hostent *lwres_getipnodebyaddr(const void *, size_t, int, int *);
+void lwres_endhostent(void);
+void lwres_sethostent(int);
+/* void lwres_sethostfile(const char *); */
+void lwres_freehostent(struct hostent *);
+
+int lwres_getrrsetbyname(const char *, unsigned int, unsigned int,
+ unsigned int, struct rrsetinfo **);
+int lwres_getrrsetbyname_all(const char *, unsigned int,
+ unsigned int,
+ unsigned int, struct rrsetinfo **);
+void lwres_freerrset(struct rrsetinfo *);
+
+#ifdef notyet
+struct netent *lwres_getnetbyaddr(unsigned long, int);
+struct netent *lwres_getnetbyname(const char *);
+struct netent *lwres_getnetent(void);
+void lwres_endnetent(void);
+void lwres_setnetent(int);
+
+struct protoent *lwres_getprotobyname(const char *);
+struct protoent *lwres_getprotobynumber(int);
+struct protoent *lwres_getprotoent(void);
+void lwres_endprotoent(void);
+void lwres_setprotoent(int);
+
+struct servent *lwres_getservbyname(const char *, const char *);
+struct servent *lwres_getservbyport(int, const char *);
+struct servent *lwres_getservent(void);
+void lwres_endservent(void);
+void lwres_setservent(int);
+#endif /* notyet */
+
+void lwres_herror(const char *);
+const char *lwres_hstrerror(int);
+
+
+struct hostent *lwres_gethostbyaddr_r(const char *, int, int, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostbyname_r(const char *, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostent_r(struct hostent *, char *, int, int *);
+void lwres_sethostent_r(int);
+void lwres_endhostent_r(void);
+
+#ifdef notyet
+struct netent *lwres_getnetbyname_r(const char *, struct netent *,
+ char *, int);
+struct netent *lwres_getnetbyaddr_r(long, int, struct netent *,
+ char *, int);
+struct netent *lwres_getnetent_r(struct netent *, char *, int);
+void lwres_setnetent_r(int);
+void lwres_endnetent_r(void);
+
+struct protoent *lwres_getprotobyname_r(const char *,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotobynumber_r(int,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotoent_r(struct protoent *, char *, int);
+void lwres_setprotoent_r(int);
+void lwres_endprotoent_r(void);
+
+struct servent *lwres_getservbyname_r(const char *name, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservbyport_r(int port, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservent_r(struct servent *, char *, int);
+void lwres_setservent_r(int);
+void lwres_endservent_r(void);
+#endif /* notyet */
+
+LWRES_LANG_ENDDECLS
+
+#ifdef notyet
+/* This is nec'y to make this include file properly replace the sun version. */
+#ifdef sun
+#ifdef __GNU_LIBRARY__
+#include <rpc/netdb.h> /* Required. */
+#else /* !__GNU_LIBRARY__ */
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+struct rpcent *lwres_getrpcbyname();
+struct rpcent *lwres_getrpcbynumber(),
+struct rpcent *lwres_getrpcent();
+#endif /* __GNU_LIBRARY__ */
+#endif /* sun */
+#endif /* notyet */
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* LWRES_NETDB_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/netdb.h.in b/src/libfreeswan/liblwres/include/lwres/netdb.h.in
new file mode 100644
index 000000000..75446e8f8
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/netdb.h.in
@@ -0,0 +1,518 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netdb.h.in,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_NETDB_H
+#define LWRES_NETDB_H 1
+
+#include <stddef.h> /* Required on FreeBSD (and others?) for size_t. */
+#include <netdb.h> /* Contractual provision. */
+
+#include <lwres/lang.h>
+
+/*
+ * Define if <netdb.h> does not declare struct addrinfo.
+ */
+@ISC_LWRES_NEEDADDRINFO@
+
+#ifdef ISC_LWRES_NEEDADDRINFO
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* Length of ai_addr */
+ char *ai_canonname; /* Canonical name for hostname */
+ struct sockaddr *ai_addr; /* Binary address */
+ struct addrinfo *ai_next; /* Next structure in linked list */
+};
+#endif
+
+/*
+ * Undefine all #defines we are interested in as <netdb.h> may or may not have
+ * defined them.
+ */
+
+/*
+ * Error return codes from gethostbyname() and gethostbyaddr()
+ * (left in extern int h_errno).
+ */
+
+#undef NETDB_INTERNAL
+#undef NETDB_SUCCESS
+#undef HOST_NOT_FOUND
+#undef TRY_AGAIN
+#undef NO_RECOVERY
+#undef NO_DATA
+#undef NO_ADDRESS
+
+#define NETDB_INTERNAL -1 /* see errno */
+#define NETDB_SUCCESS 0 /* no problem */
+#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */
+#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */
+#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
+#define NO_DATA 4 /* Valid name, no data record of requested type */
+#define NO_ADDRESS NO_DATA /* no address, look for MX record */
+
+/*
+ * Error return codes from getaddrinfo()
+ */
+
+#undef EAI_ADDRFAMILY
+#undef EAI_AGAIN
+#undef EAI_BADFLAGS
+#undef EAI_FAIL
+#undef EAI_FAMILY
+#undef EAI_MEMORY
+#undef EAI_NODATA
+#undef EAI_NONAME
+#undef EAI_SERVICE
+#undef EAI_SOCKTYPE
+#undef EAI_SYSTEM
+#undef EAI_BADHINTS
+#undef EAI_PROTOCOL
+#undef EAI_MAX
+
+#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
+#define EAI_AGAIN 2 /* temporary failure in name resolution */
+#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
+#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
+#define EAI_FAMILY 5 /* ai_family not supported */
+#define EAI_MEMORY 6 /* memory allocation failure */
+#define EAI_NODATA 7 /* no address associated with hostname */
+#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
+#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
+#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
+#define EAI_SYSTEM 11 /* system error returned in errno */
+#define EAI_BADHINTS 12
+#define EAI_PROTOCOL 13
+#define EAI_MAX 14
+
+/*
+ * Flag values for getaddrinfo()
+ */
+#undef AI_PASSIVE
+#undef AI_CANONNAME
+#undef AI_NUMERICHOST
+
+#define AI_PASSIVE 0x00000001
+#define AI_CANONNAME 0x00000002
+#define AI_NUMERICHOST 0x00000004
+
+/*
+ * Flag values for getipnodebyname()
+ */
+#undef AI_V4MAPPED
+#undef AI_ALL
+#undef AI_ADDRCONFIG
+#undef AI_DEFAULT
+
+#define AI_V4MAPPED 0x00000008
+#define AI_ALL 0x00000010
+#define AI_ADDRCONFIG 0x00000020
+#define AI_DEFAULT (AI_V4MAPPED|AI_ADDRCONFIG)
+
+/*
+ * Constants for lwres_getnameinfo()
+ */
+#undef NI_MAXHOST
+#undef NI_MAXSERV
+
+#define NI_MAXHOST 1025
+#define NI_MAXSERV 32
+
+/*
+ * Flag values for lwres_getnameinfo()
+ */
+#undef NI_NOFQDN
+#undef NI_NUMERICHOST
+#undef NI_NAMEREQD
+#undef NI_NUMERICSERV
+#undef NI_DGRAM
+#undef NI_NUMERICSCOPE
+
+#define NI_NOFQDN 0x00000001
+#define NI_NUMERICHOST 0x00000002
+#define NI_NAMEREQD 0x00000004
+#define NI_NUMERICSERV 0x00000008
+#define NI_DGRAM 0x00000010
+#define NI_NUMERICSCOPE 0x00000020 /*2553bis-00*/
+
+/*
+ * Define if <netdb.h> does not declare struct rrsetinfo.
+ */
+@ISC_LWRES_NEEDRRSETINFO@
+
+#ifdef ISC_LWRES_NEEDRRSETINFO
+/*
+ * Structures for getrrsetbyname()
+ */
+struct rdatainfo {
+ unsigned int rdi_length;
+ unsigned char *rdi_data;
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags;
+ int rri_rdclass;
+ int rri_rdtype;
+ unsigned int rri_ttl;
+ unsigned int rri_nrdatas;
+ unsigned int rri_nsigs;
+ char *rri_name;
+ struct rdatainfo *rri_rdatas;
+ struct rdatainfo *rri_sigs;
+};
+
+/*
+ * Flags for getrrsetbyname()
+ */
+#define RRSET_VALIDATED 0x00000001
+ /* Set was dnssec validated */
+
+/*
+ * Return codes for getrrsetbyname()
+ */
+#define ERRSET_SUCCESS 0
+#define ERRSET_NOMEMORY 1
+#define ERRSET_FAIL 2
+#define ERRSET_INVAL 3
+#define ERRSET_NONAME 4
+#define ERRSET_NODATA 5
+#endif
+
+/*
+ * Define to map into lwres_ namespace.
+ */
+
+#define LWRES_NAMESPACE
+
+#ifdef LWRES_NAMESPACE
+
+/*
+ * Use our versions not the ones from the C library.
+ */
+
+#ifdef getnameinfo
+#undef getnameinfo
+#endif
+#define getnameinfo lwres_getnameinfo
+
+#ifdef getaddrinfo
+#undef getaddrinfo
+#endif
+#define getaddrinfo lwres_getaddrinfo
+
+#ifdef freeaddrinfo
+#undef freeaddrinfo
+#endif
+#define freeaddrinfo lwres_freeaddrinfo
+
+#ifdef gai_strerror
+#undef gai_strerror
+#endif
+#define gai_strerror lwres_gai_strerror
+
+#ifdef herror
+#undef herror
+#endif
+#define herror lwres_herror
+
+#ifdef hstrerror
+#undef hstrerror
+#endif
+#define hstrerror lwres_hstrerror
+
+#ifdef getipnodebyname
+#undef getipnodebyname
+#endif
+#define getipnodebyname lwres_getipnodebyname
+
+#ifdef getipnodebyaddr
+#undef getipnodebyaddr
+#endif
+#define getipnodebyaddr lwres_getipnodebyaddr
+
+#ifdef freehostent
+#undef freehostent
+#endif
+#define freehostent lwres_freehostent
+
+#ifdef gethostbyname
+#undef gethostbyname
+#endif
+#define gethostbyname lwres_gethostbyname
+
+#ifdef gethostbyname2
+#undef gethostbyname2
+#endif
+#define gethostbyname2 lwres_gethostbyname2
+
+#ifdef gethostbyaddr
+#undef gethostbyaddr
+#endif
+#define gethostbyaddr lwres_gethostbyaddr
+
+#ifdef gethostent
+#undef gethostent
+#endif
+#define gethostent lwres_gethostent
+
+#ifdef sethostent
+#undef sethostent
+#endif
+#define sethostent lwres_sethostent
+
+#ifdef endhostent
+#undef endhostent
+#endif
+#define endhostent lwres_endhostent
+
+/* #define sethostfile lwres_sethostfile */
+
+#ifdef gethostbyname_r
+#undef gethostbyname_r
+#endif
+#define gethostbyname_r lwres_gethostbyname_r
+
+#ifdef gethostbyaddr_r
+#undef gethostbyaddr_r
+#endif
+#define gethostbyaddr_r lwres_gethostbyaddr_r
+
+#ifdef gethostent_r
+#undef gethostent_r
+#endif
+#define gethostent_r lwres_gethostent_r
+
+#ifdef sethostent_r
+#undef sethostent_r
+#endif
+#define sethostent_r lwres_sethostent_r
+
+#ifdef endhostent_r
+#undef endhostent_r
+#endif
+#define endhostent_r lwres_endhostent_r
+
+#ifdef getrrsetbyname
+#undef getrrsetbyname
+#endif
+#define getrrsetbyname lwres_getrrsetbyname
+
+#ifdef freerrset
+#undef freerrset
+#endif
+#define freerrset lwres_freerrset
+
+#ifdef notyet
+#define getservbyname lwres_getservbyname
+#define getservbyport lwres_getservbyport
+#define getservent lwres_getservent
+#define setservent lwres_setservent
+#define endservent lwres_endservent
+
+#define getservbyname_r lwres_getservbyname_r
+#define getservbyport_r lwres_getservbyport_r
+#define getservent_r lwres_getservent_r
+#define setservent_r lwres_setservent_r
+#define endservent_r lwres_endservent_r
+
+#define getprotobyname lwres_getprotobyname
+#define getprotobynumber lwres_getprotobynumber
+#define getprotoent lwres_getprotoent
+#define setprotoent lwres_setprotoent
+#define endprotoent lwres_endprotoent
+
+#define getprotobyname_r lwres_getprotobyname_r
+#define getprotobynumber_r lwres_getprotobynumber_r
+#define getprotoent_r lwres_getprotoent_r
+#define setprotoent_r lwres_setprotoent_r
+#define endprotoent_r lwres_endprotoent_r
+
+#ifdef getnetbyname
+#undef getnetbyname
+#endif
+#define getnetbyname lwres_getnetbyname
+
+#ifdef getnetbyaddr
+#undef getnetbyaddr
+#endif
+#define getnetbyaddr lwres_getnetbyaddr
+
+#ifdef getnetent
+#undef getnetent
+#endif
+#define getnetent lwres_getnetent
+
+#ifdef setnetent
+#undef setnetent
+#endif
+#define setnetent lwres_setnetent
+
+#ifdef endnetent
+#undef endnetent
+#endif
+#define endnetent lwres_endnetent
+
+
+#ifdef getnetbyname_r
+#undef getnetbyname_r
+#endif
+#define getnetbyname_r lwres_getnetbyname_r
+
+#ifdef getnetbyaddr_r
+#undef getnetbyaddr_r
+#endif
+#define getnetbyaddr_r lwres_getnetbyaddr_r
+
+#ifdef getnetent_r
+#undef getnetent_r
+#endif
+#define getnetent_r lwres_getnetent_r
+
+#ifdef setnetent_r
+#undef setnetent_r
+#endif
+#define setnetent_r lwres_setnetent_r
+
+#ifdef endnetent_r
+#undef endnetent_r
+#endif
+#define endnetent_r lwres_endnetent_r
+#endif /* notyet */
+
+#ifdef h_errno
+#undef h_errno
+#endif
+#define h_errno lwres_h_errno
+
+#endif /* LWRES_NAMESPACE */
+
+LWRES_LANG_BEGINDECLS
+
+extern int lwres_h_errno;
+
+int lwres_getaddrinfo(const char *, const char *,
+ const struct addrinfo *, struct addrinfo **);
+int lwres_getnameinfo(const struct sockaddr *, size_t, char *,
+ size_t, char *, size_t, int);
+void lwres_freeaddrinfo(struct addrinfo *);
+char *lwres_gai_strerror(int);
+
+struct hostent *lwres_gethostbyaddr(const char *, int, int);
+struct hostent *lwres_gethostbyname(const char *);
+struct hostent *lwres_gethostbyname2(const char *, int);
+struct hostent *lwres_gethostent(void);
+struct hostent *lwres_getipnodebyname(const char *, int, int, int *);
+struct hostent *lwres_getipnodebyaddr(const void *, size_t, int, int *);
+void lwres_endhostent(void);
+void lwres_sethostent(int);
+/* void lwres_sethostfile(const char *); */
+void lwres_freehostent(struct hostent *);
+
+int lwres_getrrsetbyname(const char *, unsigned int, unsigned int,
+ unsigned int, struct rrsetinfo **);
+void lwres_freerrset(struct rrsetinfo *);
+
+#ifdef notyet
+struct netent *lwres_getnetbyaddr(unsigned long, int);
+struct netent *lwres_getnetbyname(const char *);
+struct netent *lwres_getnetent(void);
+void lwres_endnetent(void);
+void lwres_setnetent(int);
+
+struct protoent *lwres_getprotobyname(const char *);
+struct protoent *lwres_getprotobynumber(int);
+struct protoent *lwres_getprotoent(void);
+void lwres_endprotoent(void);
+void lwres_setprotoent(int);
+
+struct servent *lwres_getservbyname(const char *, const char *);
+struct servent *lwres_getservbyport(int, const char *);
+struct servent *lwres_getservent(void);
+void lwres_endservent(void);
+void lwres_setservent(int);
+#endif /* notyet */
+
+void lwres_herror(const char *);
+const char *lwres_hstrerror(int);
+
+
+struct hostent *lwres_gethostbyaddr_r(const char *, int, int, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostbyname_r(const char *, struct hostent *,
+ char *, int, int *);
+struct hostent *lwres_gethostent_r(struct hostent *, char *, int, int *);
+void lwres_sethostent_r(int);
+void lwres_endhostent_r(void);
+
+#ifdef notyet
+struct netent *lwres_getnetbyname_r(const char *, struct netent *,
+ char *, int);
+struct netent *lwres_getnetbyaddr_r(long, int, struct netent *,
+ char *, int);
+struct netent *lwres_getnetent_r(struct netent *, char *, int);
+void lwres_setnetent_r(int);
+void lwres_endnetent_r(void);
+
+struct protoent *lwres_getprotobyname_r(const char *,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotobynumber_r(int,
+ struct protoent *, char *, int);
+struct protoent *lwres_getprotoent_r(struct protoent *, char *, int);
+void lwres_setprotoent_r(int);
+void lwres_endprotoent_r(void);
+
+struct servent *lwres_getservbyname_r(const char *name, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservbyport_r(int port, const char *,
+ struct servent *, char *, int);
+struct servent *lwres_getservent_r(struct servent *, char *, int);
+void lwres_setservent_r(int);
+void lwres_endservent_r(void);
+#endif /* notyet */
+
+LWRES_LANG_ENDDECLS
+
+#ifdef notyet
+/* This is nec'y to make this include file properly replace the sun version. */
+#ifdef sun
+#ifdef __GNU_LIBRARY__
+#include <rpc/netdb.h> /* Required. */
+#else /* !__GNU_LIBRARY__ */
+struct rpcent {
+ char *r_name; /* name of server for this rpc program */
+ char **r_aliases; /* alias list */
+ int r_number; /* rpc program number */
+};
+struct rpcent *lwres_getrpcbyname();
+struct rpcent *lwres_getrpcbynumber(),
+struct rpcent *lwres_getrpcent();
+#endif /* __GNU_LIBRARY__ */
+#endif /* sun */
+#endif /* notyet */
+
+/*
+ * Tell Emacs to use C mode on this file.
+ * Local variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* LWRES_NETDB_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/platform.h b/src/libfreeswan/liblwres/include/lwres/platform.h
new file mode 100644
index 000000000..af4c615d9
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/platform.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: platform.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_PLATFORM_H
+#define LWRES_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+/***
+ *** Network.
+ ***/
+
+/*
+ * Define if this system needs the <netinet/in6.h> header file for IPv6.
+ */
+#undef LWRES_PLATFORM_NEEDNETINETIN6H
+
+/*
+ * Define if this system needs the <netinet6/in6.h> header file for IPv6.
+ */
+#undef LWRES_PLATFORM_NEEDNETINET6IN6H
+
+/*
+ * If sockaddrs on this system have an sa_len field, LWRES_PLATFORM_HAVESALEN
+ * will be defined.
+ */
+#undef LWRES_PLATFORM_HAVESALEN
+
+/*
+ * If this system has the IPv6 structure definitions, LWRES_PLATFORM_HAVEIPV6
+ * will be defined.
+ */
+#define LWRES_PLATFORM_HAVEIPV6 1
+
+/*
+ * If this system is missing in6addr_any, LWRES_PLATFORM_NEEDIN6ADDRANY will
+ * be defined.
+ */
+#undef LWRES_PLATFORM_NEEDIN6ADDRANY
+
+/*
+ * If this system is missing in6addr_loopback,
+ * LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK will be defined.
+ */
+#undef LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK
+
+/*
+ * If this system has in_addr6, rather than in6_addr,
+ * LWRES_PLATFORM_HAVEINADDR6 will be defined.
+ */
+#undef LWRES_PLATFORM_HAVEINADDR6
+
+/*
+ * Defined if unistd.h does not cause fd_set to be delared.
+ */
+#define LWRES_PLATFORM_NEEDSYSSELECTH 1
+
+/*
+ * Used to control how extern data is linked; needed for Win32 platforms.
+ */
+#undef LWRES_PLATFORM_USEDECLSPEC
+
+#ifndef LWRES_PLATFORM_USEDECLSPEC
+#define LIBLWRES_EXTERNAL_DATA
+#else
+#ifdef LIBLWRES_EXPORTS
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif
+
+#endif /* LWRES_PLATFORM_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/platform.h.in b/src/libfreeswan/liblwres/include/lwres/platform.h.in
new file mode 100644
index 000000000..c679d8fae
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/platform.h.in
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: platform.h.in,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_PLATFORM_H
+#define LWRES_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+/***
+ *** Network.
+ ***/
+
+/*
+ * Define if this system needs the <netinet/in6.h> header file for IPv6.
+ */
+@LWRES_PLATFORM_NEEDNETINETIN6H@
+
+/*
+ * Define if this system needs the <netinet6/in6.h> header file for IPv6.
+ */
+@LWRES_PLATFORM_NEEDNETINET6IN6H@
+
+/*
+ * If sockaddrs on this system have an sa_len field, LWRES_PLATFORM_HAVESALEN
+ * will be defined.
+ */
+@LWRES_PLATFORM_HAVESALEN@
+
+/*
+ * If this system has the IPv6 structure definitions, LWRES_PLATFORM_HAVEIPV6
+ * will be defined.
+ */
+@LWRES_PLATFORM_HAVEIPV6@
+
+/*
+ * If this system is missing in6addr_any, LWRES_PLATFORM_NEEDIN6ADDRANY will
+ * be defined.
+ */
+@LWRES_PLATFORM_NEEDIN6ADDRANY@
+
+/*
+ * If this system is missing in6addr_loopback,
+ * LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK will be defined.
+ */
+@LWRES_PLATFORM_NEEDIN6ADDRLOOPBACK@
+
+/*
+ * If this system has in_addr6, rather than in6_addr,
+ * LWRES_PLATFORM_HAVEINADDR6 will be defined.
+ */
+@LWRES_PLATFORM_HAVEINADDR6@
+
+/*
+ * Defined if unistd.h does not cause fd_set to be delared.
+ */
+@LWRES_PLATFORM_NEEDSYSSELECTH@
+
+/*
+ * Used to control how extern data is linked; needed for Win32 platforms.
+ */
+@LWRES_PLATFORM_USEDECLSPEC@
+
+#ifndef LWRES_PLATFORM_USEDECLSPEC
+#define LIBLWRES_EXTERNAL_DATA
+#else
+#ifdef LIBLWRES_EXPORTS
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBLWRES_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif
+
+#endif /* LWRES_PLATFORM_H */
diff --git a/src/libfreeswan/liblwres/include/lwres/result.h b/src/libfreeswan/liblwres/include/lwres/result.h
new file mode 100644
index 000000000..42e1bccea
--- /dev/null
+++ b/src/libfreeswan/liblwres/include/lwres/result.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: result.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_RESULT_H
+#define LWRES_RESULT_H 1
+
+typedef unsigned int lwres_result_t;
+
+#define LWRES_R_SUCCESS 0
+#define LWRES_R_NOMEMORY 1
+#define LWRES_R_TIMEOUT 2
+#define LWRES_R_NOTFOUND 3
+#define LWRES_R_UNEXPECTEDEND 4 /* unexpected end of input */
+#define LWRES_R_FAILURE 5 /* generic failure */
+#define LWRES_R_IOERROR 6
+#define LWRES_R_NOTIMPLEMENTED 7
+#define LWRES_R_UNEXPECTED 8
+#define LWRES_R_TRAILINGDATA 9
+#define LWRES_R_INCOMPLETE 10
+#define LWRES_R_RETRY 11
+#define LWRES_R_TYPENOTFOUND 12
+#define LWRES_R_TOOLARGE 13
+
+#endif /* LWRES_RESULT_H */
diff --git a/src/libfreeswan/liblwres/lwbuffer.c b/src/libfreeswan/liblwres/lwbuffer.c
new file mode 100644
index 000000000..465ad2569
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwbuffer.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwbuffer.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+
+#include "assert_p.h"
+
+void
+lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length)
+{
+ /*
+ * Make 'b' refer to the 'length'-byte region starting at base.
+ */
+
+ REQUIRE(b != NULL);
+
+ b->magic = LWRES_BUFFER_MAGIC;
+ b->base = base;
+ b->length = length;
+ b->used = 0;
+ b->current = 0;
+ b->active = 0;
+}
+
+void
+lwres_buffer_invalidate(lwres_buffer_t *b)
+{
+ /*
+ * Make 'b' an invalid buffer.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+
+ b->magic = 0;
+ b->base = NULL;
+ b->length = 0;
+ b->used = 0;
+ b->current = 0;
+ b->active = 0;
+}
+
+void
+lwres_buffer_add(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Increase the 'used' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + n <= b->length);
+
+ b->used += n;
+}
+
+void
+lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Decrease the 'used' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used >= n);
+
+ b->used -= n;
+ if (b->current > b->used)
+ b->current = b->used;
+ if (b->active > b->used)
+ b->active = b->used;
+}
+
+void
+lwres_buffer_clear(lwres_buffer_t *b)
+{
+ /*
+ * Make the used region empty.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+
+ b->used = 0;
+ b->current = 0;
+ b->active = 0;
+}
+
+void
+lwres_buffer_first(lwres_buffer_t *b)
+{
+ /*
+ * Make the consumed region empty.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+
+ b->current = 0;
+}
+
+void
+lwres_buffer_forward(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Increase the 'consumed' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->current + n <= b->used);
+
+ b->current += n;
+}
+
+void
+lwres_buffer_back(lwres_buffer_t *b, unsigned int n)
+{
+ /*
+ * Decrease the 'consumed' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(n <= b->current);
+
+ b->current -= n;
+}
+
+lwres_uint8_t
+lwres_buffer_getuint8(lwres_buffer_t *b)
+{
+ unsigned char *cp;
+ lwres_uint8_t result;
+
+ /*
+ * Read an unsigned 8-bit integer from 'b' and return it.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 1);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += 1;
+ result = ((unsigned int)(cp[0]));
+
+ return (result);
+}
+
+void
+lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + 1 <= b->length);
+
+ cp = b->base;
+ cp += b->used;
+ b->used += 1;
+ cp[0] = (val & 0x00ff);
+}
+
+lwres_uint16_t
+lwres_buffer_getuint16(lwres_buffer_t *b)
+{
+ unsigned char *cp;
+ lwres_uint16_t result;
+
+ /*
+ * Read an unsigned 16-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 2);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += 2;
+ result = ((unsigned int)(cp[0])) << 8;
+ result |= ((unsigned int)(cp[1]));
+
+ return (result);
+}
+
+void
+lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + 2 <= b->length);
+
+ cp = b->base;
+ cp += b->used;
+ b->used += 2;
+ cp[0] = (val & 0xff00) >> 8;
+ cp[1] = (val & 0x00ff);
+}
+
+lwres_uint32_t
+lwres_buffer_getuint32(lwres_buffer_t *b)
+{
+ unsigned char *cp;
+ lwres_uint32_t result;
+
+ /*
+ * Read an unsigned 32-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 4);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += 4;
+ result = ((unsigned int)(cp[0])) << 24;
+ result |= ((unsigned int)(cp[1])) << 16;
+ result |= ((unsigned int)(cp[2])) << 8;
+ result |= ((unsigned int)(cp[3]));
+
+ return (result);
+}
+
+void
+lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + 4 <= b->length);
+
+ cp = b->base;
+ cp += b->used;
+ b->used += 4;
+ cp[0] = (unsigned char)((val & 0xff000000) >> 24);
+ cp[1] = (unsigned char)((val & 0x00ff0000) >> 16);
+ cp[2] = (unsigned char)((val & 0x0000ff00) >> 8);
+ cp[3] = (unsigned char)(val & 0x000000ff);
+}
+
+void
+lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base,
+ unsigned int length)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used + length <= b->length);
+
+ cp = (unsigned char *)b->base + b->used;
+ memcpy(cp, base, length);
+ b->used += length;
+}
+
+void
+lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base,
+ unsigned int length)
+{
+ unsigned char *cp;
+
+ REQUIRE(LWRES_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= length);
+
+ cp = b->base;
+ cp += b->current;
+ b->current += length;
+
+ memcpy(base, cp, length);
+}
diff --git a/src/libfreeswan/liblwres/lwconfig.c b/src/libfreeswan/liblwres/lwconfig.c
new file mode 100644
index 000000000..f1c19b697
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwconfig.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwconfig.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+/***
+ *** Module for parsing resolv.conf files.
+ ***
+ *** entry points are:
+ *** lwres_conf_init(lwres_context_t *ctx)
+ *** intializes data structure for subsequent config parsing.
+ ***
+ *** lwres_conf_parse(lwres_context_t *ctx, const char *filename)
+ *** parses a file and fills in the data structure.
+ ***
+ *** lwres_conf_print(lwres_context_t *ctx, FILE *fp)
+ *** prints the config data structure to the FILE.
+ ***
+ *** lwres_conf_clear(lwres_context_t *ctx)
+ *** frees up all the internal memory used by the config data
+ *** structure, returning it to the lwres_context_t.
+ ***
+ ***/
+
+#include <config.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwres.h>
+#include <lwres/net.h>
+#include <lwres/result.h>
+
+#include "assert_p.h"
+#include "context_p.h"
+
+
+#if ! defined(NS_INADDRSZ)
+#define NS_INADDRSZ 4
+#endif
+
+#if ! defined(NS_IN6ADDRSZ)
+#define NS_IN6ADDRSZ 16
+#endif
+
+static lwres_result_t
+lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp);
+
+static lwres_result_t
+lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
+
+static void
+lwres_resetaddr(lwres_addr_t *addr);
+
+static lwres_result_t
+lwres_create_addr(const char *buff, lwres_addr_t *addr, int convert_zero);
+
+static int lwresaddr2af(int lwresaddrtype);
+
+
+static int
+lwresaddr2af(int lwresaddrtype)
+{
+ int af = 0;
+
+ switch (lwresaddrtype) {
+ case LWRES_ADDRTYPE_V4:
+ af = AF_INET;
+ break;
+
+ case LWRES_ADDRTYPE_V6:
+ af = AF_INET6;
+ break;
+ }
+
+ return (af);
+}
+
+
+/*
+ * Eat characters from FP until EOL or EOF. Returns EOF or '\n'
+ */
+static int
+eatline(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF)
+ ch = fgetc(fp);
+
+ return (ch);
+}
+
+
+/*
+ * Eats white space up to next newline or non-whitespace character (of
+ * EOF). Returns the last character read. Comments are considered white
+ * space.
+ */
+static int
+eatwhite(FILE *fp) {
+ int ch;
+
+ ch = fgetc(fp);
+ while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
+ ch = fgetc(fp);
+
+ if (ch == ';' || ch == '#')
+ ch = eatline(fp);
+
+ return (ch);
+}
+
+
+/*
+ * Skip over any leading whitespace and then read in the next sequence of
+ * non-whitespace characters. In this context newline is not considered
+ * whitespace. Returns EOF on end-of-file, or the character
+ * that caused the reading to stop.
+ */
+static int
+getword(FILE *fp, char *buffer, size_t size) {
+ int ch;
+ char *p = buffer;
+
+ REQUIRE(buffer != NULL);
+ REQUIRE(size > 0);
+
+ *p = '\0';
+
+ ch = eatwhite(fp);
+
+ if (ch == EOF)
+ return (EOF);
+
+ do {
+ *p = '\0';
+
+ if (ch == EOF || isspace((unsigned char)ch))
+ break;
+ else if ((size_t) (p - buffer) == size - 1)
+ return (EOF); /* Not enough space. */
+
+ *p++ = (char)ch;
+ ch = fgetc(fp);
+ } while (1);
+
+ return (ch);
+}
+
+static void
+lwres_resetaddr(lwres_addr_t *addr) {
+ REQUIRE(addr != NULL);
+
+ memset(addr->address, 0, LWRES_ADDR_MAXLEN);
+ addr->family = 0;
+ addr->length = 0;
+}
+
+static char *
+lwres_strdup(lwres_context_t *ctx, const char *str) {
+ char *p;
+
+ REQUIRE(str != NULL);
+ REQUIRE(strlen(str) > 0);
+
+ p = CTXMALLOC(strlen(str) + 1);
+ if (p != NULL)
+ strcpy(p, str);
+
+ return (p);
+}
+
+void
+lwres_conf_init(lwres_context_t *ctx) {
+ int i;
+ lwres_conf_t *confdata;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ confdata->nsnext = 0;
+ confdata->lwnext = 0;
+ confdata->domainname = NULL;
+ confdata->searchnxt = 0;
+ confdata->sortlistnxt = 0;
+ confdata->resdebug = 0;
+ confdata->ndots = 1;
+ confdata->no_tld_query = 0;
+
+ for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++)
+ lwres_resetaddr(&confdata->nameservers[i]);
+
+ for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++)
+ confdata->search[i] = NULL;
+
+ for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
+ lwres_resetaddr(&confdata->sortlist[i].addr);
+ lwres_resetaddr(&confdata->sortlist[i].mask);
+ }
+}
+
+void
+lwres_conf_clear(lwres_context_t *ctx) {
+ int i;
+ lwres_conf_t *confdata;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ for (i = 0 ; i < confdata->nsnext ; i++)
+ lwres_resetaddr(&confdata->nameservers[i]);
+
+ if (confdata->domainname != NULL) {
+ CTXFREE(confdata->domainname,
+ strlen(confdata->domainname) + 1);
+ confdata->domainname = NULL;
+ }
+
+ for (i = 0 ; i < confdata->searchnxt ; i++) {
+ if (confdata->search[i] != NULL) {
+ CTXFREE(confdata->search[i],
+ strlen(confdata->search[i]) + 1);
+ confdata->search[i] = NULL;
+ }
+ }
+
+ for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
+ lwres_resetaddr(&confdata->sortlist[i].addr);
+ lwres_resetaddr(&confdata->sortlist[i].mask);
+ }
+
+ confdata->nsnext = 0;
+ confdata->lwnext = 0;
+ confdata->domainname = NULL;
+ confdata->searchnxt = 0;
+ confdata->sortlistnxt = 0;
+ confdata->resdebug = 0;
+ confdata->ndots = 1;
+ confdata->no_tld_query = 0;
+}
+
+static lwres_result_t
+lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp) {
+ char word[LWRES_CONFMAXLINELEN];
+ int res;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
+ return (LWRES_R_SUCCESS);
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (LWRES_R_FAILURE); /* Extra junk on line. */
+
+ res = lwres_create_addr(word,
+ &confdata->nameservers[confdata->nsnext++], 1);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp) {
+ char word[LWRES_CONFMAXLINELEN];
+ int res;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ if (confdata->lwnext == LWRES_CONFMAXLWSERVERS)
+ return (LWRES_R_SUCCESS);
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (LWRES_R_FAILURE); /* Extra junk on line. */
+
+ res = lwres_create_addr(word,
+ &confdata->lwservers[confdata->lwnext++], 1);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp) {
+ char word[LWRES_CONFMAXLINELEN];
+ int res, i;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ res = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing else on line. */
+ else if (res == ' ' || res == '\t')
+ res = eatwhite(fp);
+
+ if (res != EOF && res != '\n')
+ return (LWRES_R_FAILURE); /* Extra junk on line. */
+
+ if (confdata->domainname != NULL)
+ CTXFREE(confdata->domainname,
+ strlen(confdata->domainname) + 1); /* */
+
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++) {
+ if (confdata->search[i] != NULL) {
+ CTXFREE(confdata->search[i],
+ strlen(confdata->search[i])+1);
+ confdata->search[i] = NULL;
+ }
+ }
+ confdata->searchnxt = 0;
+
+ confdata->domainname = lwres_strdup(ctx, word);
+
+ if (confdata->domainname == NULL)
+ return (LWRES_R_FAILURE);
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp) {
+ int idx, delim;
+ char word[LWRES_CONFMAXLINELEN];
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ if (confdata->domainname != NULL) {
+ /*
+ * Search and domain are mutually exclusive.
+ */
+ CTXFREE(confdata->domainname,
+ strlen(confdata->domainname) + 1);
+ confdata->domainname = NULL;
+ }
+
+ /*
+ * Remove any previous search definitions.
+ */
+ for (idx = 0 ; idx < LWRES_CONFMAXSEARCH ; idx++) {
+ if (confdata->search[idx] != NULL) {
+ CTXFREE(confdata->search[idx],
+ strlen(confdata->search[idx])+1);
+ confdata->search[idx] = NULL;
+ }
+ }
+ confdata->searchnxt = 0;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Nothing else on line. */
+
+ idx = 0;
+ while (strlen(word) > 0) {
+ if (confdata->searchnxt == LWRES_CONFMAXSEARCH)
+ goto ignore; /* Too many domains. */
+
+ confdata->search[idx] = lwres_strdup(ctx, word);
+ if (confdata->search[idx] == NULL)
+ return (LWRES_R_FAILURE);
+ idx++;
+ confdata->searchnxt++;
+
+ ignore:
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_create_addr(const char *buffer, lwres_addr_t *addr, int convert_zero) {
+ struct in_addr v4;
+ struct in6_addr v6;
+
+ if (lwres_net_aton(buffer, &v4) == 1) {
+ if (convert_zero) {
+ unsigned char zeroaddress[] = {0, 0, 0, 0};
+ unsigned char loopaddress[] = {127, 0, 0, 1};
+ if (memcmp(&v4, zeroaddress, 4) == 0)
+ memcpy(&v4, loopaddress, 4);
+ }
+ addr->family = LWRES_ADDRTYPE_V4;
+ addr->length = NS_INADDRSZ;
+ memcpy((void *)addr->address, &v4, NS_INADDRSZ);
+
+ } else if (lwres_net_pton(AF_INET6, buffer, &v6) == 1) {
+ addr->family = LWRES_ADDRTYPE_V6;
+ addr->length = NS_IN6ADDRSZ;
+ memcpy((void *)addr->address, &v6, NS_IN6ADDRSZ);
+ } else {
+ return (LWRES_R_FAILURE); /* Unrecognised format. */
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp) {
+ int delim, res, idx;
+ char word[LWRES_CONFMAXLINELEN];
+ char *p;
+ lwres_conf_t *confdata;
+
+ confdata = &ctx->confdata;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Empty line after keyword. */
+
+ while (strlen(word) > 0) {
+ if (confdata->sortlistnxt == LWRES_CONFMAXSORTLIST)
+ return (LWRES_R_FAILURE); /* Too many values. */
+
+ p = strchr(word, '/');
+ if (p != NULL)
+ *p++ = '\0';
+
+ idx = confdata->sortlistnxt;
+ res = lwres_create_addr(word, &confdata->sortlist[idx].addr, 1);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+
+ if (p != NULL) {
+ res = lwres_create_addr(p,
+ &confdata->sortlist[idx].mask,
+ 0);
+ if (res != LWRES_R_SUCCESS)
+ return (res);
+ } else {
+ /*
+ * Make up a mask.
+ */
+ confdata->sortlist[idx].mask =
+ confdata->sortlist[idx].addr;
+
+ memset(&confdata->sortlist[idx].mask.address, 0xff,
+ confdata->sortlist[idx].addr.length);
+ }
+
+ confdata->sortlistnxt++;
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+static lwres_result_t
+lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp) {
+ int delim;
+ long ndots;
+ char *p;
+ char word[LWRES_CONFMAXLINELEN];
+ lwres_conf_t *confdata;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ delim = getword(fp, word, sizeof(word));
+ if (strlen(word) == 0)
+ return (LWRES_R_FAILURE); /* Empty line after keyword. */
+
+ while (strlen(word) > 0) {
+ if (strcmp("debug", word) == 0) {
+ confdata->resdebug = 1;
+ } else if (strcmp("no_tld_query", word) == 0) {
+ confdata->no_tld_query = 1;
+ } else if (strncmp("ndots:", word, 6) == 0) {
+ ndots = strtol(word + 6, &p, 10);
+ if (*p != '\0') /* Bad string. */
+ return (LWRES_R_FAILURE);
+ if (ndots < 0 || ndots > 0xff) /* Out of range. */
+ return (LWRES_R_FAILURE);
+ confdata->ndots = (lwres_uint8_t)ndots;
+ }
+
+ if (delim == EOF || delim == '\n')
+ break;
+ else
+ delim = getword(fp, word, sizeof(word));
+ }
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_conf_parse(lwres_context_t *ctx, const char *filename) {
+ FILE *fp = NULL;
+ char word[256];
+ lwres_result_t rval, ret;
+ lwres_conf_t *confdata;
+ int stopchar;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(strlen(filename) > 0);
+ REQUIRE(confdata != NULL);
+
+ errno = 0;
+ if ((fp = fopen(filename, "r")) == NULL)
+ return (LWRES_R_FAILURE);
+
+ ret = LWRES_R_SUCCESS;
+ do {
+ stopchar = getword(fp, word, sizeof(word));
+ if (stopchar == EOF) {
+ rval = LWRES_R_SUCCESS;
+ break;
+ }
+
+ if (strlen(word) == 0)
+ rval = LWRES_R_SUCCESS;
+ else if (strcmp(word, "nameserver") == 0)
+ rval = lwres_conf_parsenameserver(ctx, fp);
+ else if (strcmp(word, "lwserver") == 0)
+ rval = lwres_conf_parselwserver(ctx, fp);
+ else if (strcmp(word, "domain") == 0)
+ rval = lwres_conf_parsedomain(ctx, fp);
+ else if (strcmp(word, "search") == 0)
+ rval = lwres_conf_parsesearch(ctx, fp);
+ else if (strcmp(word, "sortlist") == 0)
+ rval = lwres_conf_parsesortlist(ctx, fp);
+ else if (strcmp(word, "option") == 0)
+ rval = lwres_conf_parseoption(ctx, fp);
+ else {
+ /* unrecognised word. Ignore entire line */
+ rval = LWRES_R_SUCCESS;
+ stopchar = eatline(fp);
+ if (stopchar == EOF) {
+ break;
+ }
+ }
+ if (ret == LWRES_R_SUCCESS && rval != LWRES_R_SUCCESS)
+ ret = rval;
+ } while (1);
+
+ fclose(fp);
+
+ return (ret);
+}
+
+lwres_result_t
+lwres_conf_print(lwres_context_t *ctx, FILE *fp) {
+ int i;
+ int af;
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
+ const char *p;
+ lwres_conf_t *confdata;
+ lwres_addr_t tmpaddr;
+
+ REQUIRE(ctx != NULL);
+ confdata = &ctx->confdata;
+
+ REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS);
+
+ for (i = 0 ; i < confdata->nsnext ; i++) {
+ af = lwresaddr2af(confdata->nameservers[i].family);
+
+ p = lwres_net_ntop(af, confdata->nameservers[i].address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, "nameserver %s\n", tmp);
+ }
+
+ for (i = 0 ; i < confdata->lwnext ; i++) {
+ af = lwresaddr2af(confdata->lwservers[i].family);
+
+ p = lwres_net_ntop(af, confdata->lwservers[i].address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, "lwserver %s\n", tmp);
+ }
+
+ if (confdata->domainname != NULL) {
+ fprintf(fp, "domain %s\n", confdata->domainname);
+ } else if (confdata->searchnxt > 0) {
+ REQUIRE(confdata->searchnxt <= LWRES_CONFMAXSEARCH);
+
+ fprintf(fp, "search");
+ for (i = 0 ; i < confdata->searchnxt ; i++)
+ fprintf(fp, " %s", confdata->search[i]);
+ fputc('\n', fp);
+ }
+
+ REQUIRE(confdata->sortlistnxt <= LWRES_CONFMAXSORTLIST);
+
+ if (confdata->sortlistnxt > 0) {
+ fputs("sortlist", fp);
+ for (i = 0 ; i < confdata->sortlistnxt ; i++) {
+ af = lwresaddr2af(confdata->sortlist[i].addr.family);
+
+ p = lwres_net_ntop(af,
+ confdata->sortlist[i].addr.address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, " %s", tmp);
+
+ tmpaddr = confdata->sortlist[i].mask;
+ memset(&tmpaddr.address, 0xff, tmpaddr.length);
+
+ if (memcmp(&tmpaddr.address,
+ confdata->sortlist[i].mask.address,
+ confdata->sortlist[i].mask.length) != 0) {
+ af = lwresaddr2af(
+ confdata->sortlist[i].mask.family);
+ p = lwres_net_ntop
+ (af,
+ confdata->sortlist[i].mask.address,
+ tmp, sizeof(tmp));
+ if (p != tmp)
+ return (LWRES_R_FAILURE);
+
+ fprintf(fp, "/%s", tmp);
+ }
+ }
+ fputc('\n', fp);
+ }
+
+ if (confdata->resdebug)
+ fprintf(fp, "options debug\n");
+
+ if (confdata->ndots > 0)
+ fprintf(fp, "options ndots:%d\n", confdata->ndots);
+
+ if (confdata->no_tld_query)
+ fprintf(fp, "options no_tld_query\n");
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_conf_t *
+lwres_conf_get(lwres_context_t *ctx) {
+ REQUIRE(ctx != NULL);
+
+ return (&ctx->confdata);
+}
diff --git a/src/libfreeswan/liblwres/lwinetaton.c b/src/libfreeswan/liblwres/lwinetaton.c
new file mode 100644
index 000000000..42a2cfa69
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwinetaton.c
@@ -0,0 +1,203 @@
+/*
+ * Portions Copyright (C) 1996-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Copyright (c) 1983, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$Id: lwinetaton.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <ctype.h>
+
+#include <stddef.h>
+
+#include <lwres/int.h>
+#include <lwres/net.h>
+
+#include "assert_p.h"
+
+/*
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+lwres_net_aton(const char *cp, struct in_addr *addr) {
+ unsigned long val;
+ int base, n;
+ unsigned char c;
+ lwres_uint8_t parts[4];
+ lwres_uint8_t *pp = parts;
+ int digit;
+
+ REQUIRE(cp != NULL);
+
+ c = *cp;
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, isdigit=decimal.
+ */
+ if (!isdigit(c & 0xff))
+ return (0);
+ val = 0;
+ base = 10;
+ digit = 0;
+ if (c == '0') {
+ c = *++cp;
+ if (c == 'x' || c == 'X') {
+ base = 16;
+ c = *++cp;
+ } else {
+ base = 8;
+ digit = 1;
+ }
+ }
+ for (;;) {
+ /*
+ * isascii() is valid for all integer values, and
+ * when it is true, c is known to be in scope
+ * for isdigit(). No cast necessary. Similar
+ * comment applies for later ctype uses.
+ */
+ if (isascii(c) && isdigit(c)) {
+ if (base == 8 && (c == '8' || c == '9'))
+ return (0);
+ val = (val * base) + (c - '0');
+ c = *++cp;
+ digit = 1;
+ } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) |
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ c = *++cp;
+ digit = 1;
+ } else
+ break;
+ }
+ if (c == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return (0);
+ *pp++ = (lwres_uint8_t)val;
+ c = *++cp;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (c != '\0' && (!isascii(c) || !isspace(c)))
+ return (0);
+ /*
+ * Did we get a valid digit?
+ */
+ if (!digit)
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr != NULL)
+ addr->s_addr = htonl(val);
+
+ return (1);
+}
diff --git a/src/libfreeswan/liblwres/lwinetntop.c b/src/libfreeswan/liblwres/lwinetntop.c
new file mode 100644
index 000000000..dfc55a97c
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwinetntop.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 1996-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] =
+ "$Id: lwinetntop.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <lwres/net.h>
+
+#define NS_INT16SZ 2
+#define NS_IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const unsigned char *src, char *dst,
+ size_t size);
+
+#ifdef AF_INET6
+static const char *inet_ntop6(const unsigned char *src, char *dst,
+ size_t size);
+#endif
+
+/* char *
+ * lwres_net_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * return:
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * author:
+ * Paul Vixie, 1996.
+ */
+const char *
+lwres_net_ntop(int af, const void *src, char *dst, size_t size) {
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+#ifdef AF_INET6
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+#endif
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address
+ * return:
+ * `dst' (as a const)
+ * notes:
+ * (1) uses no statics
+ * (2) takes a unsigned char* not an in_addr as input
+ * author:
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, size_t size) {
+ static const char fmt[] = "%u.%u.%u.%u";
+ char tmp[sizeof "255.255.255.255"];
+
+ if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
+ {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+
+ return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * author:
+ * Paul Vixie, 1996.
+ */
+#ifdef AF_INET6
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, size_t size) {
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
+ struct { int base, len; } best, cur;
+ unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof words);
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 &&
+ (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp,
+ sizeof tmp - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += sprintf(tp, "%x", words[i]);
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+#endif /* AF_INET6 */
diff --git a/src/libfreeswan/liblwres/lwinetpton.c b/src/libfreeswan/liblwres/lwinetpton.c
new file mode 100644
index 000000000..792a74775
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwinetpton.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 1996-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: lwinetpton.c,v 1.1 2004/03/15 20:35:25 as Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <lwres/net.h>
+
+#define NS_INT16SZ 2
+#define NS_INADDRSZ 4
+#define NS_IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, unsigned char *dst);
+static int inet_pton6(const char *src, unsigned char *dst);
+
+/* int
+ * lwres_net_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+lwres_net_pton(int af, const char *src, void *dst) {
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst) {
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ unsigned int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst) {
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ unsigned int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
diff --git a/src/libfreeswan/liblwres/lwpacket.c b/src/libfreeswan/liblwres/lwpacket.c
new file mode 100644
index 000000000..7bcdbbd4a
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwpacket.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwpacket.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/result.h>
+
+#include "assert_p.h"
+
+#define LWPACKET_LENGTH \
+ (sizeof(lwres_uint16_t) * 4 + sizeof(lwres_uint32_t) * 5)
+
+lwres_result_t
+lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) {
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+
+ if (!SPACE_OK(b, LWPACKET_LENGTH))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ lwres_buffer_putuint32(b, pkt->length);
+ lwres_buffer_putuint16(b, pkt->version);
+ lwres_buffer_putuint16(b, pkt->pktflags);
+ lwres_buffer_putuint32(b, pkt->serial);
+ lwres_buffer_putuint32(b, pkt->opcode);
+ lwres_buffer_putuint32(b, pkt->result);
+ lwres_buffer_putuint32(b, pkt->recvlength);
+ lwres_buffer_putuint16(b, pkt->authtype);
+ lwres_buffer_putuint16(b, pkt->authlength);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt) {
+ lwres_uint32_t space;
+
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+
+ space = LWRES_BUFFER_REMAINING(b);
+ if (space < LWPACKET_LENGTH)
+ return (LWRES_R_UNEXPECTEDEND);
+
+ pkt->length = lwres_buffer_getuint32(b);
+ /*
+ * XXXBEW/MLG Checking that the buffer is long enough probably
+ * shouldn't be done here, since this function is supposed to just
+ * parse the header.
+ */
+ if (pkt->length > space)
+ return (LWRES_R_UNEXPECTEDEND);
+ pkt->version = lwres_buffer_getuint16(b);
+ pkt->pktflags = lwres_buffer_getuint16(b);
+ pkt->serial = lwres_buffer_getuint32(b);
+ pkt->opcode = lwres_buffer_getuint32(b);
+ pkt->result = lwres_buffer_getuint32(b);
+ pkt->recvlength = lwres_buffer_getuint32(b);
+ pkt->authtype = lwres_buffer_getuint16(b);
+ pkt->authlength = lwres_buffer_getuint16(b);
+
+ return (LWRES_R_SUCCESS);
+}
diff --git a/src/libfreeswan/liblwres/lwres_gabn.c b/src/libfreeswan/liblwres/lwres_gabn.c
new file mode 100644
index 000000000..5e809ba8e
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwres_gabn.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwres_gabn.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(req->name != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ datalen = strlen(req->name);
+
+ payload_length = 4 + 4 + 2 + req->namelen + 1;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Flags.
+ */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /*
+ * Address types we'll accept.
+ */
+ lwres_buffer_putuint32(b, req->addrtypes);
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
+ lwres_buffer_putuint8(b, 0); /* trailing NUL */
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+ lwres_addr_t *addr;
+ int x;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ /* naliases, naddrs */
+ payload_length = 4 + 2 + 2;
+ /* real name encoding */
+ payload_length += 2 + req->realnamelen + 1;
+ /* each alias */
+ for (x = 0 ; x < req->naliases ; x++)
+ payload_length += 2 + req->aliaslen[x] + 1;
+ /* each address */
+ x = 0;
+ addr = LWRES_LIST_HEAD(req->addrs);
+ while (addr != NULL) {
+ payload_length += 4 + 2;
+ payload_length += addr->length;
+ addr = LWRES_LIST_NEXT(addr, link);
+ x++;
+ }
+ INSIST(x == req->naddrs);
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETADDRSBYNAME;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ /*
+ * Check space needed here.
+ */
+ INSIST(SPACE_OK(b, payload_length));
+
+ /* Flags. */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /* encode naliases and naddrs */
+ lwres_buffer_putuint16(b, req->naliases);
+ lwres_buffer_putuint16(b, req->naddrs);
+
+ /* encode the real name */
+ datalen = req->realnamelen;
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
+ lwres_buffer_putuint8(b, 0);
+
+ /* encode the aliases */
+ for (x = 0 ; x < req->naliases ; x++) {
+ datalen = req->aliaslen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
+ datalen);
+ lwres_buffer_putuint8(b, 0);
+ }
+
+ /* encode the addresses */
+ addr = LWRES_LIST_HEAD(req->addrs);
+ while (addr != NULL) {
+ lwres_buffer_putuint32(b, addr->family);
+ lwres_buffer_putuint16(b, addr->length);
+ lwres_buffer_putmem(b, addr->address, addr->length);
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+ INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp)
+{
+ int ret;
+ char *name;
+ lwres_gabnrequest_t *gabn;
+ lwres_uint32_t addrtypes;
+ lwres_uint32_t flags;
+ lwres_uint16_t namelen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ if (!SPACE_REMAINING(b, 4 + 4))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ flags = lwres_buffer_getuint32(b);
+ addrtypes = lwres_buffer_getuint32(b);
+
+ /*
+ * Pull off the name itself
+ */
+ ret = lwres_string_parse(b, &name, &namelen);
+ if (ret != LWRES_R_SUCCESS)
+ return (ret);
+
+ if (LWRES_BUFFER_REMAINING(b) != 0)
+ return (LWRES_R_TRAILINGDATA);
+
+ gabn = CTXMALLOC(sizeof(lwres_gabnrequest_t));
+ if (gabn == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ gabn->flags = flags;
+ gabn->addrtypes = addrtypes;
+ gabn->name = name;
+ gabn->namelen = namelen;
+
+ *structp = gabn;
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp)
+{
+ lwres_result_t ret;
+ unsigned int x;
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ lwres_gabnresponse_t *gabn;
+ lwres_addrlist_t addrlist;
+ lwres_addr_t *addr;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ gabn = NULL;
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ /*
+ * Pull off the name itself
+ */
+ if (!SPACE_REMAINING(b, 4 + 2 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ flags = lwres_buffer_getuint32(b);
+ naliases = lwres_buffer_getuint16(b);
+ naddrs = lwres_buffer_getuint16(b);
+
+ gabn = CTXMALLOC(sizeof(lwres_gabnresponse_t));
+ if (gabn == NULL)
+ return (LWRES_R_NOMEMORY);
+ gabn->aliases = NULL;
+ gabn->aliaslen = NULL;
+ LWRES_LIST_INIT(gabn->addrs);
+ gabn->base = NULL;
+
+ gabn->flags = flags;
+ gabn->naliases = naliases;
+ gabn->naddrs = naddrs;
+
+ LWRES_LIST_INIT(addrlist);
+
+ if (naliases > 0) {
+ gabn->aliases = CTXMALLOC(sizeof(char *) * naliases);
+ if (gabn->aliases == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ gabn->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
+ if (gabn->aliaslen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ for (x = 0 ; x < naddrs ; x++) {
+ addr = CTXMALLOC(sizeof(lwres_addr_t));
+ if (addr == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ LWRES_LINK_INIT(addr, link);
+ LWRES_LIST_APPEND(addrlist, addr, link);
+ }
+
+ /*
+ * Now, pull off the real name.
+ */
+ ret = lwres_string_parse(b, &gabn->realname, &gabn->realnamelen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Parse off the aliases.
+ */
+ for (x = 0 ; x < gabn->naliases ; x++) {
+ ret = lwres_string_parse(b, &gabn->aliases[x],
+ &gabn->aliaslen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ /*
+ * Pull off the addresses. We already strung the linked list
+ * up above.
+ */
+ addr = LWRES_LIST_HEAD(addrlist);
+ for (x = 0 ; x < gabn->naddrs ; x++) {
+ INSIST(addr != NULL);
+ ret = lwres_addr_parse(b, addr);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ addr = LWRES_LIST_NEXT(addr, link);
+ }
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ gabn->addrs = addrlist;
+
+ *structp = gabn;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (gabn != NULL) {
+ if (gabn->aliases != NULL)
+ CTXFREE(gabn->aliases, sizeof(char *) * naliases);
+ if (gabn->aliaslen != NULL)
+ CTXFREE(gabn->aliaslen,
+ sizeof(lwres_uint16_t) * naliases);
+ addr = LWRES_LIST_HEAD(addrlist);
+ while (addr != NULL) {
+ LWRES_LIST_UNLINK(addrlist, addr, link);
+ CTXFREE(addr, sizeof(lwres_addr_t));
+ addr = LWRES_LIST_HEAD(addrlist);
+ }
+ CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
+ }
+
+ return (ret);
+}
+
+void
+lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp)
+{
+ lwres_gabnrequest_t *gabn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gabn = *structp;
+ *structp = NULL;
+
+ CTXFREE(gabn, sizeof(lwres_gabnrequest_t));
+}
+
+void
+lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp)
+{
+ lwres_gabnresponse_t *gabn;
+ lwres_addr_t *addr;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gabn = *structp;
+ *structp = NULL;
+
+ if (gabn->naliases > 0) {
+ CTXFREE(gabn->aliases, sizeof(char *) * gabn->naliases);
+ CTXFREE(gabn->aliaslen,
+ sizeof(lwres_uint16_t) * gabn->naliases);
+ }
+ addr = LWRES_LIST_HEAD(gabn->addrs);
+ while (addr != NULL) {
+ LWRES_LIST_UNLINK(gabn->addrs, addr, link);
+ CTXFREE(addr, sizeof(lwres_addr_t));
+ addr = LWRES_LIST_HEAD(gabn->addrs);
+ }
+ if (gabn->base != NULL)
+ CTXFREE(gabn->base, gabn->baselen);
+ CTXFREE(gabn, sizeof(lwres_gabnresponse_t));
+}
diff --git a/src/libfreeswan/liblwres/lwres_gnba.c b/src/libfreeswan/liblwres/lwres_gnba.c
new file mode 100644
index 000000000..293eb05ac
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwres_gnba.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwres_gnba.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(req->addr.family != 0);
+ REQUIRE(req->addr.length != 0);
+ REQUIRE(req->addr.address != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ payload_length = 4 + 4 + 2 + + req->addr.length;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint32(b, req->flags);
+ lwres_buffer_putuint32(b, req->addr.family);
+ lwres_buffer_putuint16(b, req->addr.length);
+ lwres_buffer_putmem(b, (unsigned char *)req->addr.address,
+ req->addr.length);
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+ int x;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ /*
+ * Calculate packet size.
+ */
+ payload_length = 4; /* flags */
+ payload_length += 2; /* naliases */
+ payload_length += 2 + req->realnamelen + 1; /* real name encoding */
+ for (x = 0 ; x < req->naliases ; x++) /* each alias */
+ payload_length += 2 + req->aliaslen[x] + 1;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETNAMEBYADDR;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+ lwres_buffer_putuint32(b, req->flags);
+
+ /* encode naliases */
+ lwres_buffer_putuint16(b, req->naliases);
+
+ /* encode the real name */
+ datalen = req->realnamelen;
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
+ lwres_buffer_putuint8(b, 0);
+
+ /* encode the aliases */
+ for (x = 0 ; x < req->naliases ; x++) {
+ datalen = req->aliaslen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->aliases[x],
+ datalen);
+ lwres_buffer_putuint8(b, 0);
+ }
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp)
+{
+ int ret;
+ lwres_gnbarequest_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ gnba = CTXMALLOC(sizeof(lwres_gnbarequest_t));
+ if (gnba == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ if (!SPACE_REMAINING(b, 4))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ gnba->flags = lwres_buffer_getuint32(b);
+
+ ret = lwres_addr_parse(b, &gnba->addr);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ *structp = gnba;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (gnba != NULL)
+ lwres_gnbarequest_free(ctx, &gnba);
+
+ return (ret);
+}
+
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp)
+{
+ int ret;
+ unsigned int x;
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_gnbaresponse_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ gnba = NULL;
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ /*
+ * Pull off flags & naliases
+ */
+ if (!SPACE_REMAINING(b, 4 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ flags = lwres_buffer_getuint32(b);
+ naliases = lwres_buffer_getuint16(b);
+
+ gnba = CTXMALLOC(sizeof(lwres_gnbaresponse_t));
+ if (gnba == NULL)
+ return (LWRES_R_NOMEMORY);
+ gnba->base = NULL;
+ gnba->aliases = NULL;
+ gnba->aliaslen = NULL;
+
+ gnba->flags = flags;
+ gnba->naliases = naliases;
+
+ if (naliases > 0) {
+ gnba->aliases = CTXMALLOC(sizeof(char *) * naliases);
+ if (gnba->aliases == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ gnba->aliaslen = CTXMALLOC(sizeof(lwres_uint16_t) * naliases);
+ if (gnba->aliaslen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ /*
+ * Now, pull off the real name.
+ */
+ ret = lwres_string_parse(b, &gnba->realname, &gnba->realnamelen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Parse off the aliases.
+ */
+ for (x = 0 ; x < gnba->naliases ; x++) {
+ ret = lwres_string_parse(b, &gnba->aliases[x],
+ &gnba->aliaslen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ *structp = gnba;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (gnba != NULL) {
+ if (gnba->aliases != NULL)
+ CTXFREE(gnba->aliases, sizeof(char *) * naliases);
+ if (gnba->aliaslen != NULL)
+ CTXFREE(gnba->aliaslen,
+ sizeof(lwres_uint16_t) * naliases);
+ CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
+ }
+
+ return (ret);
+}
+
+void
+lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp)
+{
+ lwres_gnbarequest_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gnba = *structp;
+ *structp = NULL;
+
+ CTXFREE(gnba, sizeof(lwres_gnbarequest_t));
+}
+
+void
+lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp)
+{
+ lwres_gnbaresponse_t *gnba;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ gnba = *structp;
+ *structp = NULL;
+
+ if (gnba->naliases > 0) {
+ CTXFREE(gnba->aliases, sizeof(char *) * gnba->naliases);
+ CTXFREE(gnba->aliaslen,
+ sizeof(lwres_uint16_t) * gnba->naliases);
+ }
+ if (gnba->base != NULL)
+ CTXFREE(gnba->base, gnba->baselen);
+ CTXFREE(gnba, sizeof(lwres_gnbaresponse_t));
+}
diff --git a/src/libfreeswan/liblwres/lwres_grbn.c b/src/libfreeswan/liblwres/lwres_grbn.c
new file mode 100644
index 000000000..fd8de50a2
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwres_grbn.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwres_grbn.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(req->name != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ datalen = strlen(req->name);
+
+ payload_length = 4 + 2 + 2 + 2 + req->namelen + 1;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Flags.
+ */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /*
+ * Class.
+ */
+ lwres_buffer_putuint16(b, req->rdclass);
+
+ /*
+ * Type.
+ */
+ lwres_buffer_putuint16(b, req->rdtype);
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
+ lwres_buffer_putuint8(b, 0); /* trailing NUL */
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+ lwres_uint16_t datalen;
+ int x;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ /* flags, class, type, ttl, nrdatas, nsigs */
+ payload_length = 4 + 2 + 2 + 4 + 2 + 2;
+ /* real name encoding */
+ payload_length += 2 + req->realnamelen + 1;
+ /* each rr */
+ for (x = 0 ; x < req->nrdatas ; x++)
+ payload_length += 2 + req->rdatalen[x];
+ for (x = 0 ; x < req->nsigs ; x++)
+ payload_length += 2 + req->siglen[x];
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ /*
+ * Check space needed here.
+ */
+ INSIST(SPACE_OK(b, payload_length));
+
+ /* Flags. */
+ lwres_buffer_putuint32(b, req->flags);
+
+ /* encode class, type, ttl, and nrdatas */
+ lwres_buffer_putuint16(b, req->rdclass);
+ lwres_buffer_putuint16(b, req->rdtype);
+ lwres_buffer_putuint32(b, req->ttl);
+ lwres_buffer_putuint16(b, req->nrdatas);
+ lwres_buffer_putuint16(b, req->nsigs);
+
+ /* encode the real name */
+ datalen = req->realnamelen;
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
+ lwres_buffer_putuint8(b, 0);
+
+ /* encode the rdatas */
+ for (x = 0 ; x < req->nrdatas ; x++) {
+ datalen = req->rdatalen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, req->rdatas[x], datalen);
+ }
+
+ /* encode the signatures */
+ for (x = 0 ; x < req->nsigs ; x++) {
+ datalen = req->siglen[x];
+ lwres_buffer_putuint16(b, datalen);
+ lwres_buffer_putmem(b, req->sigs[x], datalen);
+ }
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+ INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp)
+{
+ int ret;
+ char *name;
+ lwres_grbnrequest_t *grbn;
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass, rdtype;
+ lwres_uint16_t namelen;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ if (!SPACE_REMAINING(b, 4 + 2 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ /*
+ * Pull off the flags, class, and type.
+ */
+ flags = lwres_buffer_getuint32(b);
+ rdclass = lwres_buffer_getuint16(b);
+ rdtype = lwres_buffer_getuint16(b);
+
+ /*
+ * Pull off the name itself
+ */
+ ret = lwres_string_parse(b, &name, &namelen);
+ if (ret != LWRES_R_SUCCESS)
+ return (ret);
+
+ if (LWRES_BUFFER_REMAINING(b) != 0)
+ return (LWRES_R_TRAILINGDATA);
+
+ grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t));
+ if (grbn == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ grbn->flags = flags;
+ grbn->rdclass = rdclass;
+ grbn->rdtype = rdtype;
+ grbn->name = name;
+ grbn->namelen = namelen;
+
+ *structp = grbn;
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
+{
+ lwres_result_t ret;
+ unsigned int x;
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass, rdtype;
+ lwres_uint32_t ttl;
+ lwres_uint16_t nrdatas, nsigs;
+ lwres_grbnresponse_t *grbn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ grbn = NULL;
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ /*
+ * Pull off the flags, class, type, ttl, nrdatas, and nsigs
+ */
+ if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ flags = lwres_buffer_getuint32(b);
+ rdclass = lwres_buffer_getuint16(b);
+ rdtype = lwres_buffer_getuint16(b);
+ ttl = lwres_buffer_getuint32(b);
+ nrdatas = lwres_buffer_getuint16(b);
+ nsigs = lwres_buffer_getuint16(b);
+
+ /*
+ * Pull off the name itself
+ */
+
+ grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
+ if (grbn == NULL)
+ return (LWRES_R_NOMEMORY);
+ grbn->rdatas = NULL;
+ grbn->rdatalen = NULL;
+ grbn->sigs = NULL;
+ grbn->siglen = NULL;
+ grbn->base = NULL;
+
+ grbn->flags = flags;
+ grbn->rdclass = rdclass;
+ grbn->rdtype = rdtype;
+ grbn->ttl = ttl;
+ grbn->nrdatas = nrdatas;
+ grbn->nsigs = nsigs;
+
+ if (nrdatas > 0) {
+ grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
+ if (grbn->rdatas == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
+ if (grbn->rdatalen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ if (nsigs > 0) {
+ grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
+ if (grbn->sigs == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
+ if (grbn->siglen == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+ }
+
+ /*
+ * Now, pull off the real name.
+ */
+ ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Parse off the rdatas.
+ */
+ for (x = 0 ; x < grbn->nrdatas ; x++) {
+ ret = lwres_data_parse(b, &grbn->rdatas[x],
+ &grbn->rdatalen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ /*
+ * Parse off the signatures.
+ */
+ for (x = 0 ; x < grbn->nsigs ; x++) {
+ ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ }
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ *structp = grbn;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (grbn != NULL) {
+ if (grbn->rdatas != NULL)
+ CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
+ if (grbn->rdatalen != NULL)
+ CTXFREE(grbn->rdatalen,
+ sizeof(lwres_uint16_t) * nrdatas);
+ if (grbn->sigs != NULL)
+ CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
+ if (grbn->siglen != NULL)
+ CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
+ CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
+ }
+
+ return (ret);
+}
+
+void
+lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp)
+{
+ lwres_grbnrequest_t *grbn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ grbn = *structp;
+ *structp = NULL;
+
+ CTXFREE(grbn, sizeof(lwres_grbnrequest_t));
+}
+
+void
+lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp)
+{
+ lwres_grbnresponse_t *grbn;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ grbn = *structp;
+ *structp = NULL;
+
+ if (grbn->nrdatas > 0) {
+ CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas);
+ CTXFREE(grbn->rdatalen,
+ sizeof(lwres_uint16_t) * grbn->nrdatas);
+ }
+ if (grbn->nsigs > 0) {
+ CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs);
+ CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs);
+ }
+ if (grbn->base != NULL)
+ CTXFREE(grbn->base, grbn->baselen);
+ CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
+}
diff --git a/src/libfreeswan/liblwres/lwres_noop.c b/src/libfreeswan/liblwres/lwres_noop.c
new file mode 100644
index 000000000..a75fba351
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwres_noop.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwres_noop.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwpacket.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "context_p.h"
+#include "assert_p.h"
+
+lwres_result_t
+lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ payload_length = sizeof(lwres_uint16_t) + req->datalength;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_NOOP;
+ pkt->result = 0;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, req->datalength);
+ lwres_buffer_putmem(b, req->data, req->datalength);
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
+ lwres_lwpacket_t *pkt, lwres_buffer_t *b)
+{
+ unsigned char *buf;
+ size_t buflen;
+ int ret;
+ size_t payload_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(req != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(b != NULL);
+
+ payload_length = sizeof(lwres_uint16_t) + req->datalength;
+
+ buflen = LWRES_LWPACKET_LENGTH + payload_length;
+ buf = CTXMALLOC(buflen);
+ if (buf == NULL)
+ return (LWRES_R_NOMEMORY);
+ lwres_buffer_init(b, buf, buflen);
+
+ pkt->length = buflen;
+ pkt->version = LWRES_LWPACKETVERSION_0;
+ pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
+ pkt->opcode = LWRES_OPCODE_NOOP;
+ pkt->authtype = 0;
+ pkt->authlength = 0;
+
+ ret = lwres_lwpacket_renderheader(b, pkt);
+ if (ret != LWRES_R_SUCCESS) {
+ lwres_buffer_invalidate(b);
+ CTXFREE(buf, buflen);
+ return (ret);
+ }
+
+ INSIST(SPACE_OK(b, payload_length));
+
+ /*
+ * Put the length and the data. We know this will fit because we
+ * just checked for it.
+ */
+ lwres_buffer_putuint16(b, req->datalength);
+ lwres_buffer_putmem(b, req->data, req->datalength);
+
+ INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp)
+{
+ int ret;
+ lwres_nooprequest_t *req;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
+ return (LWRES_R_FAILURE);
+
+ req = CTXMALLOC(sizeof(lwres_nooprequest_t));
+ if (req == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->datalength = lwres_buffer_getuint16(b);
+
+ if (!SPACE_REMAINING(b, req->datalength)) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->data = b->base + b->current;
+ lwres_buffer_forward(b, req->datalength);
+
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ /* success! */
+ *structp = req;
+ return (LWRES_R_SUCCESS);
+
+ /* Error return */
+ out:
+ CTXFREE(req, sizeof(lwres_nooprequest_t));
+ return (ret);
+}
+
+lwres_result_t
+lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
+ lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp)
+{
+ int ret;
+ lwres_noopresponse_t *req;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(b != NULL);
+ REQUIRE(pkt != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
+ return (LWRES_R_FAILURE);
+
+ req = CTXMALLOC(sizeof(lwres_noopresponse_t));
+ if (req == NULL)
+ return (LWRES_R_NOMEMORY);
+
+ if (!SPACE_REMAINING(b, sizeof(lwres_uint16_t))) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->datalength = lwres_buffer_getuint16(b);
+
+ if (!SPACE_REMAINING(b, req->datalength)) {
+ ret = LWRES_R_UNEXPECTEDEND;
+ goto out;
+ }
+ req->data = b->base + b->current;
+
+ lwres_buffer_forward(b, req->datalength);
+ if (LWRES_BUFFER_REMAINING(b) != 0) {
+ ret = LWRES_R_TRAILINGDATA;
+ goto out;
+ }
+
+ /* success! */
+ *structp = req;
+ return (LWRES_R_SUCCESS);
+
+ /* Error return */
+ out:
+ CTXFREE(req, sizeof(lwres_noopresponse_t));
+ return (ret);
+}
+
+void
+lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp)
+{
+ lwres_noopresponse_t *noop;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ noop = *structp;
+ *structp = NULL;
+
+ CTXFREE(noop, sizeof(lwres_noopresponse_t));
+}
+
+void
+lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp)
+{
+ lwres_nooprequest_t *noop;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(structp != NULL && *structp != NULL);
+
+ noop = *structp;
+ *structp = NULL;
+
+ CTXFREE(noop, sizeof(lwres_nooprequest_t));
+}
diff --git a/src/libfreeswan/liblwres/lwresutil.c b/src/libfreeswan/liblwres/lwresutil.c
new file mode 100644
index 000000000..60f330e76
--- /dev/null
+++ b/src/libfreeswan/liblwres/lwresutil.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lwresutil.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#include <config.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <lwres/lwbuffer.h>
+#include <lwres/lwres.h>
+#include <lwres/result.h>
+
+#include "assert_p.h"
+#include "context_p.h"
+
+/*
+ * Requires:
+ *
+ * The "current" pointer in "b" points to encoded raw data.
+ *
+ * Ensures:
+ *
+ * The address of the first byte of the data is returned via "p",
+ * and the length is returned via "len". If NULL, they are not
+ * set.
+ *
+ * On return, the current pointer of "b" will point to the character
+ * following the data length and the data.
+ *
+ */
+lwres_result_t
+lwres_data_parse(lwres_buffer_t *b, unsigned char **p, lwres_uint16_t *len)
+{
+ lwres_uint16_t datalen;
+ unsigned char *data;
+
+ REQUIRE(b != NULL);
+
+ /*
+ * Pull off the length (2 bytes)
+ */
+ if (!SPACE_REMAINING(b, 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ datalen = lwres_buffer_getuint16(b);
+
+ /*
+ * Set the pointer to this string to the right place, then
+ * advance the buffer pointer.
+ */
+ if (!SPACE_REMAINING(b, datalen))
+ return (LWRES_R_UNEXPECTEDEND);
+ data = b->base + b->current;
+ lwres_buffer_forward(b, datalen);
+
+ if (len != NULL)
+ *len = datalen;
+ if (p != NULL)
+ *p = data;
+
+ return (LWRES_R_SUCCESS);
+}
+
+/*
+ * Requires:
+ *
+ * The "current" pointer in "b" point to an encoded string.
+ *
+ * Ensures:
+ *
+ * The address of the first byte of the string is returned via "c",
+ * and the length is returned via "len". If NULL, they are not
+ * set.
+ *
+ * On return, the current pointer of "b" will point to the character
+ * following the string length, the string, and the trailing NULL.
+ *
+ */
+lwres_result_t
+lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len)
+{
+ lwres_uint16_t datalen;
+ char *string;
+
+ REQUIRE(b != NULL);
+
+ /*
+ * Pull off the length (2 bytes)
+ */
+ if (!SPACE_REMAINING(b, 2))
+ return (LWRES_R_UNEXPECTEDEND);
+ datalen = lwres_buffer_getuint16(b);
+
+ /*
+ * Set the pointer to this string to the right place, then
+ * advance the buffer pointer.
+ */
+ if (!SPACE_REMAINING(b, datalen))
+ return (LWRES_R_UNEXPECTEDEND);
+ string = (char *)b->base + b->current;
+ lwres_buffer_forward(b, datalen);
+
+ /*
+ * Skip the "must be zero" byte.
+ */
+ if (!SPACE_REMAINING(b, 1))
+ return (LWRES_R_UNEXPECTEDEND);
+ if (0 != lwres_buffer_getuint8(b))
+ return (LWRES_R_FAILURE);
+
+ if (len != NULL)
+ *len = datalen;
+ if (c != NULL)
+ *c = string;
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr)
+{
+ REQUIRE(addr != NULL);
+
+ if (!SPACE_REMAINING(b, 6))
+ return (LWRES_R_UNEXPECTEDEND);
+
+ addr->family = lwres_buffer_getuint32(b);
+ addr->length = lwres_buffer_getuint16(b);
+
+ if (!SPACE_REMAINING(b, addr->length))
+ return (LWRES_R_UNEXPECTEDEND);
+ if (addr->length > LWRES_ADDR_MAXLEN)
+ return (LWRES_R_FAILURE);
+
+ lwres_buffer_getmem(b, addr->address, addr->length);
+
+ return (LWRES_R_SUCCESS);
+}
+
+lwres_result_t
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
+ lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp)
+{
+ lwres_gabnrequest_t request;
+ lwres_gabnresponse_t *response;
+ int ret;
+ int recvlen;
+ lwres_buffer_t b_in, b_out;
+ lwres_lwpacket_t pkt;
+ lwres_uint32_t serial;
+ char *buffer;
+ char target_name[1024];
+ unsigned int target_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(addrtypes != 0);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ b_in.base = NULL;
+ b_out.base = NULL;
+ response = NULL;
+ buffer = NULL;
+ serial = lwres_context_nextserial(ctx);
+
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ target_length = strlen(name);
+ if (target_length >= sizeof(target_name))
+ return (LWRES_R_FAILURE);
+ strcpy(target_name, name); /* strcpy is safe */
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.flags = 0;
+ request.addrtypes = addrtypes;
+ request.name = target_name;
+ request.namelen = target_length;
+ pkt.pktflags = 0;
+ pkt.serial = serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ again:
+ ret = lwres_gabnrequest_render(ctx, &request, &pkt, &b_out);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer,
+ LWRES_RECVLENGTH, &recvlen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Sanity check.
+ */
+ if (pkt.serial != serial)
+ goto again;
+ if (pkt.opcode != LWRES_OPCODE_GETADDRSBYNAME)
+ goto again;
+
+ /*
+ * Free what we've transmitted
+ */
+ CTXFREE(b_out.base, b_out.length);
+ b_out.base = NULL;
+ b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_gabnresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ *structp = response;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (b_out.base != NULL)
+ CTXFREE(b_out.base, b_out.length);
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_gabnresponse_free(ctx, &response);
+
+ return (ret);
+}
+
+
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype,
+ lwres_uint16_t addrlen, const unsigned char *addr,
+ lwres_gnbaresponse_t **structp)
+{
+ lwres_gnbarequest_t request;
+ lwres_gnbaresponse_t *response;
+ int ret;
+ int recvlen;
+ lwres_buffer_t b_in, b_out;
+ lwres_lwpacket_t pkt;
+ lwres_uint32_t serial;
+ char *buffer;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(addrtype != 0);
+ REQUIRE(addrlen != 0);
+ REQUIRE(addr != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ b_in.base = NULL;
+ b_out.base = NULL;
+ response = NULL;
+ buffer = NULL;
+ serial = lwres_context_nextserial(ctx);
+
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.flags = 0;
+ request.addr.family = addrtype;
+ request.addr.length = addrlen;
+ memcpy(request.addr.address, addr, addrlen);
+ pkt.pktflags = 0;
+ pkt.serial = serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ again:
+ ret = lwres_gnbarequest_render(ctx, &request, &pkt, &b_out);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer,
+ LWRES_RECVLENGTH, &recvlen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Sanity check.
+ */
+ if (pkt.serial != serial)
+ goto again;
+ if (pkt.opcode != LWRES_OPCODE_GETNAMEBYADDR)
+ goto again;
+
+ /*
+ * Free what we've transmitted
+ */
+ CTXFREE(b_out.base, b_out.length);
+ b_out.base = NULL;
+ b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_gnbaresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ *structp = response;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (b_out.base != NULL)
+ CTXFREE(b_out.base, b_out.length);
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_gnbaresponse_free(ctx, &response);
+
+ return (ret);
+}
+
+lwres_result_t
+lwres_getrdatabyname(lwres_context_t *ctx, const char *name,
+ lwres_uint16_t rdclass, lwres_uint16_t rdtype,
+ lwres_uint32_t flags, lwres_grbnresponse_t **structp)
+{
+ int ret;
+ int recvlen;
+ lwres_buffer_t b_in, b_out;
+ lwres_lwpacket_t pkt;
+ lwres_uint32_t serial;
+ char *buffer;
+ lwres_grbnrequest_t request;
+ lwres_grbnresponse_t *response;
+ char target_name[1024];
+ unsigned int target_length;
+
+ REQUIRE(ctx != NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(structp != NULL && *structp == NULL);
+
+ b_in.base = NULL;
+ b_out.base = NULL;
+ response = NULL;
+ buffer = NULL;
+ serial = lwres_context_nextserial(ctx);
+
+ buffer = CTXMALLOC(LWRES_RECVLENGTH);
+ if (buffer == NULL) {
+ ret = LWRES_R_NOMEMORY;
+ goto out;
+ }
+
+ target_length = strlen(name);
+ if (target_length >= sizeof(target_name))
+ return (LWRES_R_FAILURE);
+ strcpy(target_name, name); /* strcpy is safe */
+
+ /*
+ * Set up our request and render it to a buffer.
+ */
+ request.rdclass = rdclass;
+ request.rdtype = rdtype;
+ request.flags = flags;
+ request.name = target_name;
+ request.namelen = target_length;
+ pkt.pktflags = 0;
+ pkt.serial = serial;
+ pkt.result = 0;
+ pkt.recvlength = LWRES_RECVLENGTH;
+
+ again:
+ ret = lwres_grbnrequest_render(ctx, &request, &pkt, &b_out);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ ret = lwres_context_sendrecv(ctx, b_out.base, b_out.length, buffer,
+ LWRES_RECVLENGTH, &recvlen);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ lwres_buffer_init(&b_in, buffer, recvlen);
+ b_in.used = recvlen;
+
+ /*
+ * Parse the packet header.
+ */
+ ret = lwres_lwpacket_parseheader(&b_in, &pkt);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+
+ /*
+ * Sanity check.
+ */
+ if (pkt.serial != serial)
+ goto again;
+ if (pkt.opcode != LWRES_OPCODE_GETRDATABYNAME)
+ goto again;
+
+ /*
+ * Free what we've transmitted
+ */
+ CTXFREE(b_out.base, b_out.length);
+ b_out.base = NULL;
+ b_out.length = 0;
+
+ if (pkt.result != LWRES_R_SUCCESS) {
+ ret = pkt.result;
+ goto out;
+ }
+
+ /*
+ * Parse the response.
+ */
+ ret = lwres_grbnresponse_parse(ctx, &b_in, &pkt, &response);
+ if (ret != LWRES_R_SUCCESS)
+ goto out;
+ response->base = buffer;
+ response->baselen = LWRES_RECVLENGTH;
+ buffer = NULL; /* don't free this below */
+
+ *structp = response;
+ return (LWRES_R_SUCCESS);
+
+ out:
+ if (b_out.base != NULL)
+ CTXFREE(b_out.base, b_out.length);
+ if (buffer != NULL)
+ CTXFREE(buffer, LWRES_RECVLENGTH);
+ if (response != NULL)
+ lwres_grbnresponse_free(ctx, &response);
+
+ return (ret);
+}
diff --git a/src/libfreeswan/liblwres/man/Makefile.in b/src/libfreeswan/liblwres/man/Makefile.in
new file mode 100644
index 000000000..d06f370ad
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/Makefile.in
@@ -0,0 +1,232 @@
+# Copyright (C) 2001 Internet Software Consortium.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: Makefile.in,v 1.1 2004/03/15 20:35:25 as Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@BIND9_MAKE_RULES@
+
+# Alphabetically
+#MANPAGES = lwres.3 lwres_addr_parse.3 lwres_buffer.3 \
+# lwres_buffer_add.3 lwres_buffer_back.3 lwres_buffer_clear.3 \
+# lwres_buffer_first.3 lwres_buffer_forward.3 \
+# lwres_buffer_getmem.3 lwres_buffer_getuint16.3 \
+# lwres_buffer_getuint32.3 lwres_buffer_getuint8.3 \
+# lwres_buffer_init.3 lwres_buffer_invalidate.3 \
+# lwres_buffer_putmem.3 lwres_buffer_putuint16.3 \
+# lwres_buffer_putuint32.3 lwres_buffer_putuint8.3 \
+# lwres_buffer_subtract.3 lwres_conf_clear.3 \
+# lwres_conf_get.3 lwres_conf_init.3 \
+# lwres_conf_parse.3 lwres_conf_print.3 \
+# lwres_config.3 lwres_context.3 \
+# lwres_context_allocmem.3 lwres_context_create.3 \
+# lwres_context_destroy.3 lwres_context_freemem.3 \
+# lwres_context_initserial.3 lwres_context_nextserial.3 \
+# lwres_context_sendrecv.3 lwres_endhostent.3 \
+# lwres_endhostent_r.3 lwres_freeaddrinfo.3 \
+# lwres_freehostent.3 lwres_gabn.3 \
+# lwres_gabnrequest_free.3 lwres_gabnrequest_parse.3 \
+# lwres_gabnrequest_render.3 lwres_gabnresponse_free.3 \
+# lwres_gabnresponse_parse.3 lwres_gabnresponse_render.3 \
+# lwres_gai_strerror.3 lwres_getaddrinfo.3 \
+# lwres_getaddrsbyname.3 lwres_gethostbyaddr.3 \
+# lwres_gethostbyaddr_r.3 lwres_gethostbyname.3 \
+# lwres_gethostbyname2.3 lwres_gethostbyname_r.3 \
+# lwres_gethostent.3 lwres_gethostent_r.3 \
+# lwres_getipnode.3 lwres_getipnodebyaddr.3 \
+# lwres_getipnodebyname.3 lwres_getnamebyaddr.3 \
+# lwres_getnameinfo.3 lwres_getrrsetbyname.3 \
+# lwres_gnba.3 lwres_gnbarequest_free.3 \
+# lwres_gnbarequest_parse.3 lwres_gnbarequest_render.3 \
+# lwres_gnbaresponse_free.3 lwres_gnbaresponse_parse.3 \
+# lwres_gnbaresponse_render.3 lwres_herror.3 \
+# lwres_hstrerror.3 lwres_inetntop.3 \
+# lwres_lwpacket_parseheader.3 lwres_lwpacket_renderheader.3 \
+# lwres_net_ntop.3 lwres_noop.3 \
+# lwres_nooprequest_free.3 lwres_nooprequest_parse.3 \
+# lwres_nooprequest_render.3 lwres_noopresponse_free.3 \
+# lwres_noopresponse_parse.3 lwres_noopresponse_render.3 \
+# lwres_packet.3 lwres_resutil.3 \
+# lwres_sethostent.3 lwres_sethostent_r.3 \
+# lwres_string_parse.3
+
+
+MANPAGES = lwres.3 lwres_buffer.3 lwres_config.3 lwres_context.3 \
+ lwres_gabn.3 lwres_gai_strerror.3 lwres_getaddrinfo.3 \
+ lwres_gethostent.3 lwres_getipnode.3 lwres_getnameinfo.3 \
+ lwres_getrrsetbyname.3 lwres_gnba.3 lwres_hstrerror.3 lwres_inetntop.3 \
+ lwres_noop.3 lwres_packet.3 lwres_resutil.3
+
+HTMLPAGES = lwres.html lwres_buffer.html lwres_config.html lwres_context.html \
+ lwres_gabn.html lwres_gai_strerror.html lwres_getaddrinfo.html \
+ lwres_gethostent.html lwres_getipnode.html lwres_getnameinfo.html \
+ lwres_getrrsetbyname.html lwres_gnba.html lwres_hstrerror.html lwres_inetntop.html \
+ lwres_noop.html lwres_packet.html lwres_resutil.html
+
+MANOBJS = ${MANPAGES} ${HTMLPAGES}
+
+doc man:: ${MANOBJS}
+
+docclean manclean maintainer-clean::
+ rm -f ${MANOBJS}
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man3
+
+man3 = ${DESTDIR}${mandir}/man3
+
+install:: installdirs
+ for m in ${MANPAGES}; do ${INSTALL_DATA} ${srcdir}/$$m ${DESTDIR}${mandir}/man3; done
+ rm -f ${man3}/lwres_addr_parse.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_addr_parse.3
+ rm -f ${man3}/lwres_buffer_add.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_add.3
+ rm -f ${man3}/lwres_buffer_back.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_back.3
+ rm -f ${man3}/lwres_buffer_clear.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_clear.3
+ rm -f ${man3}/lwres_buffer_first.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_first.3
+ rm -f ${man3}/lwres_buffer_forward.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_forward.3
+ rm -f ${man3}/lwres_buffer_getmem.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getmem.3
+ rm -f ${man3}/lwres_buffer_getuint16.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint16.3
+ rm -f ${man3}/lwres_buffer_getuint32.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint32.3
+ rm -f ${man3}/lwres_buffer_getuint8.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_getuint8.3
+ rm -f ${man3}/lwres_buffer_init.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_init.3
+ rm -f ${man3}/lwres_buffer_invalidate.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_invalidate.3
+ rm -f ${man3}/lwres_buffer_putmem.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putmem.3
+ rm -f ${man3}/lwres_buffer_putuint16.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint16.3
+ rm -f ${man3}/lwres_buffer_putuint32.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint32.3
+ rm -f ${man3}/lwres_buffer_putuint8.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_putuint8.3
+ rm -f ${man3}/lwres_buffer_subtract.3
+ @LN@ ${man3}/lwres_buffer.3 ${man3}/lwres_buffer_subtract.3
+ rm -f ${man3}/lwres_conf_clear.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_clear.3
+ rm -f ${man3}/lwres_conf_get.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_get.3
+ rm -f ${man3}/lwres_conf_init.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_init.3
+ rm -f ${man3}/lwres_conf_parse.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_parse.3
+ rm -f ${man3}/lwres_conf_print.3
+ @LN@ ${man3}/lwres_config.3 ${man3}/lwres_conf_print.3
+ rm -f ${man3}/lwres_context_allocmem.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_allocmem.3
+ rm -f ${man3}/lwres_context_create.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_create.3
+ rm -f ${man3}/lwres_context_destroy.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_destroy.3
+ rm -f ${man3}/lwres_context_freemem.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_freemem.3
+ rm -f ${man3}/lwres_context_initserial.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_initserial.3
+ rm -f ${man3}/lwres_context_nextserial.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_nextserial.3
+ rm -f ${man3}/lwres_context_sendrecv.3
+ @LN@ ${man3}/lwres_context.3 ${man3}/lwres_context_sendrecv.3
+ rm -f ${man3}/lwres_endhostent.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_endhostent.3
+ rm -f ${man3}/lwres_endhostent_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_endhostent_r.3
+ rm -f ${man3}/lwres_freeaddrinfo.3
+ @LN@ ${man3}/lwres_getaddrinfo.3 ${man3}/lwres_freeaddrinfo.3
+ rm -f ${man3}/lwres_freehostent.3
+ @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_freehostent.3
+ rm -f ${man3}/lwres_gabnrequest_free.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_free.3
+ rm -f ${man3}/lwres_gabnrequest_parse.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_parse.3
+ rm -f ${man3}/lwres_gabnrequest_render.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnrequest_render.3
+ rm -f ${man3}/lwres_gabnresponse_free.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_free.3
+ rm -f ${man3}/lwres_gabnresponse_parse.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_parse.3
+ rm -f ${man3}/lwres_gabnresponse_render.3
+ @LN@ ${man3}/lwres_gabn.3 ${man3}/lwres_gabnresponse_render.3
+ rm -f ${man3}/lwres_getaddrsbyname.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_getaddrsbyname.3
+ rm -f ${man3}/lwres_gethostbyaddr.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyaddr.3
+ rm -f ${man3}/lwres_gethostbyaddr_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyaddr_r.3
+ rm -f ${man3}/lwres_gethostbyname.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname.3
+ rm -f ${man3}/lwres_gethostbyname2.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname2.3
+ rm -f ${man3}/lwres_gethostbyname_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostbyname_r.3
+ rm -f ${man3}/lwres_gethostent_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_gethostent_r.3
+ rm -f ${man3}/lwres_getipnodebyaddr.3
+ @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_getipnodebyaddr.3
+ rm -f ${man3}/lwres_getipnodebyname.3
+ @LN@ ${man3}/lwres_getipnode.3 ${man3}/lwres_getipnodebyname.3
+ rm -f ${man3}/lwres_getnamebyaddr.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_getnamebyaddr.3
+ rm -f ${man3}/lwres_gnbarequest_free.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_free.3
+ rm -f ${man3}/lwres_gnbarequest_parse.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_parse.3
+ rm -f ${man3}/lwres_gnbarequest_render.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbarequest_render.3
+ rm -f ${man3}/lwres_gnbaresponse_free.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_free.3
+ rm -f ${man3}/lwres_gnbaresponse_parse.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_parse.3
+ rm -f ${man3}/lwres_gnbaresponse_render.3
+ @LN@ ${man3}/lwres_gnba.3 ${man3}/lwres_gnbaresponse_render.3
+ rm -f ${man3}/lwres_herror.3
+ @LN@ ${man3}/lwres_hstrerror.3 ${man3}/lwres_herror.3
+ rm -f ${man3}/lwres_lwpacket_parseheader.3
+ @LN@ ${man3}/lwres_packet.3 ${man3}/lwres_lwpacket_parseheader.3
+ rm -f ${man3}/lwres_lwpacket_renderheader.3
+ @LN@ ${man3}/lwres_packet.3 ${man3}/lwres_lwpacket_renderheader.3
+ rm -f ${man3}/lwres_net_ntop.3
+ @LN@ ${man3}/lwres_inetntop.3 ${man3}/lwres_net_ntop.3
+ rm -f ${man3}/lwres_nooprequest_free.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_free.3
+ rm -f ${man3}/lwres_nooprequest_parse.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_parse.3
+ rm -f ${man3}/lwres_nooprequest_render.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_nooprequest_render.3
+ rm -f ${man3}/lwres_noopresponse_free.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_free.3
+ rm -f ${man3}/lwres_noopresponse_parse.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_parse.3
+ rm -f ${man3}/lwres_noopresponse_render.3
+ @LN@ ${man3}/lwres_noop.3 ${man3}/lwres_noopresponse_render.3
+ rm -f ${man3}/lwres_sethostent.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_sethostent.3
+ rm -f ${man3}/lwres_sethostent_r.3
+ @LN@ ${man3}/lwres_gethostent.3 ${man3}/lwres_sethostent_r.3
+ rm -f ${man3}/lwres_string_parse.3
+ @LN@ ${man3}/lwres_resutil.3 ${man3}/lwres_string_parse.3
diff --git a/src/libfreeswan/liblwres/man/lwres.3 b/src/libfreeswan/liblwres/man/lwres.3
new file mode 100644
index 000000000..f2393912d
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres.3
@@ -0,0 +1,158 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres \- introduction to the lightweight resolver library
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>\fR
+.SH "DESCRIPTION"
+.PP
+The BIND 9 lightweight resolver library is a simple, name service
+independent stub resolver library. It provides hostname-to-address
+and address-to-hostname lookup services to applications by
+transmitting lookup requests to a resolver daemon
+\fBlwresd\fR
+running on the local host. The resover daemon performs the
+lookup using the DNS or possibly other name service protocols,
+and returns the results to the application through the library.
+The library and resolver daemon communicate using a simple
+UDP-based protocol.
+.SH "OVERVIEW"
+.PP
+The lwresd library implements multiple name service APIs.
+The standard
+\fBgethostbyname()\fR,
+\fBgethostbyaddr()\fR,
+\fBgethostbyname_r()\fR,
+\fBgethostbyaddr_r()\fR,
+\fBgetaddrinfo()\fR,
+\fBgetipnodebyname()\fR,
+and
+\fBgetipnodebyaddr()\fR
+functions are all supported. To allow the lwres library to coexist
+with system libraries that define functions of the same name,
+the library defines these functions with names prefixed by
+lwres_.
+To define the standard names, applications must include the
+header file
+\fI<lwres/netdb.h>\fR
+which contains macro definitions mapping the standard function names
+into
+lwres_
+prefixed ones. Operating system vendors who integrate the lwres
+library into their base distributions should rename the functions
+in the library proper so that the renaming macros are not needed.
+.PP
+The library also provides a native API consisting of the functions
+\fBlwres_getaddrsbyname()\fR
+and
+\fBlwres_getnamebyaddr()\fR.
+These may be called by applications that require more detailed
+control over the lookup process than the standard functions
+provide.
+.PP
+In addition to these name service independent address lookup
+functions, the library implements a new, experimental API
+for looking up arbitrary DNS resource records, using the
+\fBlwres_getaddrsbyname()\fR
+function.
+.PP
+Finally, there is a low-level API for converting lookup
+requests and responses to and from raw lwres protocol packets.
+This API can be used by clients requiring nonblocking operation,
+and is also used when implementing the server side of the lwres
+protocol, for example in the
+\fBlwresd\fR
+resolver daemon. The use of this low-level API in clients
+and servers is outlined in the following sections.
+.SH "CLIENT-SIDE LOW-LEVEL API CALL FLOW"
+.PP
+When a client program wishes to make an lwres request using the
+native low-level API, it typically performs the following
+sequence of actions.
+.PP
+(1) Allocate or use an existing \fBlwres_packet_t\fR,
+called pkt below.
+.PP
+(2) Set \fBpkt.recvlength\fR to the maximum length we will accept.
+This is done so the receiver of our packets knows how large our receive
+buffer is. The "default" is a constant in
+\fIlwres.h\fR: LWRES_RECVLENGTH = 4096.
+.PP
+(3) Set \fBpkt.serial\fR
+to a unique serial number. This value is echoed
+back to the application by the remote server.
+.PP
+(4) Set \fBpkt.pktflags\fR. Usually this is set to 0.
+.PP
+(5) Set \fBpkt.result\fR to 0.
+.PP
+(6) Call \fBlwres_*request_render()\fR,
+or marshall in the data using the primitives
+such as \fBlwres_packet_render()\fR
+and storing the packet data.
+.PP
+(7) Transmit the resulting buffer.
+.PP
+(8) Call \fBlwres_*response_parse()\fR
+to parse any packets received.
+.PP
+(9) Verify that the opcode and serial match a request, and process the
+packet specific information contained in the body.
+.SH "SERVER-SIDE LOW-LEVEL API CALL FLOW"
+.PP
+When implementing the server side of the lightweight resolver
+protocol using the lwres library, a sequence of actions like the
+following is typically involved in processing each request packet.
+.PP
+Note that the same \fBlwres_packet_t\fR is used
+in both the \fB_parse()\fR and \fB_render()\fR calls,
+with only a few modifications made
+to the packet header's contents between uses. This method is recommended
+as it keeps the serial, opcode, and other fields correct.
+.PP
+(1) When a packet is received, call \fBlwres_*request_parse()\fR to
+unmarshall it. This returns a \fBlwres_packet_t\fR (also called pkt, below)
+as well as a data specific type, such as \fBlwres_gabnrequest_t\fR.
+.PP
+(2) Process the request in the data specific type.
+.PP
+(3) Set the \fBpkt.result\fR,
+\fBpkt.recvlength\fR as above. All other fields can
+be left untouched since they were filled in by the \fB*_parse()\fR call
+above. If using \fBlwres_*response_render()\fR,
+\fBpkt.pktflags\fR will be set up
+properly. Otherwise, the LWRES_LWPACKETFLAG_RESPONSE bit should be
+set.
+.PP
+(4) Call the data specific rendering function, such as
+\fBlwres_gabnresponse_render()\fR.
+.PP
+(5) Send the resulting packet to the client.
+.PP
+.SH "SEE ALSO"
+.PP
+\fBlwres_gethostent\fR(3),
+\fBlwres_getipnode\fR(3),
+\fBlwres_getnameinfo\fR(3),
+\fBlwres_noop\fR(3),
+\fBlwres_gabn\fR(3),
+\fBlwres_gnba\fR(3),
+\fBlwres_context\fR(3),
+\fBlwres_config\fR(3),
+\fBresolver\fR(5),
+\fBlwresd\fR(8).
diff --git a/src/libfreeswan/liblwres/man/lwres.docbook b/src/libfreeswan/liblwres/man/lwres.docbook
new file mode 100644
index 000000000..15378e908
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres.docbook
@@ -0,0 +1,244 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres</refname>
+<refpurpose>introduction to the lightweight resolver library</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+The BIND 9 lightweight resolver library is a simple, name service
+independent stub resolver library. It provides hostname-to-address
+and address-to-hostname lookup services to applications by
+transmitting lookup requests to a resolver daemon
+<command>lwresd</command>
+running on the local host. The resover daemon performs the
+lookup using the DNS or possibly other name service protocols,
+and returns the results to the application through the library.
+The library and resolver daemon communicate using a simple
+UDP-based protocol.
+</para>
+</refsect1>
+
+<refsect1>
+<title>OVERVIEW</title>
+<para>
+The lwresd library implements multiple name service APIs.
+The standard
+<function>gethostbyname()</function>,
+<function>gethostbyaddr()</function>,
+<function>gethostbyname_r()</function>,
+<function>gethostbyaddr_r()</function>,
+<function>getaddrinfo()</function>,
+<function>getipnodebyname()</function>,
+and
+<function>getipnodebyaddr()</function>
+functions are all supported. To allow the lwres library to coexist
+with system libraries that define functions of the same name,
+the library defines these functions with names prefixed by
+<literal>lwres_</literal>.
+To define the standard names, applications must include the
+header file
+<filename>&lt;lwres/netdb.h&gt;</filename>
+which contains macro definitions mapping the standard function names
+into
+<literal>lwres_</literal>
+prefixed ones. Operating system vendors who integrate the lwres
+library into their base distributions should rename the functions
+in the library proper so that the renaming macros are not needed.
+</para>
+<para>
+The library also provides a native API consisting of the functions
+<function>lwres_getaddrsbyname()</function>
+and
+<function>lwres_getnamebyaddr()</function>.
+These may be called by applications that require more detailed
+control over the lookup process than the standard functions
+provide.
+</para>
+<para>
+In addition to these name service independent address lookup
+functions, the library implements a new, experimental API
+for looking up arbitrary DNS resource records, using the
+<function>lwres_getaddrsbyname()</function>
+function.
+</para>
+<para>
+Finally, there is a low-level API for converting lookup
+requests and responses to and from raw lwres protocol packets.
+This API can be used by clients requiring nonblocking operation,
+and is also used when implementing the server side of the lwres
+protocol, for example in the
+<command>lwresd</command>
+resolver daemon. The use of this low-level API in clients
+and servers is outlined in the following sections.
+</para>
+</refsect1>
+<refsect1>
+<title>CLIENT-SIDE LOW-LEVEL API CALL FLOW</title>
+<para>
+When a client program wishes to make an lwres request using the
+native low-level API, it typically performs the following
+sequence of actions.
+</para>
+<para>
+(1) Allocate or use an existing <type>lwres_packet_t</type>,
+called <varname>pkt</varname> below.
+</para>
+<para>
+(2) Set <structfield>pkt.recvlength</structfield> to the maximum length we will accept.
+This is done so the receiver of our packets knows how large our receive
+buffer is. The "default" is a constant in
+<filename>lwres.h</filename>: <constant>LWRES_RECVLENGTH = 4096</constant>.
+</para>
+<para>
+(3) Set <structfield>pkt.serial</structfield>
+to a unique serial number. This value is echoed
+back to the application by the remote server.
+</para>
+<para>
+(4) Set <structfield>pkt.pktflags</structfield>. Usually this is set to 0.
+</para>
+<para>
+(5) Set <structfield>pkt.result</structfield> to 0.
+</para>
+<para>
+(6) Call <function>lwres_*request_render()</function>,
+or marshall in the data using the primitives
+such as <function>lwres_packet_render()</function>
+and storing the packet data.
+</para>
+<para>
+(7) Transmit the resulting buffer.
+</para>
+<para>
+(8) Call <function>lwres_*response_parse()</function>
+to parse any packets received.
+</para>
+<para>
+(9) Verify that the opcode and serial match a request, and process the
+packet specific information contained in the body.
+</para>
+</refsect1>
+<refsect1>
+<title>SERVER-SIDE LOW-LEVEL API CALL FLOW</title>
+<para>
+When implementing the server side of the lightweight resolver
+protocol using the lwres library, a sequence of actions like the
+following is typically involved in processing each request packet.
+</para>
+<para>
+Note that the same <type>lwres_packet_t</type> is used
+in both the <function>_parse()</function> and <function>_render()</function> calls,
+with only a few modifications made
+to the packet header's contents between uses. This method is recommended
+as it keeps the serial, opcode, and other fields correct.
+</para>
+<para>
+(1) When a packet is received, call <function>lwres_*request_parse()</function> to
+unmarshall it. This returns a <type>lwres_packet_t</type> (also called <varname>pkt</varname>, below)
+as well as a data specific type, such as <type>lwres_gabnrequest_t</type>.
+</para>
+<para>
+(2) Process the request in the data specific type.
+</para>
+<para>
+(3) Set the <structfield>pkt.result</structfield>,
+<structfield>pkt.recvlength</structfield> as above. All other fields can
+be left untouched since they were filled in by the <function>*_parse()</function> call
+above. If using <function>lwres_*response_render()</function>,
+<structfield>pkt.pktflags</structfield> will be set up
+properly. Otherwise, the <constant>LWRES_LWPACKETFLAG_RESPONSE</constant> bit should be
+set.
+</para>
+<para>
+(4) Call the data specific rendering function, such as
+<function>lwres_gabnresponse_render()</function>.
+</para>
+<para>
+(5) Send the resulting packet to the client.
+</para>
+<para>
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_gethostent</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getipnode</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_noop</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gabn</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gnba</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_context</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_config</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>resolver</refentrytitle><manvolnum>5</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwresd</refentrytitle><manvolnum>8</manvolnum>
+</citerefentry>.
+
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres.html b/src/libfreeswan/liblwres/man/lwres.html
new file mode 100644
index 000000000..7b9f88dcb
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres.html
@@ -0,0 +1,444 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres&nbsp;--&nbsp;introduction to the lightweight resolver library</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN14"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>The BIND 9 lightweight resolver library is a simple, name service
+independent stub resolver library. It provides hostname-to-address
+and address-to-hostname lookup services to applications by
+transmitting lookup requests to a resolver daemon
+<B
+CLASS="COMMAND"
+>lwresd</B
+>
+running on the local host. The resover daemon performs the
+lookup using the DNS or possibly other name service protocols,
+and returns the results to the application through the library.
+The library and resolver daemon communicate using a simple
+UDP-based protocol.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN18"
+></A
+><H2
+>OVERVIEW</H2
+><P
+>The lwresd library implements multiple name service APIs.
+The standard
+<TT
+CLASS="FUNCTION"
+>gethostbyname()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>gethostbyaddr()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>gethostbyname_r()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>gethostbyaddr_r()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>getaddrinfo()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>getipnodebyname()</TT
+>,
+and
+<TT
+CLASS="FUNCTION"
+>getipnodebyaddr()</TT
+>
+functions are all supported. To allow the lwres library to coexist
+with system libraries that define functions of the same name,
+the library defines these functions with names prefixed by
+<TT
+CLASS="LITERAL"
+>lwres_</TT
+>.
+To define the standard names, applications must include the
+header file
+<TT
+CLASS="FILENAME"
+>&lt;lwres/netdb.h&gt;</TT
+>
+which contains macro definitions mapping the standard function names
+into
+<TT
+CLASS="LITERAL"
+>lwres_</TT
+>
+prefixed ones. Operating system vendors who integrate the lwres
+library into their base distributions should rename the functions
+in the library proper so that the renaming macros are not needed.</P
+><P
+>The library also provides a native API consisting of the functions
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>.
+These may be called by applications that require more detailed
+control over the lookup process than the standard functions
+provide.</P
+><P
+>In addition to these name service independent address lookup
+functions, the library implements a new, experimental API
+for looking up arbitrary DNS resource records, using the
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+function.</P
+><P
+>Finally, there is a low-level API for converting lookup
+requests and responses to and from raw lwres protocol packets.
+This API can be used by clients requiring nonblocking operation,
+and is also used when implementing the server side of the lwres
+protocol, for example in the
+<B
+CLASS="COMMAND"
+>lwresd</B
+>
+resolver daemon. The use of this low-level API in clients
+and servers is outlined in the following sections.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN38"
+></A
+><H2
+>CLIENT-SIDE LOW-LEVEL API CALL FLOW</H2
+><P
+>When a client program wishes to make an lwres request using the
+native low-level API, it typically performs the following
+sequence of actions.</P
+><P
+>(1) Allocate or use an existing <SPAN
+CLASS="TYPE"
+>lwres_packet_t</SPAN
+>,
+called <TT
+CLASS="VARNAME"
+>pkt</TT
+> below.</P
+><P
+>(2) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.recvlength</I
+></TT
+> to the maximum length we will accept.
+This is done so the receiver of our packets knows how large our receive
+buffer is. The "default" is a constant in
+<TT
+CLASS="FILENAME"
+>lwres.h</TT
+>: <TT
+CLASS="CONSTANT"
+>LWRES_RECVLENGTH = 4096</TT
+>.</P
+><P
+>(3) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.serial</I
+></TT
+>
+to a unique serial number. This value is echoed
+back to the application by the remote server.</P
+><P
+>(4) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.pktflags</I
+></TT
+>. Usually this is set to 0.</P
+><P
+>(5) Set <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.result</I
+></TT
+> to 0.</P
+><P
+>(6) Call <TT
+CLASS="FUNCTION"
+>lwres_*request_render()</TT
+>,
+or marshall in the data using the primitives
+such as <TT
+CLASS="FUNCTION"
+>lwres_packet_render()</TT
+>
+and storing the packet data.</P
+><P
+>(7) Transmit the resulting buffer.</P
+><P
+>(8) Call <TT
+CLASS="FUNCTION"
+>lwres_*response_parse()</TT
+>
+to parse any packets received.</P
+><P
+>(9) Verify that the opcode and serial match a request, and process the
+packet specific information contained in the body.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>SERVER-SIDE LOW-LEVEL API CALL FLOW</H2
+><P
+>When implementing the server side of the lightweight resolver
+protocol using the lwres library, a sequence of actions like the
+following is typically involved in processing each request packet.</P
+><P
+>Note that the same <SPAN
+CLASS="TYPE"
+>lwres_packet_t</SPAN
+> is used
+in both the <TT
+CLASS="FUNCTION"
+>_parse()</TT
+> and <TT
+CLASS="FUNCTION"
+>_render()</TT
+> calls,
+with only a few modifications made
+to the packet header's contents between uses. This method is recommended
+as it keeps the serial, opcode, and other fields correct.</P
+><P
+>(1) When a packet is received, call <TT
+CLASS="FUNCTION"
+>lwres_*request_parse()</TT
+> to
+unmarshall it. This returns a <SPAN
+CLASS="TYPE"
+>lwres_packet_t</SPAN
+> (also called <TT
+CLASS="VARNAME"
+>pkt</TT
+>, below)
+as well as a data specific type, such as <SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>.</P
+><P
+>(2) Process the request in the data specific type.</P
+><P
+>(3) Set the <TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.result</I
+></TT
+>,
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.recvlength</I
+></TT
+> as above. All other fields can
+be left untouched since they were filled in by the <TT
+CLASS="FUNCTION"
+>*_parse()</TT
+> call
+above. If using <TT
+CLASS="FUNCTION"
+>lwres_*response_render()</TT
+>,
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pkt.pktflags</I
+></TT
+> will be set up
+properly. Otherwise, the <TT
+CLASS="CONSTANT"
+>LWRES_LWPACKETFLAG_RESPONSE</TT
+> bit should be
+set.</P
+><P
+>(4) Call the data specific rendering function, such as
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_render()</TT
+>.</P
+><P
+>(5) Send the resulting packet to the client.</P
+><P
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN85"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gethostent</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getipnode</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnameinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_noop</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gabn</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gnba</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_context</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_config</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>resolver</SPAN
+>(5)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwresd</SPAN
+>(8)</SPAN
+>.&#13;</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_buffer.3 b/src/libfreeswan/liblwres/man/lwres_buffer.3
new file mode 100644
index 000000000..8077fc2ef
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_buffer.3
@@ -0,0 +1,277 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_BUFFER" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem \- lightweight resolver buffer management
+.SH SYNOPSIS
+\fB#include <lwres/lwbuffer.h>
+.sp
+.na
+void
+lwres_buffer_init(lwres_buffer_t *b, void *base, unsigned int length);
+.ad
+.sp
+.na
+void
+lwres_buffer_invalidate(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_add(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+void
+lwres_buffer_subtract(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+void
+lwres_buffer_clear(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_first(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_forward(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+void
+lwres_buffer_back(lwres_buffer_t *b, unsigned int n);
+.ad
+.sp
+.na
+lwres_uint8_t
+lwres_buffer_getuint8(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_putuint8(lwres_buffer_t *b, lwres_uint8_t val);
+.ad
+.sp
+.na
+lwres_uint16_t
+lwres_buffer_getuint16(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_putuint16(lwres_buffer_t *b, lwres_uint16_t val);
+.ad
+.sp
+.na
+lwres_uint32_t
+lwres_buffer_getuint32(lwres_buffer_t *b);
+.ad
+.sp
+.na
+void
+lwres_buffer_putuint32(lwres_buffer_t *b, lwres_uint32_t val);
+.ad
+.sp
+.na
+void
+lwres_buffer_putmem(lwres_buffer_t *b, const unsigned char *base, unsigned int length);
+.ad
+.sp
+.na
+void
+lwres_buffer_getmem(lwres_buffer_t *b, unsigned char *base, unsigned int length);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions provide bounds checked access to a region of memory
+where data is being read or written.
+They are based on, and similar to, the
+isc_buffer_
+functions in the ISC library.
+.PP
+A buffer is a region of memory, together with a set of related
+subregions.
+The \fBused region\fR and the
+\fBavailable\fR region are disjoint, and
+their union is the buffer's region.
+The used region extends from the beginning of the buffer region to the
+last used byte.
+The available region extends from one byte greater than the last used
+byte to the end of the buffer's region.
+The size of the used region can be changed using various
+buffer commands.
+Initially, the used region is empty.
+.PP
+The used region is further subdivided into two disjoint regions: the
+\fBconsumed region\fR and the \fBremaining region\fR.
+The union of these two regions is the used region.
+The consumed region extends from the beginning of the used region to
+the byte before the \fBcurrent\fR offset (if any).
+The \fBremaining\fR region the current pointer to the end of the used
+region.
+The size of the consumed region can be changed using various
+buffer commands.
+Initially, the consumed region is empty.
+.PP
+The \fBactive region\fR is an (optional) subregion of the remaining
+region.
+It extends from the current offset to an offset in the
+remaining region.
+Initially, the active region is empty.
+If the current offset advances beyond the chosen offset,
+the active region will also be empty.
+.PP
+.sp
+.nf
+
+ /------------entire length---------------\\\\
+ /----- used region -----\\\\/-- available --\\\\
+ +----------------------------------------+
+ | consumed | remaining | |
+ +----------------------------------------+
+ a b c d e
+
+ a == base of buffer.
+ b == current pointer. Can be anywhere between a and d.
+ c == active pointer. Meaningful between b and d.
+ d == used pointer.
+ e == length of buffer.
+
+ a-e == entire length of buffer.
+ a-d == used region.
+ a-b == consumed region.
+ b-d == remaining region.
+ b-c == optional active region.
+.sp
+.fi
+.PP
+\fBlwres_buffer_init()\fR
+initializes the
+\fBlwres_buffer_t\fR
+\fI*b\fR
+and assocates it with the memory region of size
+\fIlength\fR
+bytes starting at location
+\fIbase.\fR
+.PP
+\fBlwres_buffer_invalidate()\fR
+marks the buffer
+\fI*b\fR
+as invalid. Invalidating a buffer after use is not required,
+but makes it possible to catch its possible accidental use.
+.PP
+The functions
+\fBlwres_buffer_add()\fR
+and
+\fBlwres_buffer_subtract()\fR
+respectively increase and decrease the used space in
+buffer
+\fI*b\fR
+by
+\fIn\fR
+bytes.
+\fBlwres_buffer_add()\fR
+checks for buffer overflow and
+\fBlwres_buffer_subtract()\fR
+checks for underflow.
+These functions do not allocate or deallocate memory.
+They just change the value of
+\fBused\fR.
+.PP
+A buffer is re-initialised by
+\fBlwres_buffer_clear()\fR.
+The function sets
+\fBused\fR ,
+\fBcurrent\fR
+and
+\fBactive\fR
+to zero.
+.PP
+\fBlwres_buffer_first\fR
+makes the consumed region of buffer
+\fI*p\fR
+empty by setting
+\fBcurrent\fR
+to zero (the start of the buffer).
+.PP
+\fBlwres_buffer_forward()\fR
+increases the consumed region of buffer
+\fI*b\fR
+by
+\fIn\fR
+bytes, checking for overflow.
+Similarly,
+\fBlwres_buffer_back()\fR
+decreases buffer
+\fIb\fR's
+consumed region by
+\fIn\fR
+bytes and checks for underflow.
+.PP
+\fBlwres_buffer_getuint8()\fR
+reads an unsigned 8-bit integer from
+\fI*b\fR
+and returns it.
+\fBlwres_buffer_putuint8()\fR
+writes the unsigned 8-bit integer
+\fIval\fR
+to buffer
+\fI*b\fR.
+.PP
+\fBlwres_buffer_getuint16()\fR
+and
+\fBlwres_buffer_getuint32()\fR
+are identical to
+\fBlwres_buffer_putuint8()\fR
+except that they respectively read an unsigned 16-bit or 32-bit integer
+in network byte order from
+\fIb\fR.
+Similarly,
+\fBlwres_buffer_putuint16()\fR
+and
+\fBlwres_buffer_putuint32()\fR
+writes the unsigned 16-bit or 32-bit integer
+\fIval\fR
+to buffer
+\fIb\fR,
+in network byte order.
+.PP
+Arbitrary amounts of data are read or written from a lightweight
+resolver buffer with
+\fBlwres_buffer_getmem()\fR
+and
+\fBlwres_buffer_putmem()\fR
+respectively.
+\fBlwres_buffer_putmem()\fR
+copies
+\fIlength\fR
+bytes of memory at
+\fIbase\fR
+to
+\fIb\fR.
+Conversely,
+\fBlwres_buffer_getmem()\fR
+copies
+\fIlength\fR
+bytes of memory from
+\fIb\fR
+to
+\fIbase\fR.
diff --git a/src/libfreeswan/liblwres/man/lwres_buffer.docbook b/src/libfreeswan/liblwres/man/lwres_buffer.docbook
new file mode 100644
index 000000000..8f9d55889
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_buffer.docbook
@@ -0,0 +1,378 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_buffer.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_buffer</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_buffer_init</refname>
+<refname>lwres_buffer_invalidate</refname>
+<refname>lwres_buffer_add</refname>
+<refname>lwres_buffer_subtract</refname>
+<refname>lwres_buffer_clear</refname>
+<refname>lwres_buffer_first</refname>
+<refname>lwres_buffer_forward</refname>
+<refname>lwres_buffer_back</refname>
+<refname>lwres_buffer_getuint8</refname>
+<refname>lwres_buffer_putuint8</refname>
+<refname>lwres_buffer_getuint16</refname>
+<refname>lwres_buffer_putuint16</refname>
+<refname>lwres_buffer_getuint32</refname>
+<refname>lwres_buffer_putuint32</refname>
+<refname>lwres_buffer_putmem</refname>
+<refname>lwres_buffer_getmem</refname>
+<refpurpose>lightweight resolver buffer management</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+
+<funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;lwres/lwbuffer.h&gt;
+</funcsynopsisinfo>
+
+<funcprototype>
+
+<funcdef>
+void
+<function>lwres_buffer_init</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>void *base</paramdef>
+<paramdef>unsigned int length</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_invalidate</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_add</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_subtract</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_clear</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_first</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_forward</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+<funcprototype>
+
+<funcdef>
+void
+<function>lwres_buffer_back</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned int n</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_uint8_t
+<function>lwres_buffer_getuint8</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putuint8</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_uint8_t val</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_uint16_t
+<function>lwres_buffer_getuint16</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putuint16</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_uint16_t val</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_uint32_t
+<function>lwres_buffer_getuint32</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putuint32</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_uint32_t val</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_putmem</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>const unsigned char *base</paramdef>
+<paramdef>unsigned int length</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_buffer_getmem</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>unsigned char *base</paramdef>
+<paramdef>unsigned int length</paramdef>
+</funcprototype>
+
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+
+<title>DESCRIPTION</title>
+<para>
+These functions provide bounds checked access to a region of memory
+where data is being read or written.
+They are based on, and similar to, the
+<literal>isc_buffer_</literal>
+functions in the ISC library.
+</para>
+<para>
+A buffer is a region of memory, together with a set of related
+subregions.
+The <emphasis>used region</emphasis> and the
+<emphasis>available</emphasis> region are disjoint, and
+their union is the buffer's region.
+The used region extends from the beginning of the buffer region to the
+last used byte.
+The available region extends from one byte greater than the last used
+byte to the end of the buffer's region.
+The size of the used region can be changed using various
+buffer commands.
+Initially, the used region is empty.
+</para>
+<para>
+The used region is further subdivided into two disjoint regions: the
+<emphasis>consumed region</emphasis> and the <emphasis>remaining region</emphasis>.
+The union of these two regions is the used region.
+The consumed region extends from the beginning of the used region to
+the byte before the <emphasis>current</emphasis> offset (if any).
+The <emphasis>remaining</emphasis> region the current pointer to the end of the used
+region.
+The size of the consumed region can be changed using various
+buffer commands.
+Initially, the consumed region is empty.
+</para>
+<para>
+The <emphasis>active region</emphasis> is an (optional) subregion of the remaining
+region.
+It extends from the current offset to an offset in the
+remaining region.
+Initially, the active region is empty.
+If the current offset advances beyond the chosen offset,
+the active region will also be empty.
+</para>
+<para>
+<programlisting>
+
+ /------------entire length---------------\\
+ /----- used region -----\\/-- available --\\
+ +----------------------------------------+
+ | consumed | remaining | |
+ +----------------------------------------+
+ a b c d e
+
+ a == base of buffer.
+ b == current pointer. Can be anywhere between a and d.
+ c == active pointer. Meaningful between b and d.
+ d == used pointer.
+ e == length of buffer.
+
+ a-e == entire length of buffer.
+ a-d == used region.
+ a-b == consumed region.
+ b-d == remaining region.
+ b-c == optional active region.
+</programlisting>
+</para>
+<para>
+<function>lwres_buffer_init()</function>
+initializes the
+<type>lwres_buffer_t</type>
+<parameter>*b</parameter>
+and assocates it with the memory region of size
+<parameter>length</parameter>
+bytes starting at location
+<parameter>base.</parameter>
+</para>
+<para>
+<function>lwres_buffer_invalidate()</function>
+marks the buffer
+<parameter>*b</parameter>
+as invalid. Invalidating a buffer after use is not required,
+but makes it possible to catch its possible accidental use.
+</para>
+<para>
+The functions
+<function>lwres_buffer_add()</function>
+and
+<function>lwres_buffer_subtract()</function>
+respectively increase and decrease the used space in
+buffer
+<parameter>*b</parameter>
+by
+<parameter>n</parameter>
+bytes.
+<function>lwres_buffer_add()</function>
+checks for buffer overflow and
+<function>lwres_buffer_subtract()</function>
+checks for underflow.
+These functions do not allocate or deallocate memory.
+They just change the value of
+<structfield>used</structfield>.
+</para>
+<para>
+A buffer is re-initialised by
+<function>lwres_buffer_clear()</function>.
+The function sets
+<structfield>used</structfield> ,
+<structfield>current</structfield>
+and
+<structfield>active</structfield>
+to zero.
+</para>
+<para>
+<function>lwres_buffer_first</function>
+makes the consumed region of buffer
+<parameter>*p</parameter>
+empty by setting
+<structfield>current</structfield>
+to zero (the start of the buffer).
+</para>
+<para>
+<function>lwres_buffer_forward()</function>
+increases the consumed region of buffer
+<parameter>*b</parameter>
+by
+<parameter>n</parameter>
+bytes, checking for overflow.
+Similarly,
+<function>lwres_buffer_back()</function>
+decreases buffer
+<parameter>b</parameter>'s
+consumed region by
+<parameter>n</parameter>
+bytes and checks for underflow.
+</para>
+<para>
+<function>lwres_buffer_getuint8()</function>
+reads an unsigned 8-bit integer from
+<parameter>*b</parameter>
+and returns it.
+<function>lwres_buffer_putuint8()</function>
+writes the unsigned 8-bit integer
+<parameter>val</parameter>
+to buffer
+<parameter>*b</parameter>.
+</para>
+<para>
+<function>lwres_buffer_getuint16()</function>
+and
+<function>lwres_buffer_getuint32()</function>
+are identical to
+<function>lwres_buffer_putuint8()</function>
+except that they respectively read an unsigned 16-bit or 32-bit integer
+in network byte order from
+<parameter>b</parameter>.
+Similarly,
+<function>lwres_buffer_putuint16()</function>
+and
+<function>lwres_buffer_putuint32()</function>
+writes the unsigned 16-bit or 32-bit integer
+<parameter>val</parameter>
+to buffer
+<parameter>b</parameter>,
+in network byte order.
+</para>
+<para>
+Arbitrary amounts of data are read or written from a lightweight
+resolver buffer with
+<function>lwres_buffer_getmem()</function>
+and
+<function>lwres_buffer_putmem()</function>
+respectively.
+<function>lwres_buffer_putmem()</function>
+copies
+<parameter>length</parameter>
+bytes of memory at
+<parameter>base</parameter>
+to
+<parameter>b</parameter>.
+Conversely,
+<function>lwres_buffer_getmem()</function>
+copies
+<parameter>length</parameter>
+bytes of memory from
+<parameter>b</parameter>
+to
+<parameter>base</parameter>.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_buffer.html b/src/libfreeswan/liblwres/man/lwres_buffer.html
new file mode 100644
index 000000000..ae2ffd50c
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_buffer.html
@@ -0,0 +1,608 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_buffer</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_buffer</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_buffer_init, lwres_buffer_invalidate, lwres_buffer_add, lwres_buffer_subtract, lwres_buffer_clear, lwres_buffer_first, lwres_buffer_forward, lwres_buffer_back, lwres_buffer_getuint8, lwres_buffer_putuint8, lwres_buffer_getuint16, lwres_buffer_putuint16, lwres_buffer_getuint32, lwres_buffer_putuint32, lwres_buffer_putmem, lwres_buffer_getmem&nbsp;--&nbsp;lightweight resolver buffer management</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN26"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN27"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwbuffer.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_init</CODE
+>(lwres_buffer_t *b, void *base, unsigned int length);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_invalidate</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_add</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_subtract</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_clear</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_first</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_forward</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_back</CODE
+>(lwres_buffer_t *b, unsigned int n);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint8_t
+lwres_buffer_getuint8</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putuint8</CODE
+>(lwres_buffer_t *b, lwres_uint8_t val);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint16_t
+lwres_buffer_getuint16</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putuint16</CODE
+>(lwres_buffer_t *b, lwres_uint16_t val);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint32_t
+lwres_buffer_getuint32</CODE
+>(lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putuint32</CODE
+>(lwres_buffer_t *b, lwres_uint32_t val);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_putmem</CODE
+>(lwres_buffer_t *b, const unsigned char *base, unsigned int length);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_buffer_getmem</CODE
+>(lwres_buffer_t *b, unsigned char *base, unsigned int length);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN106"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions provide bounds checked access to a region of memory
+where data is being read or written.
+They are based on, and similar to, the
+<TT
+CLASS="LITERAL"
+>isc_buffer_</TT
+>
+functions in the ISC library.</P
+><P
+>A buffer is a region of memory, together with a set of related
+subregions.
+The <I
+CLASS="EMPHASIS"
+>used region</I
+> and the
+<I
+CLASS="EMPHASIS"
+>available</I
+> region are disjoint, and
+their union is the buffer's region.
+The used region extends from the beginning of the buffer region to the
+last used byte.
+The available region extends from one byte greater than the last used
+byte to the end of the buffer's region.
+The size of the used region can be changed using various
+buffer commands.
+Initially, the used region is empty.</P
+><P
+>The used region is further subdivided into two disjoint regions: the
+<I
+CLASS="EMPHASIS"
+>consumed region</I
+> and the <I
+CLASS="EMPHASIS"
+>remaining region</I
+>.
+The union of these two regions is the used region.
+The consumed region extends from the beginning of the used region to
+the byte before the <I
+CLASS="EMPHASIS"
+>current</I
+> offset (if any).
+The <I
+CLASS="EMPHASIS"
+>remaining</I
+> region the current pointer to the end of the used
+region.
+The size of the consumed region can be changed using various
+buffer commands.
+Initially, the consumed region is empty.</P
+><P
+>The <I
+CLASS="EMPHASIS"
+>active region</I
+> is an (optional) subregion of the remaining
+region.
+It extends from the current offset to an offset in the
+remaining region.
+Initially, the active region is empty.
+If the current offset advances beyond the chosen offset,
+the active region will also be empty.</P
+><P
+><PRE
+CLASS="PROGRAMLISTING"
+>
+ /------------entire length---------------\\
+ /----- used region -----\\/-- available --\\
+ +----------------------------------------+
+ | consumed | remaining | |
+ +----------------------------------------+
+ a b c d e
+
+ a == base of buffer.
+ b == current pointer. Can be anywhere between a and d.
+ c == active pointer. Meaningful between b and d.
+ d == used pointer.
+ e == length of buffer.
+
+ a-e == entire length of buffer.
+ a-d == used region.
+ a-b == consumed region.
+ b-d == remaining region.
+ b-c == optional active region.</PRE
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_init()</TT
+>
+initializes the
+<SPAN
+CLASS="TYPE"
+>lwres_buffer_t</SPAN
+>
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+and assocates it with the memory region of size
+<TT
+CLASS="PARAMETER"
+><I
+>length</I
+></TT
+>
+bytes starting at location
+<TT
+CLASS="PARAMETER"
+><I
+>base.</I
+></TT
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_invalidate()</TT
+>
+marks the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+as invalid. Invalidating a buffer after use is not required,
+but makes it possible to catch its possible accidental use.</P
+><P
+>The functions
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_add()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_subtract()</TT
+>
+respectively increase and decrease the used space in
+buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+by
+<TT
+CLASS="PARAMETER"
+><I
+>n</I
+></TT
+>
+bytes.
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_add()</TT
+>
+checks for buffer overflow and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_subtract()</TT
+>
+checks for underflow.
+These functions do not allocate or deallocate memory.
+They just change the value of
+<TT
+CLASS="STRUCTFIELD"
+><I
+>used</I
+></TT
+>.</P
+><P
+>A buffer is re-initialised by
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_clear()</TT
+>.
+The function sets
+<TT
+CLASS="STRUCTFIELD"
+><I
+>used</I
+></TT
+> ,
+<TT
+CLASS="STRUCTFIELD"
+><I
+>current</I
+></TT
+>
+and
+<TT
+CLASS="STRUCTFIELD"
+><I
+>active</I
+></TT
+>
+to zero.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_first</TT
+>
+makes the consumed region of buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*p</I
+></TT
+>
+empty by setting
+<TT
+CLASS="STRUCTFIELD"
+><I
+>current</I
+></TT
+>
+to zero (the start of the buffer).</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_forward()</TT
+>
+increases the consumed region of buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+by
+<TT
+CLASS="PARAMETER"
+><I
+>n</I
+></TT
+>
+bytes, checking for overflow.
+Similarly,
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_back()</TT
+>
+decreases buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>'s
+consumed region by
+<TT
+CLASS="PARAMETER"
+><I
+>n</I
+></TT
+>
+bytes and checks for underflow.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_getuint8()</TT
+>
+reads an unsigned 8-bit integer from
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>
+and returns it.
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint8()</TT
+>
+writes the unsigned 8-bit integer
+<TT
+CLASS="PARAMETER"
+><I
+>val</I
+></TT
+>
+to buffer
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_buffer_getuint16()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_getuint32()</TT
+>
+are identical to
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint8()</TT
+>
+except that they respectively read an unsigned 16-bit or 32-bit integer
+in network byte order from
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>.
+Similarly,
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint16()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putuint32()</TT
+>
+writes the unsigned 16-bit or 32-bit integer
+<TT
+CLASS="PARAMETER"
+><I
+>val</I
+></TT
+>
+to buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>,
+in network byte order.</P
+><P
+>Arbitrary amounts of data are read or written from a lightweight
+resolver buffer with
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_getmem()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putmem()</TT
+>
+respectively.
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_putmem()</TT
+>
+copies
+<TT
+CLASS="PARAMETER"
+><I
+>length</I
+></TT
+>
+bytes of memory at
+<TT
+CLASS="PARAMETER"
+><I
+>base</I
+></TT
+>
+to
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>.
+Conversely,
+<TT
+CLASS="FUNCTION"
+>lwres_buffer_getmem()</TT
+>
+copies
+<TT
+CLASS="PARAMETER"
+><I
+>length</I
+></TT
+>
+bytes of memory from
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+to
+<TT
+CLASS="PARAMETER"
+><I
+>base</I
+></TT
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_config.3 b/src/libfreeswan/liblwres/man/lwres_config.3
new file mode 100644
index 000000000..9a93cc0e7
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_config.3
@@ -0,0 +1,105 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_CONFIG" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get \- lightweight resolver configuration
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+void
+lwres_conf_init(lwres_context_t *ctx);
+.ad
+.sp
+.na
+void
+lwres_conf_clear(lwres_context_t *ctx);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_conf_parse(lwres_context_t *ctx, const char *filename);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_conf_print(lwres_context_t *ctx, FILE *fp);
+.ad
+.sp
+.na
+lwres_conf_t *
+lwres_conf_get(lwres_context_t *ctx);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_conf_init()\fR
+creates an empty
+\fBlwres_conf_t\fR
+structure for lightweight resolver context
+\fIctx\fR.
+.PP
+\fBlwres_conf_clear()\fR
+frees up all the internal memory used by
+that
+\fBlwres_conf_t\fR
+structure in resolver context
+\fIctx\fR.
+.PP
+\fBlwres_conf_parse()\fR
+opens the file
+\fIfilename\fR
+and parses it to initialise the resolver context
+\fIctx\fR's
+\fBlwres_conf_t\fR
+structure.
+.PP
+\fBlwres_conf_print()\fR
+prints the
+\fBlwres_conf_t\fR
+structure for resolver context
+\fIctx\fR
+to the
+\fBFILE\fR
+\fIfp\fR.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_conf_parse()\fR
+returns
+LWRES_R_SUCCESS
+if it successfully read and parsed
+\fIfilename\fR.
+It returns
+LWRES_R_FAILURE
+if
+\fIfilename\fR
+could not be opened or contained incorrect
+resolver statements.
+.PP
+\fBlwres_conf_print()\fR
+returns
+LWRES_R_SUCCESS
+unless an error occurred when converting the network addresses to a
+numeric host address string.
+If this happens, the function returns
+LWRES_R_FAILURE.
+.SH "SEE ALSO"
+.PP
+\fBstdio\fR(3),
+\fBresolver\fR(5).
+.SH "FILES"
+.PP
+\fI/etc/resolv.conf\fR
diff --git a/src/libfreeswan/liblwres/man/lwres_config.docbook b/src/libfreeswan/liblwres/man/lwres_config.docbook
new file mode 100644
index 000000000..03ec6c211
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_config.docbook
@@ -0,0 +1,159 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_config.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_config</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_conf_init</refname>
+<refname>lwres_conf_clear</refname>
+<refname>lwres_conf_parse</refname>
+<refname>lwres_conf_print</refname>
+<refname>lwres_conf_get</refname>
+<refpurpose>lightweight resolver configuration</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_conf_init</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_conf_clear</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_conf_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>const char *filename</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_conf_print</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>FILE *fp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_conf_t *
+<function>lwres_conf_get</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_conf_init()</function>
+creates an empty
+<type>lwres_conf_t</type>
+structure for lightweight resolver context
+<parameter>ctx</parameter>.
+</para>
+<para>
+<function>lwres_conf_clear()</function>
+frees up all the internal memory used by
+that
+<type>lwres_conf_t</type>
+structure in resolver context
+<parameter>ctx</parameter>.
+</para>
+<para>
+<function>lwres_conf_parse()</function>
+opens the file
+<parameter>filename</parameter>
+and parses it to initialise the resolver context
+<parameter>ctx</parameter>'s
+<type>lwres_conf_t</type>
+structure.
+</para>
+<para>
+<function>lwres_conf_print()</function>
+prints the
+<type>lwres_conf_t</type>
+structure for resolver context
+<parameter>ctx</parameter>
+to the
+<type>FILE</type>
+<parameter>fp</parameter>.
+</para>
+</refsect1>
+<refsect1>
+
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_conf_parse()</function>
+returns
+<errorcode>LWRES_R_SUCCESS</errorcode>
+if it successfully read and parsed
+<parameter>filename</parameter>.
+It returns
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<parameter>filename</parameter>
+could not be opened or contained incorrect
+resolver statements.
+</para>
+<para>
+<function>lwres_conf_print()</function>
+returns
+<errorcode>LWRES_R_SUCCESS</errorcode>
+unless an error occurred when converting the network addresses to a
+numeric host address string.
+If this happens, the function returns
+<errorcode>LWRES_R_FAILURE</errorcode>.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>stdio</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>resolver</refentrytitle><manvolnum>5</manvolnum>
+</citerefentry>.
+</refsect1>
+<refsect1>
+<title>FILES</title>
+<para>
+<filename>/etc/resolv.conf</filename>
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_config.html b/src/libfreeswan/liblwres/man/lwres_config.html
new file mode 100644
index 000000000..67fbcdd88
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_config.html
@@ -0,0 +1,295 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_config</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_config</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_conf_init, lwres_conf_clear, lwres_conf_parse, lwres_conf_print, lwres_conf_get&nbsp;--&nbsp;lightweight resolver configuration</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN15"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN16"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_conf_init</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_conf_clear</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_conf_parse</CODE
+>(lwres_context_t *ctx, const char *filename);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_conf_print</CODE
+>(lwres_context_t *ctx, FILE *fp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_conf_t *
+lwres_conf_get</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN40"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_init()</TT
+>
+creates an empty
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure for lightweight resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_clear()</TT
+>
+frees up all the internal memory used by
+that
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure in resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_parse()</TT
+>
+opens the file
+<TT
+CLASS="PARAMETER"
+><I
+>filename</I
+></TT
+>
+and parses it to initialise the resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>'s
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_print()</TT
+>
+prints the
+<SPAN
+CLASS="TYPE"
+>lwres_conf_t</SPAN
+>
+structure for resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+to the
+<SPAN
+CLASS="TYPE"
+>FILE</SPAN
+>
+<TT
+CLASS="PARAMETER"
+><I
+>fp</I
+></TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_parse()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+if it successfully read and parsed
+<TT
+CLASS="PARAMETER"
+><I
+>filename</I
+></TT
+>.
+It returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="PARAMETER"
+><I
+>filename</I
+></TT
+>
+could not be opened or contained incorrect
+resolver statements.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_conf_print()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+unless an error occurred when converting the network addresses to a
+numeric host address string.
+If this happens, the function returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN73"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>stdio</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>resolver</SPAN
+>(5)</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN82"
+></A
+><H2
+>FILES</H2
+><P
+><TT
+CLASS="FILENAME"
+>/etc/resolv.conf</TT
+></P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_context.3 b/src/libfreeswan/liblwres/man/lwres_context.3
new file mode 100644
index 000000000..d55c14fef
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_context.3
@@ -0,0 +1,194 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_CONTEXT" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv \- lightweight resolver context management
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_context_create(lwres_context_t **contextp, void *arg, lwres_malloc_t malloc_function, lwres_free_t free_function);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_context_destroy(lwres_context_t **contextp);
+.ad
+.sp
+.na
+void
+lwres_context_initserial(lwres_context_t *ctx, lwres_uint32_t serial);
+.ad
+.sp
+.na
+lwres_uint32_t
+lwres_context_nextserial(lwres_context_t *ctx);
+.ad
+.sp
+.na
+void
+lwres_context_freemem(lwres_context_t *ctx, void *mem, size_t len);
+.ad
+.sp
+.na
+void
+lwres_context_allocmem(lwres_context_t *ctx, size_t len);
+.ad
+.sp
+.na
+void *
+lwres_context_sendrecv(lwres_context_t *ctx, void *sendbase, int sendlen, void *recvbase, int recvlen, int *recvd_len);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_context_create()\fR
+creates a
+\fBlwres_context_t\fR
+structure for use in lightweight resolver operations.
+It holds a socket and other data needed for communicating
+with a resolver daemon.
+The new
+\fBlwres_context_t\fR
+is returned throught
+\fIcontextp\fR,
+a pointer to a
+\fBlwres_context_t\fR
+pointer. This
+\fBlwres_context_t\fR
+pointer must initially be NULL, and is modified
+to point to the newly created
+\fBlwres_context_t\fR.
+.PP
+When the lightweight resolver needs to perform dynamic memory
+allocation, it will call
+\fImalloc_function\fR
+to allocate memory and
+\fIfree_function\fR
+to free it. If
+\fImalloc_function\fR
+and
+\fIfree_function\fR
+are NULL, memory is allocated using
+\&.Xr malloc 3
+and
+\fBfree\fR(3).
+It is not permitted to have a NULL
+\fImalloc_function\fR
+and a non-NULL
+\fIfree_function\fR
+or vice versa.
+\fIarg\fR
+is passed as the first parameter to the memory
+allocation functions.
+If
+\fImalloc_function\fR
+and
+\fIfree_function\fR
+are NULL,
+\fIarg\fR
+is unused and should be passed as NULL.
+.PP
+Once memory for the structure has been allocated,
+it is initialized using
+\fBlwres_conf_init\fR(3)
+and returned via
+\fI*contextp\fR.
+.PP
+\fBlwres_context_destroy()\fR
+destroys a
+\fBlwres_context_t\fR,
+closing its socket.
+\fIcontextp\fR
+is a pointer to a pointer to the context that is to be destroyed.
+The pointer will be set to NULL when the context has been destroyed.
+.PP
+The context holds a serial number that is used to identify resolver
+request packets and associate responses with the corresponding requests.
+This serial number is controlled using
+\fBlwres_context_initserial()\fR
+and
+\fBlwres_context_nextserial()\fR.
+\fBlwres_context_initserial()\fR
+sets the serial number for context
+\fI*ctx\fR
+to
+\fIserial\fR.
+\fBlwres_context_nextserial()\fR
+increments the serial number and returns the previous value.
+.PP
+Memory for a lightweight resolver context is allocated and freed using
+\fBlwres_context_allocmem()\fR
+and
+\fBlwres_context_freemem()\fR.
+These use whatever allocations were defined when the context was
+created with
+\fBlwres_context_create()\fR.
+\fBlwres_context_allocmem()\fR
+allocates
+\fIlen\fR
+bytes of memory and if successful returns a pointer to the allocated
+storage.
+\fBlwres_context_freemem()\fR
+frees
+\fIlen\fR
+bytes of space starting at location
+\fImem\fR.
+.PP
+\fBlwres_context_sendrecv()\fR
+performs I/O for the context
+\fIctx\fR.
+Data are read and written from the context's socket.
+It writes data from
+\fIsendbase\fR
+\(em typically a lightweight resolver query packet \(em
+and waits for a reply which is copied to the receive buffer at
+\fIrecvbase\fR.
+The number of bytes that were written to this receive buffer is
+returned in
+\fI*recvd_len\fR.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_context_create()\fR
+returns
+LWRES_R_NOMEMORY
+if memory for the
+\fBstruct lwres_context\fR
+could not be allocated,
+LWRES_R_SUCCESS
+otherwise.
+.PP
+Successful calls to the memory allocator
+\fBlwres_context_allocmem()\fR
+return a pointer to the start of the allocated space.
+It returns NULL if memory could not be allocated.
+.PP
+LWRES_R_SUCCESS
+is returned when
+\fBlwres_context_sendrecv()\fR
+completes successfully.
+LWRES_R_IOERROR
+is returned if an I/O error occurs and
+LWRES_R_TIMEOUT
+is returned if
+\fBlwres_context_sendrecv()\fR
+times out waiting for a response.
+.SH "SEE ALSO"
+.PP
+\fBlwres_conf_init\fR(3),
+\fBmalloc\fR(3),
+\fBfree\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_context.docbook b/src/libfreeswan/liblwres/man/lwres_context.docbook
new file mode 100644
index 000000000..9cdfa7525
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_context.docbook
@@ -0,0 +1,283 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_context.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_context</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres_context_create</refname>
+<refname>lwres_context_destroy</refname>
+<refname>lwres_context_nextserial</refname>
+<refname>lwres_context_initserial</refname>
+<refname>lwres_context_freemem</refname>
+<refname>lwres_context_allocmem</refname>
+<refname>lwres_context_sendrecv</refname>
+<refpurpose>lightweight resolver context management</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_context_create</function></funcdef>
+<paramdef>lwres_context_t **contextp</paramdef>
+<paramdef>void *arg</paramdef>
+<paramdef>lwres_malloc_t malloc_function</paramdef>
+<paramdef>lwres_free_t free_function</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_context_destroy</function></funcdef>
+<paramdef>lwres_context_t **contextp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_context_initserial</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_uint32_t serial</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_uint32_t
+<function>lwres_context_nextserial</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_context_freemem</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>void *mem</paramdef>
+<paramdef>size_t len</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_context_allocmem</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>size_t len</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void *
+<function>lwres_context_sendrecv</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>void *sendbase</paramdef>
+<paramdef>int sendlen</paramdef>
+<paramdef>void *recvbase</paramdef>
+<paramdef>int recvlen</paramdef>
+<paramdef>int *recvd_len</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_context_create()</function>
+creates a
+<type>lwres_context_t</type>
+structure for use in lightweight resolver operations.
+It holds a socket and other data needed for communicating
+with a resolver daemon.
+The new
+<type>lwres_context_t</type>
+is returned throught
+<parameter>contextp</parameter>,
+
+a pointer to a
+<type>lwres_context_t</type>
+pointer. This
+<type>lwres_context_t</type>
+pointer must initially be NULL, and is modified
+to point to the newly created
+<type>lwres_context_t</type>.
+
+</para>
+<para>
+When the lightweight resolver needs to perform dynamic memory
+allocation, it will call
+<parameter>malloc_function</parameter>
+to allocate memory and
+<parameter>free_function</parameter>
+
+to free it. If
+<parameter>malloc_function</parameter>
+and
+<parameter>free_function</parameter>
+
+are NULL, memory is allocated using
+.Xr malloc 3
+and
+<citerefentry>
+<refentrytitle>free</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+
+It is not permitted to have a NULL
+<parameter>malloc_function</parameter>
+and a non-NULL
+<parameter>free_function</parameter>
+or vice versa.
+<parameter>arg</parameter>
+is passed as the first parameter to the memory
+allocation functions.
+If
+<parameter>malloc_function</parameter>
+and
+<parameter>free_function</parameter>
+are NULL,
+<parameter>arg</parameter>
+
+is unused and should be passed as NULL.
+</para>
+<para>
+Once memory for the structure has been allocated,
+it is initialized using
+<citerefentry>
+<refentrytitle>lwres_conf_init</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>
+
+and returned via
+<parameter>*contextp</parameter>.
+
+</para>
+<para>
+<function>lwres_context_destroy()</function>
+destroys a
+<type>lwres_context_t</type>,
+
+closing its socket.
+<parameter>contextp</parameter>
+is a pointer to a pointer to the context that is to be destroyed.
+The pointer will be set to NULL when the context has been destroyed.
+</para>
+<para>
+The context holds a serial number that is used to identify resolver
+request packets and associate responses with the corresponding requests.
+This serial number is controlled using
+<function>lwres_context_initserial()</function>
+and
+<function>lwres_context_nextserial()</function>.
+<function>lwres_context_initserial()</function>
+sets the serial number for context
+<parameter>*ctx</parameter>
+to
+<parameter>serial</parameter>.
+
+<function>lwres_context_nextserial()</function>
+increments the serial number and returns the previous value.
+</para>
+<para>
+Memory for a lightweight resolver context is allocated and freed using
+<function>lwres_context_allocmem()</function>
+and
+<function>lwres_context_freemem()</function>.
+These use whatever allocations were defined when the context was
+created with
+<function>lwres_context_create()</function>.
+<function>lwres_context_allocmem()</function>
+allocates
+<parameter>len</parameter>
+bytes of memory and if successful returns a pointer to the allocated
+storage.
+<function>lwres_context_freemem()</function>
+frees
+<parameter>len</parameter>
+bytes of space starting at location
+<parameter>mem</parameter>.
+
+</para>
+<para>
+<function>lwres_context_sendrecv()</function>
+performs I/O for the context
+<parameter>ctx</parameter>.
+
+Data are read and written from the context's socket.
+It writes data from
+<parameter>sendbase</parameter>
+&mdash; typically a lightweight resolver query packet &mdash;
+and waits for a reply which is copied to the receive buffer at
+<parameter>recvbase</parameter>.
+
+The number of bytes that were written to this receive buffer is
+returned in
+<parameter>*recvd_len</parameter>.
+
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_context_create()</function>
+returns
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory for the
+<type>struct lwres_context</type>
+could not be allocated,
+<errorcode>LWRES_R_SUCCESS</errorcode>
+otherwise.
+</para>
+<para>
+Successful calls to the memory allocator
+<function>lwres_context_allocmem()</function>
+return a pointer to the start of the allocated space.
+It returns NULL if memory could not be allocated.
+</para>
+<para>
+<errorcode>LWRES_R_SUCCESS</errorcode>
+is returned when
+<function>lwres_context_sendrecv()</function>
+completes successfully.
+<errorcode>LWRES_R_IOERROR</errorcode>
+is returned if an I/O error occurs and
+<errorcode>LWRES_R_TIMEOUT</errorcode>
+is returned if
+<function>lwres_context_sendrecv()</function>
+times out waiting for a response.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_conf_init</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>malloc</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>free</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_context.html b/src/libfreeswan/liblwres/man/lwres_context.html
new file mode 100644
index 000000000..377125c43
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_context.html
@@ -0,0 +1,519 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_context</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_context</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_context_create, lwres_context_destroy, lwres_context_nextserial, lwres_context_initserial, lwres_context_freemem, lwres_context_allocmem, lwres_context_sendrecv&nbsp;--&nbsp;lightweight resolver context management</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN17"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN18"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_context_create</CODE
+>(lwres_context_t **contextp, void *arg, lwres_malloc_t malloc_function, lwres_free_t free_function);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_context_destroy</CODE
+>(lwres_context_t **contextp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_context_initserial</CODE
+>(lwres_context_t *ctx, lwres_uint32_t serial);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_uint32_t
+lwres_context_nextserial</CODE
+>(lwres_context_t *ctx);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_context_freemem</CODE
+>(lwres_context_t *ctx, void *mem, size_t len);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_context_allocmem</CODE
+>(lwres_context_t *ctx, size_t len);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void *
+lwres_context_sendrecv</CODE
+>(lwres_context_t *ctx, void *sendbase, int sendlen, void *recvbase, int recvlen, int *recvd_len);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN60"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_create()</TT
+>
+creates a
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+structure for use in lightweight resolver operations.
+It holds a socket and other data needed for communicating
+with a resolver daemon.
+The new
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+is returned throught
+<TT
+CLASS="PARAMETER"
+><I
+>contextp</I
+></TT
+>,
+
+a pointer to a
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+pointer. This
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>
+pointer must initially be NULL, and is modified
+to point to the newly created
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>.&#13;</P
+><P
+>When the lightweight resolver needs to perform dynamic memory
+allocation, it will call
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+to allocate memory and
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+
+to free it. If
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+
+are NULL, memory is allocated using
+.Xr malloc 3
+and
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>free</SPAN
+>(3)</SPAN
+>.
+
+It is not permitted to have a NULL
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+and a non-NULL
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+or vice versa.
+<TT
+CLASS="PARAMETER"
+><I
+>arg</I
+></TT
+>
+is passed as the first parameter to the memory
+allocation functions.
+If
+<TT
+CLASS="PARAMETER"
+><I
+>malloc_function</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>free_function</I
+></TT
+>
+are NULL,
+<TT
+CLASS="PARAMETER"
+><I
+>arg</I
+></TT
+>
+
+is unused and should be passed as NULL.</P
+><P
+>Once memory for the structure has been allocated,
+it is initialized using
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_conf_init</SPAN
+>(3)</SPAN
+>
+
+and returned via
+<TT
+CLASS="PARAMETER"
+><I
+>*contextp</I
+></TT
+>.&#13;</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_destroy()</TT
+>
+destroys a
+<SPAN
+CLASS="TYPE"
+>lwres_context_t</SPAN
+>,
+
+closing its socket.
+<TT
+CLASS="PARAMETER"
+><I
+>contextp</I
+></TT
+>
+is a pointer to a pointer to the context that is to be destroyed.
+The pointer will be set to NULL when the context has been destroyed.</P
+><P
+>The context holds a serial number that is used to identify resolver
+request packets and associate responses with the corresponding requests.
+This serial number is controlled using
+<TT
+CLASS="FUNCTION"
+>lwres_context_initserial()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_context_nextserial()</TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_context_initserial()</TT
+>
+sets the serial number for context
+<TT
+CLASS="PARAMETER"
+><I
+>*ctx</I
+></TT
+>
+to
+<TT
+CLASS="PARAMETER"
+><I
+>serial</I
+></TT
+>.
+
+<TT
+CLASS="FUNCTION"
+>lwres_context_nextserial()</TT
+>
+increments the serial number and returns the previous value.</P
+><P
+>Memory for a lightweight resolver context is allocated and freed using
+<TT
+CLASS="FUNCTION"
+>lwres_context_allocmem()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_context_freemem()</TT
+>.
+These use whatever allocations were defined when the context was
+created with
+<TT
+CLASS="FUNCTION"
+>lwres_context_create()</TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_context_allocmem()</TT
+>
+allocates
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+>
+bytes of memory and if successful returns a pointer to the allocated
+storage.
+<TT
+CLASS="FUNCTION"
+>lwres_context_freemem()</TT
+>
+frees
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+>
+bytes of space starting at location
+<TT
+CLASS="PARAMETER"
+><I
+>mem</I
+></TT
+>.&#13;</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_sendrecv()</TT
+>
+performs I/O for the context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>.
+
+Data are read and written from the context's socket.
+It writes data from
+<TT
+CLASS="PARAMETER"
+><I
+>sendbase</I
+></TT
+>
+&mdash; typically a lightweight resolver query packet &mdash;
+and waits for a reply which is copied to the receive buffer at
+<TT
+CLASS="PARAMETER"
+><I
+>recvbase</I
+></TT
+>.
+
+The number of bytes that were written to this receive buffer is
+returned in
+<TT
+CLASS="PARAMETER"
+><I
+>*recvd_len</I
+></TT
+>.&#13;</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN115"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_context_create()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory for the
+<SPAN
+CLASS="TYPE"
+>struct lwres_context</SPAN
+>
+could not be allocated,
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+otherwise.</P
+><P
+>Successful calls to the memory allocator
+<TT
+CLASS="FUNCTION"
+>lwres_context_allocmem()</TT
+>
+return a pointer to the start of the allocated space.
+It returns NULL if memory could not be allocated.</P
+><P
+><SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+is returned when
+<TT
+CLASS="FUNCTION"
+>lwres_context_sendrecv()</TT
+>
+completes successfully.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_IOERROR</SPAN
+>
+is returned if an I/O error occurs and
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_TIMEOUT</SPAN
+>
+is returned if
+<TT
+CLASS="FUNCTION"
+>lwres_context_sendrecv()</TT
+>
+times out waiting for a response.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN130"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_conf_init</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>malloc</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>free</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_gabn.3 b/src/libfreeswan/liblwres/man/lwres_gabn.3
new file mode 100644
index 000000000..79a22c14f
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gabn.3
@@ -0,0 +1,193 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GABN" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free \- lightweight resolver getaddrbyname message handling
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These are low-level routines for creating and parsing
+lightweight resolver name-to-address lookup request and
+response messages.
+.PP
+There are four main functions for the getaddrbyname opcode.
+One render function converts a getaddrbyname request structure \(em
+\fBlwres_gabnrequest_t\fR \(em
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getaddrbyname request structure.
+Another render function converts the getaddrbyname response structure \(em
+\fBlwres_gabnresponse_t\fR \(em
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getaddrbyname response structure.
+.PP
+These structures are defined in
+\fI<lwres/lwres.h>\fR.
+They are shown below.
+.sp
+.nf
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+.sp
+.fi
+.PP
+\fBlwres_gabnrequest_render()\fR
+uses resolver context
+\fIctx\fR
+to convert getaddrbyname request structure
+\fIreq\fR
+to canonical format.
+The packet header structure
+\fIpkt\fR
+is initialised and transferred to
+buffer
+\fIb\fR.
+The contents of
+\fI*req\fR
+are then appended to the buffer in canonical format.
+\fBlwres_gabnresponse_render()\fR
+performs the same task, except it converts a getaddrbyname response structure
+\fBlwres_gabnresponse_t\fR
+to the lightweight resolver's canonical format.
+.PP
+\fBlwres_gabnrequest_parse()\fR
+uses context
+\fIctx\fR
+to convert the contents of packet
+\fIpkt\fR
+to a
+\fBlwres_gabnrequest_t\fR
+structure.
+Buffer
+\fIb\fR
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+\fBlwres_gabnrequest_t\fR
+is made available through
+\fI*structp\fR.
+\fBlwres_gabnresponse_parse()\fR
+offers the same semantics as
+\fBlwres_gabnrequest_parse()\fR
+except it yields a
+\fBlwres_gabnresponse_t\fR
+structure.
+.PP
+\fBlwres_gabnresponse_free()\fR
+and
+\fBlwres_gabnrequest_free()\fR
+release the memory in resolver context
+\fIctx\fR
+that was allocated to the
+\fBlwres_gabnresponse_t\fR
+or
+\fBlwres_gabnrequest_t\fR
+structures referenced via
+\fIstructp\fR.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+.SH "RETURN VALUES"
+.PP
+The getaddrbyname opcode functions
+\fBlwres_gabnrequest_render()\fR,
+\fBlwres_gabnresponse_render()\fR
+\fBlwres_gabnrequest_parse()\fR
+and
+\fBlwres_gabnresponse_parse()\fR
+all return
+LWRES_R_SUCCESS
+on success.
+They return
+LWRES_R_NOMEMORY
+if memory allocation fails.
+LWRES_R_UNEXPECTEDEND
+is returned if the available space in the buffer
+\fIb\fR
+is too small to accommodate the packet header or the
+\fBlwres_gabnrequest_t\fR
+and
+\fBlwres_gabnresponse_t\fR
+structures.
+\fBlwres_gabnrequest_parse()\fR
+and
+\fBlwres_gabnresponse_parse()\fR
+will return
+LWRES_R_UNEXPECTEDEND
+if the buffer is not empty after decoding the received packet.
+These functions will return
+LWRES_R_FAILURE
+if
+\fBpktflags\fR
+in the packet header structure
+\fBlwres_lwpacket_t\fR
+indicate that the packet is not a response to an earlier query.
+.SH "SEE ALSO"
+.PP
+\fBlwres_packet\fR(3)
diff --git a/src/libfreeswan/liblwres/man/lwres_gabn.docbook b/src/libfreeswan/liblwres/man/lwres_gabn.docbook
new file mode 100644
index 000000000..91f549564
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gabn.docbook
@@ -0,0 +1,255 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_gabn.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_gabn</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres_gabnrequest_render</refname>
+<refname>lwres_gabnresponse_render</refname>
+<refname>lwres_gabnrequest_parse</refname>
+<refname>lwres_gabnresponse_parse</refname>
+<refname>lwres_gabnresponse_free</refname>
+<refname>lwres_gabnrequest_free</refname>
+<refpurpose>lightweight resolver getaddrbyname message handling</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnrequest_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnrequest_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnresponse_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnresponse_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnrequest_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gabnrequest_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gabnresponse_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gabnresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gabnresponse_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gabnrequest_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gabnrequest_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These are low-level routines for creating and parsing
+lightweight resolver name-to-address lookup request and
+response messages.
+</para><para>
+There are four main functions for the getaddrbyname opcode.
+One render function converts a getaddrbyname request structure &mdash;
+<type>lwres_gabnrequest_t</type> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getaddrbyname request structure.
+Another render function converts the getaddrbyname response structure &mdash;
+<type>lwres_gabnresponse_t</type> &mdash;
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getaddrbyname response structure.
+</para>
+<para>
+These structures are defined in
+<filename>&lt;lwres/lwres.h&gt;</filename>.
+They are shown below.
+<programlisting>
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+</programlisting>
+</para>
+<para>
+<function>lwres_gabnrequest_render()</function>
+uses resolver context
+<parameter>ctx</parameter>
+to convert getaddrbyname request structure
+<parameter>req</parameter>
+to canonical format.
+The packet header structure
+<parameter>pkt</parameter>
+is initialised and transferred to
+buffer
+<parameter>b</parameter>.
+
+The contents of
+<parameter>*req</parameter>
+are then appended to the buffer in canonical format.
+<function>lwres_gabnresponse_render()</function>
+performs the same task, except it converts a getaddrbyname response structure
+<type>lwres_gabnresponse_t</type>
+to the lightweight resolver's canonical format.
+</para>
+<para>
+<function>lwres_gabnrequest_parse()</function>
+uses context
+<parameter>ctx</parameter>
+to convert the contents of packet
+<parameter>pkt</parameter>
+to a
+<type>lwres_gabnrequest_t</type>
+structure.
+Buffer
+<parameter>b</parameter>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<type>lwres_gabnrequest_t</type>
+is made available through
+<parameter>*structp</parameter>.
+
+<function>lwres_gabnresponse_parse()</function>
+offers the same semantics as
+<function>lwres_gabnrequest_parse()</function>
+except it yields a
+<type>lwres_gabnresponse_t</type>
+structure.
+</para>
+<para>
+<function>lwres_gabnresponse_free()</function>
+and
+<function>lwres_gabnrequest_free()</function>
+release the memory in resolver context
+<parameter>ctx</parameter>
+that was allocated to the
+<type>lwres_gabnresponse_t</type>
+or
+<type>lwres_gabnrequest_t</type>
+structures referenced via
+<parameter>structp</parameter>.
+
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The getaddrbyname opcode functions
+<function>lwres_gabnrequest_render()</function>,
+<function>lwres_gabnresponse_render()</function>
+<function>lwres_gabnrequest_parse()</function>
+and
+<function>lwres_gabnresponse_parse()</function>
+all return
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success.
+They return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory allocation fails.
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+is returned if the available space in the buffer
+<parameter>b</parameter>
+is too small to accommodate the packet header or the
+<type>lwres_gabnrequest_t</type>
+and
+<type>lwres_gabnresponse_t</type>
+structures.
+<function>lwres_gabnrequest_parse()</function>
+and
+<function>lwres_gabnresponse_parse()</function>
+will return
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<structfield>pktflags</structfield>
+in the packet header structure
+<type>lwres_lwpacket_t</type>
+indicate that the packet is not a response to an earlier query.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_packet</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_gabn.html b/src/libfreeswan/liblwres/man/lwres_gabn.html
new file mode 100644
index 000000000..5611cac6c
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gabn.html
@@ -0,0 +1,442 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gabn</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gabn</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_gabnrequest_render, lwres_gabnresponse_render, lwres_gabnrequest_parse, lwres_gabnresponse_parse, lwres_gabnresponse_free, lwres_gabnrequest_free&nbsp;--&nbsp;lightweight resolver getaddrbyname message handling</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN16"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN17"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnrequest_render</CODE
+>(lwres_context_t *ctx, lwres_gabnrequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnresponse_render</CODE
+>(lwres_context_t *ctx, lwres_gabnresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnrequest_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gabnresponse_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gabnresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gabnresponse_free</CODE
+>(lwres_context_t *ctx, lwres_gabnresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gabnrequest_free</CODE
+>(lwres_context_t *ctx, lwres_gabnrequest_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These are low-level routines for creating and parsing
+lightweight resolver name-to-address lookup request and
+response messages.</P
+><P
+>There are four main functions for the getaddrbyname opcode.
+One render function converts a getaddrbyname request structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getaddrbyname request structure.
+Another render function converts the getaddrbyname response structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+> &mdash;
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getaddrbyname response structure.</P
+><P
+>These structures are defined in
+<TT
+CLASS="FILENAME"
+>&lt;lwres/lwres.h&gt;</TT
+>.
+They are shown below.
+<PRE
+CLASS="PROGRAMLISTING"
+>#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ char *name;
+} lwres_gabnrequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;</PRE
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_render()</TT
+>
+uses resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+to convert getaddrbyname request structure
+<TT
+CLASS="PARAMETER"
+><I
+>req</I
+></TT
+>
+to canonical format.
+The packet header structure
+<TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+>
+is initialised and transferred to
+buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>.
+
+The contents of
+<TT
+CLASS="PARAMETER"
+><I
+>*req</I
+></TT
+>
+are then appended to the buffer in canonical format.
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_render()</TT
+>
+performs the same task, except it converts a getaddrbyname response structure
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+to the lightweight resolver's canonical format.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+uses context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+to convert the contents of packet
+<TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+>
+to a
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+structure.
+Buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+is made available through
+<TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.
+
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_parse()</TT
+>
+offers the same semantics as
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+except it yields a
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_free()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_free()</TT
+>
+release the memory in resolver context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+>
+that was allocated to the
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+structures referenced via
+<TT
+CLASS="PARAMETER"
+><I
+>structp</I
+></TT
+>.
+
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN93"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The getaddrbyname opcode functions
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_render()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_render()</TT
+>
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_parse()</TT
+>
+all return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success.
+They return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory allocation fails.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+is returned if the available space in the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+is too small to accommodate the packet header or the
+<SPAN
+CLASS="TYPE"
+>lwres_gabnrequest_t</SPAN
+>
+and
+<SPAN
+CLASS="TYPE"
+>lwres_gabnresponse_t</SPAN
+>
+structures.
+<TT
+CLASS="FUNCTION"
+>lwres_gabnrequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gabnresponse_parse()</TT
+>
+will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pktflags</I
+></TT
+>
+in the packet header structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>
+indicate that the packet is not a response to an earlier query.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN112"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_packet</SPAN
+>(3)</SPAN
+></P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_gai_strerror.3 b/src/libfreeswan/liblwres/man/lwres_gai_strerror.3
new file mode 100644
index 000000000..a8287e924
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gai_strerror.3
@@ -0,0 +1,86 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GAI_STRERROR" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+gai_strerror \- print suitable error string
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+char *
+gai_strerror(int ecode);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_gai_strerror()\fR
+returns an error message corresponding to an error code returned by
+\fBgetaddrinfo()\fR.
+The following error codes and their meaning are defined in
+\fIinclude/lwres/netdb.h\fR.
+.TP
+\fBEAI_ADDRFAMILY\fR
+address family for hostname not supported
+.TP
+\fBEAI_AGAIN\fR
+temporary failure in name resolution
+.TP
+\fBEAI_BADFLAGS\fR
+invalid value for
+ai_flags
+.TP
+\fBEAI_FAIL\fR
+non-recoverable failure in name resolution
+.TP
+\fBEAI_FAMILY\fR
+ai_family not supported
+.TP
+\fBEAI_MEMORY\fR
+memory allocation failure
+.TP
+\fBEAI_NODATA\fR
+no address associated with hostname
+.TP
+\fBEAI_NONAME\fR
+hostname or servname not provided, or not known
+.TP
+\fBEAI_SERVICE\fR
+servname not supported for ai_socktype
+.TP
+\fBEAI_SOCKTYPE\fR
+ai_socktype not supported
+.TP
+\fBEAI_SYSTEM\fR
+system error returned in errno
+.PP
+The message \fBinvalid error code\fR is returned if
+\fIecode\fR
+is out of range.
+.PP
+ai_flags,
+ai_family
+and
+ai_socktype
+are elements of the
+\fBstruct addrinfo\fR
+used by
+\fBlwres_getaddrinfo()\fR.
+.SH "SEE ALSO"
+.PP
+\fBstrerror\fR(3),
+\fBlwres_getaddrinfo\fR(3),
+\fBgetaddrinfo\fR(3),
+\fBRFC2133\fR.
diff --git a/src/libfreeswan/liblwres/man/lwres_gai_strerror.docbook b/src/libfreeswan/liblwres/man/lwres_gai_strerror.docbook
new file mode 100644
index 000000000..6ffe8fc47
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gai_strerror.docbook
@@ -0,0 +1,161 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_gai_strerror.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Jun 30, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_gai_strerror</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>gai_strerror</refname>
+<refpurpose>print suitable error string</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+char *
+<function>gai_strerror</function></funcdef>
+<paramdef>int ecode</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_gai_strerror()</function>
+returns an error message corresponding to an error code returned by
+<function>getaddrinfo()</function>.
+The following error codes and their meaning are defined in
+<filename>include/lwres/netdb.h</filename>.
+<variablelist>
+<varlistentry><term><errorcode>EAI_ADDRFAMILY</errorcode></term>
+<listitem>
+<para>
+address family for hostname not supported
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_AGAIN</errorcode></term>
+<listitem>
+<para>
+temporary failure in name resolution
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_BADFLAGS</errorcode></term>
+<listitem>
+<para>
+invalid value for
+<constant>ai_flags</constant>
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_FAIL</errorcode></term>
+<listitem>
+<para>
+non-recoverable failure in name resolution
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_FAMILY</errorcode></term>
+<listitem>
+<para>
+<constant>ai_family</constant> not supported
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_MEMORY</errorcode></term>
+<listitem>
+<para>
+memory allocation failure
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_NODATA</errorcode></term>
+<listitem>
+<para>
+no address associated with hostname
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_NONAME</errorcode></term>
+<listitem>
+<para>
+hostname or servname not provided, or not known
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_SERVICE</errorcode></term>
+<listitem>
+<para>
+servname not supported for <constant>ai_socktype</constant>
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_SOCKTYPE</errorcode></term>
+<listitem>
+<para>
+<constant>ai_socktype</constant> not supported
+</para>
+</listitem></varlistentry>
+<varlistentry><term><errorcode>EAI_SYSTEM</errorcode></term>
+<listitem>
+<para>
+system error returned in errno
+</para>
+</listitem></varlistentry>
+</variablelist>
+The message <errorname>invalid error code</errorname> is returned if
+<parameter>ecode</parameter>
+is out of range.
+</para>
+<para>
+<constant>ai_flags</constant>,
+<constant>ai_family</constant>
+and
+<constant>ai_socktype</constant>
+are elements of the
+<type>struct addrinfo</type>
+used by
+<function>lwres_getaddrinfo()</function>.
+</para>
+</refsect1>
+
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>strerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>RFC2133</refentrytitle>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_gai_strerror.html b/src/libfreeswan/liblwres/man/lwres_gai_strerror.html
new file mode 100644
index 000000000..7f245ba4e
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gai_strerror.html
@@ -0,0 +1,294 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gai_strerror</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gai_strerror</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>gai_strerror&nbsp;--&nbsp;print suitable error string</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>char *
+gai_strerror</CODE
+>(int ecode);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN18"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gai_strerror()</TT
+>
+returns an error message corresponding to an error code returned by
+<TT
+CLASS="FUNCTION"
+>getaddrinfo()</TT
+>.
+The following error codes and their meaning are defined in
+<TT
+CLASS="FILENAME"
+>include/lwres/netdb.h</TT
+>.
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_ADDRFAMILY</SPAN
+></DT
+><DD
+><P
+>address family for hostname not supported</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_AGAIN</SPAN
+></DT
+><DD
+><P
+>temporary failure in name resolution</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_BADFLAGS</SPAN
+></DT
+><DD
+><P
+>invalid value for
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_FAIL</SPAN
+></DT
+><DD
+><P
+>non-recoverable failure in name resolution</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_FAMILY</SPAN
+></DT
+><DD
+><P
+><TT
+CLASS="CONSTANT"
+>ai_family</TT
+> not supported</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_MEMORY</SPAN
+></DT
+><DD
+><P
+>memory allocation failure</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_NODATA</SPAN
+></DT
+><DD
+><P
+>no address associated with hostname</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_NONAME</SPAN
+></DT
+><DD
+><P
+>hostname or servname not provided, or not known</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_SERVICE</SPAN
+></DT
+><DD
+><P
+>servname not supported for <TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_SOCKTYPE</SPAN
+></DT
+><DD
+><P
+><TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+> not supported</P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>EAI_SYSTEM</SPAN
+></DT
+><DD
+><P
+>system error returned in errno</P
+></DD
+></DL
+></DIV
+>
+The message <SPAN
+CLASS="ERRORNAME"
+>invalid error code</SPAN
+> is returned if
+<TT
+CLASS="PARAMETER"
+><I
+>ecode</I
+></TT
+>
+is out of range.</P
+><P
+><TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>,
+<TT
+CLASS="CONSTANT"
+>ai_family</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+>
+are elements of the
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>
+used by
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN92"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>strerror</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2133</SPAN
+></SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_getaddrinfo.3 b/src/libfreeswan/liblwres/man/lwres_getaddrinfo.3
new file mode 100644
index 000000000..b7ea46128
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getaddrinfo.3
@@ -0,0 +1,247 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GETADDRINFO" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_getaddrinfo, lwres_freeaddrinfo \- socket address structure to host and service name
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+int
+lwres_getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
+.ad
+.sp
+.na
+void
+lwres_freeaddrinfo(struct addrinfo *ai);
+.ad
+\fR.PP
+If the operating system does not provide a
+\fBstruct addrinfo\fR,
+the following structure is used:
+.sp
+.nf
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+.sp
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBlwres_getaddrinfo()\fR
+is used to get a list of IP addresses and port numbers for host
+\fIhostname\fR
+and service
+\fIservname\fR.
+The function is the lightweight resolver's implementation of
+\fBgetaddrinfo()\fR
+as defined in RFC2133.
+\fIhostname\fR
+and
+\fIservname\fR
+are pointers to null-terminated
+strings or
+\fBNULL\fR.
+\fIhostname\fR
+is either a host name or a numeric host address string: a dotted decimal
+IPv4 address or an IPv6 address.
+\fIservname\fR
+is either a decimal port number or a service name as listed in
+\fI/etc/services\fR.
+.PP
+\fIhints\fR
+is an optional pointer to a
+\fBstruct addrinfo\fR.
+This structure can be used to provide hints concerning the type of socket
+that the caller supports or wishes to use.
+The caller can supply the following structure elements in
+\fI*hints\fR:
+.TP
+\fBai_family\fR
+The protocol family that should be used.
+When
+ai_family
+is set to
+\fBPF_UNSPEC\fR,
+it means the caller will accept any protocol family supported by the
+operating system.
+.TP
+\fBai_socktype\fR
+denotes the type of socket \(em
+\fBSOCK_STREAM\fR,
+\fBSOCK_DGRAM\fR
+or
+\fBSOCK_RAW\fR
+\(em that is wanted.
+When
+ai_socktype
+is zero the caller will accept any socket type.
+.TP
+\fBai_protocol\fR
+indicates which transport protocol is wanted: IPPROTO_UDP or
+IPPROTO_TCP.
+If
+ai_protocol
+is zero the caller will accept any protocol.
+.TP
+\fBai_flags\fR
+Flag bits.
+If the
+\fBAI_CANONNAME\fR
+bit is set, a successful call to
+\fBlwres_getaddrinfo()\fR
+will return a a null-terminated string containing the canonical name
+of the specified hostname in
+ai_canonname
+of the first
+\fBaddrinfo\fR
+structure returned.
+Setting the
+\fBAI_PASSIVE\fR
+bit indicates that the returned socket address structure is intended
+for used in a call to
+\fBbind\fR(2).
+In this case, if the hostname argument is a
+\fBNULL\fR
+pointer, then the IP address portion of the socket
+address structure will be set to
+\fBINADDR_ANY\fR
+for an IPv4 address or
+\fBIN6ADDR_ANY_INIT\fR
+for an IPv6 address.
+
+When
+ai_flags
+does not set the
+\fBAI_PASSIVE\fR
+bit, the returned socket address structure will be ready
+for use in a call to
+\fBconnect\fR(2)
+for a connection-oriented protocol or
+\fBconnect\fR(2),
+\fBsendto\fR(2),
+or
+\fBsendmsg\fR(2)
+if a connectionless protocol was chosen.
+The IP address portion of the socket address structure will be
+set to the loopback address if
+\fIhostname\fR
+is a
+\fBNULL\fR
+pointer and
+\fBAI_PASSIVE\fR
+is not set in
+ai_flags.
+
+If
+ai_flags
+is set to
+\fBAI_NUMERICHOST\fR
+it indicates that
+\fIhostname\fR
+should be treated as a numeric string defining an IPv4 or IPv6 address
+and no name resolution should be attempted.
+.PP
+All other elements of the \fBstruct addrinfo\fR passed
+via \fIhints\fR must be zero.
+.PP
+A \fIhints\fR of \fBNULL\fR is treated as if
+the caller provided a \fBstruct addrinfo\fR initialized to zero
+with ai_familyset to
+PF_UNSPEC.
+.PP
+After a successful call to
+\fBlwres_getaddrinfo()\fR,
+\fI*res\fR
+is a pointer to a linked list of one or more
+\fBaddrinfo\fR
+structures.
+Each
+\fBstruct addrinfo\fR
+in this list cn be processed by following
+the
+ai_next
+pointer, until a
+\fBNULL\fR
+pointer is encountered.
+The three members
+ai_family,
+ai_socktype,
+and
+ai_protocol
+in each
+returned
+\fBaddrinfo\fR
+structure contain the corresponding arguments for a call to
+\fBsocket\fR(2).
+For each
+\fBaddrinfo\fR
+structure in the list, the
+ai_addr
+member points to a filled-in socket address structure of length
+ai_addrlen.
+.PP
+All of the information returned by
+\fBlwres_getaddrinfo()\fR
+is dynamically allocated: the addrinfo structures, and the socket
+address structures and canonical host name strings pointed to by the
+addrinfostructures.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+\fBlwres_getaddrinfo()\fR
+is released by
+\fBlwres_freeaddrinfo()\fR.
+\fIai\fR
+is a pointer to a
+\fBstruct addrinfo\fR
+created by a call to
+\fBlwres_getaddrinfo()\fR.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_getaddrinfo()\fR
+returns zero on success or one of the error codes listed in
+\fBgai_strerror\fR(3)
+if an error occurs.
+If both
+\fIhostname\fR
+and
+\fIservname\fR
+are
+\fBNULL\fR
+\fBlwres_getaddrinfo()\fR
+returns
+EAI_NONAME.
+.SH "SEE ALSO"
+.PP
+\fBlwres\fR(3),
+\fBlwres_getaddrinfo\fR(3),
+\fBlwres_freeaddrinfo\fR(3),
+\fBlwres_gai_strerror\fR(3),
+\fBRFC2133\fR,
+\fBgetservbyname\fR(3),
+\fBbind\fR(2),
+\fBconnect\fR(2),
+\fBsendto\fR(2),
+\fBsendmsg\fR(2),
+\fBsocket\fR(2).
diff --git a/src/libfreeswan/liblwres/man/lwres_getaddrinfo.docbook b/src/libfreeswan/liblwres/man/lwres_getaddrinfo.docbook
new file mode 100644
index 000000000..f89107304
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getaddrinfo.docbook
@@ -0,0 +1,372 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_getaddrinfo.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_getaddrinfo</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_getaddrinfo</refname>
+<refname>lwres_freeaddrinfo</refname>
+<refpurpose>socket address structure to host and service name</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+int
+<function>lwres_getaddrinfo</function></funcdef>
+<paramdef>const char *hostname</paramdef>
+<paramdef>const char *servname</paramdef>
+<paramdef>const struct addrinfo *hints</paramdef>
+<paramdef>struct addrinfo **res</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_freeaddrinfo</function></funcdef>
+<paramdef>struct addrinfo *ai</paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+If the operating system does not provide a
+<type>struct addrinfo</type>,
+the following structure is used:
+
+<programlisting>
+struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};
+</programlisting>
+</para>
+
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_getaddrinfo()</function>
+is used to get a list of IP addresses and port numbers for host
+<parameter>hostname</parameter>
+and service
+<parameter>servname</parameter>.
+
+The function is the lightweight resolver's implementation of
+<function>getaddrinfo()</function>
+as defined in RFC2133.
+<parameter>hostname</parameter>
+and
+<parameter>servname</parameter>
+are pointers to null-terminated
+strings or
+<type>NULL</type>.
+
+<parameter>hostname</parameter>
+is either a host name or a numeric host address string: a dotted decimal
+IPv4 address or an IPv6 address.
+<parameter>servname</parameter>
+is either a decimal port number or a service name as listed in
+<filename>/etc/services</filename>.
+</para>
+
+<para>
+<parameter>hints</parameter>
+is an optional pointer to a
+<type>struct addrinfo</type>.
+This structure can be used to provide hints concerning the type of socket
+that the caller supports or wishes to use.
+The caller can supply the following structure elements in
+<parameter>*hints</parameter>:
+
+<variablelist>
+<varlistentry><term><constant>ai_family</constant></term>
+<listitem>
+<para>The protocol family that should be used.
+When
+<constant>ai_family</constant>
+is set to
+<type>PF_UNSPEC</type>,
+it means the caller will accept any protocol family supported by the
+operating system.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>ai_socktype</constant></term>
+<listitem>
+<para>
+denotes the type of socket &mdash;
+<type>SOCK_STREAM</type>,
+<type>SOCK_DGRAM</type>
+or
+<type>SOCK_RAW</type>
+&mdash; that is wanted.
+When
+<constant>ai_socktype</constant>
+is zero the caller will accept any socket type.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term><constant>ai_protocol</constant></term>
+<listitem>
+<para>
+indicates which transport protocol is wanted: IPPROTO_UDP or
+IPPROTO_TCP.
+If
+<constant>ai_protocol</constant>
+is zero the caller will accept any protocol.
+</para>
+</listitem>
+</varlistentry>
+<varlistentry><term><constant>ai_flags</constant></term>
+<listitem>
+<para>
+Flag bits.
+If the
+<type>AI_CANONNAME</type>
+bit is set, a successful call to
+<function>lwres_getaddrinfo()</function>
+will return a a null-terminated string containing the canonical name
+of the specified hostname in
+<constant>ai_canonname</constant>
+of the first
+<type>addrinfo</type>
+structure returned.
+Setting the
+<type>AI_PASSIVE</type>
+bit indicates that the returned socket address structure is intended
+for used in a call to
+<citerefentry>
+<refentrytitle>bind</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>.
+
+In this case, if the hostname argument is a
+<type>NULL</type>
+pointer, then the IP address portion of the socket
+address structure will be set to
+<type>INADDR_ANY</type>
+for an IPv4 address or
+<type>IN6ADDR_ANY_INIT</type>
+for an IPv6 address.
+</para>
+<para>
+When
+<constant>ai_flags</constant>
+does not set the
+<type>AI_PASSIVE</type>
+bit, the returned socket address structure will be ready
+for use in a call to
+<citerefentry>
+<refentrytitle>connect</refentrytitle><manvolnum>2
+</manvolnum>
+</citerefentry>
+for a connection-oriented protocol or
+<citerefentry>
+<refentrytitle>connect</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>sendto</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+or
+<citerefentry>
+<refentrytitle>sendmsg</refentrytitle><manvolnum>2
+</manvolnum>
+</citerefentry>
+if a connectionless protocol was chosen.
+The IP address portion of the socket address structure will be
+set to the loopback address if
+<parameter>hostname</parameter>
+is a
+<type>NULL</type>
+pointer and
+<type>AI_PASSIVE</type>
+is not set in
+<constant>ai_flags</constant>.
+</para>
+<para>
+If
+<constant>ai_flags</constant>
+is set to
+<type>AI_NUMERICHOST</type>
+it indicates that
+<parameter>hostname</parameter>
+should be treated as a numeric string defining an IPv4 or IPv6 address
+and no name resolution should be attempted.
+</para>
+</listitem>
+</varlistentry>
+</variablelist>
+</para>
+
+<para>
+All other elements of the <type>struct addrinfo</type> passed
+via <parameter>hints</parameter> must be zero.
+</para>
+
+<para>
+A <parameter>hints</parameter> of <type>NULL</type> is treated as if
+the caller provided a <type>struct addrinfo</type> initialized to zero
+with <constant>ai_family</constant>set to
+<constant>PF_UNSPEC</constant>.
+</para>
+
+<para>
+After a successful call to
+<function>lwres_getaddrinfo()</function>,
+<parameter>*res</parameter>
+is a pointer to a linked list of one or more
+<type>addrinfo</type>
+structures.
+Each
+<type>struct addrinfo</type>
+in this list cn be processed by following
+the
+<constant>ai_next</constant>
+pointer, until a
+<type>NULL</type>
+pointer is encountered.
+The three members
+<constant>ai_family</constant>,
+<constant>ai_socktype</constant>,
+and
+<constant>ai_protocol</constant>
+in each
+returned
+<type>addrinfo</type>
+structure contain the corresponding arguments for a call to
+<citerefentry>
+<refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>.
+For each
+<type>addrinfo</type>
+structure in the list, the
+<constant>ai_addr</constant>
+member points to a filled-in socket address structure of length
+<constant>ai_addrlen</constant>.
+</para>
+
+<para>
+All of the information returned by
+<function>lwres_getaddrinfo()</function>
+is dynamically allocated: the addrinfo structures, and the socket
+address structures and canonical host name strings pointed to by the
+<constant>addrinfo</constant>structures.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<function>lwres_getaddrinfo()</function>
+is released by
+<function>lwres_freeaddrinfo()</function>.
+<parameter>ai</parameter>
+is a pointer to a
+<type>struct addrinfo</type>
+created by a call to
+<function>lwres_getaddrinfo()</function>.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_getaddrinfo()</function>
+returns zero on success or one of the error codes listed in
+<citerefentry>
+<refentrytitle>gai_strerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+if an error occurs.
+If both
+<parameter>hostname</parameter>
+and
+<parameter>servname</parameter>
+are
+<type>NULL</type>
+<function>lwres_getaddrinfo()</function>
+returns
+<errorcode>EAI_NONAME</errorcode>.
+
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_freeaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gai_strerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>RFC2133</refentrytitle>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>getservbyname</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>bind</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>connect</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>sendto</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>sendmsg</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_getaddrinfo.html b/src/libfreeswan/liblwres/man/lwres_getaddrinfo.html
new file mode 100644
index 000000000..d04ecc1a2
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getaddrinfo.html
@@ -0,0 +1,722 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getaddrinfo</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getaddrinfo</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getaddrinfo, lwres_freeaddrinfo&nbsp;--&nbsp;socket address structure to host and service name</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>int
+lwres_getaddrinfo</CODE
+>(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_freeaddrinfo</CODE
+>(struct addrinfo *ai);</CODE
+></P
+><P
+></P
+></DIV
+><P
+>If the operating system does not provide a
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>,
+the following structure is used:
+
+<PRE
+CLASS="PROGRAMLISTING"
+>struct addrinfo {
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
+};</PRE
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN29"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+is used to get a list of IP addresses and port numbers for host
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+and service
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>.
+
+The function is the lightweight resolver's implementation of
+<TT
+CLASS="FUNCTION"
+>getaddrinfo()</TT
+>
+as defined in RFC2133.
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>
+are pointers to null-terminated
+strings or
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>.
+
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+is either a host name or a numeric host address string: a dotted decimal
+IPv4 address or an IPv6 address.
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>
+is either a decimal port number or a service name as listed in
+<TT
+CLASS="FILENAME"
+>/etc/services</TT
+>.</P
+><P
+><TT
+CLASS="PARAMETER"
+><I
+>hints</I
+></TT
+>
+is an optional pointer to a
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>.
+This structure can be used to provide hints concerning the type of socket
+that the caller supports or wishes to use.
+The caller can supply the following structure elements in
+<TT
+CLASS="PARAMETER"
+><I
+>*hints</I
+></TT
+>:
+
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_family</TT
+></DT
+><DD
+><P
+>The protocol family that should be used.
+When
+<TT
+CLASS="CONSTANT"
+>ai_family</TT
+>
+is set to
+<SPAN
+CLASS="TYPE"
+>PF_UNSPEC</SPAN
+>,
+it means the caller will accept any protocol family supported by the
+operating system.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+></DT
+><DD
+><P
+>denotes the type of socket &mdash;
+<SPAN
+CLASS="TYPE"
+>SOCK_STREAM</SPAN
+>,
+<SPAN
+CLASS="TYPE"
+>SOCK_DGRAM</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>SOCK_RAW</SPAN
+>
+&mdash; that is wanted.
+When
+<TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+>
+is zero the caller will accept any socket type.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_protocol</TT
+></DT
+><DD
+><P
+>indicates which transport protocol is wanted: IPPROTO_UDP or
+IPPROTO_TCP.
+If
+<TT
+CLASS="CONSTANT"
+>ai_protocol</TT
+>
+is zero the caller will accept any protocol.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ai_flags</TT
+></DT
+><DD
+><P
+>Flag bits.
+If the
+<SPAN
+CLASS="TYPE"
+>AI_CANONNAME</SPAN
+>
+bit is set, a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+will return a a null-terminated string containing the canonical name
+of the specified hostname in
+<TT
+CLASS="CONSTANT"
+>ai_canonname</TT
+>
+of the first
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structure returned.
+Setting the
+<SPAN
+CLASS="TYPE"
+>AI_PASSIVE</SPAN
+>
+bit indicates that the returned socket address structure is intended
+for used in a call to
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>bind</SPAN
+>(2)</SPAN
+>.
+
+In this case, if the hostname argument is a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer, then the IP address portion of the socket
+address structure will be set to
+<SPAN
+CLASS="TYPE"
+>INADDR_ANY</SPAN
+>
+for an IPv4 address or
+<SPAN
+CLASS="TYPE"
+>IN6ADDR_ANY_INIT</SPAN
+>
+for an IPv6 address.</P
+><P
+>When
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>
+does not set the
+<SPAN
+CLASS="TYPE"
+>AI_PASSIVE</SPAN
+>
+bit, the returned socket address structure will be ready
+for use in a call to
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>connect</SPAN
+>(2)</SPAN
+>
+for a connection-oriented protocol or
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>connect</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendto</SPAN
+>(2)</SPAN
+>,
+
+or
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendmsg</SPAN
+>(2)</SPAN
+>
+if a connectionless protocol was chosen.
+The IP address portion of the socket address structure will be
+set to the loopback address if
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+is a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer and
+<SPAN
+CLASS="TYPE"
+>AI_PASSIVE</SPAN
+>
+is not set in
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>.</P
+><P
+>If
+<TT
+CLASS="CONSTANT"
+>ai_flags</TT
+>
+is set to
+<SPAN
+CLASS="TYPE"
+>AI_NUMERICHOST</SPAN
+>
+it indicates that
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+should be treated as a numeric string defining an IPv4 or IPv6 address
+and no name resolution should be attempted.</P
+></DD
+></DL
+></DIV
+></P
+><P
+>All other elements of the <SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+> passed
+via <TT
+CLASS="PARAMETER"
+><I
+>hints</I
+></TT
+> must be zero.</P
+><P
+>A <TT
+CLASS="PARAMETER"
+><I
+>hints</I
+></TT
+> of <SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> is treated as if
+the caller provided a <SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+> initialized to zero
+with <TT
+CLASS="CONSTANT"
+>ai_family</TT
+>set to
+<TT
+CLASS="CONSTANT"
+>PF_UNSPEC</TT
+>.</P
+><P
+>After a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>,
+<TT
+CLASS="PARAMETER"
+><I
+>*res</I
+></TT
+>
+is a pointer to a linked list of one or more
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structures.
+Each
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>
+in this list cn be processed by following
+the
+<TT
+CLASS="CONSTANT"
+>ai_next</TT
+>
+pointer, until a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer is encountered.
+The three members
+<TT
+CLASS="CONSTANT"
+>ai_family</TT
+>,
+<TT
+CLASS="CONSTANT"
+>ai_socktype</TT
+>,
+and
+<TT
+CLASS="CONSTANT"
+>ai_protocol</TT
+>
+in each
+returned
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structure contain the corresponding arguments for a call to
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>socket</SPAN
+>(2)</SPAN
+>.
+For each
+<SPAN
+CLASS="TYPE"
+>addrinfo</SPAN
+>
+structure in the list, the
+<TT
+CLASS="CONSTANT"
+>ai_addr</TT
+>
+member points to a filled-in socket address structure of length
+<TT
+CLASS="CONSTANT"
+>ai_addrlen</TT
+>.</P
+><P
+>All of the information returned by
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+is dynamically allocated: the addrinfo structures, and the socket
+address structures and canonical host name strings pointed to by the
+<TT
+CLASS="CONSTANT"
+>addrinfo</TT
+>structures.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+is released by
+<TT
+CLASS="FUNCTION"
+>lwres_freeaddrinfo()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>ai</I
+></TT
+>
+is a pointer to a
+<SPAN
+CLASS="TYPE"
+>struct addrinfo</SPAN
+>
+created by a call to
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN142"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+returns zero on success or one of the error codes listed in
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>gai_strerror</SPAN
+>(3)</SPAN
+>
+if an error occurs.
+If both
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+and
+<TT
+CLASS="PARAMETER"
+><I
+>servname</I
+></TT
+>
+are
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrinfo()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>EAI_NONAME</SPAN
+>.&#13;</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN154"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_freeaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gai_strerror</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2133</SPAN
+></SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getservbyname</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>bind</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>connect</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendto</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>sendmsg</SPAN
+>(2)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>socket</SPAN
+>(2)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_gethostent.3 b/src/libfreeswan/liblwres/man/lwres_gethostent.3
new file mode 100644
index 000000000..44811ef4d
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gethostent.3
@@ -0,0 +1,270 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GETHOSTENT" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r \- lightweight resolver get network host entry
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+struct hostent *
+lwres_gethostbyname(const char *name);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyname2(const char *name, int af);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyaddr(const char *addr, int len, int type);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostent(void);
+.ad
+.sp
+.na
+void
+lwres_sethostent(int stayopen);
+.ad
+.sp
+.na
+void
+lwres_endhostent(void);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyname_r(const char *name, struct hostent *resbuf, char *buf, int buflen, int *error);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostbyaddr_r(const char *addr, int len, int type, struct hostent *resbuf, char *buf, int buflen, int *error);
+.ad
+.sp
+.na
+struct hostent *
+lwres_gethostent_r(struct hostent *resbuf, char *buf, int buflen, int *error);
+.ad
+.sp
+.na
+void
+lwres_sethostent_r(int stayopen);
+.ad
+.sp
+.na
+void
+lwres_endhostent_r(void);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions provide hostname-to-address and
+address-to-hostname lookups by means of the lightweight resolver.
+They are similar to the standard
+\fBgethostent\fR(3)
+functions provided by most operating systems.
+They use a
+\fBstruct hostent\fR
+which is usually defined in
+\fI<namedb.h>\fR.
+.sp
+.nf
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.sp
+.fi
+.PP
+The members of this structure are:
+.TP
+\fBh_name\fR
+The official (canonical) name of the host.
+.TP
+\fBh_aliases\fR
+A NULL-terminated array of alternate names (nicknames) for the host.
+.TP
+\fBh_addrtype\fR
+The type of address being returned \(em
+\fBPF_INET\fR
+or
+\fBPF_INET6\fR.
+.TP
+\fBh_length\fR
+The length of the address in bytes.
+.TP
+\fBh_addr_list\fR
+A \fBNULL\fR
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.PP
+For backward compatibility with very old software,
+h_addr
+is the first address in
+h_addr_list.
+.PP
+\fBlwres_gethostent()\fR,
+\fBlwres_sethostent()\fR,
+\fBlwres_endhostent()\fR,
+\fBlwres_gethostent_r()\fR,
+\fBlwres_sethostent_r()\fR
+and
+\fBlwres_endhostent_r()\fR
+provide iteration over the known host entries on systems that
+provide such functionality through facilities like
+\fI/etc/hosts\fR
+or NIS. The lightweight resolver does not currently implement
+these functions; it only provides them as stub functions that always
+return failure.
+.PP
+\fBlwres_gethostbyname()\fR and
+\fBlwres_gethostbyname2()\fR look up the hostname
+\fIname\fR.
+\fBlwres_gethostbyname()\fR always looks for an IPv4
+address while \fBlwres_gethostbyname2()\fR looks for an
+address of protocol family \fIaf\fR: either
+\fBPF_INET\fR or \fBPF_INET6\fR \(em IPv4 or IPV6
+addresses respectively. Successful calls of the functions return a
+\fBstruct hostent\fRfor the name that was looked up.
+\fBNULL\fR is returned if the lookups by
+\fBlwres_gethostbyname()\fR or
+\fBlwres_gethostbyname2()\fR fail.
+.PP
+Reverse lookups of addresses are performed by
+\fBlwres_gethostbyaddr()\fR.
+\fIaddr\fR is an address of length
+\fIlen\fR bytes and protocol family
+\fItype\fR \(em \fBPF_INET\fR or
+\fBPF_INET6\fR.
+\fBlwres_gethostbyname_r()\fR is a thread-safe function
+for forward lookups. If an error occurs, an error code is returned in
+\fI*error\fR.
+\fIresbuf\fR is a pointer to a \fBstruct
+hostent\fR which is initialised by a successful call to
+\fBlwres_gethostbyname_r()\fR .
+\fIbuf\fR is a buffer of length
+\fIlen\fR bytes which is used to store the
+h_name, h_aliases, and
+h_addr_list elements of the \fBstruct
+hostent\fR returned in \fIresbuf\fR.
+Successful calls to \fBlwres_gethostbyname_r()\fR
+return \fIresbuf\fR,
+which is a pointer to the \fBstruct hostent\fR it created.
+.PP
+\fBlwres_gethostbyaddr_r()\fR is a thread-safe function
+that performs a reverse lookup of address \fIaddr\fR
+which is \fIlen\fR bytes long and is of protocol
+family \fItype\fR \(em \fBPF_INET\fR or
+\fBPF_INET6\fR. If an error occurs, the error code is returned
+in \fI*error\fR. The other function parameters are
+identical to those in \fBlwres_gethostbyname_r()\fR.
+\fIresbuf\fR is a pointer to a \fBstruct
+hostent\fR which is initialised by a successful call to
+\fBlwres_gethostbyaddr_r()\fR.
+\fIbuf\fR is a buffer of length
+\fIlen\fR bytes which is used to store the
+h_name, h_aliases, and
+h_addr_list elements of the \fBstruct
+hostent\fR returned in \fIresbuf\fR. Successful
+calls to \fBlwres_gethostbyaddr_r()\fR return
+\fIresbuf\fR, which is a pointer to the
+\fBstruct hostent()\fR it created.
+.SH "RETURN VALUES"
+.PP
+The functions
+\fBlwres_gethostbyname()\fR,
+\fBlwres_gethostbyname2()\fR,
+\fBlwres_gethostbyaddr()\fR,
+and
+\fBlwres_gethostent()\fR
+return NULL to indicate an error. In this case the global variable
+\fBlwres_h_errno\fR
+will contain one of the following error codes defined in
+\fI<lwres/netdb.h>\fR:
+.TP
+\fBHOST_NOT_FOUND\fR
+The host or address was not found.
+.TP
+\fBTRY_AGAIN\fR
+A recoverable error occurred, e.g., a timeout.
+Retrying the lookup may succeed.
+.TP
+\fBNO_RECOVERY\fR
+A non-recoverable error occurred.
+.TP
+\fBNO_DATA\fR
+The name exists, but has no address information
+associated with it (or vice versa in the case
+of a reverse lookup). The code NO_ADDRESS
+is accepted as a synonym for NO_DATA for backwards
+compatibility.
+.PP
+\fBlwres_hstrerror\fR(3)
+translates these error codes to suitable error messages.
+.PP
+\fBlwres_gethostent()\fR
+and
+\fBlwres_gethostent_r()\fR
+always return
+\fBNULL\fR.
+.PP
+Successful calls to \fBlwres_gethostbyname_r()\fR and
+\fBlwres_gethostbyaddr_r()\fR return
+\fIresbuf\fR, a pointer to the \fBstruct
+hostent\fR that was initialised by these functions. They return
+\fBNULL\fR if the lookups fail or if \fIbuf\fR
+was too small to hold the list of addresses and names referenced by
+the h_name, h_aliases, and
+h_addr_list elements of the \fBstruct
+hostent\fR. If \fIbuf\fR was too small, both
+\fBlwres_gethostbyname_r()\fR and
+\fBlwres_gethostbyaddr_r()\fR set the global variable
+\fBerrno\fR to ERANGE.
+.SH "SEE ALSO"
+.PP
+\fBgethostent\fR(3),
+\fBlwres_getipnode\fR(3),
+\fBlwres_hstrerror\fR(3)
+.SH "BUGS"
+.PP
+\fBlwres_gethostbyname()\fR,
+\fBlwres_gethostbyname2()\fR,
+\fBlwres_gethostbyaddr()\fR
+and
+\fBlwres_endhostent()\fR
+are not thread safe; they return pointers to static data and
+provide error codes through a global variable.
+Thread-safe versions for name and address lookup are provided by
+\fBlwres_gethostbyname_r()\fR,
+and
+\fBlwres_gethostbyaddr_r()\fR
+respectively.
+.PP
+The resolver daemon does not currently support any non-DNS
+name services such as
+\fI/etc/hosts\fR
+or
+\fBNIS\fR,
+consequently the above functions don't, either.
diff --git a/src/libfreeswan/liblwres/man/lwres_gethostent.docbook b/src/libfreeswan/liblwres/man/lwres_gethostent.docbook
new file mode 100644
index 000000000..22717821c
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gethostent.docbook
@@ -0,0 +1,407 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_gethostent.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_gethostent</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_gethostbyname</refname>
+<refname>lwres_gethostbyname2</refname>
+<refname>lwres_gethostbyaddr</refname>
+<refname>lwres_gethostent</refname>
+<refname>lwres_sethostent</refname>
+<refname>lwres_endhostent</refname>
+<refname>lwres_gethostbyname_r</refname>
+<refname>lwres_gethostbyaddr_r</refname>
+<refname>lwres_gethostent_r</refname>
+<refname>lwres_sethostent_r</refname>
+<refname>lwres_endhostent_r</refname>
+<refpurpose>lightweight resolver get network host entry</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyname</function></funcdef>
+<paramdef>const char *name</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyname2</function></funcdef>
+<paramdef>const char *name</paramdef>
+<paramdef>int af</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyaddr</function></funcdef>
+<paramdef>const char *addr</paramdef>
+<paramdef>int len</paramdef>
+<paramdef>int type</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostent</function></funcdef>
+<paramdef>void</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_sethostent</function></funcdef>
+<paramdef>int stayopen</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_endhostent</function></funcdef>
+<paramdef>void</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyname_r</function></funcdef>
+<paramdef>const char *name</paramdef>
+<paramdef>struct hostent *resbuf</paramdef>
+<paramdef>char *buf</paramdef>
+<paramdef>int buflen</paramdef>
+<paramdef>int *error</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostbyaddr_r</function></funcdef>
+<paramdef>const char *addr</paramdef>
+<paramdef>int len</paramdef>
+<paramdef>int type</paramdef>
+<paramdef>struct hostent *resbuf</paramdef>
+<paramdef>char *buf</paramdef>
+<paramdef>int buflen</paramdef>
+<paramdef>int *error</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_gethostent_r</function></funcdef>
+<paramdef>struct hostent *resbuf</paramdef>
+<paramdef>char *buf</paramdef>
+<paramdef>int buflen</paramdef>
+<paramdef>int *error</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_sethostent_r</function></funcdef>
+<paramdef>int stayopen</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_endhostent_r</function></funcdef>
+<paramdef>void</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These functions provide hostname-to-address and
+address-to-hostname lookups by means of the lightweight resolver.
+They are similar to the standard
+<citerefentry>
+<refentrytitle>gethostent</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+functions provided by most operating systems.
+They use a
+<type>struct hostent</type>
+which is usually defined in
+<filename>&lt;namedb.h&gt;</filename>.
+
+<programlisting>
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+</programlisting>
+</para>
+<para>
+The members of this structure are:
+<variablelist>
+<varlistentry><term><constant>h_name</constant></term>
+<listitem>
+<para>
+The official (canonical) name of the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_aliases</constant></term>
+<listitem>
+<para>
+A NULL-terminated array of alternate names (nicknames) for the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addrtype</constant></term>
+<listitem>
+<para>
+The type of address being returned &mdash;
+<type>PF_INET</type>
+or
+<type>PF_INET6</type>.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_length</constant></term>
+<listitem>
+<para>
+The length of the address in bytes.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addr_list</constant></term>
+<listitem>
+<para>
+A <type>NULL</type>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+For backward compatibility with very old software,
+<constant>h_addr</constant>
+is the first address in
+<constant>h_addr_list.</constant>
+</para>
+<para>
+<function>lwres_gethostent()</function>,
+<function>lwres_sethostent()</function>,
+<function>lwres_endhostent()</function>,
+<function>lwres_gethostent_r()</function>,
+<function>lwres_sethostent_r()</function>
+and
+<function>lwres_endhostent_r()</function>
+provide iteration over the known host entries on systems that
+provide such functionality through facilities like
+<filename>/etc/hosts</filename>
+or NIS. The lightweight resolver does not currently implement
+these functions; it only provides them as stub functions that always
+return failure.
+</para>
+
+<para>
+<function>lwres_gethostbyname()</function> and
+<function>lwres_gethostbyname2()</function> look up the hostname
+<parameter>name</parameter>.
+<function>lwres_gethostbyname()</function> always looks for an IPv4
+address while <function>lwres_gethostbyname2()</function> looks for an
+address of protocol family <parameter>af</parameter>: either
+<type>PF_INET</type> or <type>PF_INET6</type> &mdash; IPv4 or IPV6
+addresses respectively. Successful calls of the functions return a
+<type>struct hostent</type>for the name that was looked up.
+<type>NULL</type> is returned if the lookups by
+<function>lwres_gethostbyname()</function> or
+<function>lwres_gethostbyname2()</function> fail.
+</para>
+
+<para>
+Reverse lookups of addresses are performed by
+<function>lwres_gethostbyaddr()</function>.
+<parameter>addr</parameter> is an address of length
+<parameter>len</parameter> bytes and protocol family
+<parameter>type</parameter> &mdash; <type>PF_INET</type> or
+<type>PF_INET6</type>.
+<function>lwres_gethostbyname_r()</function> is a thread-safe function
+for forward lookups. If an error occurs, an error code is returned in
+<parameter>*error</parameter>.
+<parameter>resbuf</parameter> is a pointer to a <type>struct
+hostent</type> which is initialised by a successful call to
+<function>lwres_gethostbyname_r()</function> .
+<parameter>buf</parameter> is a buffer of length
+<parameter>len</parameter> bytes which is used to store the
+<constant>h_name</constant>, <constant>h_aliases</constant>, and
+<constant>h_addr_list</constant> elements of the <type>struct
+hostent</type> returned in <parameter>resbuf</parameter>.
+Successful calls to <function>lwres_gethostbyname_r()</function>
+return <parameter>resbuf</parameter>,
+which is a pointer to the <type>struct hostent</type> it created.
+</para>
+
+<para>
+<function>lwres_gethostbyaddr_r()</function> is a thread-safe function
+that performs a reverse lookup of address <parameter>addr</parameter>
+which is <parameter>len</parameter> bytes long and is of protocol
+family <parameter>type</parameter> &mdash; <type>PF_INET</type> or
+<type>PF_INET6</type>. If an error occurs, the error code is returned
+in <parameter>*error</parameter>. The other function parameters are
+identical to those in <function>lwres_gethostbyname_r()</function>.
+<parameter>resbuf</parameter> is a pointer to a <type>struct
+hostent</type> which is initialised by a successful call to
+<function>lwres_gethostbyaddr_r()</function>.
+<parameter>buf</parameter> is a buffer of length
+<parameter>len</parameter> bytes which is used to store the
+<constant>h_name</constant>, <constant>h_aliases</constant>, and
+<constant>h_addr_list</constant> elements of the <type>struct
+hostent</type> returned in <parameter>resbuf</parameter>. Successful
+calls to <function>lwres_gethostbyaddr_r()</function> return
+<parameter>resbuf</parameter>, which is a pointer to the
+<function>struct hostent()</function> it created.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The functions
+<function>lwres_gethostbyname()</function>,
+<function>lwres_gethostbyname2()</function>,
+<function>lwres_gethostbyaddr()</function>,
+and
+<function>lwres_gethostent()</function>
+return NULL to indicate an error. In this case the global variable
+<type>lwres_h_errno</type>
+will contain one of the following error codes defined in
+<filename>&lt;lwres/netdb.h&gt;</filename>:
+
+<variablelist>
+<varlistentry><term><constant>HOST_NOT_FOUND</constant></term>
+<listitem>
+<para>
+The host or address was not found.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>TRY_AGAIN</constant></term>
+<listitem>
+<para>
+A recoverable error occurred, e.g., a timeout.
+Retrying the lookup may succeed.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_RECOVERY</constant></term>
+<listitem>
+<para>
+A non-recoverable error occurred.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_DATA</constant></term>
+<listitem>
+<para>
+The name exists, but has no address information
+associated with it (or vice versa in the case
+of a reverse lookup). The code NO_ADDRESS
+is accepted as a synonym for NO_DATA for backwards
+compatibility.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+
+<para>
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+translates these error codes to suitable error messages.
+</para>
+
+<para>
+<function>lwres_gethostent()</function>
+and
+<function>lwres_gethostent_r()</function>
+always return
+<type>NULL</type>.
+</para>
+
+<para>
+Successful calls to <function>lwres_gethostbyname_r()</function> and
+<function>lwres_gethostbyaddr_r()</function> return
+<parameter>resbuf</parameter>, a pointer to the <type>struct
+hostent</type> that was initialised by these functions. They return
+<type>NULL</type> if the lookups fail or if <parameter>buf</parameter>
+was too small to hold the list of addresses and names referenced by
+the <constant>h_name</constant>, <constant>h_aliases</constant>, and
+<constant>h_addr_list</constant> elements of the <type>struct
+hostent</type>. If <parameter>buf</parameter> was too small, both
+<function>lwres_gethostbyname_r()</function> and
+<function>lwres_gethostbyaddr_r()</function> set the global variable
+<type>errno</type> to <errorcode>ERANGE</errorcode>.
+</para>
+
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>gethostent</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getipnode</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+
+<refsect1>
+<title>BUGS</title>
+<para>
+<function>lwres_gethostbyname()</function>,
+<function>lwres_gethostbyname2()</function>,
+<function>lwres_gethostbyaddr()</function>
+and
+<function>lwres_endhostent()</function>
+are not thread safe; they return pointers to static data and
+provide error codes through a global variable.
+Thread-safe versions for name and address lookup are provided by
+<function>lwres_gethostbyname_r()</function>,
+and
+<function>lwres_gethostbyaddr_r()</function>
+respectively.
+</para>
+<para>
+The resolver daemon does not currently support any non-DNS
+name services such as
+<filename>/etc/hosts</filename>
+or
+<type>NIS</type>,
+consequently the above functions don't, either.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_gethostent.html b/src/libfreeswan/liblwres/man/lwres_gethostent.html
new file mode 100644
index 000000000..28671b86b
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gethostent.html
@@ -0,0 +1,827 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gethostent</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gethostent</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_gethostbyname, lwres_gethostbyname2, lwres_gethostbyaddr, lwres_gethostent, lwres_sethostent, lwres_endhostent, lwres_gethostbyname_r, lwres_gethostbyaddr_r, lwres_gethostent_r, lwres_sethostent_r, lwres_endhostent_r&nbsp;--&nbsp;lightweight resolver get network host entry</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN21"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN22"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyname</CODE
+>(const char *name);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyname2</CODE
+>(const char *name, int af);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyaddr</CODE
+>(const char *addr, int len, int type);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostent</CODE
+>(void);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_sethostent</CODE
+>(int stayopen);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_endhostent</CODE
+>(void);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyname_r</CODE
+>(const char *name, struct hostent *resbuf, char *buf, int buflen, int *error);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostbyaddr_r</CODE
+>(const char *addr, int len, int type, struct hostent *resbuf, char *buf, int buflen, int *error);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_gethostent_r</CODE
+>(struct hostent *resbuf, char *buf, int buflen, int *error);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_sethostent_r</CODE
+>(int stayopen);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_endhostent_r</CODE
+>(void);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN84"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions provide hostname-to-address and
+address-to-hostname lookups by means of the lightweight resolver.
+They are similar to the standard
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>gethostent</SPAN
+>(3)</SPAN
+>
+functions provided by most operating systems.
+They use a
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>
+which is usually defined in
+<TT
+CLASS="FILENAME"
+>&lt;namedb.h&gt;</TT
+>.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */</PRE
+></P
+><P
+>The members of this structure are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>h_name</TT
+></DT
+><DD
+><P
+>The official (canonical) name of the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_aliases</TT
+></DT
+><DD
+><P
+>A NULL-terminated array of alternate names (nicknames) for the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addrtype</TT
+></DT
+><DD
+><P
+>The type of address being returned &mdash;
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_length</TT
+></DT
+><DD
+><P
+>The length of the address in bytes.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+></DT
+><DD
+><P
+>A <SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.</P
+></DD
+></DL
+></DIV
+></P
+><P
+>For backward compatibility with very old software,
+<TT
+CLASS="CONSTANT"
+>h_addr</TT
+>
+is the first address in
+<TT
+CLASS="CONSTANT"
+>h_addr_list.</TT
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostent()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_sethostent()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_endhostent()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostent_r()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_sethostent_r()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_endhostent_r()</TT
+>
+provide iteration over the known host entries on systems that
+provide such functionality through facilities like
+<TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>
+or NIS. The lightweight resolver does not currently implement
+these functions; it only provides them as stub functions that always
+return failure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+> look up the hostname
+<TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+> always looks for an IPv4
+address while <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+> looks for an
+address of protocol family <TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>: either
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+> or <SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+> &mdash; IPv4 or IPV6
+addresses respectively. Successful calls of the functions return a
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>for the name that was looked up.
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> is returned if the lookups by
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+> or
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+> fail.</P
+><P
+>Reverse lookups of addresses are performed by
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>addr</I
+></TT
+> is an address of length
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes and protocol family
+<TT
+CLASS="PARAMETER"
+><I
+>type</I
+></TT
+> &mdash; <SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+> or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> is a thread-safe function
+for forward lookups. If an error occurs, an error code is returned in
+<TT
+CLASS="PARAMETER"
+><I
+>*error</I
+></TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+> is a pointer to a <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> which is initialised by a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> .
+<TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+> is a buffer of length
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes which is used to store the
+<TT
+CLASS="CONSTANT"
+>h_name</TT
+>, <TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>, and
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+> elements of the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> returned in <TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>.
+Successful calls to <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+>
+return <TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>,
+which is a pointer to the <SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+> it created.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> is a thread-safe function
+that performs a reverse lookup of address <TT
+CLASS="PARAMETER"
+><I
+>addr</I
+></TT
+>
+which is <TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes long and is of protocol
+family <TT
+CLASS="PARAMETER"
+><I
+>type</I
+></TT
+> &mdash; <SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+> or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>. If an error occurs, the error code is returned
+in <TT
+CLASS="PARAMETER"
+><I
+>*error</I
+></TT
+>. The other function parameters are
+identical to those in <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+> is a pointer to a <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> which is initialised by a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+>.
+<TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+> is a buffer of length
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+> bytes which is used to store the
+<TT
+CLASS="CONSTANT"
+>h_name</TT
+>, <TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>, and
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+> elements of the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> returned in <TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>. Successful
+calls to <TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> return
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>, which is a pointer to the
+<TT
+CLASS="FUNCTION"
+>struct hostent()</TT
+> it created.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN191"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The functions
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr()</TT
+>,
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostent()</TT
+>
+return NULL to indicate an error. In this case the global variable
+<SPAN
+CLASS="TYPE"
+>lwres_h_errno</SPAN
+>
+will contain one of the following error codes defined in
+<TT
+CLASS="FILENAME"
+>&lt;lwres/netdb.h&gt;</TT
+>:
+
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>HOST_NOT_FOUND</TT
+></DT
+><DD
+><P
+>The host or address was not found.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>TRY_AGAIN</TT
+></DT
+><DD
+><P
+>A recoverable error occurred, e.g., a timeout.
+Retrying the lookup may succeed.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_RECOVERY</TT
+></DT
+><DD
+><P
+>A non-recoverable error occurred.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_DATA</TT
+></DT
+><DD
+><P
+>The name exists, but has no address information
+associated with it (or vice versa in the case
+of a reverse lookup). The code NO_ADDRESS
+is accepted as a synonym for NO_DATA for backwards
+compatibility.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>
+translates these error codes to suitable error messages.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostent()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostent_r()</TT
+>
+always return
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>.</P
+><P
+>Successful calls to <TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> return
+<TT
+CLASS="PARAMETER"
+><I
+>resbuf</I
+></TT
+>, a pointer to the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+> that was initialised by these functions. They return
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> if the lookups fail or if <TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+>
+was too small to hold the list of addresses and names referenced by
+the <TT
+CLASS="CONSTANT"
+>h_name</TT
+>, <TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>, and
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+> elements of the <SPAN
+CLASS="TYPE"
+>struct
+hostent</SPAN
+>. If <TT
+CLASS="PARAMETER"
+><I
+>buf</I
+></TT
+> was too small, both
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+> set the global variable
+<SPAN
+CLASS="TYPE"
+>errno</SPAN
+> to <SPAN
+CLASS="ERRORCODE"
+>ERANGE</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN245"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>gethostent</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getipnode</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN257"
+></A
+><H2
+>BUGS</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gethostbyname()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname2()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_endhostent()</TT
+>
+are not thread safe; they return pointers to static data and
+provide error codes through a global variable.
+Thread-safe versions for name and address lookup are provided by
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyname_r()</TT
+>,
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gethostbyaddr_r()</TT
+>
+respectively.</P
+><P
+>The resolver daemon does not currently support any non-DNS
+name services such as
+<TT
+CLASS="FILENAME"
+>/etc/hosts</TT
+>
+or
+<SPAN
+CLASS="TYPE"
+>NIS</SPAN
+>,
+consequently the above functions don't, either.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_getipnode.3 b/src/libfreeswan/liblwres/man/lwres_getipnode.3
new file mode 100644
index 000000000..39dfc984a
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getipnode.3
@@ -0,0 +1,187 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GETIPNODE" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent \- lightweight resolver nodename / address translation API
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+struct hostent *
+lwres_getipnodebyname(const char *name, int af, int flags, int *error_num);
+.ad
+.sp
+.na
+struct hostent *
+lwres_getipnodebyaddr(const void *src, size_t len, int af, int *error_num);
+.ad
+.sp
+.na
+void
+lwres_freehostent(struct hostent *he);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions perform thread safe, protocol independent
+nodename-to-address and address-to-nodename
+translation as defined in RFC2553.
+.PP
+They use a
+\fBstruct hostent\fR
+which is defined in
+\fInamedb.h\fR:
+.sp
+.nf
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+.sp
+.fi
+.PP
+The members of this structure are:
+.TP
+\fBh_name\fR
+The official (canonical) name of the host.
+.TP
+\fBh_aliases\fR
+A NULL-terminated array of alternate names (nicknames) for the host.
+.TP
+\fBh_addrtype\fR
+The type of address being returned - usually
+\fBPF_INET\fR
+or
+\fBPF_INET6\fR.
+.TP
+\fBh_length\fR
+The length of the address in bytes.
+.TP
+\fBh_addr_list\fR
+A
+\fBNULL\fR
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+.PP
+\fBlwres_getipnodebyname()\fR
+looks up addresses of protocol family
+\fIaf\fR
+for the hostname
+\fIname\fR.
+The
+\fIflags\fR
+parameter contains ORed flag bits to
+specify the types of addresses that are searched
+for, and the types of addresses that are returned.
+The flag bits are:
+.TP
+\fBAI_V4MAPPED\fR
+This is used with an
+\fIaf\fR
+of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped
+IPv6 addresses.
+.TP
+\fBAI_ALL\fR
+This is used with an
+\fIaf\fR
+of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned.
+If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped
+IPv6 addresses.
+.TP
+\fBAI_ADDRCONFIG\fR
+Only return an IPv6 or IPv4 address if here is an active network
+interface of that type. This is not currently implemented
+in the BIND 9 lightweight resolver, and the flag is ignored.
+.TP
+\fBAI_DEFAULT\fR
+This default sets the
+AI_V4MAPPED
+and
+AI_ADDRCONFIG
+flag bits.
+.PP
+\fBlwres_getipnodebyaddr()\fR
+performs a reverse lookup
+of address
+\fIsrc\fR
+which is
+\fIlen\fR
+bytes long.
+\fIaf\fR
+denotes the protocol family, typically
+\fBPF_INET\fR
+or
+\fBPF_INET6\fR.
+.PP
+\fBlwres_freehostent()\fR
+releases all the memory associated with
+the
+\fBstruct hostent\fR
+pointer
+\fIhe\fR.
+Any memory allocated for the
+h_name,
+h_addr_list
+and
+h_aliases
+is freed, as is the memory for the
+\fBhostent\fR
+structure itself.
+.SH "RETURN VALUES"
+.PP
+If an error occurs,
+\fBlwres_getipnodebyname()\fR
+and
+\fBlwres_getipnodebyaddr()\fR
+set
+\fI*error_num\fR
+to an approriate error code and the function returns a
+\fBNULL\fR
+pointer.
+The error codes and their meanings are defined in
+\fI<lwres/netdb.h>\fR:
+.TP
+\fBHOST_NOT_FOUND\fR
+No such host is known.
+.TP
+\fBNO_ADDRESS\fR
+The server recognised the request and the name but no address is
+available. Another type of request to the name server for the
+domain might return an answer.
+.TP
+\fBTRY_AGAIN\fR
+A temporary and possibly transient error occurred, such as a
+failure of a server to respond. The request may succeed if
+retried.
+.TP
+\fBNO_RECOVERY\fR
+An unexpected failure occurred, and retrying the request
+is pointless.
+.PP
+\fBlwres_hstrerror\fR(3)
+translates these error codes to suitable error messages.
+.SH "SEE ALSO"
+.PP
+\fBRFC2553\fR,
+\fBlwres\fR(3),
+\fBlwres_gethostent\fR(3),
+\fBlwres_getaddrinfo\fR(3),
+\fBlwres_getnameinfo\fR(3),
+\fBlwres_hstrerror\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_getipnode.docbook b/src/libfreeswan/liblwres/man/lwres_getipnode.docbook
new file mode 100644
index 000000000..3d4fa7f15
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getipnode.docbook
@@ -0,0 +1,307 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_getipnode.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_getipnode</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_getipnodebyname</refname>
+<refname>lwres_getipnodebyaddr</refname>
+<refname>lwres_freehostent</refname>
+<refpurpose>lightweight resolver nodename / address translation API</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_getipnodebyname</function></funcdef>
+<paramdef>const char *name</paramdef>
+<paramdef>int af</paramdef>
+<paramdef>int flags</paramdef>
+<paramdef>int *error_num</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+struct hostent *
+<function>lwres_getipnodebyaddr</function></funcdef>
+<paramdef>const void *src</paramdef>
+<paramdef>size_t len</paramdef>
+<paramdef>int af</paramdef>
+<paramdef>int *error_num</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_freehostent</function></funcdef>
+<paramdef>struct hostent *he</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+These functions perform thread safe, protocol independent
+nodename-to-address and address-to-nodename
+translation as defined in RFC2553.
+</para>
+
+<para>
+They use a
+<type>struct hostent</type>
+which is defined in
+<filename>namedb.h</filename>:
+<programlisting>
+struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */
+</programlisting>
+</para>
+
+<para>
+The members of this structure are:
+<variablelist>
+<varlistentry><term><constant>h_name</constant></term>
+<listitem>
+<para>
+The official (canonical) name of the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_aliases</constant></term>
+<listitem>
+<para>
+A NULL-terminated array of alternate names (nicknames) for the host.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addrtype</constant></term>
+<listitem>
+<para>
+The type of address being returned - usually
+<type>PF_INET</type>
+or
+<type>PF_INET6</type>.
+
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_length</constant></term>
+<listitem>
+<para>
+The length of the address in bytes.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>h_addr_list</constant></term>
+<listitem>
+<para>
+A
+<type>NULL</type>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+<function>lwres_getipnodebyname()</function>
+looks up addresses of protocol family
+<parameter>af</parameter>
+
+for the hostname
+<parameter>name</parameter>.
+
+The
+<parameter>flags</parameter>
+parameter contains ORed flag bits to
+specify the types of addresses that are searched
+for, and the types of addresses that are returned.
+The flag bits are:
+<variablelist>
+<varlistentry><term><constant>AI_V4MAPPED</constant></term>
+<listitem>
+<para>
+This is used with an
+<parameter>af</parameter>
+of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped
+IPv6 addresses.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>AI_ALL</constant></term>
+<listitem>
+<para>
+This is used with an
+<parameter>af</parameter>
+of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned.
+If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped
+IPv6 addresses.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>AI_ADDRCONFIG</constant></term>
+<listitem>
+<para>
+Only return an IPv6 or IPv4 address if here is an active network
+interface of that type. This is not currently implemented
+in the BIND 9 lightweight resolver, and the flag is ignored.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>AI_DEFAULT</constant></term>
+<listitem>
+<para>
+This default sets the
+<constant>AI_V4MAPPED</constant>
+and
+<constant>AI_ADDRCONFIG</constant>
+flag bits.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+<function>lwres_getipnodebyaddr()</function>
+performs a reverse lookup
+of address
+<parameter>src</parameter>
+which is
+<parameter>len</parameter>
+bytes long.
+<parameter>af</parameter>
+denotes the protocol family, typically
+<type>PF_INET</type>
+or
+<type>PF_INET6</type>.
+
+</para>
+<para>
+<function>lwres_freehostent()</function>
+releases all the memory associated with
+the
+<type>struct hostent</type>
+pointer
+<parameter>he</parameter>.
+
+Any memory allocated for the
+<constant>h_name</constant>,
+
+<constant>h_addr_list</constant>
+and
+<constant>h_aliases</constant>
+is freed, as is the memory for the
+<type>hostent</type>
+structure itself.
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+If an error occurs,
+<function>lwres_getipnodebyname()</function>
+and
+<function>lwres_getipnodebyaddr()</function>
+set
+<parameter>*error_num</parameter>
+to an approriate error code and the function returns a
+<type>NULL</type>
+pointer.
+The error codes and their meanings are defined in
+<filename>&lt;lwres/netdb.h&gt;</filename>:
+<variablelist>
+<varlistentry><term><constant>HOST_NOT_FOUND</constant></term>
+<listitem>
+<para>
+No such host is known.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_ADDRESS</constant></term>
+<listitem>
+<para>
+The server recognised the request and the name but no address is
+available. Another type of request to the name server for the
+domain might return an answer.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>TRY_AGAIN</constant></term>
+<listitem>
+<para>
+A temporary and possibly transient error occurred, such as a
+failure of a server to respond. The request may succeed if
+retried.
+</para>
+</listitem></varlistentry>
+<varlistentry><term><constant>NO_RECOVERY</constant></term>
+<listitem>
+<para>
+An unexpected failure occurred, and retrying the request
+is pointless.
+</para>
+</listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+translates these error codes to suitable error messages.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>RFC2553</refentrytitle>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gethostent</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getaddrinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_getipnode.html b/src/libfreeswan/liblwres/man/lwres_getipnode.html
new file mode 100644
index 000000000..d0a71e69d
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getipnode.html
@@ -0,0 +1,529 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getipnode</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getipnode</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getipnodebyname, lwres_getipnodebyaddr, lwres_freehostent&nbsp;--&nbsp;lightweight resolver nodename / address translation API</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN13"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN14"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_getipnodebyname</CODE
+>(const char *name, int af, int flags, int *error_num);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>struct hostent *
+lwres_getipnodebyaddr</CODE
+>(const void *src, size_t len, int af, int *error_num);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_freehostent</CODE
+>(struct hostent *he);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN34"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions perform thread safe, protocol independent
+nodename-to-address and address-to-nodename
+translation as defined in RFC2553.</P
+><P
+>They use a
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>
+which is defined in
+<TT
+CLASS="FILENAME"
+>namedb.h</TT
+>:
+<PRE
+CLASS="PROGRAMLISTING"
+>struct hostent {
+ char *h_name; /* official name of host */
+ char **h_aliases; /* alias list */
+ int h_addrtype; /* host address type */
+ int h_length; /* length of address */
+ char **h_addr_list; /* list of addresses from name server */
+};
+#define h_addr h_addr_list[0] /* address, for backward compatibility */</PRE
+></P
+><P
+>The members of this structure are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>h_name</TT
+></DT
+><DD
+><P
+>The official (canonical) name of the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_aliases</TT
+></DT
+><DD
+><P
+>A NULL-terminated array of alternate names (nicknames) for the host.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addrtype</TT
+></DT
+><DD
+><P
+>The type of address being returned - usually
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.&#13;</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_length</TT
+></DT
+><DD
+><P
+>The length of the address in bytes.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+></DT
+><DD
+><P
+>A
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+terminated array of network addresses for the host.
+Host addresses are returned in network byte order.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getipnodebyname()</TT
+>
+looks up addresses of protocol family
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+
+for the hostname
+<TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+>.
+
+The
+<TT
+CLASS="PARAMETER"
+><I
+>flags</I
+></TT
+>
+parameter contains ORed flag bits to
+specify the types of addresses that are searched
+for, and the types of addresses that are returned.
+The flag bits are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_V4MAPPED</TT
+></DT
+><DD
+><P
+>This is used with an
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+of AF_INET6, and causes IPv4 addresses to be returned as IPv4-mapped
+IPv6 addresses.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_ALL</TT
+></DT
+><DD
+><P
+>This is used with an
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+of AF_INET6, and causes all known addresses (IPv6 and IPv4) to be returned.
+If AI_V4MAPPED is also set, the IPv4 addresses are return as mapped
+IPv6 addresses.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_ADDRCONFIG</TT
+></DT
+><DD
+><P
+>Only return an IPv6 or IPv4 address if here is an active network
+interface of that type. This is not currently implemented
+in the BIND 9 lightweight resolver, and the flag is ignored.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>AI_DEFAULT</TT
+></DT
+><DD
+><P
+>This default sets the
+<TT
+CLASS="CONSTANT"
+>AI_V4MAPPED</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>AI_ADDRCONFIG</TT
+>
+flag bits.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getipnodebyaddr()</TT
+>
+performs a reverse lookup
+of address
+<TT
+CLASS="PARAMETER"
+><I
+>src</I
+></TT
+>
+which is
+<TT
+CLASS="PARAMETER"
+><I
+>len</I
+></TT
+>
+bytes long.
+<TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+>
+denotes the protocol family, typically
+<SPAN
+CLASS="TYPE"
+>PF_INET</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>PF_INET6</SPAN
+>.&#13;</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_freehostent()</TT
+>
+releases all the memory associated with
+the
+<SPAN
+CLASS="TYPE"
+>struct hostent</SPAN
+>
+pointer
+<TT
+CLASS="PARAMETER"
+><I
+>he</I
+></TT
+>.
+
+Any memory allocated for the
+<TT
+CLASS="CONSTANT"
+>h_name</TT
+>,
+
+<TT
+CLASS="CONSTANT"
+>h_addr_list</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>h_aliases</TT
+>
+is freed, as is the memory for the
+<SPAN
+CLASS="TYPE"
+>hostent</SPAN
+>
+structure itself.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN116"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>If an error occurs,
+<TT
+CLASS="FUNCTION"
+>lwres_getipnodebyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getipnodebyaddr()</TT
+>
+set
+<TT
+CLASS="PARAMETER"
+><I
+>*error_num</I
+></TT
+>
+to an approriate error code and the function returns a
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+>
+pointer.
+The error codes and their meanings are defined in
+<TT
+CLASS="FILENAME"
+>&lt;lwres/netdb.h&gt;</TT
+>:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>HOST_NOT_FOUND</TT
+></DT
+><DD
+><P
+>No such host is known.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_ADDRESS</TT
+></DT
+><DD
+><P
+>The server recognised the request and the name but no address is
+available. Another type of request to the name server for the
+domain might return an answer.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>TRY_AGAIN</TT
+></DT
+><DD
+><P
+>A temporary and possibly transient error occurred, such as a
+failure of a server to respond. The request may succeed if
+retried.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NO_RECOVERY</TT
+></DT
+><DD
+><P
+>An unexpected failure occurred, and retrying the request
+is pointless.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>
+translates these error codes to suitable error messages.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN149"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2553</SPAN
+></SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gethostent</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getaddrinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnameinfo</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_getnameinfo.3 b/src/libfreeswan/liblwres/man/lwres_getnameinfo.3
new file mode 100644
index 000000000..61f3ba426
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getnameinfo.3
@@ -0,0 +1,84 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GETNAMEINFO" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_getnameinfo \- lightweight resolver socket address structure to hostname and service name
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+int
+lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+This function is equivalent to the \fBgetnameinfo\fR(3) function defined in RFC2133.
+\fBlwres_getnameinfo()\fR returns the hostname for the
+\fBstruct sockaddr\fR \fIsa\fR which is
+\fIsalen\fR bytes long. The hostname is of length
+\fIhostlen\fR and is returned via
+\fI*host.\fR The maximum length of the hostname is
+1025 bytes: NI_MAXHOST.
+.PP
+The name of the service associated with the port number in
+\fIsa\fR is returned in \fI*serv.\fR
+It is \fIservlen\fR bytes long. The maximum length
+of the service name is NI_MAXSERV - 32 bytes.
+.PP
+The \fIflags\fR argument sets the following
+bits:
+.TP
+\fBNI_NOFQDN\fR
+A fully qualified domain name is not required for local hosts.
+The local part of the fully qualified domain name is returned instead.
+.TP
+\fBNI_NUMERICHOST\fR
+Return the address in numeric form, as if calling inet_ntop(),
+instead of a host name.
+.TP
+\fBNI_NAMEREQD\fR
+A name is required. If the hostname cannot be found in the DNS and
+this flag is set, a non-zero error code is returned.
+If the hostname is not found and the flag is not set, the
+address is returned in numeric form.
+.TP
+\fBNI_NUMERICSERV\fR
+The service name is returned as a digit string representing the port number.
+.TP
+\fBNI_DGRAM\fR
+Specifies that the service being looked up is a datagram
+service, and causes getservbyport() to be called with a second
+argument of "udp" instead of its default of "tcp". This is required
+for the few ports (512-514) that have different services for UDP and
+TCP.
+.SH "RETURN VALUES"
+.PP
+\fBlwres_getnameinfo()\fR
+returns 0 on success or a non-zero error code if an error occurs.
+.SH "SEE ALSO"
+.PP
+\fBRFC2133\fR,
+\fBgetservbyport\fR(3),
+\fBlwres\fR(3),
+\fBlwres_getnameinfo\fR(3),
+\fBlwres_getnamebyaddr\fR(3).
+\fBlwres_net_ntop\fR(3).
+.SH "BUGS"
+.PP
+RFC2133 fails to define what the nonzero return values of
+\fBgetnameinfo\fR(3)
+are.
diff --git a/src/libfreeswan/liblwres/man/lwres_getnameinfo.docbook b/src/libfreeswan/liblwres/man/lwres_getnameinfo.docbook
new file mode 100644
index 000000000..56bcd8b9f
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getnameinfo.docbook
@@ -0,0 +1,154 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_getnameinfo.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_getnameinfo</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_getnameinfo</refname>
+<refpurpose>lightweight resolver socket address structure to hostname and service name</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+int
+<function>lwres_getnameinfo</function></funcdef>
+<paramdef>const struct sockaddr *sa</paramdef>
+<paramdef>size_t salen</paramdef>
+<paramdef>char *host</paramdef>
+<paramdef>size_t hostlen</paramdef>
+<paramdef>char *serv</paramdef>
+<paramdef>size_t servlen</paramdef>
+<paramdef>int flags</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para> This function is equivalent to the <citerefentry>
+<refentrytitle>getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry> function defined in RFC2133.
+<function>lwres_getnameinfo()</function> returns the hostname for the
+<type>struct sockaddr</type> <parameter>sa</parameter> which is
+<parameter>salen</parameter> bytes long. The hostname is of length
+<parameter>hostlen</parameter> and is returned via
+<parameter>*host.</parameter> The maximum length of the hostname is
+1025 bytes: <constant>NI_MAXHOST</constant>.</para>
+
+<para> The name of the service associated with the port number in
+<parameter>sa</parameter> is returned in <parameter>*serv.</parameter>
+It is <parameter>servlen</parameter> bytes long. The maximum length
+of the service name is <constant>NI_MAXSERV</constant> - 32 bytes.
+</para>
+
+<para> The <parameter>flags</parameter> argument sets the following
+bits:
+<variablelist>
+<varlistentry><term><constant>NI_NOFQDN</constant></term>
+<listitem>
+<para>
+A fully qualified domain name is not required for local hosts.
+The local part of the fully qualified domain name is returned instead.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_NUMERICHOST</constant></term>
+<listitem>
+<para>
+Return the address in numeric form, as if calling inet_ntop(),
+instead of a host name.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_NAMEREQD</constant></term>
+<listitem>
+<para>
+A name is required. If the hostname cannot be found in the DNS and
+this flag is set, a non-zero error code is returned.
+If the hostname is not found and the flag is not set, the
+address is returned in numeric form.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_NUMERICSERV</constant></term>
+<listitem>
+<para>
+The service name is returned as a digit string representing the port number.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>NI_DGRAM</constant></term>
+<listitem>
+<para>
+Specifies that the service being looked up is a datagram
+service, and causes getservbyport() to be called with a second
+argument of "udp" instead of its default of "tcp". This is required
+for the few ports (512-514) that have different services for UDP and
+TCP.
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_getnameinfo()</function>
+returns 0 on success or a non-zero error code if an error occurs.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>RFC2133</refentrytitle>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>getservbyport</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>lwres_getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>lwres_getnamebyaddr</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+<citerefentry>
+<refentrytitle>lwres_net_ntop</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</refsect1>
+<refsect1>
+<title>BUGS</title>
+<para>
+RFC2133 fails to define what the nonzero return values of
+<citerefentry>
+<refentrytitle>getnameinfo</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>
+are.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_getnameinfo.html b/src/libfreeswan/liblwres/man/lwres_getnameinfo.html
new file mode 100644
index 000000000..b98a92848
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getnameinfo.html
@@ -0,0 +1,303 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getnameinfo</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getnameinfo</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getnameinfo&nbsp;--&nbsp;lightweight resolver socket address structure to hostname and service name</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>int
+lwres_getnameinfo</CODE
+>(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN24"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+> This function is equivalent to the <SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getnameinfo</SPAN
+>(3)</SPAN
+> function defined in RFC2133.
+<TT
+CLASS="FUNCTION"
+>lwres_getnameinfo()</TT
+> returns the hostname for the
+<SPAN
+CLASS="TYPE"
+>struct sockaddr</SPAN
+> <TT
+CLASS="PARAMETER"
+><I
+>sa</I
+></TT
+> which is
+<TT
+CLASS="PARAMETER"
+><I
+>salen</I
+></TT
+> bytes long. The hostname is of length
+<TT
+CLASS="PARAMETER"
+><I
+>hostlen</I
+></TT
+> and is returned via
+<TT
+CLASS="PARAMETER"
+><I
+>*host.</I
+></TT
+> The maximum length of the hostname is
+1025 bytes: <TT
+CLASS="CONSTANT"
+>NI_MAXHOST</TT
+>.</P
+><P
+> The name of the service associated with the port number in
+<TT
+CLASS="PARAMETER"
+><I
+>sa</I
+></TT
+> is returned in <TT
+CLASS="PARAMETER"
+><I
+>*serv.</I
+></TT
+>
+It is <TT
+CLASS="PARAMETER"
+><I
+>servlen</I
+></TT
+> bytes long. The maximum length
+of the service name is <TT
+CLASS="CONSTANT"
+>NI_MAXSERV</TT
+> - 32 bytes.</P
+><P
+> The <TT
+CLASS="PARAMETER"
+><I
+>flags</I
+></TT
+> argument sets the following
+bits:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NOFQDN</TT
+></DT
+><DD
+><P
+>A fully qualified domain name is not required for local hosts.
+The local part of the fully qualified domain name is returned instead.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NUMERICHOST</TT
+></DT
+><DD
+><P
+>Return the address in numeric form, as if calling inet_ntop(),
+instead of a host name.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NAMEREQD</TT
+></DT
+><DD
+><P
+>A name is required. If the hostname cannot be found in the DNS and
+this flag is set, a non-zero error code is returned.
+If the hostname is not found and the flag is not set, the
+address is returned in numeric form.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_NUMERICSERV</TT
+></DT
+><DD
+><P
+>The service name is returned as a digit string representing the port number.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>NI_DGRAM</TT
+></DT
+><DD
+><P
+>Specifies that the service being looked up is a datagram
+service, and causes getservbyport() to be called with a second
+argument of "udp" instead of its default of "tcp". This is required
+for the few ports (512-514) that have different services for UDP and
+TCP.</P
+></DD
+></DL
+></DIV
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN70"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getnameinfo()</TT
+>
+returns 0 on success or a non-zero error code if an error occurs.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN74"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC2133</SPAN
+></SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getservbyport</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnameinfo</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_getnamebyaddr</SPAN
+>(3)</SPAN
+>.
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_net_ntop</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN94"
+></A
+><H2
+>BUGS</H2
+><P
+>RFC2133 fails to define what the nonzero return values of
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>getnameinfo</SPAN
+>(3)</SPAN
+>
+are.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.3 b/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.3
new file mode 100644
index 000000000..301630e23
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.3
@@ -0,0 +1,142 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GETRRSETBYNAME" "3" "Oct 18, 2000" "BIND9" ""
+.SH NAME
+lwres_getrrsetbyname, lwres_freerrset \- retrieve DNS records
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+int
+lwres_getrrsetbyname(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res);
+.ad
+.sp
+.na
+void
+lwres_freerrset(struct rrsetinfo *rrset);
+.ad
+\fR.PP
+The following structures are used:
+.sp
+.nf
+struct rdatainfo {
+ unsigned int rdi_length; /* length of data */
+ unsigned char *rdi_data; /* record data */
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags; /* RRSET_VALIDATED... */
+ unsigned int rri_rdclass; /* class number */
+ unsigned int rri_rdtype; /* RR type number */
+ unsigned int rri_ttl; /* time to live */
+ unsigned int rri_nrdatas; /* size of rdatas array */
+ unsigned int rri_nsigs; /* size of sigs array */
+ char *rri_name; /* canonical name */
+ struct rdatainfo *rri_rdatas; /* individual records */
+ struct rdatainfo *rri_sigs; /* individual signatures */
+};
+.sp
+.fi
+.SH "DESCRIPTION"
+.PP
+\fBlwres_getrrsetbyname()\fR
+gets a set of resource records associated with a
+\fIhostname\fR,
+\fIclass\fR,
+and
+\fItype\fR.
+\fIhostname\fR
+is
+a pointer a to null-terminated string. The
+\fIflags\fR
+field is currently unused and must be zero.
+.PP
+After a successful call to
+\fBlwres_getrrsetbyname()\fR,
+\fI*res\fR
+is a pointer to an
+\fBrrsetinfo\fR
+structure, containing a list of one or more
+\fBrdatainfo\fR
+structures containing resource records and potentially another list of
+\fBrdatainfo\fR
+structures containing SIG resource records
+associated with those records.
+The members
+rri_rdclass
+and
+rri_rdtype
+are copied from the parameters.
+rri_ttl
+and
+rri_name
+are properties of the obtained rrset.
+The resource records contained in
+rri_rdatas
+and
+rri_sigs
+are in uncompressed DNS wire format.
+Properties of the rdataset are represented in the
+rri_flags
+bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC
+validated and the signatures verified.
+.PP
+All of the information returned by
+\fBlwres_getrrsetbyname()\fR
+is dynamically allocated: the
+rrsetinfo
+and
+rdatainfo
+structures,
+and the canonical host name strings pointed to by the
+rrsetinfostructure.
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+\fBlwres_getrrsetbyname()\fR
+is released by
+\fBlwres_freerrset()\fR.
+\fIrrset\fR
+is a pointer to a
+\fBstruct rrset\fR
+created by a call to
+\fBlwres_getrrsetbyname()\fR.
+.PP
+.SH "RETURN VALUES"
+.PP
+\fBlwres_getrrsetbyname()\fR
+returns zero on success, and one of the following error
+codes if an error occurred:
+.TP
+\fBERRSET_NONAME\fR
+the name does not exist
+.TP
+\fBERRSET_NODATA\fR
+the name exists, but does not have data of the desired type
+.TP
+\fBERRSET_NOMEMORY\fR
+memory could not be allocated
+.TP
+\fBERRSET_INVAL\fR
+a parameter is invalid
+.TP
+\fBERRSET_FAIL\fR
+other failure
+.TP
+\fB\fR
+.SH "SEE ALSO"
+.PP
+\fBlwres\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.docbook b/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.docbook
new file mode 100644
index 000000000..9151c9c57
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.docbook
@@ -0,0 +1,208 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_getrrsetbyname.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+<refentryinfo>
+
+
+<date>Oct 18, 2000</date>
+</refentryinfo>
+<refmeta>
+<refentrytitle>lwres_getrrsetbyname</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+<refnamediv>
+<refname>lwres_getrrsetbyname</refname>
+<refname>lwres_freerrset</refname>
+<refpurpose>retrieve DNS records</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+int
+<function>lwres_getrrsetbyname</function></funcdef>
+<paramdef>const char *hostname</paramdef>
+<paramdef>unsigned int rdclass</paramdef>
+<paramdef>unsigned int rdtype</paramdef>
+<paramdef>unsigned int flags</paramdef>
+<paramdef>struct rrsetinfo **res</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_freerrset</function></funcdef>
+<paramdef>struct rrsetinfo *rrset</paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para>
+The following structures are used:
+<programlisting>
+struct rdatainfo {
+ unsigned int rdi_length; /* length of data */
+ unsigned char *rdi_data; /* record data */
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags; /* RRSET_VALIDATED... */
+ unsigned int rri_rdclass; /* class number */
+ unsigned int rri_rdtype; /* RR type number */
+ unsigned int rri_ttl; /* time to live */
+ unsigned int rri_nrdatas; /* size of rdatas array */
+ unsigned int rri_nsigs; /* size of sigs array */
+ char *rri_name; /* canonical name */
+ struct rdatainfo *rri_rdatas; /* individual records */
+ struct rdatainfo *rri_sigs; /* individual signatures */
+};
+</programlisting>
+</para>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+<function>lwres_getrrsetbyname()</function>
+gets a set of resource records associated with a
+<parameter>hostname</parameter>,
+
+<parameter>class</parameter>,
+
+and
+<parameter>type</parameter>.
+
+<parameter>hostname</parameter>
+is
+a pointer a to null-terminated string. The
+<parameter>flags</parameter>
+field is currently unused and must be zero.
+</para>
+<para>
+After a successful call to
+<function>lwres_getrrsetbyname()</function>,
+
+<parameter>*res</parameter>
+is a pointer to an
+<type>rrsetinfo</type>
+structure, containing a list of one or more
+<type>rdatainfo</type>
+structures containing resource records and potentially another list of
+<type>rdatainfo</type>
+structures containing SIG resource records
+associated with those records.
+The members
+<constant>rri_rdclass</constant>
+and
+<constant>rri_rdtype</constant>
+are copied from the parameters.
+<constant>rri_ttl</constant>
+and
+<constant>rri_name</constant>
+are properties of the obtained rrset.
+The resource records contained in
+<constant>rri_rdatas</constant>
+and
+<constant>rri_sigs</constant>
+are in uncompressed DNS wire format.
+Properties of the rdataset are represented in the
+<constant>rri_flags</constant>
+bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC
+validated and the signatures verified.
+</para>
+<para>
+All of the information returned by
+<function>lwres_getrrsetbyname()</function>
+is dynamically allocated: the
+<constant>rrsetinfo</constant>
+and
+<constant>rdatainfo</constant>
+structures,
+and the canonical host name strings pointed to by the
+<constant>rrsetinfo</constant>structure.
+
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<function>lwres_getrrsetbyname()</function>
+is released by
+<function>lwres_freerrset()</function>.
+
+<parameter>rrset</parameter>
+is a pointer to a
+<type>struct rrset</type>
+created by a call to
+<function>lwres_getrrsetbyname()</function>.
+
+</para>
+<para>
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+<function>lwres_getrrsetbyname()</function>
+returns zero on success, and one of the following error
+codes if an error occurred:
+<variablelist>
+
+<varlistentry><term><constant>ERRSET_NONAME</constant></term>
+<listitem><para>
+the name does not exist
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_NODATA</constant></term>
+<listitem><para>
+the name exists, but does not have data of the desired type
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_NOMEMORY</constant></term>
+<listitem><para>
+memory could not be allocated
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_INVAL</constant></term>
+<listitem><para>
+a parameter is invalid
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant>ERRSET_FAIL</constant></term>
+<listitem><para>
+other failure
+</para></listitem></varlistentry>
+
+<varlistentry><term><constant></constant></term>
+<listitem><para>
+</para></listitem></varlistentry>
+
+</variablelist>
+
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.html b/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.html
new file mode 100644
index 000000000..3e5ab615c
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_getrrsetbyname.html
@@ -0,0 +1,371 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_getrrsetbyname</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_getrrsetbyname</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_getrrsetbyname, lwres_freerrset&nbsp;--&nbsp;retrieve DNS records</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>int
+lwres_getrrsetbyname</CODE
+>(const char *hostname, unsigned int rdclass, unsigned int rdtype, unsigned int flags, struct rrsetinfo **res);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_freerrset</CODE
+>(struct rrsetinfo *rrset);</CODE
+></P
+><P
+></P
+></DIV
+><P
+>The following structures are used:
+<PRE
+CLASS="PROGRAMLISTING"
+>struct rdatainfo {
+ unsigned int rdi_length; /* length of data */
+ unsigned char *rdi_data; /* record data */
+};
+
+struct rrsetinfo {
+ unsigned int rri_flags; /* RRSET_VALIDATED... */
+ unsigned int rri_rdclass; /* class number */
+ unsigned int rri_rdtype; /* RR type number */
+ unsigned int rri_ttl; /* time to live */
+ unsigned int rri_nrdatas; /* size of rdatas array */
+ unsigned int rri_nsigs; /* size of sigs array */
+ char *rri_name; /* canonical name */
+ struct rdatainfo *rri_rdatas; /* individual records */
+ struct rdatainfo *rri_sigs; /* individual signatures */
+};</PRE
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN29"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+gets a set of resource records associated with a
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>,
+
+<TT
+CLASS="PARAMETER"
+><I
+>class</I
+></TT
+>,
+
+and
+<TT
+CLASS="PARAMETER"
+><I
+>type</I
+></TT
+>.
+
+<TT
+CLASS="PARAMETER"
+><I
+>hostname</I
+></TT
+>
+is
+a pointer a to null-terminated string. The
+<TT
+CLASS="PARAMETER"
+><I
+>flags</I
+></TT
+>
+field is currently unused and must be zero.</P
+><P
+>After a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>,
+
+<TT
+CLASS="PARAMETER"
+><I
+>*res</I
+></TT
+>
+is a pointer to an
+<SPAN
+CLASS="TYPE"
+>rrsetinfo</SPAN
+>
+structure, containing a list of one or more
+<SPAN
+CLASS="TYPE"
+>rdatainfo</SPAN
+>
+structures containing resource records and potentially another list of
+<SPAN
+CLASS="TYPE"
+>rdatainfo</SPAN
+>
+structures containing SIG resource records
+associated with those records.
+The members
+<TT
+CLASS="CONSTANT"
+>rri_rdclass</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rri_rdtype</TT
+>
+are copied from the parameters.
+<TT
+CLASS="CONSTANT"
+>rri_ttl</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rri_name</TT
+>
+are properties of the obtained rrset.
+The resource records contained in
+<TT
+CLASS="CONSTANT"
+>rri_rdatas</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rri_sigs</TT
+>
+are in uncompressed DNS wire format.
+Properties of the rdataset are represented in the
+<TT
+CLASS="CONSTANT"
+>rri_flags</TT
+>
+bitfield. If the RRSET_VALIDATED bit is set, the data has been DNSSEC
+validated and the signatures verified. </P
+><P
+>All of the information returned by
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+is dynamically allocated: the
+<TT
+CLASS="CONSTANT"
+>rrsetinfo</TT
+>
+and
+<TT
+CLASS="CONSTANT"
+>rdatainfo</TT
+>
+structures,
+and the canonical host name strings pointed to by the
+<TT
+CLASS="CONSTANT"
+>rrsetinfo</TT
+>structure.
+
+Memory allocated for the dynamically allocated structures created by
+a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+is released by
+<TT
+CLASS="FUNCTION"
+>lwres_freerrset()</TT
+>.
+
+<TT
+CLASS="PARAMETER"
+><I
+>rrset</I
+></TT
+>
+is a pointer to a
+<SPAN
+CLASS="TYPE"
+>struct rrset</SPAN
+>
+created by a call to
+<TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>.&#13;</P
+><P
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN62"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getrrsetbyname()</TT
+>
+returns zero on success, and one of the following error
+codes if an error occurred:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_NONAME</TT
+></DT
+><DD
+><P
+>the name does not exist</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_NODATA</TT
+></DT
+><DD
+><P
+>the name exists, but does not have data of the desired type</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_NOMEMORY</TT
+></DT
+><DD
+><P
+>memory could not be allocated</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_INVAL</TT
+></DT
+><DD
+><P
+>a parameter is invalid</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>ERRSET_FAIL</TT
+></DT
+><DD
+><P
+>other failure</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+></TT
+></DT
+><DD
+><P
+></P
+></DD
+></DL
+></DIV
+>&#13;</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN97"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_gnba.3 b/src/libfreeswan/liblwres/man/lwres_gnba.3
new file mode 100644
index 000000000..515224f77
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gnba.3
@@ -0,0 +1,186 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_GNBA" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free \- lightweight resolver getnamebyaddress message handling
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_gnbarequest_render(lwres_context_t *\fIctx\fB, lwres_gnbarequest_t *\fIreq\fB, lwres_lwpacket_t *\fIpkt\fB, lwres_buffer_t *\fIb\fB);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These are low-level routines for creating and parsing
+lightweight resolver address-to-name lookup request and
+response messages.
+.PP
+There are four main functions for the getnamebyaddr opcode.
+One render function converts a getnamebyaddr request structure \(em
+\fBlwres_gnbarequest_t\fR \(em
+to the lightweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getnamebyaddr request structure.
+Another render function converts the getnamebyaddr response structure \(em
+\fBlwres_gnbaresponse_t\fR
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getnamebyaddr response structure.
+.PP
+These structures are defined in
+\fIlwres/lwres.h\fR.
+They are shown below.
+.sp
+.nf
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;
+.sp
+.fi
+.PP
+\fBlwres_gnbarequest_render()\fR
+uses resolver context
+ctx
+to convert getnamebyaddr request structure
+req
+to canonical format.
+The packet header structure
+pkt
+is initialised and transferred to
+buffer
+b.
+The contents of
+*req
+are then appended to the buffer in canonical format.
+\fBlwres_gnbaresponse_render()\fR
+performs the same task, except it converts a getnamebyaddr response structure
+\fBlwres_gnbaresponse_t\fR
+to the lightweight resolver's canonical format.
+.PP
+\fBlwres_gnbarequest_parse()\fR
+uses context
+ctx
+to convert the contents of packet
+pkt
+to a
+\fBlwres_gnbarequest_t\fR
+structure.
+Buffer
+b
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+\fBlwres_gnbarequest_t\fR
+is made available through
+*structp.
+\fBlwres_gnbaresponse_parse()\fR
+offers the same semantics as
+\fBlwres_gnbarequest_parse()\fR
+except it yields a
+\fBlwres_gnbaresponse_t\fR
+structure.
+.PP
+\fBlwres_gnbaresponse_free()\fR
+and
+\fBlwres_gnbarequest_free()\fR
+release the memory in resolver context
+ctx
+that was allocated to the
+\fBlwres_gnbaresponse_t\fR
+or
+\fBlwres_gnbarequest_t\fR
+structures referenced via
+structp.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+.SH "RETURN VALUES"
+.PP
+The getnamebyaddr opcode functions
+\fBlwres_gnbarequest_render()\fR,
+\fBlwres_gnbaresponse_render()\fR
+\fBlwres_gnbarequest_parse()\fR
+and
+\fBlwres_gnbaresponse_parse()\fR
+all return
+LWRES_R_SUCCESS
+on success.
+They return
+LWRES_R_NOMEMORY
+if memory allocation fails.
+LWRES_R_UNEXPECTEDEND
+is returned if the available space in the buffer
+b
+is too small to accommodate the packet header or the
+\fBlwres_gnbarequest_t\fR
+and
+\fBlwres_gnbaresponse_t\fR
+structures.
+\fBlwres_gnbarequest_parse()\fR
+and
+\fBlwres_gnbaresponse_parse()\fR
+will return
+LWRES_R_UNEXPECTEDEND
+if the buffer is not empty after decoding the received packet.
+These functions will return
+LWRES_R_FAILURE
+if
+\fBpktflags\fR
+in the packet header structure
+\fBlwres_lwpacket_t\fR
+indicate that the packet is not a response to an earlier query.
+.SH "SEE ALSO"
+.PP
+\fBlwres_packet\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_gnba.docbook b/src/libfreeswan/liblwres/man/lwres_gnba.docbook
new file mode 100644
index 000000000..525452085
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gnba.docbook
@@ -0,0 +1,259 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_gnba.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_gnba</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_gnbarequest_render</refname>
+<refname>lwres_gnbaresponse_render</refname>
+<refname>lwres_gnbarequest_parse</refname>
+<refname>lwres_gnbaresponse_parse</refname>
+<refname>lwres_gnbaresponse_free</refname>
+<refname>lwres_gnbarequest_free</refname>
+<refpurpose>lightweight resolver getnamebyaddress message handling</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+
+<funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;lwres/lwres.h&gt;
+</funcsynopsisinfo>
+
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbarequest_render</function>
+</funcdef>
+<paramdef>lwres_context_t *<parameter>ctx</parameter></paramdef>
+<paramdef>lwres_gnbarequest_t *<parameter>req</parameter></paramdef>
+<paramdef>lwres_lwpacket_t *<parameter>pkt</parameter></paramdef>
+<paramdef>lwres_buffer_t *<parameter>b</parameter></paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbaresponse_render</function>
+</funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gnbaresponse_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbarequest_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gnbarequest_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_gnbaresponse_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_gnbaresponse_t **structp</paramdef>
+</funcprototype>
+
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gnbaresponse_free</function>
+</funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gnbaresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_gnbarequest_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_gnbarequest_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These are low-level routines for creating and parsing
+lightweight resolver address-to-name lookup request and
+response messages.
+</para>
+<para>
+There are four main functions for the getnamebyaddr opcode.
+One render function converts a getnamebyaddr request structure &mdash;
+<type>lwres_gnbarequest_t</type> &mdash;
+to the lightweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getnamebyaddr request structure.
+Another render function converts the getnamebyaddr response structure &mdash;
+<type>lwres_gnbaresponse_t</type>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getnamebyaddr response structure.
+</para>
+<para>
+These structures are defined in
+<filename>lwres/lwres.h</filename>.
+They are shown below.
+<programlisting>
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;
+</programlisting>
+</para>
+<para>
+<function>lwres_gnbarequest_render()</function>
+uses resolver context
+<varname>ctx</varname>
+to convert getnamebyaddr request structure
+<varname>req</varname>
+to canonical format.
+The packet header structure
+<varname>pkt</varname>
+is initialised and transferred to
+buffer
+<varname>b</varname>.
+The contents of
+<varname>*req</varname>
+are then appended to the buffer in canonical format.
+<function>lwres_gnbaresponse_render()</function>
+performs the same task, except it converts a getnamebyaddr response structure
+<type>lwres_gnbaresponse_t</type>
+to the lightweight resolver's canonical format.
+</para>
+<para>
+<function>lwres_gnbarequest_parse()</function>
+uses context
+<varname>ctx</varname>
+to convert the contents of packet
+<varname>pkt</varname>
+to a
+<type>lwres_gnbarequest_t</type>
+structure.
+Buffer
+<varname>b</varname>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<type>lwres_gnbarequest_t</type>
+is made available through
+<varname>*structp</varname>.
+<function>lwres_gnbaresponse_parse()</function>
+offers the same semantics as
+<function>lwres_gnbarequest_parse()</function>
+except it yields a
+<type>lwres_gnbaresponse_t</type>
+structure.
+</para>
+<para>
+<function>lwres_gnbaresponse_free()</function>
+and
+<function>lwres_gnbarequest_free()</function>
+release the memory in resolver context
+<varname>ctx</varname>
+that was allocated to the
+<type>lwres_gnbaresponse_t</type>
+or
+<type>lwres_gnbarequest_t</type>
+structures referenced via
+<varname>structp</varname>.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.
+</para>
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The getnamebyaddr opcode functions
+<function>lwres_gnbarequest_render()</function>,
+<function>lwres_gnbaresponse_render()</function>
+<function>lwres_gnbarequest_parse()</function>
+and
+<function>lwres_gnbaresponse_parse()</function>
+all return
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success.
+They return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory allocation fails.
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+is returned if the available space in the buffer
+<varname>b</varname>
+is too small to accommodate the packet header or the
+<type>lwres_gnbarequest_t</type>
+and
+<type>lwres_gnbaresponse_t</type>
+structures.
+<function>lwres_gnbarequest_parse()</function>
+and
+<function>lwres_gnbaresponse_parse()</function>
+will return
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<structfield>pktflags</structfield>
+in the packet header structure
+<type>lwres_lwpacket_t</type>
+indicate that the packet is not a response to an earlier query.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_packet</refentrytitle>
+<manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_gnba.html b/src/libfreeswan/liblwres/man/lwres_gnba.html
new file mode 100644
index 000000000..98cc04dd6
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_gnba.html
@@ -0,0 +1,408 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_gnba</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_gnba</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_gnbarequest_render, lwres_gnbaresponse_render, lwres_gnbarequest_parse, lwres_gnbaresponse_parse, lwres_gnbaresponse_free, lwres_gnbarequest_free&nbsp;--&nbsp;lightweight resolver getnamebyaddress message handling</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN16"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN17"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbarequest_render</CODE
+>(lwres_context_t *ctx, lwres_gnbarequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbaresponse_render</CODE
+>(lwres_context_t *ctx, lwres_gnbaresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbarequest_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_gnbaresponse_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_gnbaresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gnbaresponse_free</CODE
+>(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_gnbarequest_free</CODE
+>(lwres_context_t *ctx, lwres_gnbarequest_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN61"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These are low-level routines for creating and parsing
+lightweight resolver address-to-name lookup request and
+response messages.</P
+><P
+>There are four main functions for the getnamebyaddr opcode.
+One render function converts a getnamebyaddr request structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+> &mdash;
+to the lightweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a getnamebyaddr request structure.
+Another render function converts the getnamebyaddr response structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a getnamebyaddr response structure.</P
+><P
+>These structures are defined in
+<TT
+CLASS="FILENAME"
+>lwres/lwres.h</TT
+>.
+They are shown below.
+<PRE
+CLASS="PROGRAMLISTING"
+>#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+} lwres_gnbarequest_t;
+
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ void *base;
+ size_t baselen;
+} lwres_gnbaresponse_t;</PRE
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_render()</TT
+>
+uses resolver context
+<TT
+CLASS="VARNAME"
+>ctx</TT
+>
+to convert getnamebyaddr request structure
+<TT
+CLASS="VARNAME"
+>req</TT
+>
+to canonical format.
+The packet header structure
+<TT
+CLASS="VARNAME"
+>pkt</TT
+>
+is initialised and transferred to
+buffer
+<TT
+CLASS="VARNAME"
+>b</TT
+>.
+The contents of
+<TT
+CLASS="VARNAME"
+>*req</TT
+>
+are then appended to the buffer in canonical format.
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_render()</TT
+>
+performs the same task, except it converts a getnamebyaddr response structure
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+to the lightweight resolver's canonical format.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+uses context
+<TT
+CLASS="VARNAME"
+>ctx</TT
+>
+to convert the contents of packet
+<TT
+CLASS="VARNAME"
+>pkt</TT
+>
+to a
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+structure.
+Buffer
+<TT
+CLASS="VARNAME"
+>b</TT
+>
+provides space to be used for storing this structure.
+When the function succeeds, the resulting
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+is made available through
+<TT
+CLASS="VARNAME"
+>*structp</TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_parse()</TT
+>
+offers the same semantics as
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+except it yields a
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_free()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_free()</TT
+>
+release the memory in resolver context
+<TT
+CLASS="VARNAME"
+>ctx</TT
+>
+that was allocated to the
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+or
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+structures referenced via
+<TT
+CLASS="VARNAME"
+>structp</TT
+>.
+Any memory associated with ancillary buffers and strings for those
+structures is also discarded.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN97"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The getnamebyaddr opcode functions
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_render()</TT
+>,
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_render()</TT
+>
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_parse()</TT
+>
+all return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success.
+They return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory allocation fails.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+is returned if the available space in the buffer
+<TT
+CLASS="VARNAME"
+>b</TT
+>
+is too small to accommodate the packet header or the
+<SPAN
+CLASS="TYPE"
+>lwres_gnbarequest_t</SPAN
+>
+and
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+structures.
+<TT
+CLASS="FUNCTION"
+>lwres_gnbarequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_gnbaresponse_parse()</TT
+>
+will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="STRUCTFIELD"
+><I
+>pktflags</I
+></TT
+>
+in the packet header structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>
+indicate that the packet is not a response to an earlier query.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN116"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_packet</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_hstrerror.3 b/src/libfreeswan/liblwres/man/lwres_hstrerror.3
new file mode 100644
index 000000000..dd7fa9c4c
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_hstrerror.3
@@ -0,0 +1,67 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_HSTRERROR" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_herror, lwres_hstrerror \- lightweight resolver error message generation
+.SH SYNOPSIS
+\fB#include <lwres/netdb.h>
+.sp
+.na
+void
+lwres_herror(const char *s);
+.ad
+.sp
+.na
+const char *
+lwres_hstrerror(int err);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_herror()\fR prints the string
+\fIs\fR on \fBstderr\fR followed by the string
+generated by \fBlwres_hstrerror()\fR for the error code
+stored in the global variable lwres_h_errno.
+.PP
+\fBlwres_hstrerror()\fR returns an appropriate string
+for the error code gievn by \fIerr\fR. The values of
+the error codes and messages are as follows:
+.TP
+\fBNETDB_SUCCESS\fR
+\fBResolver Error 0 (no error)\fR
+.TP
+\fBHOST_NOT_FOUND\fR
+\fBUnknown host\fR
+.TP
+\fBTRY_AGAIN\fR
+\fBHost name lookup failure\fR
+.TP
+\fBNO_RECOVERY\fR
+\fBUnknown server error\fR
+.TP
+\fBNO_DATA\fR
+\fBNo address associated with name\fR
+.SH "RETURN VALUES"
+.PP
+The string \fBUnknown resolver error\fR is returned by
+\fBlwres_hstrerror()\fR
+when the value of
+lwres_h_errno
+is not a valid error code.
+.SH "SEE ALSO"
+.PP
+\fBherror\fR(3),
+\fBlwres_hstrerror\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_hstrerror.docbook b/src/libfreeswan/liblwres/man/lwres_hstrerror.docbook
new file mode 100644
index 000000000..2f4c06a11
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_hstrerror.docbook
@@ -0,0 +1,124 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_hstrerror.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_hstrerror</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_herror</refname>
+<refname>lwres_hstrerror</refname>
+<refpurpose>lightweight resolver error message generation</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/netdb.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_herror</function></funcdef>
+<paramdef>const char *s</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+const char *
+<function>lwres_hstrerror</function></funcdef>
+<paramdef>int err</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+<function>lwres_herror()</function> prints the string
+<parameter>s</parameter> on <type>stderr</type> followed by the string
+generated by <function>lwres_hstrerror()</function> for the error code
+stored in the global variable <constant>lwres_h_errno</constant>.
+</para>
+
+<para>
+<function>lwres_hstrerror()</function> returns an appropriate string
+for the error code gievn by <parameter>err</parameter>. The values of
+the error codes and messages are as follows:
+
+<variablelist>
+<varlistentry><term><errorcode>NETDB_SUCCESS</errorcode></term>
+<listitem>
+<para>
+<errorname>Resolver Error 0 (no error)</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>HOST_NOT_FOUND</errorcode></term>
+<listitem>
+<para>
+<errorname>Unknown host</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>TRY_AGAIN</errorcode></term>
+<listitem>
+<para>
+<errorname>Host name lookup failure</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>NO_RECOVERY</errorcode></term>
+<listitem>
+<para>
+<errorname>Unknown server error</errorname>
+</para></listitem></varlistentry>
+<varlistentry><term><errorcode>NO_DATA</errorcode></term>
+<listitem>
+<para>
+<errorname>No address associated with name</errorname>
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The string <errorname>Unknown resolver error</errorname> is returned by
+<function>lwres_hstrerror()</function>
+when the value of
+<constant>lwres_h_errno</constant>
+is not a valid error code.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>herror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_hstrerror</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_hstrerror.html b/src/libfreeswan/liblwres/man/lwres_hstrerror.html
new file mode 100644
index 000000000..128b7e4f8
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_hstrerror.html
@@ -0,0 +1,242 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_hstrerror</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_hstrerror</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_herror, lwres_hstrerror&nbsp;--&nbsp;lightweight resolver error message generation</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/netdb.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_herror</CODE
+>(const char *s);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>const char *
+lwres_hstrerror</CODE
+>(int err);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN23"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_herror()</TT
+> prints the string
+<TT
+CLASS="PARAMETER"
+><I
+>s</I
+></TT
+> on <SPAN
+CLASS="TYPE"
+>stderr</SPAN
+> followed by the string
+generated by <TT
+CLASS="FUNCTION"
+>lwres_hstrerror()</TT
+> for the error code
+stored in the global variable <TT
+CLASS="CONSTANT"
+>lwres_h_errno</TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_hstrerror()</TT
+> returns an appropriate string
+for the error code gievn by <TT
+CLASS="PARAMETER"
+><I
+>err</I
+></TT
+>. The values of
+the error codes and messages are as follows:
+
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>NETDB_SUCCESS</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Resolver Error 0 (no error)</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>HOST_NOT_FOUND</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Unknown host</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>TRY_AGAIN</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Host name lookup failure</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>NO_RECOVERY</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>Unknown server error</SPAN
+></P
+></DD
+><DT
+><SPAN
+CLASS="ERRORCODE"
+>NO_DATA</SPAN
+></DT
+><DD
+><P
+><SPAN
+CLASS="ERRORNAME"
+>No address associated with name</SPAN
+></P
+></DD
+></DL
+></DIV
+></P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN65"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The string <SPAN
+CLASS="ERRORNAME"
+>Unknown resolver error</SPAN
+> is returned by
+<TT
+CLASS="FUNCTION"
+>lwres_hstrerror()</TT
+>
+when the value of
+<TT
+CLASS="CONSTANT"
+>lwres_h_errno</TT
+>
+is not a valid error code.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN71"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>herror</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_hstrerror</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_inetntop.3 b/src/libfreeswan/liblwres/man/lwres_inetntop.3
new file mode 100644
index 000000000..983a33d85
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_inetntop.3
@@ -0,0 +1,52 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_INETNTOP" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_net_ntop \- lightweight resolver IP address presentation
+.SH SYNOPSIS
+\fB#include <lwres/net.h>
+.sp
+.na
+const char *
+lwres_net_ntop(int af, const void *src, char *dst, size_t size);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_net_ntop()\fR converts an IP address of
+protocol family \fIaf\fR \(em IPv4 or IPv6 \(em
+at location \fIsrc\fR from network format to its
+conventional representation as a string. For IPv4 addresses, that
+string would be a dotted-decimal. An IPv6 address would be
+represented in colon notation as described in RFC1884.
+.PP
+The generated string is copied to \fIdst\fR provided
+\fIsize\fR indicates it is long enough to store the
+ASCII representation of the address.
+.SH "RETURN VALUES"
+.PP
+If successful, the function returns \fIdst\fR:
+a pointer to a string containing the presentation format of the
+address. \fBlwres_net_ntop()\fR returns
+\fBNULL\fR and sets the global variable
+errno to EAFNOSUPPORT if
+the protocol family given in \fIaf\fR is not
+supported.
+.SH "SEE ALSO"
+.PP
+\fBRFC1884\fR,
+\fBinet_ntop\fR(3),
+\fBerrno\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_inetntop.docbook b/src/libfreeswan/liblwres/man/lwres_inetntop.docbook
new file mode 100644
index 000000000..8daa36351
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_inetntop.docbook
@@ -0,0 +1,99 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_inetntop.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_inetntop</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_net_ntop</refname>
+<refpurpose>lightweight resolver IP address presentation</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/net.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+const char *
+<function>lwres_net_ntop</function></funcdef>
+<paramdef>int af</paramdef>
+<paramdef>const void *src</paramdef>
+<paramdef>char *dst</paramdef>
+<paramdef>size_t size</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+<function>lwres_net_ntop()</function> converts an IP address of
+protocol family <parameter>af</parameter> &mdash; IPv4 or IPv6 &mdash;
+at location <parameter>src</parameter> from network format to its
+conventional representation as a string. For IPv4 addresses, that
+string would be a dotted-decimal. An IPv6 address would be
+represented in colon notation as described in RFC1884.
+</para>
+
+<para>
+The generated string is copied to <parameter>dst</parameter> provided
+<parameter>size</parameter> indicates it is long enough to store the
+ASCII representation of the address.
+</para>
+
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+
+<para>
+If successful, the function returns <parameter>dst</parameter>:
+a pointer to a string containing the presentation format of the
+address. <function>lwres_net_ntop()</function> returns
+<type>NULL</type> and sets the global variable
+<constant>errno</constant> to <errorcode>EAFNOSUPPORT</errorcode> if
+the protocol family given in <parameter>af</parameter> is not
+supported.
+</para>
+
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>RFC1884</refentrytitle>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>inet_ntop</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+<citerefentry>
+<refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_inetntop.html b/src/libfreeswan/liblwres/man/lwres_inetntop.html
new file mode 100644
index 000000000..09d4fea34
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_inetntop.html
@@ -0,0 +1,186 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_inetntop</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_inetntop</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_net_ntop&nbsp;--&nbsp;lightweight resolver IP address presentation</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN11"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN12"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/net.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>const char *
+lwres_net_ntop</CODE
+>(int af, const void *src, char *dst, size_t size);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN21"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_net_ntop()</TT
+> converts an IP address of
+protocol family <TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+> &mdash; IPv4 or IPv6 &mdash;
+at location <TT
+CLASS="PARAMETER"
+><I
+>src</I
+></TT
+> from network format to its
+conventional representation as a string. For IPv4 addresses, that
+string would be a dotted-decimal. An IPv6 address would be
+represented in colon notation as described in RFC1884.</P
+><P
+>The generated string is copied to <TT
+CLASS="PARAMETER"
+><I
+>dst</I
+></TT
+> provided
+<TT
+CLASS="PARAMETER"
+><I
+>size</I
+></TT
+> indicates it is long enough to store the
+ASCII representation of the address.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN30"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>If successful, the function returns <TT
+CLASS="PARAMETER"
+><I
+>dst</I
+></TT
+>:
+a pointer to a string containing the presentation format of the
+address. <TT
+CLASS="FUNCTION"
+>lwres_net_ntop()</TT
+> returns
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> and sets the global variable
+<TT
+CLASS="CONSTANT"
+>errno</TT
+> to <SPAN
+CLASS="ERRORCODE"
+>EAFNOSUPPORT</SPAN
+> if
+the protocol family given in <TT
+CLASS="PARAMETER"
+><I
+>af</I
+></TT
+> is not
+supported.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN39"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>RFC1884</SPAN
+></SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>inet_ntop</SPAN
+>(3)</SPAN
+>,
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>errno</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_noop.3 b/src/libfreeswan/liblwres/man/lwres_noop.3
new file mode 100644
index 000000000..50d127029
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_noop.3
@@ -0,0 +1,160 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_NOOP" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free \- lightweight resolver no-op message handling
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);
+.ad
+.sp
+.na
+void
+lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These are low-level routines for creating and parsing
+lightweight resolver no-op request and response messages.
+.PP
+The no-op message is analogous to a \fBping\fR packet:
+a packet is sent to the resolver daemon and is simply echoed back.
+The opcode is intended to allow a client to determine if the server is
+operational or not.
+.PP
+There are four main functions for the no-op opcode.
+One render function converts a no-op request structure \(em
+\fBlwres_nooprequest_t\fR \(em
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a no-op request structure.
+Another render function converts the no-op response structure \(em
+\fBlwres_noopresponse_t\fR
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a no-op response structure.
+.PP
+These structures are defined in
+\fIlwres/lwres.h\fR.
+They are shown below.
+.sp
+.nf
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;
+.sp
+.fi
+Although the structures have different types, they are identical.
+This is because the no-op opcode simply echos whatever data was sent:
+the response is therefore identical to the request.
+.PP
+\fBlwres_nooprequest_render()\fR uses resolver
+context \fIctx\fR to convert no-op request structure
+\fIreq\fR to canonical format. The packet header
+structure \fIpkt\fR is initialised and transferred to
+buffer \fIb\fR. The contents of
+\fI*req\fR are then appended to the buffer in
+canonical format. \fBlwres_noopresponse_render()\fR
+performs the same task, except it converts a no-op response structure
+\fBlwres_noopresponse_t\fR to the lightweight resolver's
+canonical format.
+.PP
+\fBlwres_nooprequest_parse()\fR uses context
+\fIctx\fR to convert the contents of packet
+\fIpkt\fR to a \fBlwres_nooprequest_t\fR
+structure. Buffer \fIb\fR provides space to be used
+for storing this structure. When the function succeeds, the resulting
+\fBlwres_nooprequest_t\fR is made available through
+\fI*structp\fR.
+\fBlwres_noopresponse_parse()\fR offers the same
+semantics as \fBlwres_nooprequest_parse()\fR except it
+yields a \fBlwres_noopresponse_t\fR structure.
+.PP
+\fBlwres_noopresponse_free()\fR and
+\fBlwres_nooprequest_free()\fR release the memory in
+resolver context \fIctx\fR that was allocated to the
+\fBlwres_noopresponse_t\fR or \fBlwres_nooprequest_t\fR
+structures referenced via \fIstructp\fR.
+.SH "RETURN VALUES"
+.PP
+The no-op opcode functions
+\fBlwres_nooprequest_render()\fR,
+\fBlwres_noopresponse_render()\fR
+\fBlwres_nooprequest_parse()\fR
+and
+\fBlwres_noopresponse_parse()\fR
+all return
+LWRES_R_SUCCESS
+on success.
+They return
+LWRES_R_NOMEMORY
+if memory allocation fails.
+LWRES_R_UNEXPECTEDEND
+is returned if the available space in the buffer
+\fIb\fR
+is too small to accommodate the packet header or the
+\fBlwres_nooprequest_t\fR
+and
+\fBlwres_noopresponse_t\fR
+structures.
+\fBlwres_nooprequest_parse()\fR
+and
+\fBlwres_noopresponse_parse()\fR
+will return
+LWRES_R_UNEXPECTEDEND
+if the buffer is not empty after decoding the received packet.
+These functions will return
+LWRES_R_FAILURE
+if
+pktflags
+in the packet header structure
+\fBlwres_lwpacket_t\fR
+indicate that the packet is not a response to an earlier query.
+.SH "SEE ALSO"
+.PP
+\fBlwres_packet\fR(3)
diff --git a/src/libfreeswan/liblwres/man/lwres_noop.docbook b/src/libfreeswan/liblwres/man/lwres_noop.docbook
new file mode 100644
index 000000000..18762e515
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_noop.docbook
@@ -0,0 +1,229 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_noop.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_noop</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_nooprequest_render</refname>
+<refname>lwres_noopresponse_render</refname>
+<refname>lwres_nooprequest_parse</refname>
+<refname>lwres_noopresponse_parse</refname>
+<refname>lwres_noopresponse_free</refname>
+<refname>lwres_nooprequest_free</refname>
+<refpurpose>lightweight resolver no-op message handling</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>
+#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_nooprequest_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_nooprequest_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_noopresponse_render</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_noopresponse_t *req</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_nooprequest_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_nooprequest_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_noopresponse_parse</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+<paramdef>lwres_noopresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_noopresponse_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_noopresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+void
+<function>lwres_nooprequest_free</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_nooprequest_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These are low-level routines for creating and parsing
+lightweight resolver no-op request and response messages.
+</para>
+<para>
+The no-op message is analogous to a <command>ping</command> packet:
+a packet is sent to the resolver daemon and is simply echoed back.
+The opcode is intended to allow a client to determine if the server is
+operational or not.
+</para>
+<para>
+There are four main functions for the no-op opcode.
+One render function converts a no-op request structure &mdash;
+<type>lwres_nooprequest_t</type> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a no-op request structure.
+Another render function converts the no-op response structure &mdash;
+<type>lwres_noopresponse_t</type>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a no-op response structure.
+</para>
+<para>
+These structures are defined in
+<filename>lwres/lwres.h</filename>.
+
+They are shown below.
+<programlisting>
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;
+</programlisting>
+Although the structures have different types, they are identical.
+This is because the no-op opcode simply echos whatever data was sent:
+the response is therefore identical to the request.
+</para>
+
+<para>
+<function>lwres_nooprequest_render()</function> uses resolver
+context <parameter>ctx</parameter> to convert no-op request structure
+<parameter>req</parameter> to canonical format. The packet header
+structure <parameter>pkt</parameter> is initialised and transferred to
+buffer <parameter>b</parameter>. The contents of
+<parameter>*req</parameter> are then appended to the buffer in
+canonical format. <function>lwres_noopresponse_render()</function>
+performs the same task, except it converts a no-op response structure
+<type>lwres_noopresponse_t</type> to the lightweight resolver's
+canonical format.
+</para>
+
+<para>
+<function>lwres_nooprequest_parse()</function> uses context
+<parameter>ctx</parameter> to convert the contents of packet
+<parameter>pkt</parameter> to a <type>lwres_nooprequest_t</type>
+structure. Buffer <parameter>b</parameter> provides space to be used
+for storing this structure. When the function succeeds, the resulting
+<type>lwres_nooprequest_t</type> is made available through
+<parameter>*structp</parameter>.
+<function>lwres_noopresponse_parse()</function> offers the same
+semantics as <function>lwres_nooprequest_parse()</function> except it
+yields a <type>lwres_noopresponse_t</type> structure.
+</para>
+
+<para>
+<function>lwres_noopresponse_free()</function> and
+<function>lwres_nooprequest_free()</function> release the memory in
+resolver context <parameter>ctx</parameter> that was allocated to the
+<type>lwres_noopresponse_t</type> or <type>lwres_nooprequest_t</type>
+structures referenced via <parameter>structp</parameter>.
+</para>
+
+</refsect1>
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+The no-op opcode functions
+<function>lwres_nooprequest_render()</function>,
+
+<function>lwres_noopresponse_render()</function>
+<function>lwres_nooprequest_parse()</function>
+and
+<function>lwres_noopresponse_parse()</function>
+all return
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success.
+They return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+if memory allocation fails.
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+is returned if the available space in the buffer
+<parameter>b</parameter>
+is too small to accommodate the packet header or the
+<type>lwres_nooprequest_t</type>
+and
+<type>lwres_noopresponse_t</type>
+structures.
+<function>lwres_nooprequest_parse()</function>
+and
+<function>lwres_noopresponse_parse()</function>
+will return
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if
+<constant>pktflags</constant>
+in the packet header structure
+<type>lwres_lwpacket_t</type>
+indicate that the packet is not a response to an earlier query.
+</para>
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_packet</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+</para>
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_noop.html b/src/libfreeswan/liblwres/man/lwres_noop.html
new file mode 100644
index 000000000..fdb5da103
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_noop.html
@@ -0,0 +1,409 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_noop</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_noop</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_nooprequest_render, lwres_noopresponse_render, lwres_nooprequest_parse, lwres_noopresponse_parse, lwres_noopresponse_free, lwres_nooprequest_free&nbsp;--&nbsp;lightweight resolver no-op message handling</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN16"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN17"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_nooprequest_render</CODE
+>(lwres_context_t *ctx, lwres_nooprequest_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_noopresponse_render</CODE
+>(lwres_context_t *ctx, lwres_noopresponse_t *req, lwres_lwpacket_t *pkt, lwres_buffer_t *b);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_nooprequest_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_noopresponse_parse</CODE
+>(lwres_context_t *ctx, lwres_buffer_t *b, lwres_lwpacket_t *pkt, lwres_noopresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_noopresponse_free</CODE
+>(lwres_context_t *ctx, lwres_noopresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>void
+lwres_nooprequest_free</CODE
+>(lwres_context_t *ctx, lwres_nooprequest_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN57"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These are low-level routines for creating and parsing
+lightweight resolver no-op request and response messages.</P
+><P
+>The no-op message is analogous to a <B
+CLASS="COMMAND"
+>ping</B
+> packet:
+a packet is sent to the resolver daemon and is simply echoed back.
+The opcode is intended to allow a client to determine if the server is
+operational or not.</P
+><P
+>There are four main functions for the no-op opcode.
+One render function converts a no-op request structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+> &mdash;
+to the lighweight resolver's canonical format.
+It is complemented by a parse function that converts a packet in this
+canonical format to a no-op request structure.
+Another render function converts the no-op response structure &mdash;
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+>
+to the canonical format.
+This is complemented by a parse function which converts a packet in
+canonical format to a no-op response structure.</P
+><P
+>These structures are defined in
+<TT
+CLASS="FILENAME"
+>lwres/lwres.h</TT
+>.
+
+They are shown below.
+<PRE
+CLASS="PROGRAMLISTING"
+>#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_nooprequest_t;
+
+typedef struct {
+ lwres_uint16_t datalength;
+ unsigned char *data;
+} lwres_noopresponse_t;</PRE
+>
+Although the structures have different types, they are identical.
+This is because the no-op opcode simply echos whatever data was sent:
+the response is therefore identical to the request.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_nooprequest_render()</TT
+> uses resolver
+context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> to convert no-op request structure
+<TT
+CLASS="PARAMETER"
+><I
+>req</I
+></TT
+> to canonical format. The packet header
+structure <TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+> is initialised and transferred to
+buffer <TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>. The contents of
+<TT
+CLASS="PARAMETER"
+><I
+>*req</I
+></TT
+> are then appended to the buffer in
+canonical format. <TT
+CLASS="FUNCTION"
+>lwres_noopresponse_render()</TT
+>
+performs the same task, except it converts a no-op response structure
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+> to the lightweight resolver's
+canonical format.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+> uses context
+<TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> to convert the contents of packet
+<TT
+CLASS="PARAMETER"
+><I
+>pkt</I
+></TT
+> to a <SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+>
+structure. Buffer <TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+> provides space to be used
+for storing this structure. When the function succeeds, the resulting
+<SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+> is made available through
+<TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_parse()</TT
+> offers the same
+semantics as <TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+> except it
+yields a <SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+> structure.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_noopresponse_free()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_free()</TT
+> release the memory in
+resolver context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> that was allocated to the
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+> or <SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+>
+structures referenced via <TT
+CLASS="PARAMETER"
+><I
+>structp</I
+></TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN95"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>The no-op opcode functions
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_render()</TT
+>,
+
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_render()</TT
+>
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_parse()</TT
+>
+all return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success.
+They return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+if memory allocation fails.
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+is returned if the available space in the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>
+is too small to accommodate the packet header or the
+<SPAN
+CLASS="TYPE"
+>lwres_nooprequest_t</SPAN
+>
+and
+<SPAN
+CLASS="TYPE"
+>lwres_noopresponse_t</SPAN
+>
+structures.
+<TT
+CLASS="FUNCTION"
+>lwres_nooprequest_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_noopresponse_parse()</TT
+>
+will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer is not empty after decoding the received packet.
+These functions will return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if
+<TT
+CLASS="CONSTANT"
+>pktflags</TT
+>
+in the packet header structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>
+indicate that the packet is not a response to an earlier query.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN114"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_packet</SPAN
+>(3)</SPAN
+></P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_packet.3 b/src/libfreeswan/liblwres/man/lwres_packet.3
new file mode 100644
index 000000000..d7fb6f077
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_packet.3
@@ -0,0 +1,149 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_PACKET" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_lwpacket_renderheader, lwres_lwpacket_parseheader \- lightweight resolver packet handling functions
+.SH SYNOPSIS
+\fB#include <lwres/lwpacket.h>
+.sp
+.na
+lwres_result_t
+lwres_lwpacket_renderheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_lwpacket_parseheader(lwres_buffer_t *b, lwres_lwpacket_t *pkt);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+These functions rely on a
+\fBstruct lwres_lwpacket\fR
+which is defined in
+\fIlwres/lwpacket.h\fR.
+.sp
+.nf
+typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+.sp
+.fi
+.PP
+The elements of this structure are:
+.TP
+\fBlength\fR
+the overall packet length, including the entire packet header.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBversion\fR
+the header format. There is currently only one format,
+\fBLWRES_LWPACKETVERSION_0\fR.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBpktflags\fR
+library-defined flags for this packet: for instance whether the packet
+is a request or a reply. Flag values can be set, but not defined by
+the caller.
+This field is filled in by the application wit the exception of the
+LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the
+lwres_gabn_*() and lwres_gnba_*() calls.
+.TP
+\fBserial\fR
+is set by the requestor and is returned in all replies. If two or more
+packets from the same source have the same serial number and are from
+the same source, they are assumed to be duplicates and the latter ones
+may be dropped.
+This field must be set by the application.
+.TP
+\fBopcode\fR
+indicates the operation.
+Opcodes between 0x00000000 and 0x03ffffff are
+reserved for use by the lightweight resolver library. Opcodes between
+0x04000000 and 0xffffffff are application defined.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBresult\fR
+is only valid for replies.
+Results between 0x04000000 and 0xffffffff are application defined.
+Results between 0x00000000 and 0x03ffffff are reserved for library use.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+.TP
+\fBrecvlength\fR
+is the maximum buffer size that the receiver can handle on requests
+and the size of the buffer needed to satisfy a request when the buffer
+is too large for replies.
+This field is supplied by the application.
+.TP
+\fBauthtype\fR
+defines the packet level authentication that is used.
+Authorisation types between 0x1000 and 0xffff are application defined
+and types between 0x0000 and 0x0fff are reserved for library use.
+Currently these are not used and must be zero.
+.TP
+\fBauthlen\fR
+gives the length of the authentication data.
+Since packet authentication is currently not used, this must be zero.
+.PP
+The following opcodes are currently defined:
+.TP
+\fBNOOP\fR
+Success is always returned and the packet contents are echoed.
+The lwres_noop_*() functions should be used for this type.
+.TP
+\fBGETADDRSBYNAME\fR
+returns all known addresses for a given name.
+The lwres_gabn_*() functions should be used for this type.
+.TP
+\fBGETNAMEBYADDR\fR
+return the hostname for the given address.
+The lwres_gnba_*() functions should be used for this type.
+.PP
+\fBlwres_lwpacket_renderheader()\fR transfers the
+contents of lightweight resolver packet structure
+\fBlwres_lwpacket_t\fR \fI*pkt\fR in network
+byte order to the lightweight resolver buffer,
+\fI*b\fR.
+.PP
+\fBlwres_lwpacket_parseheader()\fR performs the
+converse operation. It transfers data in network byte order from
+buffer \fI*b\fR to resolver packet
+\fI*pkt\fR. The contents of the buffer
+\fIb\fR should correspond to a
+\fBlwres_lwpacket_t\fR.
+.SH "RETURN VALUES"
+.PP
+Successful calls to
+\fBlwres_lwpacket_renderheader()\fR and
+\fBlwres_lwpacket_parseheader()\fR return
+LWRES_R_SUCCESS. If there is insufficient
+space to copy data between the buffer \fI*b\fR and
+lightweight resolver packet \fI*pkt\fR both functions
+return LWRES_R_UNEXPECTEDEND.
diff --git a/src/libfreeswan/liblwres/man/lwres_packet.docbook b/src/libfreeswan/liblwres/man/lwres_packet.docbook
new file mode 100644
index 000000000..7b9ed38b3
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_packet.docbook
@@ -0,0 +1,218 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_packet.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+<refentrytitle>lwres_packet</refentrytitle>
+<manvolnum>3</manvolnum>
+<refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_lwpacket_renderheader</refname>
+<refname>lwres_lwpacket_parseheader</refname>
+<refpurpose>lightweight resolver packet handling functions</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwpacket.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_lwpacket_renderheader</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_lwpacket_parseheader</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_lwpacket_t *pkt</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+<refsect1>
+<title>DESCRIPTION</title>
+<para>
+These functions rely on a
+<type>struct lwres_lwpacket</type>
+which is defined in
+<filename>lwres/lwpacket.h</filename>.
+
+<programlisting>
+typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+</programlisting>
+</para>
+
+<para>
+The elements of this structure are:
+<variablelist>
+<varlistentry><term><constant>length</constant></term>
+<listitem>
+<para>
+the overall packet length, including the entire packet header.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>version</constant></term>
+<listitem>
+<para>
+the header format. There is currently only one format,
+<type>LWRES_LWPACKETVERSION_0</type>.
+
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>pktflags</constant></term>
+<listitem>
+<para>
+library-defined flags for this packet: for instance whether the packet
+is a request or a reply. Flag values can be set, but not defined by
+the caller.
+This field is filled in by the application wit the exception of the
+LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the
+lwres_gabn_*() and lwres_gnba_*() calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>serial</constant></term>
+<listitem>
+<para>
+is set by the requestor and is returned in all replies. If two or more
+packets from the same source have the same serial number and are from
+the same source, they are assumed to be duplicates and the latter ones
+may be dropped.
+This field must be set by the application.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>opcode</constant></term>
+<listitem>
+<para>
+indicates the operation.
+Opcodes between 0x00000000 and 0x03ffffff are
+reserved for use by the lightweight resolver library. Opcodes between
+0x04000000 and 0xffffffff are application defined.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>result</constant></term>
+<listitem>
+<para>
+is only valid for replies.
+Results between 0x04000000 and 0xffffffff are application defined.
+Results between 0x00000000 and 0x03ffffff are reserved for library use.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>recvlength</constant></term>
+<listitem>
+<para>
+is the maximum buffer size that the receiver can handle on requests
+and the size of the buffer needed to satisfy a request when the buffer
+is too large for replies.
+This field is supplied by the application.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>authtype</constant></term>
+<listitem>
+<para>
+defines the packet level authentication that is used.
+Authorisation types between 0x1000 and 0xffff are application defined
+and types between 0x0000 and 0x0fff are reserved for library use.
+Currently these are not used and must be zero.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>authlen</constant></term>
+<listitem>
+<para>
+gives the length of the authentication data.
+Since packet authentication is currently not used, this must be zero.
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+<para>
+The following opcodes are currently defined:
+<variablelist>
+<varlistentry><term><constant>NOOP</constant></term>
+<listitem>
+<para>
+Success is always returned and the packet contents are echoed.
+The lwres_noop_*() functions should be used for this type.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>GETADDRSBYNAME</constant></term>
+<listitem>
+<para>
+returns all known addresses for a given name.
+The lwres_gabn_*() functions should be used for this type.
+</para></listitem></varlistentry>
+<varlistentry><term><constant>GETNAMEBYADDR</constant></term>
+<listitem>
+<para>
+return the hostname for the given address.
+The lwres_gnba_*() functions should be used for this type.
+</para></listitem></varlistentry>
+</variablelist>
+</para>
+
+<para>
+<function>lwres_lwpacket_renderheader()</function> transfers the
+contents of lightweight resolver packet structure
+<type>lwres_lwpacket_t</type> <parameter>*pkt</parameter> in network
+byte order to the lightweight resolver buffer,
+<parameter>*b</parameter>.
+</para>
+
+<para>
+<function>lwres_lwpacket_parseheader()</function> performs the
+converse operation. It transfers data in network byte order from
+buffer <parameter>*b</parameter> to resolver packet
+<parameter>*pkt</parameter>. The contents of the buffer
+<parameter>b</parameter> should correspond to a
+<type>lwres_lwpacket_t</type>.
+</para>
+
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para> Successful calls to
+<function>lwres_lwpacket_renderheader()</function> and
+<function>lwres_lwpacket_parseheader()</function> return
+<errorcode>LWRES_R_SUCCESS</errorcode>. If there is insufficient
+space to copy data between the buffer <parameter>*b</parameter> and
+lightweight resolver packet <parameter>*pkt</parameter> both functions
+return <errorcode>LWRES_R_UNEXPECTEDEND</errorcode>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_packet.html b/src/libfreeswan/liblwres/man/lwres_packet.html
new file mode 100644
index 000000000..5c5828f49
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_packet.html
@@ -0,0 +1,373 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_packet</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_packet</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_lwpacket_renderheader, lwres_lwpacket_parseheader&nbsp;--&nbsp;lightweight resolver packet handling functions</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN12"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN13"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwpacket.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_lwpacket_renderheader</CODE
+>(lwres_buffer_t *b, lwres_lwpacket_t *pkt);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_lwpacket_parseheader</CODE
+>(lwres_buffer_t *b, lwres_lwpacket_t *pkt);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN25"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+>These functions rely on a
+<SPAN
+CLASS="TYPE"
+>struct lwres_lwpacket</SPAN
+>
+which is defined in
+<TT
+CLASS="FILENAME"
+>lwres/lwpacket.h</TT
+>.
+
+<PRE
+CLASS="PROGRAMLISTING"
+>typedef struct lwres_lwpacket lwres_lwpacket_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};</PRE
+></P
+><P
+>The elements of this structure are:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>length</TT
+></DT
+><DD
+><P
+>the overall packet length, including the entire packet header.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>version</TT
+></DT
+><DD
+><P
+>the header format. There is currently only one format,
+<SPAN
+CLASS="TYPE"
+>LWRES_LWPACKETVERSION_0</SPAN
+>.
+
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>pktflags</TT
+></DT
+><DD
+><P
+>library-defined flags for this packet: for instance whether the packet
+is a request or a reply. Flag values can be set, but not defined by
+the caller.
+This field is filled in by the application wit the exception of the
+LWRES_LWPACKETFLAG_RESPONSE bit, which is set by the library in the
+lwres_gabn_*() and lwres_gnba_*() calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>serial</TT
+></DT
+><DD
+><P
+>is set by the requestor and is returned in all replies. If two or more
+packets from the same source have the same serial number and are from
+the same source, they are assumed to be duplicates and the latter ones
+may be dropped.
+This field must be set by the application.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>opcode</TT
+></DT
+><DD
+><P
+>indicates the operation.
+Opcodes between 0x00000000 and 0x03ffffff are
+reserved for use by the lightweight resolver library. Opcodes between
+0x04000000 and 0xffffffff are application defined.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>result</TT
+></DT
+><DD
+><P
+>is only valid for replies.
+Results between 0x04000000 and 0xffffffff are application defined.
+Results between 0x00000000 and 0x03ffffff are reserved for library use.
+This field is filled in by the lwres_gabn_*() and lwres_gnba_*()
+calls.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>recvlength</TT
+></DT
+><DD
+><P
+>is the maximum buffer size that the receiver can handle on requests
+and the size of the buffer needed to satisfy a request when the buffer
+is too large for replies.
+This field is supplied by the application.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>authtype</TT
+></DT
+><DD
+><P
+>defines the packet level authentication that is used.
+Authorisation types between 0x1000 and 0xffff are application defined
+and types between 0x0000 and 0x0fff are reserved for library use.
+Currently these are not used and must be zero.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>authlen</TT
+></DT
+><DD
+><P
+>gives the length of the authentication data.
+Since packet authentication is currently not used, this must be zero.</P
+></DD
+></DL
+></DIV
+></P
+><P
+>The following opcodes are currently defined:
+<P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><TT
+CLASS="CONSTANT"
+>NOOP</TT
+></DT
+><DD
+><P
+>Success is always returned and the packet contents are echoed.
+The lwres_noop_*() functions should be used for this type.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>GETADDRSBYNAME</TT
+></DT
+><DD
+><P
+>returns all known addresses for a given name.
+The lwres_gabn_*() functions should be used for this type.</P
+></DD
+><DT
+><TT
+CLASS="CONSTANT"
+>GETNAMEBYADDR</TT
+></DT
+><DD
+><P
+>return the hostname for the given address.
+The lwres_gnba_*() functions should be used for this type.</P
+></DD
+></DL
+></DIV
+></P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_lwpacket_renderheader()</TT
+> transfers the
+contents of lightweight resolver packet structure
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+> <TT
+CLASS="PARAMETER"
+><I
+>*pkt</I
+></TT
+> in network
+byte order to the lightweight resolver buffer,
+<TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_lwpacket_parseheader()</TT
+> performs the
+converse operation. It transfers data in network byte order from
+buffer <TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+> to resolver packet
+<TT
+CLASS="PARAMETER"
+><I
+>*pkt</I
+></TT
+>. The contents of the buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+> should correspond to a
+<SPAN
+CLASS="TYPE"
+>lwres_lwpacket_t</SPAN
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN107"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+> Successful calls to
+<TT
+CLASS="FUNCTION"
+>lwres_lwpacket_renderheader()</TT
+> and
+<TT
+CLASS="FUNCTION"
+>lwres_lwpacket_parseheader()</TT
+> return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>. If there is insufficient
+space to copy data between the buffer <TT
+CLASS="PARAMETER"
+><I
+>*b</I
+></TT
+> and
+lightweight resolver packet <TT
+CLASS="PARAMETER"
+><I
+>*pkt</I
+></TT
+> both functions
+return <SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/man/lwres_resutil.3 b/src/libfreeswan/liblwres/man/lwres_resutil.3
new file mode 100644
index 000000000..6db4825b0
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_resutil.3
@@ -0,0 +1,151 @@
+.\"
+.\" Copyright (C) 2000, 2001 Internet Software Consortium.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+.\" DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+.\" INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+.\" FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+.\" NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+.\" WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.TH "LWRES_RESUTIL" "3" "Jun 30, 2000" "BIND9" ""
+.SH NAME
+lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr \- lightweight resolver utility functions
+.SH SYNOPSIS
+\fB#include <lwres/lwres.h>
+.sp
+.na
+lwres_result_t
+lwres_string_parse(lwres_buffer_t *b, char **c, lwres_uint16_t *len);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_getaddrsbyname(lwres_context_t *ctx, const char *name, lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);
+.ad
+.sp
+.na
+lwres_result_t
+lwres_getnamebyaddr(lwres_context_t *ctx, lwres_uint32_t addrtype, lwres_uint16_t addrlen, const unsigned char *addr, lwres_gnbaresponse_t **structp);
+.ad
+\fR.SH "DESCRIPTION"
+.PP
+\fBlwres_string_parse()\fR retrieves a DNS-encoded
+string starting the current pointer of lightweight resolver buffer
+\fIb\fR: i.e. b->current.
+When the function returns, the address of the first byte of the
+encoded string is returned via \fI*c\fR and the
+length of that string is given by \fI*len\fR. The
+buffer's current pointer is advanced to point at the character
+following the string length, the encoded string, and the trailing
+\fBNULL\fR character.
+.PP
+\fBlwres_addr_parse()\fR extracts an address from the
+buffer \fIb\fR. The buffer's current pointer
+b->current is presumed to point at an encoded
+address: the address preceded by a 32-bit protocol family identifier
+and a 16-bit length field. The encoded address is copied to
+addr->address and
+addr->length indicates the size in bytes of
+the address that was copied. b->current is
+advanced to point at the next byte of available data in the buffer
+following the encoded address.
+.PP
+\fBlwres_getaddrsbyname()\fR
+and
+\fBlwres_getnamebyaddr()\fR
+use the
+\fBlwres_gnbaresponse_t\fR
+structure defined below:
+.sp
+.nf
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+.sp
+.fi
+The contents of this structure are not manipulated directly but
+they are controlled through the
+\fBlwres_gabn\fR(3)
+functions.
+.PP
+The lightweight resolver uses
+\fBlwres_getaddrsbyname()\fR to perform foward lookups.
+Hostname \fIname\fR is looked up using the resolver
+context \fIctx\fR for memory allocation.
+\fIaddrtypes\fR is a bitmask indicating which type of
+addresses are to be looked up. Current values for this bitmask are
+\fBLWRES_ADDRTYPE_V4\fR for IPv4 addresses and
+\fBLWRES_ADDRTYPE_V6\fR for IPv6 addresses. Results of the
+lookup are returned in \fI*structp\fR.
+.PP
+\fBlwres_getnamebyaddr()\fR performs reverse lookups.
+Resolver context \fIctx\fR is used for memory
+allocation. The address type is indicated by
+\fIaddrtype\fR: \fBLWRES_ADDRTYPE_V4\fR or
+\fBLWRES_ADDRTYPE_V6\fR. The address to be looked up is given
+by \fIaddr\fR and its length is
+\fIaddrlen\fR bytes. The result of the function call
+is made available through \fI*structp\fR.
+.SH "RETURN VALUES"
+.PP
+Successful calls to
+\fBlwres_string_parse()\fR
+and
+\fBlwres_addr_parse()\fR
+return
+LWRES_R_SUCCESS.
+Both functions return
+LWRES_R_FAILURE
+if the buffer is corrupt or
+LWRES_R_UNEXPECTEDEND
+if the buffer has less space than expected for the components of the
+encoded string or address.
+.PP
+\fBlwres_getaddrsbyname()\fR
+returns
+LWRES_R_SUCCESS
+on success and it returns
+LWRES_R_NOTFOUND
+if the hostname
+\fIname\fR
+could not be found.
+.PP
+LWRES_R_SUCCESS
+is returned by a successful call to
+\fBlwres_getnamebyaddr()\fR.
+.PP
+Both
+\fBlwres_getaddrsbyname()\fR
+and
+\fBlwres_getnamebyaddr()\fR
+return
+LWRES_R_NOMEMORY
+when memory allocation requests fail and
+LWRES_R_UNEXPECTEDEND
+if the buffers used for sending queries and receiving replies are too
+small.
+.SH "SEE ALSO"
+.PP
+\fBlwres_buffer\fR(3),
+\fBlwres_gabn\fR(3).
diff --git a/src/libfreeswan/liblwres/man/lwres_resutil.docbook b/src/libfreeswan/liblwres/man/lwres_resutil.docbook
new file mode 100644
index 000000000..72d6dc614
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_resutil.docbook
@@ -0,0 +1,221 @@
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
+<!--
+ - Copyright (C) 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+
+<!-- $Id: lwres_resutil.docbook,v 1.1 2004/03/15 20:35:25 as Exp $ -->
+
+<refentry>
+
+<refentryinfo>
+<date>Jun 30, 2000</date>
+</refentryinfo>
+
+<refmeta>
+ <refentrytitle>lwres_resutil</refentrytitle>
+ <manvolnum>3</manvolnum>
+ <refmiscinfo>BIND9</refmiscinfo>
+</refmeta>
+
+<refnamediv>
+<refname>lwres_string_parse</refname>
+<refname>lwres_addr_parse</refname>
+<refname>lwres_getaddrsbyname</refname>
+<refname>lwres_getnamebyaddr</refname>
+<refpurpose>lightweight resolver utility functions</refpurpose>
+</refnamediv>
+<refsynopsisdiv>
+<funcsynopsis>
+<funcsynopsisinfo>#include &lt;lwres/lwres.h&gt;</funcsynopsisinfo>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_string_parse</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>char **c</paramdef>
+<paramdef>lwres_uint16_t *len</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_addr_parse</function></funcdef>
+<paramdef>lwres_buffer_t *b</paramdef>
+<paramdef>lwres_addr_t *addr</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_getaddrsbyname</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>const char *name</paramdef>
+<paramdef>lwres_uint32_t addrtypes</paramdef>
+<paramdef>lwres_gabnresponse_t **structp</paramdef>
+</funcprototype>
+<funcprototype>
+<funcdef>
+lwres_result_t
+<function>lwres_getnamebyaddr</function></funcdef>
+<paramdef>lwres_context_t *ctx</paramdef>
+<paramdef>lwres_uint32_t addrtype</paramdef>
+<paramdef>lwres_uint16_t addrlen</paramdef>
+<paramdef>const unsigned char *addr</paramdef>
+<paramdef>lwres_gnbaresponse_t **structp</paramdef>
+</funcprototype>
+</funcsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+<title>DESCRIPTION</title>
+
+<para>
+<function>lwres_string_parse()</function> retrieves a DNS-encoded
+string starting the current pointer of lightweight resolver buffer
+<parameter>b</parameter>: i.e. <constant>b-&gt;current</constant>.
+When the function returns, the address of the first byte of the
+encoded string is returned via <parameter>*c</parameter> and the
+length of that string is given by <parameter>*len</parameter>. The
+buffer's current pointer is advanced to point at the character
+following the string length, the encoded string, and the trailing
+<type>NULL</type> character.
+</para>
+
+<para>
+<function>lwres_addr_parse()</function> extracts an address from the
+buffer <parameter>b</parameter>. The buffer's current pointer
+<constant>b-&gt;current</constant> is presumed to point at an encoded
+address: the address preceded by a 32-bit protocol family identifier
+and a 16-bit length field. The encoded address is copied to
+<constant>addr-&gt;address</constant> and
+<constant>addr-&gt;length</constant> indicates the size in bytes of
+the address that was copied. <constant>b-&gt;current</constant> is
+advanced to point at the next byte of available data in the buffer
+following the encoded address.
+</para>
+
+<para>
+<function>lwres_getaddrsbyname()</function>
+and
+<function>lwres_getnamebyaddr()</function>
+use the
+<type>lwres_gnbaresponse_t</type>
+structure defined below:
+<programlisting>
+typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;
+</programlisting>
+The contents of this structure are not manipulated directly but
+they are controlled through the
+<citerefentry>
+<refentrytitle>lwres_gabn</refentrytitle><manvolnum>3
+</manvolnum>
+</citerefentry>
+functions.
+</para>
+
+<para>
+The lightweight resolver uses
+<function>lwres_getaddrsbyname()</function> to perform foward lookups.
+Hostname <parameter>name</parameter> is looked up using the resolver
+context <parameter>ctx</parameter> for memory allocation.
+<parameter>addrtypes</parameter> is a bitmask indicating which type of
+addresses are to be looked up. Current values for this bitmask are
+<type>LWRES_ADDRTYPE_V4</type> for IPv4 addresses and
+<type>LWRES_ADDRTYPE_V6</type> for IPv6 addresses. Results of the
+lookup are returned in <parameter>*structp</parameter>.
+</para>
+
+<para>
+<function>lwres_getnamebyaddr()</function> performs reverse lookups.
+Resolver context <parameter>ctx</parameter> is used for memory
+allocation. The address type is indicated by
+<parameter>addrtype</parameter>: <type>LWRES_ADDRTYPE_V4</type> or
+<type>LWRES_ADDRTYPE_V6</type>. The address to be looked up is given
+by <parameter>addr</parameter> and its length is
+<parameter>addrlen</parameter> bytes. The result of the function call
+is made available through <parameter>*structp</parameter>.
+</para>
+</refsect1>
+
+<refsect1>
+<title>RETURN VALUES</title>
+<para>
+Successful calls to
+<function>lwres_string_parse()</function>
+and
+<function>lwres_addr_parse()</function>
+return
+<errorcode>LWRES_R_SUCCESS.</errorcode>
+Both functions return
+<errorcode>LWRES_R_FAILURE</errorcode>
+if the buffer is corrupt or
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffer has less space than expected for the components of the
+encoded string or address.
+</para>
+<para>
+<function>lwres_getaddrsbyname()</function>
+returns
+<errorcode>LWRES_R_SUCCESS</errorcode>
+on success and it returns
+<errorcode>LWRES_R_NOTFOUND</errorcode>
+if the hostname
+<parameter>name</parameter>
+could not be found.
+</para>
+<para>
+<errorcode>LWRES_R_SUCCESS</errorcode>
+is returned by a successful call to
+<function>lwres_getnamebyaddr()</function>.
+</para>
+
+<para>
+Both
+<function>lwres_getaddrsbyname()</function>
+and
+<function>lwres_getnamebyaddr()</function>
+return
+<errorcode>LWRES_R_NOMEMORY</errorcode>
+when memory allocation requests fail and
+<errorcode>LWRES_R_UNEXPECTEDEND</errorcode>
+if the buffers used for sending queries and receiving replies are too
+small.
+</para>
+
+</refsect1>
+<refsect1>
+<title>SEE ALSO</title>
+<para>
+<citerefentry>
+<refentrytitle>lwres_buffer</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>,
+
+<citerefentry>
+<refentrytitle>lwres_gabn</refentrytitle><manvolnum>3</manvolnum>
+</citerefentry>.
+</para>
+
+</refsect1>
+</refentry>
diff --git a/src/libfreeswan/liblwres/man/lwres_resutil.html b/src/libfreeswan/liblwres/man/lwres_resutil.html
new file mode 100644
index 000000000..ae3a2f646
--- /dev/null
+++ b/src/libfreeswan/liblwres/man/lwres_resutil.html
@@ -0,0 +1,412 @@
+<!--
+ - Copyright (C) 2000, 2001 Internet Software Consortium.
+ -
+ - Permission to use, copy, modify, and distribute this software for any
+ - purpose with or without fee is hereby granted, provided that the above
+ - copyright notice and this permission notice appear in all copies.
+ -
+ - THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ - DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ - INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+-->
+<HTML
+><HEAD
+><TITLE
+>lwres_resutil</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.61
+"></HEAD
+><BODY
+CLASS="REFENTRY"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><H1
+><A
+NAME="AEN1"
+>lwres_resutil</A
+></H1
+><DIV
+CLASS="REFNAMEDIV"
+><A
+NAME="AEN8"
+></A
+><H2
+>Name</H2
+>lwres_string_parse, lwres_addr_parse, lwres_getaddrsbyname, lwres_getnamebyaddr&nbsp;--&nbsp;lightweight resolver utility functions</DIV
+><DIV
+CLASS="REFSYNOPSISDIV"
+><A
+NAME="AEN14"
+></A
+><H2
+>Synopsis</H2
+><DIV
+CLASS="FUNCSYNOPSIS"
+><A
+NAME="AEN15"
+></A
+><P
+></P
+><PRE
+CLASS="FUNCSYNOPSISINFO"
+>#include &lt;lwres/lwres.h&gt;</PRE
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_string_parse</CODE
+>(lwres_buffer_t *b, char **c, lwres_uint16_t *len);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_addr_parse</CODE
+>(lwres_buffer_t *b, lwres_addr_t *addr);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_getaddrsbyname</CODE
+>(lwres_context_t *ctx, const char *name, lwres_uint32_t addrtypes, lwres_gabnresponse_t **structp);</CODE
+></P
+><P
+><CODE
+><CODE
+CLASS="FUNCDEF"
+>lwres_result_t
+lwres_getnamebyaddr</CODE
+>(lwres_context_t *ctx, lwres_uint32_t addrtype, lwres_uint16_t addrlen, const unsigned char *addr, lwres_gnbaresponse_t **structp);</CODE
+></P
+><P
+></P
+></DIV
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN43"
+></A
+><H2
+>DESCRIPTION</H2
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_string_parse()</TT
+> retrieves a DNS-encoded
+string starting the current pointer of lightweight resolver buffer
+<TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>: i.e. <TT
+CLASS="CONSTANT"
+>b-&gt;current</TT
+>.
+When the function returns, the address of the first byte of the
+encoded string is returned via <TT
+CLASS="PARAMETER"
+><I
+>*c</I
+></TT
+> and the
+length of that string is given by <TT
+CLASS="PARAMETER"
+><I
+>*len</I
+></TT
+>. The
+buffer's current pointer is advanced to point at the character
+following the string length, the encoded string, and the trailing
+<SPAN
+CLASS="TYPE"
+>NULL</SPAN
+> character.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_addr_parse()</TT
+> extracts an address from the
+buffer <TT
+CLASS="PARAMETER"
+><I
+>b</I
+></TT
+>. The buffer's current pointer
+<TT
+CLASS="CONSTANT"
+>b-&gt;current</TT
+> is presumed to point at an encoded
+address: the address preceded by a 32-bit protocol family identifier
+and a 16-bit length field. The encoded address is copied to
+<TT
+CLASS="CONSTANT"
+>addr-&gt;address</TT
+> and
+<TT
+CLASS="CONSTANT"
+>addr-&gt;length</TT
+> indicates the size in bytes of
+the address that was copied. <TT
+CLASS="CONSTANT"
+>b-&gt;current</TT
+> is
+advanced to point at the next byte of available data in the buffer
+following the encoded address.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>
+use the
+<SPAN
+CLASS="TYPE"
+>lwres_gnbaresponse_t</SPAN
+>
+structure defined below:
+<PRE
+CLASS="PROGRAMLISTING"
+>typedef struct {
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ char *realname;
+ char **aliases;
+ lwres_uint16_t realnamelen;
+ lwres_uint16_t *aliaslen;
+ lwres_addrlist_t addrs;
+ void *base;
+ size_t baselen;
+} lwres_gabnresponse_t;</PRE
+>
+The contents of this structure are not manipulated directly but
+they are controlled through the
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gabn</SPAN
+>(3)</SPAN
+>
+functions.</P
+><P
+>The lightweight resolver uses
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+> to perform foward lookups.
+Hostname <TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+> is looked up using the resolver
+context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> for memory allocation.
+<TT
+CLASS="PARAMETER"
+><I
+>addrtypes</I
+></TT
+> is a bitmask indicating which type of
+addresses are to be looked up. Current values for this bitmask are
+<SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V4</SPAN
+> for IPv4 addresses and
+<SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V6</SPAN
+> for IPv6 addresses. Results of the
+lookup are returned in <TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+> performs reverse lookups.
+Resolver context <TT
+CLASS="PARAMETER"
+><I
+>ctx</I
+></TT
+> is used for memory
+allocation. The address type is indicated by
+<TT
+CLASS="PARAMETER"
+><I
+>addrtype</I
+></TT
+>: <SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V4</SPAN
+> or
+<SPAN
+CLASS="TYPE"
+>LWRES_ADDRTYPE_V6</SPAN
+>. The address to be looked up is given
+by <TT
+CLASS="PARAMETER"
+><I
+>addr</I
+></TT
+> and its length is
+<TT
+CLASS="PARAMETER"
+><I
+>addrlen</I
+></TT
+> bytes. The result of the function call
+is made available through <TT
+CLASS="PARAMETER"
+><I
+>*structp</I
+></TT
+>.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN84"
+></A
+><H2
+>RETURN VALUES</H2
+><P
+>Successful calls to
+<TT
+CLASS="FUNCTION"
+>lwres_string_parse()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_addr_parse()</TT
+>
+return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS.</SPAN
+>
+Both functions return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_FAILURE</SPAN
+>
+if the buffer is corrupt or
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffer has less space than expected for the components of the
+encoded string or address.</P
+><P
+><TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+on success and it returns
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOTFOUND</SPAN
+>
+if the hostname
+<TT
+CLASS="PARAMETER"
+><I
+>name</I
+></TT
+>
+could not be found.</P
+><P
+><SPAN
+CLASS="ERRORCODE"
+>LWRES_R_SUCCESS</SPAN
+>
+is returned by a successful call to
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>.</P
+><P
+>Both
+<TT
+CLASS="FUNCTION"
+>lwres_getaddrsbyname()</TT
+>
+and
+<TT
+CLASS="FUNCTION"
+>lwres_getnamebyaddr()</TT
+>
+return
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_NOMEMORY</SPAN
+>
+when memory allocation requests fail and
+<SPAN
+CLASS="ERRORCODE"
+>LWRES_R_UNEXPECTEDEND</SPAN
+>
+if the buffers used for sending queries and receiving replies are too
+small.</P
+></DIV
+><DIV
+CLASS="REFSECT1"
+><A
+NAME="AEN105"
+></A
+><H2
+>SEE ALSO</H2
+><P
+><SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_buffer</SPAN
+>(3)</SPAN
+>,
+
+<SPAN
+CLASS="CITEREFENTRY"
+><SPAN
+CLASS="REFENTRYTITLE"
+>lwres_gabn</SPAN
+>(3)</SPAN
+>.</P
+></DIV
+></BODY
+></HTML
+> \ No newline at end of file
diff --git a/src/libfreeswan/liblwres/unix/include/lwres/net.h b/src/libfreeswan/liblwres/unix/include/lwres/net.h
new file mode 100644
index 000000000..cb17700cd
--- /dev/null
+++ b/src/libfreeswan/liblwres/unix/include/lwres/net.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: net.h,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+#ifndef LWRES_NET_H
+#define LWRES_NET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Basic Networking Types
+ *
+ * This module is responsible for defining the following basic networking
+ * types:
+ *
+ * struct in_addr
+ * struct in6_addr
+ * struct sockaddr
+ * struct sockaddr_in
+ * struct sockaddr_in6
+ *
+ * It ensures that the AF_ and PF_ macros are defined.
+ *
+ * It declares ntoh[sl]() and hton[sl]().
+ *
+ * It declares lwres_net_aton(), lwres_net_ntop(), and lwres_net_pton().
+ *
+ * It ensures that INADDR_LOOPBACK, INADDR_ANY and IN6ADDR_ANY_INIT
+ * are defined.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <lwres/platform.h> /* Required for LWRES_PLATFORM_*. */
+
+#include <sys/types.h>
+#include <sys/socket.h> /* Contractual promise. */
+#include <sys/time.h>
+#include <sys/un.h>
+
+#include <netinet/in.h> /* Contractual promise. */
+#include <arpa/inet.h> /* Contractual promise. */
+#ifdef LWRES_PLATFORM_NEEDNETINETIN6H
+#include <netinet/in6.h> /* Required on UnixWare. */
+#endif
+#ifdef LWRES_PLATFORM_NEEDNETINET6IN6H
+#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */
+#endif
+
+#include <lwres/lang.h>
+
+#ifndef LWRES_PLATFORM_HAVEIPV6
+#include <lwres/ipv6.h> /* Contractual promise. */
+#endif
+
+#ifdef LWRES_PLATFORM_HAVEINADDR6
+#define in6_addr in_addr6 /* Required for pre RFC2133 implementations. */
+#endif
+
+/*
+ * Required for some pre RFC2133 implementations.
+ * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
+ * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
+ * If 's6_addr' is defined then assume that there is a union and three
+ * levels otherwise assume two levels required.
+ */
+#ifndef IN6ADDR_ANY_INIT
+#ifdef s6_addr
+#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#else
+#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
+#endif
+#endif
+
+#ifndef IN6ADDR_LOOPBACK_INIT
+#ifdef s6_addr
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+#else
+#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
+#endif
+#endif
+
+#ifndef AF_INET6
+#define AF_INET6 99
+#endif
+
+#ifndef PF_INET6
+#define PF_INET6 AF_INET6
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001UL
+#endif
+
+LWRES_LANG_BEGINDECLS
+
+const char *
+lwres_net_ntop(int af, const void *src, char *dst, size_t size);
+
+int
+lwres_net_pton(int af, const char *src, void *dst);
+
+int
+lwres_net_aton(const char *cp, struct in_addr *addr);
+
+LWRES_LANG_ENDDECLS
+
+#endif /* LWRES_NET_H */
diff --git a/src/libfreeswan/liblwres/version.c b/src/libfreeswan/liblwres/version.c
new file mode 100644
index 000000000..ce0380d23
--- /dev/null
+++ b/src/libfreeswan/liblwres/version.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: version.c,v 1.1 2004/03/15 20:35:25 as Exp $ */
+
+char lwres_version[] = VERSION;
+
+unsigned int lwres_libinterface = LIBINTERFACE;
+unsigned int lwres_librevision = LIBREVISION;
+unsigned int lwres_libage = LIBAGE;