summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2013-02-07 00:48:42 +0000
committerobrien <obrien@FreeBSD.org>2013-02-07 00:48:42 +0000
commit952a6d5a7cd3d3f9007acfa06805262fc04a105f (patch)
tree4226b7d3d85625d95ad5c539915c73d9bf0b873f
parent5fe646bf30efb481b8410f525dd916b2c189bd7a (diff)
downloadFreeBSD-src-952a6d5a7cd3d3f9007acfa06805262fc04a105f.zip
FreeBSD-src-952a6d5a7cd3d3f9007acfa06805262fc04a105f.tar.gz
Correct the r242545 sync with head@242525.
-rw-r--r--contrib/gnu-sort/ABOUT-NLS716
-rw-r--r--contrib/gnu-sort/AUTHORS86
-rw-r--r--contrib/gnu-sort/COPYING340
-rw-r--r--contrib/gnu-sort/ChangeLog7511
-rw-r--r--contrib/gnu-sort/FREEBSD-upgrade14
-rw-r--r--contrib/gnu-sort/INSTALL229
-rw-r--r--contrib/gnu-sort/NEWS904
-rw-r--r--contrib/gnu-sort/README147
-rw-r--r--contrib/gnu-sort/THANKS463
-rw-r--r--contrib/gnu-sort/THANKS-to-translators36
-rw-r--r--contrib/gnu-sort/TODO171
-rw-r--r--contrib/gnu-sort/lib/__fpending.c30
-rw-r--r--contrib/gnu-sort/lib/__fpending.h17
-rw-r--r--contrib/gnu-sort/lib/argmatch.c278
-rw-r--r--contrib/gnu-sort/lib/argmatch.h112
-rw-r--r--contrib/gnu-sort/lib/closeout.c93
-rw-r--r--contrib/gnu-sort/lib/closeout.h33
-rw-r--r--contrib/gnu-sort/lib/dup-safer.c59
-rw-r--r--contrib/gnu-sort/lib/error.c306
-rw-r--r--contrib/gnu-sort/lib/error.h66
-rw-r--r--contrib/gnu-sort/lib/exit.h32
-rw-r--r--contrib/gnu-sort/lib/exitfail.c27
-rw-r--r--contrib/gnu-sort/lib/exitfail.h20
-rw-r--r--contrib/gnu-sort/lib/fopen-safer.c72
-rw-r--r--contrib/gnu-sort/lib/gettext.h68
-rw-r--r--contrib/gnu-sort/lib/hard-locale.c76
-rw-r--r--contrib/gnu-sort/lib/hard-locale.h26
-rw-r--r--contrib/gnu-sort/lib/human.c485
-rw-r--r--contrib/gnu-sort/lib/human.h88
-rw-r--r--contrib/gnu-sort/lib/inttostr.c49
-rw-r--r--contrib/gnu-sort/lib/inttostr.h47
-rw-r--r--contrib/gnu-sort/lib/long-options.c91
-rw-r--r--contrib/gnu-sort/lib/long-options.h26
-rw-r--r--contrib/gnu-sort/lib/memcoll.c85
-rw-r--r--contrib/gnu-sort/lib/memcoll.h28
-rw-r--r--contrib/gnu-sort/lib/pathmax.h54
-rw-r--r--contrib/gnu-sort/lib/physmem.c307
-rw-r--r--contrib/gnu-sort/lib/physmem.h27
-rw-r--r--contrib/gnu-sort/lib/posixver.c59
-rw-r--r--contrib/gnu-sort/lib/posixver.h1
-rw-r--r--contrib/gnu-sort/lib/quote.c41
-rw-r--r--contrib/gnu-sort/lib/quote.h22
-rw-r--r--contrib/gnu-sort/lib/quotearg.c673
-rw-r--r--contrib/gnu-sort/lib/quotearg.h137
-rw-r--r--contrib/gnu-sort/lib/stat-macros.h255
-rw-r--r--contrib/gnu-sort/lib/stdio-safer.h23
-rw-r--r--contrib/gnu-sort/lib/strnlen.c48
-rw-r--r--contrib/gnu-sort/lib/timespec.h71
-rw-r--r--contrib/gnu-sort/lib/umaxtostr.c3
-rw-r--r--contrib/gnu-sort/lib/unistd-safer.h21
-rw-r--r--contrib/gnu-sort/lib/version-etc.c181
-rw-r--r--contrib/gnu-sort/lib/version-etc.h37
-rw-r--r--contrib/gnu-sort/lib/xalloc-die.c45
-rw-r--r--contrib/gnu-sort/lib/xalloc.h90
-rw-r--r--contrib/gnu-sort/lib/xmalloc.c221
-rw-r--r--contrib/gnu-sort/lib/xmemcoll.c59
-rw-r--r--contrib/gnu-sort/lib/xmemcoll.h2
-rw-r--r--contrib/gnu-sort/lib/xstrtol.c291
-rw-r--r--contrib/gnu-sort/lib/xstrtol.h89
-rw-r--r--contrib/gnu-sort/lib/xstrtoul.c6
-rw-r--r--contrib/gnu-sort/lib/xstrtoumax.c33
-rw-r--r--contrib/gnu-sort/man/sort.1113
-rw-r--r--contrib/gnu-sort/src/sort.c3237
-rw-r--r--contrib/gnu-sort/src/system.h831
-rw-r--r--crypto/openssl/fips/Makefile230
-rw-r--r--crypto/openssl/fips/aes/Makefile111
-rw-r--r--crypto/openssl/fips/aes/fips_aes_selftest.c101
-rw-r--r--crypto/openssl/fips/aes/fips_aesavs.c939
-rw-r--r--crypto/openssl/fips/des/Makefile111
-rw-r--r--crypto/openssl/fips/des/fips_des_selftest.c137
-rw-r--r--crypto/openssl/fips/des/fips_desmovs.c702
-rw-r--r--crypto/openssl/fips/dh/Makefile115
-rw-r--r--crypto/openssl/fips/dh/dh_gen.c179
-rw-r--r--crypto/openssl/fips/dh/fips_dh_check.c147
-rw-r--r--crypto/openssl/fips/dh/fips_dh_gen.c192
-rw-r--r--crypto/openssl/fips/dh/fips_dh_key.c276
-rw-r--r--crypto/openssl/fips/dh/fips_dh_lib.c95
-rw-r--r--crypto/openssl/fips/dsa/Makefile191
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_gen.c339
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_key.c169
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_lib.c95
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_ossl.c435
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_selftest.c180
-rw-r--r--crypto/openssl/fips/dsa/fips_dsa_sign.c258
-rw-r--r--crypto/openssl/fips/dsa/fips_dsatest.c271
-rw-r--r--crypto/openssl/fips/dsa/fips_dssvs.c537
-rw-r--r--crypto/openssl/fips/fips-nodiff.txt7
-rw-r--r--crypto/openssl/fips/fips.c519
-rw-r--r--crypto/openssl/fips/fips.h163
-rw-r--r--crypto/openssl/fips/fips_canister.c187
-rw-r--r--crypto/openssl/fips/fips_locl.h74
-rw-r--r--crypto/openssl/fips/fips_premain.c176
-rw-r--r--crypto/openssl/fips/fips_premain.c.sha11
-rw-r--r--crypto/openssl/fips/fips_test_suite.c579
-rw-r--r--crypto/openssl/fips/fips_utl.h359
-rwxr-xr-xcrypto/openssl/fips/fipsalgtest.pl887
-rwxr-xr-xcrypto/openssl/fips/fipsld178
-rwxr-xr-xcrypto/openssl/fips/fipstests.sh400
-rw-r--r--crypto/openssl/fips/hmac/Makefile123
-rw-r--r--crypto/openssl/fips/hmac/fips_hmac.c191
-rw-r--r--crypto/openssl/fips/hmac/fips_hmac_selftest.c135
-rw-r--r--crypto/openssl/fips/hmac/fips_hmactest.c328
-rwxr-xr-xcrypto/openssl/fips/mkfipsscr.pl657
-rwxr-xr-xcrypto/openssl/fips/openssl_fips_fingerprint31
-rw-r--r--crypto/openssl/fips/rand/Makefile149
-rw-r--r--crypto/openssl/fips/rand/fips_rand.c410
-rw-r--r--crypto/openssl/fips/rand/fips_rand.h77
-rw-r--r--crypto/openssl/fips/rand/fips_rand_selftest.c371
-rw-r--r--crypto/openssl/fips/rand/fips_randtest.c248
-rw-r--r--crypto/openssl/fips/rand/fips_rngvs.c230
-rw-r--r--crypto/openssl/fips/rsa/Makefile215
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_eay.c934
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_gen.c310
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_lib.c101
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_selftest.c432
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_sign.c554
-rw-r--r--crypto/openssl/fips/rsa/fips_rsa_x931g.c280
-rw-r--r--crypto/openssl/fips/rsa/fips_rsagtest.c390
-rw-r--r--crypto/openssl/fips/rsa/fips_rsastest.c370
-rw-r--r--crypto/openssl/fips/rsa/fips_rsavtest.c378
-rw-r--r--crypto/openssl/fips/sha/Makefile162
-rw-r--r--crypto/openssl/fips/sha/fips_sha1_selftest.c97
-rw-r--r--crypto/openssl/fips/sha/fips_shatest.c388
-rw-r--r--crypto/openssl/fips/sha/fips_standalone_sha1.c173
-rw-r--r--gnu/lib/libstdc++/Makefile4
-rw-r--r--gnu/usr.bin/sort/Makefile46
-rw-r--r--gnu/usr.bin/sort/Makefile.depend19
-rw-r--r--gnu/usr.bin/sort/alloca.h2
-rw-r--r--gnu/usr.bin/sort/config.h1519
-rw-r--r--gnu/usr.bin/sort/localedir.h2
-rw-r--r--gnu/usr.bin/sort/unlocked-io.h2
-rw-r--r--lib/libc/arm/Symbol.map4
-rw-r--r--sys/contrib/pf/net/if_pflog.c435
-rw-r--r--sys/contrib/pf/net/if_pflog.h101
-rw-r--r--sys/contrib/pf/net/if_pflow.h126
-rw-r--r--sys/contrib/pf/net/if_pfsync.c3474
-rw-r--r--sys/contrib/pf/net/if_pfsync.h324
-rw-r--r--sys/contrib/pf/net/pf.c7620
-rw-r--r--sys/contrib/pf/net/pf_if.c1111
-rw-r--r--sys/contrib/pf/net/pf_ioctl.c4420
-rw-r--r--sys/contrib/pf/net/pf_lb.c793
-rw-r--r--sys/contrib/pf/net/pf_mtag.h84
-rw-r--r--sys/contrib/pf/net/pf_norm.c2359
-rw-r--r--sys/contrib/pf/net/pf_osfp.c698
-rw-r--r--sys/contrib/pf/net/pf_ruleset.c457
-rw-r--r--sys/contrib/pf/net/pf_table.c2516
-rw-r--r--sys/contrib/pf/net/pfvar.h2234
-rw-r--r--sys/contrib/pf/netinet/in4_cksum.c120
-rw-r--r--sys/netinet/ipfw/dn_heap.c552
-rw-r--r--sys/netinet/ipfw/dn_heap.h191
-rw-r--r--sys/netinet/ipfw/dn_sched.h191
-rw-r--r--sys/netinet/ipfw/dn_sched_fifo.c120
-rw-r--r--sys/netinet/ipfw/dn_sched_prio.c229
-rw-r--r--sys/netinet/ipfw/dn_sched_qfq.c864
-rw-r--r--sys/netinet/ipfw/dn_sched_rr.c307
-rw-r--r--sys/netinet/ipfw/dn_sched_wf2q.c373
-rw-r--r--sys/netinet/ipfw/dummynet.txt860
-rw-r--r--sys/netinet/ipfw/ip_dn_glue.c845
-rw-r--r--sys/netinet/ipfw/ip_dn_io.c851
-rw-r--r--sys/netinet/ipfw/ip_dn_private.h403
-rw-r--r--sys/netinet/ipfw/ip_dummynet.c2313
-rw-r--r--sys/netinet/ipfw/ip_fw2.c2783
-rw-r--r--sys/netinet/ipfw/ip_fw_dynamic.c1242
-rw-r--r--sys/netinet/ipfw/ip_fw_log.c469
-rw-r--r--sys/netinet/ipfw/ip_fw_nat.c661
-rw-r--r--sys/netinet/ipfw/ip_fw_pfil.c460
-rw-r--r--sys/netinet/ipfw/ip_fw_private.h313
-rw-r--r--sys/netinet/ipfw/ip_fw_sockopt.c1448
-rw-r--r--sys/netinet/ipfw/ip_fw_table.c758
-rw-r--r--sys/netinet/ipfw/test/Makefile51
-rw-r--r--sys/netinet/ipfw/test/dn_test.h175
-rw-r--r--sys/netinet/ipfw/test/main.c636
-rw-r--r--sys/netinet/ipfw/test/mylist.h49
-rw-r--r--sys/netinet/ipfw/test/test_dn_heap.c162
-rw-r--r--sys/netinet/ipfw/test/test_dn_sched.c89
175 files changed, 4 insertions, 82743 deletions
diff --git a/contrib/gnu-sort/ABOUT-NLS b/contrib/gnu-sort/ABOUT-NLS
deleted file mode 100644
index 8ffb467..0000000
--- a/contrib/gnu-sort/ABOUT-NLS
+++ /dev/null
@@ -1,716 +0,0 @@
-Notes on the Free Translation Project
-*************************************
-
-Free software is going international! The Free Translation Project is
-a way to get maintainers of free software, translators, and users all
-together, so that will gradually become able to speak many languages.
-A few packages already provide translations for their messages.
-
- If you found this `ABOUT-NLS' file inside a distribution, you may
-assume that the distributed package does use GNU `gettext' internally,
-itself available at your nearest GNU archive site. But you do _not_
-need to install GNU `gettext' prior to configuring, installing or using
-this package with messages translated.
-
- Installers will find here some useful hints. These notes also
-explain how users should proceed for getting the programs to use the
-available translations. They tell how people wanting to contribute and
-work at translations should contact the appropriate team.
-
- When reporting bugs in the `intl/' directory or bugs which may be
-related to internationalization, you should tell about the version of
-`gettext' which is used. The information can be found in the
-`intl/VERSION' file, in internationalized packages.
-
-Quick configuration advice
-==========================
-
-If you want to exploit the full power of internationalization, you
-should configure it using
-
- ./configure --with-included-gettext
-
-to force usage of internationalizing routines provided within this
-package, despite the existence of internationalizing capabilities in the
-operating system where this package is being installed. So far, only
-the `gettext' implementation in the GNU C library version 2 provides as
-many features (such as locale alias, message inheritance, automatic
-charset conversion or plural form handling) as the implementation here.
-It is also not possible to offer this additional functionality on top
-of a `catgets' implementation. Future versions of GNU `gettext' will
-very likely convey even more functionality. So it might be a good idea
-to change to GNU `gettext' as soon as possible.
-
- So you need _not_ provide this option if you are using GNU libc 2 or
-you have installed a recent copy of the GNU gettext package with the
-included `libintl'.
-
-INSTALL Matters
-===============
-
-Some packages are "localizable" when properly installed; the programs
-they contain can be made to speak your own native language. Most such
-packages use GNU `gettext'. Other packages have their own ways to
-internationalization, predating GNU `gettext'.
-
- By default, this package will be installed to allow translation of
-messages. It will automatically detect whether the system already
-provides the GNU `gettext' functions. If not, the GNU `gettext' own
-library will be used. This library is wholly contained within this
-package, usually in the `intl/' subdirectory, so prior installation of
-the GNU `gettext' package is _not_ required. Installers may use
-special options at configuration time for changing the default
-behaviour. The commands:
-
- ./configure --with-included-gettext
- ./configure --disable-nls
-
-will respectively bypass any pre-existing `gettext' to use the
-internationalizing routines provided within this package, or else,
-_totally_ disable translation of messages.
-
- When you already have GNU `gettext' installed on your system and run
-configure without an option for your new package, `configure' will
-probably detect the previously built and installed `libintl.a' file and
-will decide to use this. This might be not what is desirable. You
-should use the more recent version of the GNU `gettext' library. I.e.
-if the file `intl/VERSION' shows that the library which comes with this
-package is more recent, you should use
-
- ./configure --with-included-gettext
-
-to prevent auto-detection.
-
- The configuration process will not test for the `catgets' function
-and therefore it will not be used. The reason is that even an
-emulation of `gettext' on top of `catgets' could not provide all the
-extensions of the GNU `gettext' library.
-
- Internationalized packages have usually many `po/LL.po' files, where
-LL gives an ISO 639 two-letter code identifying the language. Unless
-translations have been forbidden at `configure' time by using the
-`--disable-nls' switch, all available translations are installed
-together with the package. However, the environment variable `LINGUAS'
-may be set, prior to configuration, to limit the installed set.
-`LINGUAS' should then contain a space separated list of two-letter
-codes, stating which languages are allowed.
-
-Using This Package
-==================
-
-As a user, if your language has been installed for this package, you
-only have to set the `LANG' environment variable to the appropriate
-`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
-and `CC' is an ISO 3166 two-letter country code. For example, let's
-suppose that you speak German and live in Germany. At the shell
-prompt, merely execute `setenv LANG de_DE' (in `csh'),
-`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
-This can be done from your `.login' or `.profile' file, once and for
-all.
-
- You might think that the country code specification is redundant.
-But in fact, some languages have dialects in different countries. For
-example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
-country code serves to distinguish the dialects.
-
- The locale naming convention of `LL_CC', with `LL' denoting the
-language and `CC' denoting the country, is the one use on systems based
-on GNU libc. On other systems, some variations of this scheme are
-used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
-locales supported by your system for your country by running the command
-`locale -a | grep '^LL''.
-
- Not all programs have translations for all languages. By default, an
-English message is shown in place of a nonexistent translation. If you
-understand other languages, you can set up a priority list of languages.
-This is done through a different environment variable, called
-`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
-for the purpose of message handling, but you still need to have `LANG'
-set to the primary language; this is required by other parts of the
-system libraries. For example, some Swedish users who would rather
-read translations in German than English for when Swedish is not
-available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
-
- In the `LANGUAGE' environment variable, but not in the `LANG'
-environment variable, `LL_CC' combinations can be abbreviated as `LL'
-to denote the language's main dialect. For example, `de' is equivalent
-to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
-(Portuguese as spoken in Portugal) in this context.
-
-Translating Teams
-=================
-
-For the Free Translation Project to be a success, we need interested
-people who like their own language and write it well, and who are also
-able to synergize with other translators speaking the same language.
-Each translation team has its own mailing list. The up-to-date list of
-teams can be found at the Free Translation Project's homepage,
-`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
-area.
-
- If you'd like to volunteer to _work_ at translating messages, you
-should become a member of the translating team for your own language.
-The subscribing address is _not_ the same as the list itself, it has
-`-request' appended. For example, speakers of Swedish can send a
-message to `sv-request@li.org', having this message body:
-
- subscribe
-
- Keep in mind that team members are expected to participate
-_actively_ in translations, or at solving translational difficulties,
-rather than merely lurking around. If your team does not exist yet and
-you want to start one, or if you are unsure about what to do or how to
-get started, please write to `translation@iro.umontreal.ca' to reach the
-coordinator for all translator teams.
-
- The English team is special. It works at improving and uniformizing
-the terminology in use. Proven linguistic skill are praised more than
-programming skill, here.
-
-Available Packages
-==================
-
-Languages are not equally supported in all packages. The following
-matrix shows the current state of internationalization, as of December
-2003. The matrix shows, in regard of each package, for which languages
-PO files have been submitted to translation coordination, with a
-translation percentage of at least 50%.
-
- Ready PO files am az be bg ca cs da de el en en_GB eo es
- +-------------------------------------------+
- a2ps | [] [] [] [] |
- aegis | () |
- ant-phone | () |
- anubis | |
- ap-utils | |
- bash | [] [] [] [] |
- batchelor | |
- bfd | [] [] |
- binutils | [] [] |
- bison | [] [] [] |
- bluez-pin | [] [] |
- clisp | |
- clisp | [] [] [] |
- coreutils | [] [] [] [] |
- cpio | [] [] [] |
- darkstat | [] () [] |
- diffutils | [] [] [] [] [] [] [] |
- e2fsprogs | [] [] |
- enscript | [] [] [] [] |
- error | [] [] [] [] [] |
- fetchmail | [] () [] [] [] [] |
- fileutils | [] [] [] |
- findutils | [] [] [] [] [] [] [] |
- flex | [] [] [] [] |
- fslint | |
- gas | [] |
- gawk | [] [] [] [] |
- gbiff | [] |
- gcal | [] |
- gcc | [] [] |
- gettext | [] [] [] [] [] |
- gettext-examples | [] [] [] |
- gettext-runtime | [] [] [] [] [] |
- gettext-tools | [] [] [] |
- gimp-print | [] [] [] [] [] |
- gliv | |
- glunarclock | [] [] |
- gnubiff | [] |
- gnucash | [] () [] [] |
- gnucash-glossary | [] () [] |
- gnupg | [] () [] [] [] [] |
- gpe-aerial | [] |
- gpe-beam | [] [] |
- gpe-calendar | [] [] |
- gpe-clock | [] [] |
- gpe-conf | [] [] |
- gpe-contacts | [] [] |
- gpe-edit | [] |
- gpe-go | [] |
- gpe-login | [] [] |
- gpe-ownerinfo | [] [] |
- gpe-sketchbook | [] [] |
- gpe-su | [] [] |
- gpe-taskmanager | [] [] |
- gpe-timesheet | [] |
- gpe-today | [] [] |
- gpe-todo | [] [] |
- gphoto2 | [] [] [] [] |
- gprof | [] [] [] |
- gpsdrive | () () () |
- gramadoir | [] |
- grep | [] [] [] [] [] [] |
- gretl | [] |
- gtick | () |
- hello | [] [] [] [] [] [] |
- id-utils | [] [] |
- indent | [] [] [] [] |
- jpilot | [] [] [] |
- jtag | |
- jwhois | [] |
- kbd | [] [] [] [] [] |
- latrine | () |
- ld | [] [] |
- libc | [] [] [] [] [] [] |
- libgpewidget | [] [] |
- libiconv | [] [] [] [] [] |
- lifelines | [] () |
- lilypond | [] |
- lingoteach | |
- lingoteach_lessons | () () |
- lynx | [] [] [] [] |
- m4 | [] [] [] [] |
- mailutils | [] [] |
- make | [] [] [] |
- man-db | [] () [] [] () |
- minicom | [] [] [] |
- mysecretdiary | [] [] [] |
- nano | [] () [] [] [] |
- nano_1_0 | [] () [] [] [] |
- opcodes | [] |
- parted | [] [] [] [] [] |
- ptx | [] [] [] [] [] |
- python | |
- radius | [] |
- recode | [] [] [] [] [] [] [] |
- rpm | [] [] |
- screem | |
- scrollkeeper | [] [] [] [] [] [] |
- sed | [] [] [] [] [] |
- sh-utils | [] [] [] |
- shared-mime-info | |
- sharutils | [] [] [] [] [] [] |
- silky | () |
- skencil | [] () [] |
- sketch | [] () [] |
- soundtracker | [] [] [] |
- sp | [] |
- tar | [] [] [] [] |
- texinfo | [] [] [] |
- textutils | [] [] [] [] |
- tin | () () |
- tuxpaint | [] [] [] [] [] [] [] |
- util-linux | [] [] [] [] [] |
- vorbis-tools | [] [] [] [] |
- wastesedge | () |
- wdiff | [] [] [] [] |
- wget | [] [] [] [] [] [] |
- xchat | [] [] [] [] |
- xfree86_xkb_xml | [] |
- xpad | [] |
- +-------------------------------------------+
- am az be bg ca cs da de el en en_GB eo es
- 0 0 8 3 37 38 56 73 15 1 5 12 64
-
- et fa fi fr ga gl he hr hu id is it ja
- +----------------------------------------+
- a2ps | [] [] [] () |
- aegis | |
- ant-phone | |
- anubis | [] |
- ap-utils | [] |
- bash | [] [] |
- batchelor | [] |
- bfd | [] |
- binutils | [] [] |
- bison | [] [] [] [] |
- bluez-pin | [] [] [] [] [] |
- clisp | |
- clisp | [] |
- coreutils | [] [] [] [] [] [] |
- cpio | [] [] [] |
- darkstat | () [] [] [] |
- diffutils | [] [] [] [] [] [] [] |
- e2fsprogs | |
- enscript | [] [] |
- error | [] [] [] [] |
- fetchmail | [] |
- fileutils | [] [] [] [] [] [] |
- findutils | [] [] [] [] [] [] [] [] [] [] |
- flex | [] [] |
- fslint | |
- gas | [] |
- gawk | [] [] [] |
- gbiff | |
- gcal | [] |
- gcc | [] |
- gettext | [] [] |
- gettext-examples | [] [] |
- gettext-runtime | [] [] [] [] |
- gettext-tools | [] [] |
- gimp-print | [] [] |
- gliv | () |
- glunarclock | [] [] [] [] |
- gnubiff | |
- gnucash | () [] |
- gnucash-glossary | [] |
- gnupg | [] [] [] [] [] [] [] |
- gpe-aerial | [] |
- gpe-beam | [] |
- gpe-calendar | [] [] [] |
- gpe-clock | [] |
- gpe-conf | [] |
- gpe-contacts | [] [] |
- gpe-edit | [] [] |
- gpe-go | [] |
- gpe-login | [] [] |
- gpe-ownerinfo | [] [] [] |
- gpe-sketchbook | [] |
- gpe-su | [] |
- gpe-taskmanager | [] |
- gpe-timesheet | [] [] [] |
- gpe-today | [] [] |
- gpe-todo | [] [] |
- gphoto2 | [] [] [] |
- gprof | [] [] |
- gpsdrive | () [] () () |
- gramadoir | [] |
- grep | [] [] [] [] [] [] [] [] [] [] [] |
- gretl | [] |
- gtick | [] [] |
- hello | [] [] [] [] [] [] [] [] [] [] [] [] |
- id-utils | [] [] [] [] |
- indent | [] [] [] [] [] [] [] [] [] |
- jpilot | [] () |
- jtag | |
- jwhois | [] [] [] [] |
- kbd | [] |
- latrine | |
- ld | [] |
- libc | [] [] [] [] [] |
- libgpewidget | [] [] [] [] |
- libiconv | [] [] [] [] [] [] [] [] [] |
- lifelines | () |
- lilypond | [] |
- lingoteach | [] [] |
- lingoteach_lessons | |
- lynx | [] [] [] [] |
- m4 | [] [] [] [] |
- mailutils | |
- make | [] [] [] [] [] |
- man-db | () () |
- minicom | [] [] [] [] |
- mysecretdiary | [] [] |
- nano | [] [] [] [] |
- nano_1_0 | [] [] [] [] |
- opcodes | [] |
- parted | [] [] [] |
- ptx | [] [] [] [] [] [] [] |
- python | |
- radius | [] |
- recode | [] [] [] [] [] [] |
- rpm | |
- screem | |
- scrollkeeper | [] |
- sed | [] [] [] [] [] [] [] [] [] |
- sh-utils | [] [] [] [] [] [] [] |
- shared-mime-info | [] |
- sharutils | [] [] [] [] [] |
- silky | [] () |
- skencil | [] |
- sketch | [] |
- soundtracker | [] [] [] [] |
- sp | [] () |
- tar | [] [] [] [] [] [] [] [] [] |
- texinfo | [] [] [] [] |
- textutils | [] [] [] [] [] |
- tin | [] () |
- tuxpaint | [] [] [] [] [] [] [] [] |
- util-linux | [] [] [] [] () [] |
- vorbis-tools | [] |
- wastesedge | () |
- wdiff | [] [] [] [] [] [] |
- wget | [] [] [] [] [] [] [] |
- xchat | [] [] [] |
- xfree86_xkb_xml | |
- xpad | [] |
- +----------------------------------------+
- et fa fi fr ga gl he hr hu id is it ja
- 21 1 25 86 24 24 8 10 38 31 1 23 32
-
- ko lg lt lv ms nb nl nn no pl pt pt_BR ro
- +-------------------------------------------+
- a2ps | () [] [] () () [] [] |
- aegis | () () |
- ant-phone | [] [] |
- anubis | [] [] [] [] [] |
- ap-utils | [] () [] |
- bash | [] [] |
- batchelor | [] |
- bfd | [] |
- binutils | |
- bison | [] [] [] [] |
- bluez-pin | [] [] [] |
- clisp | |
- clisp | [] |
- coreutils | [] |
- cpio | [] [] [] [] [] |
- darkstat | [] [] [] [] |
- diffutils | [] [] [] [] |
- e2fsprogs | [] |
- enscript | [] [] [] |
- error | [] [] [] |
- fetchmail | [] [] () |
- fileutils | [] [] |
- findutils | [] [] [] [] [] |
- flex | [] [] [] [] |
- fslint | [] [] |
- gas | |
- gawk | [] [] [] |
- gbiff | [] [] |
- gcal | |
- gcc | |
- gettext | [] [] [] |
- gettext-examples | [] [] |
- gettext-runtime | [] [] [] |
- gettext-tools | [] [] [] |
- gimp-print | [] |
- gliv | [] [] [] |
- glunarclock | [] [] [] |
- gnubiff | |
- gnucash | [] [] () |
- gnucash-glossary | [] [] |
- gnupg | [] |
- gpe-aerial | [] [] [] |
- gpe-beam | [] [] [] |
- gpe-calendar | [] [] [] |
- gpe-clock | [] [] [] |
- gpe-conf | [] [] [] |
- gpe-contacts | [] [] [] |
- gpe-edit | [] [] [] |
- gpe-go | [] [] |
- gpe-login | [] [] [] |
- gpe-ownerinfo | [] [] [] |
- gpe-sketchbook | [] [] [] |
- gpe-su | [] [] [] |
- gpe-taskmanager | [] [] [] |
- gpe-timesheet | [] [] [] |
- gpe-today | [] [] [] |
- gpe-todo | [] [] [] |
- gphoto2 | [] |
- gprof | [] [] |
- gpsdrive | () () () [] |
- gramadoir | [] |
- grep | [] [] [] [] |
- gretl | |
- gtick | [] [] |
- hello | [] [] [] [] [] [] [] [] [] [] |
- id-utils | [] [] [] |
- indent | [] [] [] |
- jpilot | () () |
- jtag | |
- jwhois | [] [] [] [] |
- kbd | [] [] [] |
- latrine | [] |
- ld | |
- libc | [] [] [] [] [] |
- libgpewidget | [] [] [] |
- libiconv | [] [] [] [] |
- lifelines | |
- lilypond | |
- lingoteach | |
- lingoteach_lessons | |
- lynx | [] [] |
- m4 | [] [] [] [] |
- mailutils | [] [] |
- make | [] [] [] [] |
- man-db | [] |
- minicom | [] [] [] |
- mysecretdiary | [] [] [] |
- nano | [] [] [] [] |
- nano_1_0 | [] [] [] [] [] |
- opcodes | [] [] |
- parted | [] [] [] [] |
- ptx | [] [] [] [] [] [] [] |
- python | |
- radius | [] |
- recode | [] [] [] |
- rpm | [] [] |
- screem | |
- scrollkeeper | [] [] [] [] |
- sed | [] [] [] |
- sh-utils | [] |
- shared-mime-info | [] |
- sharutils | [] |
- silky | |
- skencil | [] [] |
- sketch | [] [] |
- soundtracker | |
- sp | |
- tar | [] [] [] [] [] [] |
- texinfo | [] [] [] |
- textutils | [] [] |
- tin | |
- tuxpaint | [] [] [] [] [] [] [] [] [] |
- util-linux | [] [] |
- vorbis-tools | [] [] |
- wastesedge | |
- wdiff | [] [] [] [] |
- wget | [] [] |
- xchat | [] [] |
- xfree86_xkb_xml | [] |
- xpad | [] [] |
- +-------------------------------------------+
- ko lg lt lv ms nb nl nn no pl pt pt_BR ro
- 12 0 1 2 12 10 60 4 4 38 25 35 76
-
- ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW
- +-------------------------------------------+
- a2ps | [] [] [] [] [] | 16
- aegis | () | 0
- ant-phone | | 2
- anubis | [] [] [] | 9
- ap-utils | () | 3
- bash | [] | 9
- batchelor | | 2
- bfd | [] [] | 6
- binutils | [] [] [] | 7
- bison | [] [] [] | 14
- bluez-pin | [] [] [] | 13
- clisp | | 0
- clisp | | 5
- coreutils | [] [] [] [] [] | 16
- cpio | [] [] [] | 14
- darkstat | [] [] [] () () | 12
- diffutils | [] [] [] [] | 22
- e2fsprogs | [] [] | 5
- enscript | [] [] [] | 12
- error | [] [] [] | 15
- fetchmail | [] [] [] | 11
- fileutils | [] [] [] [] [] [] | 17
- findutils | [] [] [] [] [] [] [] | 29
- flex | [] [] [] | 13
- fslint | | 2
- gas | [] | 3
- gawk | [] [] | 12
- gbiff | | 3
- gcal | [] [] | 4
- gcc | [] | 4
- gettext | [] [] [] [] [] [] | 16
- gettext-examples | [] [] [] [] | 11
- gettext-runtime | [] [] [] [] [] [] [] [] [] | 21
- gettext-tools | [] [] [] [] [] [] | 14
- gimp-print | [] [] | 10
- gliv | | 3
- glunarclock | [] [] [] [] | 13
- gnubiff | | 1
- gnucash | [] [] [] | 9
- gnucash-glossary | [] [] [] | 8
- gnupg | [] [] [] [] | 17
- gpe-aerial | [] [] | 7
- gpe-beam | [] [] | 8
- gpe-calendar | [] [] [] [] [] | 13
- gpe-clock | [] [] [] [] | 10
- gpe-conf | [] [] [] | 9
- gpe-contacts | [] [] [] [] | 11
- gpe-edit | [] [] [] [] [] [] | 12
- gpe-go | [] | 5
- gpe-login | [] [] [] [] [] [] | 13
- gpe-ownerinfo | [] [] [] [] [] | 13
- gpe-sketchbook | [] [] [] | 9
- gpe-su | [] [] [] [] | 10
- gpe-taskmanager | [] [] [] [] | 10
- gpe-timesheet | [] [] [] [] [] | 12
- gpe-today | [] [] [] [] [] [] | 13
- gpe-todo | [] [] [] [] [] | 12
- gphoto2 | [] [] [] | 11
- gprof | [] [] | 9
- gpsdrive | [] [] | 4
- gramadoir | | 3
- grep | [] [] [] [] [] | 26
- gretl | | 2
- gtick | [] | 5
- hello | [] [] [] [] [] | 33
- id-utils | [] [] [] | 12
- indent | [] [] [] [] [] | 21
- jpilot | [] [] [] [] [] | 9
- jtag | [] | 1
- jwhois | () () [] [] | 11
- kbd | [] [] | 11
- latrine | | 1
- ld | [] [] | 5
- libc | [] [] [] [] | 20
- libgpewidget | [] [] [] [] | 13
- libiconv | [] [] [] [] [] [] [] [] [] | 27
- lifelines | [] | 2
- lilypond | [] | 3
- lingoteach | | 2
- lingoteach_lessons | () | 0
- lynx | [] [] [] [] | 14
- m4 | [] [] [] | 15
- mailutils | [] | 5
- make | [] [] [] [] | 16
- man-db | [] | 5
- minicom | [] | 11
- mysecretdiary | [] [] | 10
- nano | [] [] [] [] [] | 17
- nano_1_0 | [] [] [] [] | 17
- opcodes | [] [] | 6
- parted | [] [] [] | 15
- ptx | [] [] [] | 22
- python | | 0
- radius | [] | 4
- recode | [] [] [] [] | 20
- rpm | [] [] [] | 7
- screem | [] [] | 2
- scrollkeeper | [] [] [] [] | 15
- sed | [] [] [] [] [] [] | 23
- sh-utils | [] [] [] | 14
- shared-mime-info | [] [] | 4
- sharutils | [] [] [] [] [] | 17
- silky | () | 2
- skencil | [] | 6
- sketch | [] | 6
- soundtracker | [] [] | 9
- sp | [] | 3
- tar | [] [] [] [] [] | 24
- texinfo | [] [] [] [] | 14
- textutils | [] [] [] [] [] | 16
- tin | | 1
- tuxpaint | [] [] [] [] [] | 29
- util-linux | [] [] [] | 15
- vorbis-tools | [] | 8
- wastesedge | | 0
- wdiff | [] [] [] [] | 18
- wget | [] [] [] [] [] [] [] [] | 23
- xchat | [] [] [] [] [] | 14
- xfree86_xkb_xml | [] [] [] [] [] [] | 8
- xpad | | 4
- +-------------------------------------------+
- 51 teams ru sk sl sr sv ta tr uk vi wa zh_CN zh_TW
- 120 domains 59 42 16 25 81 0 56 12 1 10 21 22 1260
-
- Some counters in the preceding matrix are higher than the number of
-visible blocks let us expect. This is because a few extra PO files are
-used for implementing regional variants of languages, or language
-dialects.
-
- For a PO file in the matrix above to be effective, the package to
-which it applies should also have been internationalized and
-distributed as such by its maintainer. There might be an observable
-lag between the mere existence a PO file and its wide availability in a
-distribution.
-
- If December 2003 seems to be old, you may fetch a more recent copy
-of this `ABOUT-NLS' file on most GNU archive sites. The most
-up-to-date matrix with full percentage details can be found at
-`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
-
-Using `gettext' in new packages
-===============================
-
-If you are writing a freely available program and want to
-internationalize it you are welcome to use GNU `gettext' in your
-package. Of course you have to respect the GNU Library General Public
-License which covers the use of the GNU `gettext' library. This means
-in particular that even non-free programs can use `libintl' as a shared
-library, whereas only free software can use `libintl' as a static
-library or use modified versions of `libintl'.
-
- Once the sources are changed appropriately and the setup can handle
-the use of `gettext' the only thing missing are the translations. The
-Free Translation Project is also available for packages which are not
-developed inside the GNU project. Therefore the information given above
-applies also for every other Free Software Project. Contact
-`translation@iro.umontreal.ca' to make the `.pot' files available to
-the translation teams.
diff --git a/contrib/gnu-sort/AUTHORS b/contrib/gnu-sort/AUTHORS
deleted file mode 100644
index 4e8a5d4..0000000
--- a/contrib/gnu-sort/AUTHORS
+++ /dev/null
@@ -1,86 +0,0 @@
-Here are the names of the programs in this package,
-each followed by the name(s) of its author(s).
-
-basename: FIXME unknown
-cat: Torbjorn Granlund and Richard M. Stallman
-chgrp: David MacKenzie
-chmod: David MacKenzie
-chown: David MacKenzie
-chroot: Roland McGrath
-cksum: Q. Frank Xia
-comm: Richard Stallman and David MacKenzie
-cp: Torbjorn Granlund, David MacKenzie, and Jim Meyering
-csplit: Stuart Kemp and David MacKenzie
-cut: David Ihnat, David MacKenzie, and Jim Meyering
-date: David MacKenzie
-dd: Paul Rubin, David MacKenzie, and Stuart Kemp
-df: Torbjorn Granlund, David MacKenzie, Larry McVoy, and Paul Eggert
-dircolors: H. Peter Anvin
-dirname: David MacKenzie and Jim Meyering
-du: Torbjorn Granlund, David MacKenzie, Larry McVoy, and Paul Eggert
-echo: FIXME unknown
-env: Richard Mlynarik and David MacKenzie
-expand: David MacKenzie
-expr: Mike Parker
-factor: Paul Rubin
-false: no one
-fmt: Ross Paterson
-fold: David MacKenzie
-head: David MacKenzie
-hostid: Jim Meyering
-hostname: Jim Meyering
-id: Arnold Robbins and David MacKenzie
-install: David MacKenzie
-join: Mike Haertel
-kill: Paul Eggert
-link: Michael Stone
-ln: Mike Parker and David MacKenzie
-logname: FIXME: unknown
-ls: Richard Stallman and David MacKenzie
-md5sum: Ulrich Drepper and Scott Miller
-mkdir: David MacKenzie
-mkfifo: David MacKenzie
-mknod: David MacKenzie
-mv: Mike Parker, David MacKenzie, and Jim Meyering
-nice: David MacKenzie
-nl: Scott Bartram and David MacKenzie
-od: Jim Meyering
-paste: David M. Ihnat and David MacKenzie
-pathchk: David MacKenzie and Jim Meyering
-pinky: Joseph Arceneaux, David MacKenzie, and Kaveh Ghazi
-pr: Pete TerMaat and Roland Huebner
-printenv: David MacKenzie and Richard Mlynarik
-printf: David MacKenzie
-ptx: François Pinard
-pwd: Jim Meyering
-rm: Paul Rubin, David MacKenzie, Richard Stallman, and Jim Meyering
-rmdir: David MacKenzie
-seq: Ulrich Drepper
-shred: Colin Plumb
-sleep: Jim Meyering and Paul Eggert
-sort: Mike Haertel and Paul Eggert
-split: Torbjorn Granlund and Richard M. Stallman
-stat: Michael Meskes
-stty: David MacKenzie
-su: David MacKenzie
-sum: Kayvan Aghaiepour and David MacKenzie
-sync: Jim Meyering
-tac: Jay Lepreau and David MacKenzie
-tail: Paul Rubin, David MacKenzie, Ian Lance Taylor, and Jim Meyering
-tee: Mike Parker, Richard M. Stallman, and David MacKenzie
-test: FIXME: ksb and mjb
-touch: Paul Rubin, Arnold Robbins, Jim Kingdon, David MacKenzie, and Randy Smith
-tr: Jim Meyering
-true: no one
-tsort: Mark Kettenis
-tty: David MacKenzie
-uname: David MacKenzie
-unexpand: David MacKenzie
-uniq: Richard Stallman and David MacKenzie
-unlink: Michael Stone
-uptime: Joseph Arceneaux, David MacKenzie, and Kaveh Ghazi
-users: Joseph Arceneaux and David MacKenzie
-wc: Paul Rubin and David MacKenzie
-who: Joseph Arceneaux, David MacKenzie, and Michael Stone
-whoami: Richard Mlynarik
-yes: David MacKenzie
diff --git a/contrib/gnu-sort/COPYING b/contrib/gnu-sort/COPYING
deleted file mode 100644
index d60c31a..0000000
--- a/contrib/gnu-sort/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 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.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, 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 software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, 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 redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-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 give any other recipients of the Program a copy of this License
-along with the Program.
-
-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 Program or any portion
-of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-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 Program, 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 Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) 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; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, 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 executable. 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.
-
-If distribution of executable or 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 counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program 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.
-
- 5. 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 Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program 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.
-
- 7. 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 Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program 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 Program.
-
-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.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program 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.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the 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 Program
-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 Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, 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
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), 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 Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- 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.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/contrib/gnu-sort/ChangeLog b/contrib/gnu-sort/ChangeLog
deleted file mode 100644
index c027655..0000000
--- a/contrib/gnu-sort/ChangeLog
+++ /dev/null
@@ -1,7511 +0,0 @@
-2004-08-11 Paul Eggert <eggert@cs.ucla.edu>
-
- * tests/install/basic-1: Test for the -d regression.
-
-2004-08-11 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/install.c (main): Fix -d regression introduced with
- --target-directory support at 2004-06-25.
-
-2004-08-11 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/copy.c (copy_internal): When preserving links, unlink
- a destination with link count greater than one. This is so
- that commands like "cp -a" don't get confused when copying into
- a destination that already contains many hard links. Problem
- reported by Tim Waugh in:
- http://lists.gnu.org/archive/html/bug-coreutils/2004-08/msg00053.html
-
-2004-08-10 Paul Eggert <eggert@cs.ucla.edu>
-
- Convert all files to UTF-8.
- * tests/fmt/basic (8-bit-pfx): Use UTF-8, not Latin-1.
- * tests/sort/Test.pm (16a): Likewise.
- * tests/uniq/Test.pm (8): Likewise.
- * tests/misc/printf-hex: Use ASCII, not Latin-1.
-
- * NEWS: Document "sort -o -" and "tee -" POSIX-conformance fixes.
- * src/shred.c (usage): "-" is an operand, not an option.
- * src/sort.c (die, xfopen, mergefps, first_same_file, merge):
- A null file arg means standard output.
- (main): "-o -" means to write to a file named "-",
- not to standard output.
- * src/tee.c (usage, tee): "tee -" writes to standard output, not
- to a file named "-".
-
-2004-08-10 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/install.c (change_timestamps): Fix int->bool conversion
- bugs introduced on 2004-07-29.
-
-2004-08-09 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/shred.c (wipename): Work even if the directory is writeable
- and not readable. Prefer write access, since this should work
- better with fdatasync.
-
- * src/csplit.c (xalloc_die): New function.
- (main): Remove now-obsolete initialization of xalloc_fail_func.
-
- * src/md5sum.c: Adjust to sha->sha1 renaming.
-
-2004-08-08 Dmitry V. Levin <ldv@altlinux.org>
-
- Minor code cleanup.
- * src/readlink.c (canonicalize_fname): Remove unneeded proxy function.
- (can_mode): Make variable local.
-
-2004-08-07 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/system.h (O_BINARY) [!O_BINARY && defined O_BINARY]:
- Do not define, to avoid annoying compiler messages on QNX 6.3.
- Problem reported by Johan in:
- http://lists.gnu.org/archive/html/bug-coreutils/2004-08/msg00050.html
-
-2004-08-04 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/system.h (PRIdMAX, PRIoMAX, PRIuMAX, PRIxMAX):
- Define to a concatenation of string literals, not to an expression;
- needed for concatenation contexts.
- (INTMAX_MAX, INTMAX_MIN): New macros.
-
- * src/stat.c (print_stat): Don't assume st_ino / st_dev fits in
- unsigned long; this isn't true for st_ino on Solaris 9.
-
-2004-08-03 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/uname.c: Do not depend on HAVE_SYSCTL when deciding
- whether to include files. Include <sys/param.h> if
- HAVE_SYS_PARAM_H (not HAVE_SYSCTL).
- (main) [defined __POWERPC__]: Add a kludge to work around a
- Mac OS X bug, so that uname -p defaults to "powerpc" if
- sysctl ((int[]) {CTL_HW, HW_MACHINE_ARCH}, 2, buffer, &bufsize, 0, 0)
- fails. Problem reported by Petter Reinholdtsen in:
- http://lists.gnu.org/archive/html/bug-gnu-utils/2003-02/msg00201.html
-
- * src/uniq.c (hard_LC_COLLATE, ignore_case, different, check_file,
- main): Use bool for booleans.
- (writeline, check_file): Use uintmax_t for line counts.
- (check_file): Check for and report line number overflow,
- when that matters.
- * src/wc.c (iswspace, wc): Use to_uchar rather than a cast.
- (print_lines, print_words, print_chars, print_bytes, print_linelength,
- have_read_stdin, wc, wc_file, main):
- Use bool for booleans.
- (exit_status): Remove.
- (wc, wc_file): Return bool status. All callers changed.
- * src/who.c (scan_entries): 0 -> STDIN_FILENO.
- * src/whoami.c (main): Print uids using unsigned long int, not
- unsigned int.
-
- * src/unexpand.c: Int cleanup and minor reorganization to be more
- like src/expand.c.
- Include quote.h, xstrndup.h.
- (TAB_STOP_SENTINEL): Increase from INT_MAX to INTMAX_MAX.
- (convert_entire_line, have_read_stdin, parse_tabstops, next_file,
- unexpand, main):
- Use bool for booleans.
- (tab_size, tab_list, add_tabstop, validate_tabstops, unexpand):
- Use uintmax_t for column counts.
- (first_free_tab, validate_tabstops, unexpand): Use size_t for sizes.
- (add_tabstop, parse_tabstops, main): Don't reserve UINTMAX_MAX
- as a tab stop.
- (parse_tabstops): Don't use ISBLANK on possibly-signed char.
- Detect overflow in tab stop string.
- (next_file, main): Use EXIT_FAILURE/EXIT_SUCCESS instead of 1/0.
- (unexpand): Concatenate input files the same way expand does.
-
- * src/touch.c (no_create, use_ref, posix_date, amtime_now,
- touch, main): Use bool for booleans.
- (main): Avoid integer overflow when given more than INT_MAX
- options.
- * src/tsort.c (struct item, n_strings): Use size_t for sizes.
- (have_read_stdin, count_items, scan_zeros, detect_loop,
- recurse_tree, walk_tree, tsort, main):
- Use bool for booleans.
- (exit_status): Remove.
- (tsort): Return a success flag instead of storing into a global.
- (main): Use it.
- * src/tty.c (silent, main): Use bool for booleans.
- (main): 0 -> STDIN_FILENO.
- * src/uname.c (print_element): Use bool for booleans.
-
- * src/test.c (TRUE, FALSE, SHELL_BOOLEAN, TRUTH_OR, TRUTH_AND):
- Remove. All uses replaced by C99 boolean primitives.
- (TEST_TRUE, TEST_FALSE): New constants, for readability.
- (test_unop, binop, unary_operator, binary_operator, two_arguments,
- three_arguments, posixtest, expr, term, and, or, is_int, age_of,
- one_argument, main): Use bool for booleans.
- (advance, unary_advance): Now inline procedures rather than a macros.
- (is_int): Renamed from isint, to avoid namespace clash with ctype.h.
- (term, and, or): When it's easy, loop instead of recursing.
- (term): Avoid integer overflow if there are INT_MAX-3 args (!).
- (binary_operator, unary_operator): Simplify by systematically rewriting
- true==FOO to FOO (where FOO is a boolean).
- (unary_operator): Don't consider a file to be a regular file
- merely because its mode&S_IFMT is zero. Just use S_ISREG.
- Remove unnecessary casts. Remove ifdefs for things like
- S_ISSOCK that are no longer needed, since stat-macros.h always
- defines them now.
-
- * src/tac-pipe.c (buf_init_from_stdin, find_bol, tac_mem):
- Use bool for booleans.
- (buf_init_from_stdin, buf_free, find_bol, print_line):
- Use size_t for sizes.
- * src/tac.c (separator_ends_record, tac_seekable, tac_file,
- tac_stdin, tac_stdin_to_mem, main): Use bool for booleans.
- (match_length, G_buffer_size, tac_seekable, main): Use size_t for sizes.
- (tac_seekable): Use ptrdiff_t for pointer subtraction.
- Report an error if the result is out of range.
- (tac_seekable, main): Check for integer overflow in buffer size
- calculations.
- (main): Remove unnecessary casts.
-
- * src/su.c (run_shell): Pass a new n_additional_args arg, so that
- the callee doesn't have to count 'em. All callers changed.
- Don't allocate more space for the arg vector than we'll need.
- Use memcpy to copy the args rather than rolling our own loop.
- Use size_t for sizes.
- (fast_startup, simulate_login, change_environment, log_su,
- correct_password, restricted_shell, main): Use bool for booleans.
- (longopts): Don't assume change_environment is an int.
- Use NULL, not 0, for pointers.
- (xsetenv): New function, replacing xputenv and concat.
- All callers changed.
- (elements): Remove; no longer needed.
- (log_su, correct_passwd, main): Prefer !x to x==NULL.
- (log_su): 2 -> STDERR_FILENO.
- (modify_environment, main): Don't assume that getenv's returned value
- has an indefinite lifetime.
- (modify_environment): Allocate a larger environ.
- (main): Remove an impossible 'case 0'; if it happens now, it'll
- get diagnosed. Don't assume getpwnam results outlive endpwent.
- Check for null or empty pw_name, pw_dir and for null pw_passwd.
-
- * src/stty.c (VA_START): Remove. All callers now use va_start.
- (_POSIX_VDISABLE): Remove unnecessary cast.
- (struct control_info, visible): Use cc_t for control chars.
- (struct control_info): Use size_t for sizes.
- (recover_mode, set_mode, display_speed, display_window_size,
- valid_options, main, display_changed):
- Use bool for booleans.
- (integer_arg): Return unsigned long int, not long int.
- Accept new max arg; all callers changed, to specify a maximum
- value for integer parameters instead of silently overflowing.
- (wrap): Do not overrun the stack buffer if the output contains
- more than 1024 bytes. Instead, malloc a buffer.
- (main): Remove a "what is this?!?" FIXME. Nobody knows what it is.
- Remove unnecessary casts.
- (set_control_char): Allow int values only up to cc_t range.
- (screen_columns): Don't reject INT_MAX.
- (display_changed, display_all, display_speed, recover_mode):
- Don't assume cc_t fits in int.
-
- * src/remove.h: Add copyright notice.
- (struct rm_options): Use bool for booleans.
- * src/rmdir.c (empty_paths, ignore_fail_on_non_empty, verbose,
- errno_rmdir_non_empty, remove_parents, main): Likewise.
- * src/sum.c (have_read_stdin, bsd_sum_file, sysv_sum_file,
- main): Likewise.
- (main): Don't dump core if invoked with argv[0]==NULL.
- * src/tee.c (tee, append, ignore_interrupts, main, tee):
- Use bool for booleans.
- (tee): Use ssize_t for read returns.
-
- * src/ptx.c: Add a FIXME mentioning that there are many
- unchecked integer overflows in this file.
- (gnu_extensions, auto_reference, input_reference, right_reference,
- ignore_case, initialize_regex, fix_output_parameters,
- output_one_roff_line, output_one_text_line, output_one_dumb_line, main):
- Use bool for booleans.
- (SKIP_SOMETHING, compare_words, digest_break_file,
- find_occurs_in_text, fix_output_parameters):
- Use to_uchar instead of a caset.
- (print_field): Rewrite to avoid cast.
-
- * src/printf.c (posixly_correct): Use bool for booleans.
- (verify, main): Use EXIT_FAILURE/EXIT_SUCCESS instead of 1/0.
- (STRTOX): Rewrite to avoid casts.
- (print_esc_char): Arg is char, not int.
- * src/readlink.c (canonicalize): Remove. All uses now merely inspect
- can_mode.
- (no_newline, verbose): Use bool for booleans.
- (can_mode): Now of type int; use -1 to denote otherwise-uninitialized.
- * src/shred.c (struct Options, main): Use bool for booleans.
- (isaac_seed_data, fillpattern, wipefile): Rewrite to avoid casts.
- * src/split.c (cwrite, bytes_split, lines_split, line_bytes_split):
- Use bool for booleans.
- * src/stat.c (G_fail): Remove.
- (print_statfs): Print various gotta-be-nonnegative values using
- unsigned long int, not long int or int.
- (do_statfs, do_stat): Return a boolean success flag.
- (do_stat, main): Use bool for booleans.
-
- * src/pr.c: Add a FIXME mentioning that there are many
- unchecked integer overflows in this file.
- (TRUE, FALSE): Remove. All uses replaced by true and false.
- (struct COLUMN, read_line, print_page, print_stored, open_file,
- skip_to_page, init_fps, parallel_files, align_empty_cols,
- empty_line, FF_only, explicit_columns, extremities, keep_FF,
- print_a_FF, print_a_header, use_form_feed, have_read_stdin,
- print_across_flag, storing_columns, balance_columns,
- truncate_lines, join_lines, untabify_input, failed_opens,
- numbered_lines, skip_count, use_esc_sequence, use_cntrl_prefix,
- double_space, ignore_failed_opens, use_col_separator,
- pad_vertically, last_line, main, init_parameters, skip_read,
- read_line, print_stored):
- Use bool for booleans.
- (struct COLUMN, char_to_clump, store_char, print_char):
- Use char for chars.
- (clump_buff, print_clump): Use char[], not int[], for an array whose
- elements are always chars.
- (first_last_page, main, getoptarg, balance, add_line_number,
- char_to_uclump): Remove unnecessary casts.
- (init_parameters): Allocate chars, not ints, for clump_buff.
- (print_char): Use to_uchar before invoking ISPRINT.
- (char_to_clump): Convert to unsigned char before invoking ISPRINT.
-
- * src/nohup.c (main): Use bool for booleans.
- * src/paste.c (paste_parallel, paste_serial, main): Likewise.
- * src/pathchk.c (validate-path, main, portable_chars_only): Likewise.
- (portable_chars_only): Use to_uchar rather than a cast.
- * src/printenv.c (main): Use bool for booleans.
- Do not assume that the environ has at most one matching entry
- for each option (integer overflow was possible otherwise).
-
- * src/od.c (FMT_BYTES_ALLOCATED): Now an enum, not a decimal
- constant. Do not assume PRIdMAX etc. are strings of length 3 or
- less.
- (struct tspec): Use it. fmt_string is now an array, not
- a pointer, as there's little point to the indirection here.
- (struct tspec, flag_dump_strings,
- traditional, flag_pseudo_start, limit_bytes_to_format,
- abbreviate_duplicate_blocks, have_read_stdin, simple_strtoul,
- decode_one_format, open_next_file, check_and_close,
- decode_format_string, skip, write_block, read_char, read_block,
- parse_old_offset, dump, dump_strings, main):
- Use bool for booleans.
- (struct tspec): Use void *, not char *, for generic pointers.
- (bytes_to_oct_digits, bytes_to_signed_dec_digits,
- bytes_to_unsigned_dec_digits, bytes_to_hex_digits):
- Use char, not unsigned int, since char suffices.
- (print_s_char, print_char, print_s_short, print_short,
- print_int, print_long, print_long_long, print_float,
- print_double, print_long_double): Rewrite to avoid casts.
- These now take void * arguments, instead of char *.
- Use the same body for all functions, except for the choice
- of type. Assume C89 to simplify handling of signed char.
- (dump_hexl_mode_trailer, print_named_ascii, print_ascii):
- Rewrite to avoid casts.
- (print_named_ascii, print_ascii): Now takes void *, not char *.
- (decode_one_format): Use int for printf field widths, not
- unsigned int. Pass void * to subsidiary printers,
- not char *. Simplify handling of floating-point formats
- by factoring out common code dealing with precision and field width.
- (decode_format_string): Avoid need for temporary copy of
- each decoded struct tspec.
- (get_lcm): Remove unnecessary cast.
- (main): Fix bug where more than INT_MAX failed decodes were ignored.
-
-2004-08-02 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/nl.c (TRUE, FALSE): Remove; all uses changed to true, false.
- (enum number_format): Remove.
- (FORMAT_RIGHT_NOLZ, FORMAT_RIGHT_LZ, FORMAT_LEFT): Now strings,
- not enum values.
- (DEFAULT_SECTION_DELIMITERS): Now an array constant, not a macro.
- (section_del): Now const.
- (print_fmt): Remove.
- (starting_line_number, page_incr, blank_join, line_no,
- print_lineno, proc_text, main):
- Use intmax_t for line numbers.
- (reset_numbers, have_read_stdin, build_type_arg, nl_file, main):
- Use bool for booleans.
- (lineno_format): Now a string, not an enum value.
- (build_print_fmt): Remove. All calls removed. This work is
- now done within print_lineno.
- (build_type_arg): Use size_t for sizes.
- (print_lineno): Check for line number overflow.
- (proc_text, main): Remove unnecessary cast.
-
- * src/ln.c (symbolic_link, interactive, remove_existing_files,
- verbose, hard_dir_link, dereference_dest_dir_symlinks,
- do_link, main): Use bool for booleans.
-
- * src/ls.c (struct fileinfo, file_interesting,
- extract_dirs_from_files, color_symlink_as_referent,
- FILE_OR_LINK_MODE, sort_reverse, print_owner, print_group,
- numeric_ids, print_block_size, dired, print_with_color,
- check_symlink_color, print_inode, recursive, immediate_dirs,
- all_files, really_all_files, qmark_funny_chars,
- print_dir_name, format_needs_stat, format_needs_type, visit_dir,
- main, decode_switches, parse_ls_color, print_dir, file_interesting,
- gobble_file, make_link_path, basename_is_dot_or_dotdot,
- extract_dirs_from_files, print_long_format):
- Use bool for booleans.
- (dir_defaulted): Remove; no longer needed.
- (main): Use int to count files, since it suffices for argv.
- Rewrite to avoid need for dir_defaulted.
- (main, print_dir, gobble_file, get_link_name,
- xstrcoll):
- Set exit status to EXIT_SUCCES/EXIT_FAILURE rather than 0/1.
- (decode_switches): Put back check for ws.ws_col <= SIZE_MAX.
- Remove unnecessary cast to int. Use int instead of unsigned
- int to count from 0 to 1.
- (get_funky_string, print_type_indicator): Use char for bytes, not int.
- (make_link_path): Use NULL for null pointers.
- (quote_name): Use to_uchar instead of cast.
-
- * src/id.c (use_name, main, print_user, xgetgroups, print_group_list,
- print_full_info): Use bool for booleans.
- (problems): Remove, replacing with....
- (ok): New var (inverted from old sense).
- (print_user, print_group, print_full_info):
- Print uids/gids with %lu, not %u.
- (xgetgroups): Don't run out of memory if getgroups or getugroups
- returns -1.
- * src/setuidgid.c (main): Print uids/gids with %lu, not %ld.
-
- * src/factor.c (wheel_tab): Use unsigned char instead of unsigned
- int, since it suffices.
- (factor, print_factors): Use size_t for sizes.
- (print_factors, do_stdin, main): Use bool for booleans.
- * src/fold.c (TAB_WIDTH): New macro; use it instead of "8".
- (fold_file, main): Use bool for booleans.
- (fold_file, main): Use size_t for sizes.
- (main): Allow -w options up to SIZE_MAX - TAB_WIDTH - 1, instead
- of prohibiting widths greater than INT_MAX.
- * src/head.c (presume_input_pipe, print_headers, have_read_stdin,
- write_header, elide_tail_bytes_pipe, elide_tail_bytes_file,
- elide_tail_lines_pipe, elide_tail_lines_seekable,
- elide_tail_lines_file, head_bytes, head_lines, head, head_file,
- string_to_integer, main):
- Use bool for booleans.
- (main): Rewrite to avoid cast.
-
- * src/csplit.c (struct line): Use size_t for sizes.
- (main): Remove unnecessary cast.
- * src/cut.c (cut_fields): Use to_uchar rather than a cast.
- * src/cut.c (cut_file, main): Use bool for booleans.
- * src/date.c (show_date, rfc_format, batch_convert, main): Likewise.
- * src/env.c (main): Likewise.
- * src/expr.c (nextarg): Likewise.
- * src/env.c (main): Remove unused and nonstandard envp arg.
-
- * src/fmt.c (COST, MAXWORDS): Add a comment describing some of
- fmt's arbitrary limits.
- (TRUE, FALSE): Remove; all uses changed to (true, false).
- (main): Use bool for booleans.
- Limit maximum width to MAXCHARS / 2. Use xstrtoul, not xstrtol,
- to parse width.
- (copy_rest): Remove unnecessary cast.
- (get_prefix): Rewrite to avoid cast.
- (check_punctuation): Use char *, not unsigned char *; C89 requires
- this. Avoid off-by-one buffer read overrun when line is empty.
- (flush_paragraph): Don't assume wptr-parabuf is <= INT_MAX.
- Remove unnecessary casts.
- * tests/fmt/basic (wide-1, wide-2, bad-suffix): Adjust to above
- changes.
-
- * src/expand.c (convert_entire_line, have_read_stdin, parse_tabstops,
- next_file, expand, main):
- Use bool for booleans.
- (tab_size, tab_list, add_tabstop, parse_tabstops, validate_tabstops,
- expand, main):
- Use uintmax_t for column counts.
- (add_tabstop): Don't reserve -1 (now UINTMAX_MAX) as a special value.
- All callers changed.
- (parse_tabstops): Don't pass a negative char to isblank.
- Avoid memory leak with large tab stops.
- (validate_tabstops, expand): Don't assume number of tab stops is
- <= INT_MAX.
- (next_file, main): Use EXIT_SUCCESS/EXIT_FAILURE rather than 0/1 when
- storing values into exit_status.
- (expand): Use same pattern as unexpand for reading chars.
- Report an error when input line is too long, instead of silently
- screwing up. Do not mishandle tab stops when backspacing left
- over start of line.
-
- * src/dircolors.c (have_read_stdin, append_quoted,
- dc_parse_stream, dc_parse_file, main): Use bool for booleans.
- (dc_parse_stream): Use enum for state, rather than int.
- Use ssize_t to store getline result.
-
- * src/dd.c (translation_needed, parse_integer, scanargs,
- apply_translations, char_is_saved, swab_buffer, skip_via_lseek):
- Use bool for booleans.
- (translate_buffer): Use to_uchar rather than a cast.
- (swab_buffer, copy_simple, copy_with_unblock):
- Use size_t for sizes.
-
- * src/seq.c (equal_width, valid_format, main): Use bool for booleans.
- * src/sleep.c (apply_suffix): Likewise.
- * src/tail.c (struct File_spec, reopen_inaccessible_files, count_lines,
- forever, from_start, print_headers, have_read_stdin, valid_file_spec,
- write_header, file_lines, pipe_lines, pipe_bytes, recheck,
- tail_forever, tail_bytes, tail_lines, tail, tail_file,
- parse_obsolescent_option, parse_options, main): Likewise.
- * src/sleep.c (apply_suffix): Invert sense of result.
- Use int (not unsigned int) for multiplier, as this generates better
- code with some compilers. Simplify code a bit.
- * src/tail.c (struct File_spec, max_n_unchanged_stats_between_opens,
- parse_options): Use uintmax_t, not unsigned int or unsigned long int,
- for state counters.
- (tail_bytes, tail_lines): Redo test of return value (-1, 0, 1) to
- make it a bit clearer.
-
- * src/hostname.c: Include "xgethostname.h".
- (xgethostname): Remove decl; xgethostname.h has it.
- (sethostname) [!defined(HAVE_SETHOSTNAME) && defined(HAVE_SYSINFO)
- && defined (HAVE_SYS_SYSTEMINFO_H) && defined(HAVE_LIMITS_H)]: Use
- prototypes rather than K&R form. Assume any negative value from
- sysinfo denotes failure, not just -1.
- (main): Simplify use of sethostname.
-
- * src/pinky.c (include_idle, include_heading, include_fullname,
- include_project, include_plan, include_home_and_shell, do_short_format,
- include_where, main): Use bool for booleans.
- (count_ampersands, create_fullname, scan_entries, short_pinky):
- Use size_t for sizes.
- (create_fullname): Check for overflow in size calculations.
- (idle_string): Don't assume that the number of idle days
- is less than 10**8 and/or INT_MAX/(24*60*60).
- (main): No need to pass a non-NULL last arg to getopt_long.
- * src/uptime.c (print_uptime, uptime): Use size_t for sizes.
- (print_uptime): Remove unused local variable.
- (main): No need to pass a non-NULL last arg to getopt_long.
- * src/users.c (list_entries_users, users): Use size_t for sizes.
- (list_entries_users): Use char for bytes.
- (main): No need to pass a non-NULL last arg to getopt_long.
- * src/who.c (do_lookup, short_list, short_output, include_idle,
- include_heading, include_mesg, include_exit, need_boottime,
- need_deadprocs, need_login, need_initspawn, need_clockchange,
- need_runlevel, need_users, my_line_only, main): Use bool for booleans.
- (print_runlevel): Use unsigned char for bytes.
- (list_entries_who, scan_entries, who): Use size_t for sizes.
- (main): No need to pass a non-NULL last arg to getopt_long.
-
- * src/install.c (isdir): Remove decl.
- (install_file_to_path): Rely on make_path to fail if the destination
- is not a directory, by passing preserve_existing==true to it.
- Hence we no longer need to call isdir.
- Free dest_dir immediately when it's no longer needed, rather than
- waiting until the end of the function.
- (copy_file): Don't bother calling isdir, as copy will do the
- right thing if the destination is a directory.
-
- * src/du.c (fts_debug, opt_all, apparent_size, opt_count_all,
- print_grand_total, opt_separate_dirs, hash_ins, process_file, main):
- Use bool for booleans.
- (max_depth): Now size_t, not int, to avoid an arbitrary limit
- of INT_MAX on depth.
- (G_fail): Remove: no longer needed, now that the relevant
- functions return bool.
- (process_file): Use return value to signal success rather than
- setting a global. Remove first_call static var; not needed, since
- we can look at n_alloc. Use size_t for depths. Remove FIXME
- about size_t casts, as it's now fixed. Use xnrealloc rather
- than the obsolescent XREALLOC. Don't bother to check whether
- reallocation is needed unless level > prev_level.
- (du_files): Invert sense of result, for consistency with
- other coreutils code. All callers changed.
- (main): Allow --max-depth values up to SIZE_MAX.
-
- * src/df.c (inode_format, show_all_fs, show_local_fs,
- show_listed_fs, posix_format, require_sync, print_type,
- selected_fstype, excluded_fstype, show_dev, show_point, main):
- Use bool for booleans.
- (df_readable, show_dev): Use UINTMAX_MAX instead of -1.
- (show_dev, show_point, main):
- Use EXIT_SUCCESS/EXIT_FAILURE instead of 0/1.
- Don't assume disk name lengths are <= INT_MAX.
- Rewrite pct calculation to avoid cast.
- (show_point): Don't assume resolved length is <= SSIZE_MAX.
-
- * src/cut.c (hash_int) [!defined UINTPTR_MAX]: Use size_t
- instead of uintptr_t.
- * src/shred.c (UINT_MAX_32_BITS): Remove.
- (word32): Remove. All uses changed to uint32_t.
- (isaac_seed_data): Remove unnecessary cast.
- * src/system.h (ptr_align): Use size_t; in practice, this is just as
- good as uintptr_t in checking for alignments, and has fewer
- configuration hassles.
-
- * src/Makefile.am (localedir.h): Make it readonly; this
- undoes part of the 2004-07-27 patch.
-
-2004-07-30 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/sort.c (UCHAR): Remove; all uses changed to to_uchar.
- (IS_THOUSANDS_SEP): Use bool when appropriate.
- (numcompare, main): Use char, not int, when the value is always a char.
- (numcompare): Remove "register"; compilers are smart enough these days.
- * src/system.h (errno, CHAR_BIT): Remove decls;
- no longer needed now we assume C89 or better.
- Include <inttypes.h> before <stdint.h>, as it's the
- Autoconf-recommended pattern.
- (to_uchar): New inline function, moved here from tr.c.
- Use full names for int types, e.g. "long int" rather than "long".
- * src/tr.c (to_uchar): Remove; now in system.h.
- (is_char_class_member): Use bool when appropriate.
-
- * src/mkdir.c (create_parents, main): Use bool when appropriate.
- (main): Use EXIT_SUCCESS/EXIT_FAILURE instead of 0/1.
-
-2004-07-29 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/mkfifo.c (main): Use EXIT_SUCCESS and EXIT_FAILURE, not 0 and 1.
-
- * src/chmod.c (recurse, force_silent, process_file, process_files,
- main): Use bool when appropriate.
- * src/cksum.c (cksum, main): Likewise.
- * src/comm.c (hard_LC_COLLATE, only_file_1, only_file_2, both,
- compare_files, main): Likewise.
-
- * src/copy.h (struct cp_options): Likewise.
- * src/copy.c (copy_internal, is_ancestor, copy_dir, copy_reg,
- same_file_ok, seen_file, copy_internal, valid_options, copy): Likewise.
- * src/cp-hash.h (remember_created): Likewise.
- * src/cp-hash.c (remember_created): Likewise.
- * src/cp.c (struct dir_attr, flag_path, remove_trailing_slashes,
- re_protect, make_path_private, target_directory_operand, do_copy,
- cp_option_init, decode_preserve_arg, main): Likewise.
- * src/install.c (isdir, change_timestamps, change_attributes,
- copy_file, install_file_to_path, install_file_in_dir,
- install_file_in_file, strip_files, dir_arg, cp_option_init, main,
- change_attributes, change_timestamps): Likewise.
- * src/mv.c (remove_trailing_slashes, rm_option_init,
- cp_option_init, do_move, movefile, main): Likewise.
- * src/remove.c (right_justify), full_filename_, AD_pop_and_chdir,
- AD_push, prompt, remove_dir): Likewise.
- * src/rm.c (rm_option_init, main): Likewise.
-
- * src/remove.c (top_dir, pop_dir, full_filename_):
- Use size_t for sizes.
- * src/cp.c (target_directory_operand): Do not clear *NEW_DST if stat
- succeeds. It's not necessary in that case, as *NEW_DST is always
- false already.
- (do_copy): Rewrite slightly to avoid need for "unreachable" comment.
- (main): Use EXIT_SUCCESS, EXIT_FAILURE instead of 0, 1.
- * src/rm.c (main): Likewise.
-
- md5sum, sha1sum integer cleanups.
-
- * src/checksum.h: Don't include config.h, sys/types.h, stdio.h:
- not needed.
- (ALG_UNSPECIFIED): Remove.
- (ALG_MDT): Don't make it equal to CHAR_MAX + 1; this isn't necessary.
- * src/md5.c: Don't include any files other than checksum.h.
- * src/sha1sum.c: Likewise.
- * src/md5sum.c (OPENOPTS, have_read_stdin, status_only, warn,
- bsd_split_3, split_3, hex_digits, digest_file, digest_check, main):
- Use bool when appropriate.
- (digest_check): Increase limit of number of input lines to
- UINTMAX_MAX from INT_MAX. Diagnose any overflows of this counter.
- Use ngettext instead of hard-to-i18nize hardcoded stuff for plurals.
-
-2004-07-28 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/cat.c (exit_status): Remove. Now done by passing a boolean
- 'ok' flag around.
- (simple_cat, cat): Return true if successful. All callers changed.
- (simple_cat, cat, main): Use bool for booleans.
- (simple_cat): Use size_t for sizes.
- (cat, main): Use the same names for parameters that we use for
- long options, to avoid confusion. This inverts the sense of the
- show_tabs (formerly output_tabs) and number_nonblank
- (formerly numbers_at_empty_lines) variables.
- (main): Don't mess up (due to integer overflow) if we are given
- INT_MAX - INT_MIN + 1 options.
- [O_BINARY]: Don't invoke isatty unless the other options require it.
- (main): When deciding whether to use simple_cat, don't worry
- about binary option; it's irrelevant.
-
- * src/dcgen: Remove comments, trailing white space, and empty
- lines from the output strings, to save space.
- Use a narrower type like 'unsigned char' for line lengths, if
- that will do.
- Make the output variables static, not extern.
-
- * src/chgrp.c (parse_group): Require base 10 when parsing
- groups as integers.
- (main): int -> bool when appropriate.
- * src/chown.c (main): Likewise.
- * src/chown-core.c: Include inttostr.h.
- (UINT_MAX_DECIMAL_DIGITS, uint_to_string): Remove.
- (gid_to_name, uid_to_name): Use imaxtostr/umaxtostr
- instead of uint_to_string).
- (describe_change): Instead of an int flag, use a char *
- auxiliary; this avoids the need for casts.
- Assume free (NULL) works.
- (change_file_owner): Return true/false, not 0/-1, since
- we don't set errno. All callers changed.
- Use bool when appropriate.
- (chown_files): Likewise.
- * src/chown-core.h (chown_files): Likewise.
-
- * tests/chown/basic: Test for proper handling of uids like
- "010", which must be parsed as decimal.
-
- * tests/misc/pwd: Don't assume that Perl's getpwd agrees with our
- pwd when there are multiple names for the working directory
- (which can happen with an automounter, sigh).
-
- * src/Makefile.am ($(SCRIPTS)): Don't depend on Makefile;
- this causes Solaris 8 'make' to refuse to build "groups".
- (localedir.h): Don't depend on Makefile: this causes Solaris
- 8 'make' to build localedir.h unnecessarily. The dependence
- on Makefile is ineffective anyway, since $(localedir) might
- change even if Makefile hasn't.
-
- * src/remove.c (remove_dir): If we can't save the state of the
- working directory, pretend we started from "/", not ".".
- This avoids a bug on hosts like Solaris that don't let you
- remove the working directory.
-
-2004-07-27 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/printf.c (strtiomax, strtoumax): Declare if not already
- declared: this fixes a portability bug with Solaris 8 + GCC.
- (STRTOX): Parenthesize use of macro arg as expression.
- (vstrtoimax, vstrtoumax, vstrtold): Remove now-unnecessary
- parentheses.
- * configure.ac: Check for declaration of strtoumax, for
- src/printf.c.
-
- * src/Makefile.am (cp_LDADD, ginstall_LDADD, mv_LDADD,
- pathchk_LDADD, rm_LDADD, test_LDADD): New vars, for eaccess.
-
- * tests/readlink/can-e: Don't assume that we can remove the
- working directory: this isn't possible under Solaris 8, say.
- * tests/readlink/can-f: Likewise.
- * tests/readlink/can-m: Likewise.
-
- * src/copy.c (copy_internal): find_backup_file_name no longer
- returns NULL, so don't bother to check for this.
- * src/cp.c (do_copy): Likewise.
- * src/ln.c (do_link): Likewise.
-
-2004-07-25 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/nice.c (GET_NICE_VALUE): Renamed from GET_PRIORITY.
- All uses changed.
- (NZERO): New macro, if system doesn't define it already.
- (usage): Distinguish priorities from nice values.
- Don't assume NZERO is 20.
- (main): Use bool instead of int where appropriate.
- If user specifies an adjustment out of range, always truncate it
- to an inrange value instead of sometimes giving an error message
- and sometimes not.
- Do not assume that -1 is an error return from "nice" or
- "getpriority", as it might be the current nice value minus NZERO.
- If nice/setpriority fails with errno == EPERM, go ahead and run
- the command anyway; POSIX requires this.
-
- * src/pathchk.c: Include euidaccess.h.
- (dir_ok): Use euidaccess, not access.
- * src/test.c (R_OK, W_OK, X_OK, FOK): Remove; system.h defines them.
- (eaccess): Remove. All users changed to use euidaccess instead.
-
-2004-07-24 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/uptime.c (print_uptime) [defined BOOT_MSG]:
- Don't assume ut_line is null-terminated.
- * src/who.c (print_line): New arguments USERLEN and LINELEN,
- since USER and LINE might not be null terminated. All callers
- changed.
-
-2004-07-23 Paul Eggert <eggert@cs.ucla.edu>
-
- Fix bug with "tail -f" reported by Rob Holland in
- <http://lists.gnu.org/archive/html/bug-coreutils/2004-07/msg00054.html>.
- Also, remove the undocumented and unsupported-since-2000
- --max-consecutive-size-changes options. Fix another related bug:
- "tail" got confused if stdin, stdout, or stderr were closed.
- Also, use output buffering even with "tail -f".
-
- * NEWS: Document this, plus yesterday's patch.
- * doc/coreutils.texi (tail invocation): "size has remained the same"
- -> "file has not changed", which is more accurate for fifos.
- * src/tail.c: Include fcntl-safer.h.
- (COPY_TO_EOF): Set to UINTMAX_MAX, not OFF_T_MAX (which was wrong).
- (COPY_A_BUFFER): New macro.
- (struct File_spec): New members mtime, mode, blocking.
- Remove member n_consecutive_size_changes.
- (DEFAULT_MAX_N_CONSECUTIVE_SIZE_CHANGES,
- max_n_consecutive_size_changes_between_opens,
- MAX_CONSECUTIVE_SIZE_CHANGES_OPTION): Remove.
- (long_options, tail_forever, parse_options):
- Remove (non-)support for --max-consecutive-size-changes.
- (record_open_fd): New function.
- (recheck, tail_file): Use it. Don't assume that stdin is open.
- (dump_remainder): Add support for new COPY_A_BUFFER special value.
- Treat errno==EAGAIN like EOF, since it might be a nonblocking read.
- (recheck): New arg BLOCKING, specifying whether to use blocking reads.
- All uses changed.
- (n_live_files): Remove, replacing with...
- (any_live_files): New function. All uses changed.
- (tail_forever): Use nonblocking I/O unless we know that blocking I/O
- is safe; this avoids some hangs when reading from a fifo.
- Avoid invoking fstat or sleep when using blocking I/O.
- Do not check for changes to size if the file is not a regular file,
- as the size is undefined in that case.
- Check for changes to mtime or mode, too; this works for non-regular
- files.
- (tail_forever, main): Redo fflush strategy to work even when input
- is nonblocking. Don't use unbuffered output; just flush when needed.
-
-2004-07-22 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/tail.c (main): Ignore -f if no file operand is specified
- and standard input is a pipe.
- * doc/coreutils.texi (tail invocation): Do not ignore -f for
- all pipes, just for when standard input is a pipe and no
- file operand is specified.
- * tests/tail/Test.pm: Reinstate f-1 test, since we now pass.
- Add a new commented-out f-2 test, which we still fail.
- (test_vector): All f-* tests are special cases, not just f-1.
-
-2004-07-12 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/uptime.c: Include c-strtod.h.
- (print_uptime): Use c_strtod instead of setlocale and sscanf.
- Use long int rather than int to count days (for 64-bit hosts),
- and check for arithmetic overflow when converting double to time_t.
-
-2004-07-11 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/printf.c (vstrtold): Renamed from vstrtod.
- Now returns long double. All uses changed.
- (print_direc): Use "L" length modifier when printing floating point
- numbers, since we're now printing long double.
-
-2004-07-06 Paul Eggert <eggert@cs.ucla.edu>
-
- * Version 5.3.0.
-
- printf cleanup, to avoid undefined behavior, to add support for
- formats that Bash supports, and to support wide integers like
- Bash does.
-
- * NEWS: Document this.
- * src/printf.c (UNSPECIFIED): Remove. All uses now replaced by
- booleans, so that we don't reserve any values for precision or
- width (like Bash).
- (STRTOX): Use prototype, not K&R-style definition.
- (vstrtoimax): Renamed from xstrtol (to avoid confusion with xstrtol
- in ../lib), with type change to intmax_t.
- All uses changed.
- (vstrtoumax): Renamed from xstrtoul, with type change to uintmax_t.
- All uses changed.
- (vstrtod): Renamed from xstrtod. All uses changed.
- (print_direc): Use boolean arg instead of special value to indicate
- a missing precision or width. LENGTH no longer includes
- length modifiers or conversion character. New arg CONVERSION
- now specifies conversion character.
- Use intmax_t-width formatting for integers (like Bash).
- Add support for C99 %a, %A, %F (like Bash).
- Add support for field width with %c (POSIX requires this).
- Add a FIXME for lack of support for field width and precision
- for %b.
- Add support for '\'', '0' flags.
- Check for invalid combinations of flags, field width, precision,
- and conversion, to prevent use of undefined behavior.
- Allow multiple length modifiers, for formats like "%lld" (like Bash).
- Add support for C99 'j', 't', 'z' length modifiers (like Bash).
- In error message, output entire invalid conversion specification,
- instead of merely outputting % followed by the conversion char.
- * tests/misc/printf: Add tests for the above.
-
-2004-04-03 Dmitry V. Levin <ldv@altlinux.org>
-
- Change "readlink -f" to be more compatible with prior implementations.
- Add more canonicalize options, -e and -m.
- Add comprehensive tests for all readlink modes.
-
- * m4/canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME):
- Do not add canonicalize.c here.
-
- * src/readlink.c (longopts): Add new options.
- (usage): Document them.
- (canonicalize_fname): New proxy function.
- (main): Handle new options.
- * doc/coreutils.texi (readlink invocation): Document new
- "readlink -f" behaviour and new canonicalize options, -e and -m.
-
- * configure.ac (AC_CONFIG_FILES): Add tests/readlink/Makefile.
- * tests/Makefile.am (SUBDIRS): Add readlink.
- * tests/readlink/Makefile.am: New file.
- * tests/readlink/{rl-1,can-e,can-f,can-m}: New readlink tests.
- * tests/misc/Makefile.am (TESTS): Remove basic readlink test.
- * tests/misc/readlink: Remove file.
-
-2004-07-04 Jim Meyering <jim@meyering.net>
-
- * src/copy.c (copy_internal): Add a FIXME comment.
-
-2004-07-02 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/copy.c (copy_dir): Assume path_concat returns non-NULL.
- * src/cp.c (do_copy): Likewise.
- * src/mv.c (movefile): Likewise.
-
- * src/cp.c (make_path_private): 2nd arg is now size_t, not int,
- to avoid problem when path_concat dir name is longer than 2 GiB (!).
-
- * src/nohup.c (main): Don't pass NULL first argument to path_concat.
- This cleans up the semantics a bit, as we no longer try to open the
- same file twice.
-
-2004-07-01 Paul Eggert <eggert@cs.ucla.edu>
-
- * NEWS: Add short names -t and -T for --target-directory
- and --no-target-directory options, respectively.
-
- * src/cp.c (NO_TARGET_DIRECTORY_OPTION, TARGET_DIRECTORY_OPTION):
- Remove. All uses changed to 'T' and 't', respectively.
- * src/install.c, src/ln.c, src/mv.c: Likewise.
-
- * src/cp.c (long_opts, usage, do_copy, main): Add -t and -T as
- aliases for --target-directory and --no-target-directory,
- respectively.
- * src/install.c (long_options, main, usage): Likewise.
- * src/ln.c, src/mv.c: Likewise.
-
-2004-07-01 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_file_system): New target.
- (syntax-check-rules): Add it.
- .x-sc_file_system: New file.
- * Makefile.am (EXTRA_DIST): Add it.
-
- * man/sync.x: Use "file system" rather than "filesystem".
- * man/stat.x, man/df.x: Likewise.
-
-2004-06-30 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/df.c (usage, main): Output "file system" rather than
- "filesystem".
- * src/du.c (usage): Likewise.
- * src/shred.c (usage): Likewise.
- * src/stat.c (usage): Likewise.
- * src/stat.c (long_options, usage): Rename "--filesystem" to
- "--file-system". But keep the old name around, for compatibility
- reasons.
-
-2004-06-29 Paul Eggert <eggert@cs.ucla.edu>
-
- Add support for --no-target-directory option.
-
- * NEWS: Document it.
- * doc/coreutils.texi (Common options, Target directory, cp
- invocation, install invocation, mv invocation, ln invocation):
- Likewise.
- (link invocation): Explain how to rewrite link using ln now
- that we have --no-target-directory.
- (ln invocation): Explain that --no-target-directory subsumes
- --no-dereference.
- (unlink invocation): Modify wording to match new wording in
- link invocation.
-
- * src/cp.c (NO_TARGET_DIRECTORY_OPTION): New constant.
- (long_opts, usage, do_copy, main): Add support for
- --no-target-directory,
- * src/install.c (NO_TARGET_DIRECTORY_OPTION, long_options, main,
- usage): Likewise.
- * src/ln.c (NO_TARGET_DIRECTORY_OPTION, long_options, usage,
- main): Likewise.
- * src/mv.c (NO_TARGET_DIRECTORY_OPTION, long_options, usage,
- main): Likewise.
- * src/mv.c (enum): Sort values.
-
-2004-06-29 Jim Meyering <jim@meyering.net>
-
- Don't let verbose-mode output from a subshell obscure actual differences.
- * tests/rm/inaccessible: Turn off command-echoing just before
- invoking subshell, then turn it back on if VERBOSE=yes afterward.
-
-2004-06-25 Paul Eggert <eggert@cs.ucla.edu>
-
- Add support for 'install --target-directory', an option
- that has been documented for years but not implemented (!).
- * doc/coreutils.texi (install invocation): Document
- --target-directory in synopsis, too.
- * src/install.c (TARGET_DIRECTORY_OPTION): New var.
- (long_options, main, usage): Add --target-directory.
- (target_directory_operand): New function, stolen from mv.c.
- (main): Use it. Check for -d and --target-directory.
- Alter wording of diagnostics to match other programs.
-
-2004-06-28 Jim Meyering <jim@meyering.net>
-
- * src/cp.c (usage): Fix copy+paste error in description of
- --target-directory: s/move/copy/. From Paul Jarc.
-
-2004-06-27 Paul Eggert <eggert@cs.ucla.edu>
-
- Use more-consistent rules among cp, ln, and mv when dealing with
- last operands that are (or look like) directories.
-
- * src/cp.c (target_directory_operand): New, nearly-common function,
- It reports an error if the destination appears to be a directory
- (e.g., because it has a trailing slash) but is not.
- * src/ln.c, src/mv.c: Likewise.
- * src/cp.c (do_copy): Use it.
- * src/ln.c (main): Likewise.
- * src/mv.c (main): Likewise.
-
- * src/cp.c (do_copy): Don't assume argc is positive.
- Don't bother to lstat dest, since copy() will do that for us.
- Use "const" to avoid the need for cast.
-
- * src/cp.c (do_copy): Don't output a usage message because of file
- problems (e.g., an operand is not a directory). Use it only for
- syntax. Standardize on "target %s is not a directory" for the
- diagnostic.
- * src/ln.c (main): Likewise.
- * src/mv.c (main): Likewise.
-
- * src/cp.c (do_copy): Remove test for trailing slash, since
- target_directory_operand now does this.
- * src/ln.c (main): Likewise.
- * src/mv.c (movefile): Likewise.
-
- * src/cp.c (main): Reject multiple target directories.
- Check whether a specified target is a directory when parsing the
- options, using stat. This gives more-accurate diagnostics.
- * src/ln.c (main): Likewise.
-
- * src/ln.c (isdir): Remove decl; no longer needed.
- * src/mv.c (isdir, lstat): Likewise.
-
- * src/ln.c (do_link): New arg dest_is_dir. All uses changed.
- Don't check the destination ourself; rely on dest_is_dir.
- This way we can avoid lstatting the destination in the
- usual case, and in the worst case we lstat 1, not 3 times.
- Don't bother to unlink unless link failed; this saves a syscall.
- Remove unnecessary backup_succeeded flag;
- it was identical to "dest_backup != NULL".
-
- * src/ln.c (main): Use int to count to argc, not unsigned int.
- This handles negative operand counts.
- * src/mv.c (main): Likewise.
-
- * src/mv.c (do_move): Don't call hash_init; expect the caller to
- do it, for consistency with cp.c and ln.c. All callers changed.
- (movefile): dest_is_dir parameter is now bool, not int.
- (main): Standardize on "missing destination file operand after %s"
- for the diagnostic, for consistency with cp.c.
-
- * tests/mv/diag: Don't assume "mv --target=nonexistentdir"
- will complain about the arg count.
- Adjust to new (briefer) diagnostics.
- * tests/cp/fail-perm: Add a test to verify that we get the new
- diagnostic when failing to copy through a symlink-to-inaccessible-dir.
-
-2004-06-27 Paul Eggert <eggert@cs.ucla.edu>
-
- Fix a bug: formerly, if d/x was a directory and x a file, "ln x
- d/" incorrectly created a link d/x/x. It also saves some system
- calls.
-
- * NEWS: Document the fix.
-
- * src/ln.c (main): Don't append basename to dest if this
- results in an existing directory name.
- * tests/ln/misc: See whether a trailing slash is followed too far.
-
-2004-06-26 Jim Meyering <jim@meyering.net>
-
- * src/printf.c (main): When given no arguments, print the standard
- "missing operand\nTry printf --help..." message -- to be consistent.
-
-2004-06-26 Jim Meyering <jim@meyering.net>
-
- * src/mknod.c (main): Add \n at the end of message output via fprintf.
-
-2004-06-25 Jim Meyering <jim@meyering.net>
-
- * tests/ln/misc: Add test for ln subscript error.
-
-2004-06-23 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/ln.c (do_link): Remove unnecessary call to lstat.
- (main): Avoid subscript error when the destination is "".
-
-2004-06-23 Jim Meyering <jim@meyering.net>
-
- * tests/*: Replace all occurrences of `(exit N); exit' with
- `(exit N); exit N'. Otherwise, those many tests could exit with
- improper exit status when exiting via e.g., a trapped interrupt.
- Thanks to a report from Bob Proulx.
-
-2004-06-22 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/who.c (idle_string, print_user): New arg boottime,
- specifying the most recent boot time. All uses changed.
- (idle_string) Consider a line to be "old" if it hasn't been used
- since the last boot time. Watch out for overflow when computing
- times, and for times in the future.
- (idle_string): Record latest boot time.
-
-2004-06-22 Jim Meyering <jim@meyering.net>
-
- * src/test.c (usage): Correct description of `-t FD'. The file
- descriptor, FD, is no longer optional. Reported by Ton Nijkes.
-
-2004-06-21 Paul Eggert <eggert@cs.ucla.edu>
-
- The 2004-06-19 fix for who and pinky was incomplete, as ctime
- has undefined behavior if the year precedes -999 or follows 9999.
- Since we have to stop using ctime anyway, we might as well use
- strftime and fix the FIXME, and support internationalized dates.
-
- * NEWS: Document the new behavior.
- * src/who.c: Include "hard-locale.h".
- (time_format, time_format_width): New vars.
- (time_string, print_line): Use them.
- (main): Set them.
- (time_string): Use localtime + strftime instead of
- ctime, to avoid problems with years before -999 or after 9999.
- * src/pinky.c: Likewise.
-
-2004-06-21 Paul Eggert <eggert@cs.ucla.edu>
-
- Fix bug: GNU 'ls' didn't count columns correctly if user or group
- names contained multibyte characters where the column count
- differed from the byte count. This patch also corrects
- some comments.
-
- * src/ls.c (format_user_or_group): New function, which counts
- columns correctly.
- (format_user, format_group): Use it.
- (format_user_or_group_width): New function, which counts columns
- correctly.
- (format_user_width, format_group_width): Use it.
-
-2004-06-21 Jim Meyering <jim@meyering.net>
-
- * tests/priv-check: Quote "$PATH" in PATH=$PATH.
- Suggestion from Andreas Schwab.
-
- * tests/priv-check: When running as root, be sure to propagate
- PATH through to the process we exec as non-root.
- Reported by michael@aplatform.com.
-
- * src/mknod.c (main): Don't segfault when calculating the
- expected number of operands for `mknod NAME'.
-
-2004-06-20 Jim Meyering <jim@meyering.net>
-
- * src/dd.c (input_seek_errno): Declare file-scoped variable as static.
-
-2004-06-20 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/basename.c (main):
- Standardize on the diagnostics given when someone gives
- too few operands ("missing operand after `xxx'") or
- too many operands ("extra operand `xxx'").
- Include "quote.h" and/or "error.h" if it wasn't already being included.
- * src/chgrp.c (main): Likewise.
- * src/chmod.c (main): Likewise.
- * src/chown.c (main): Likewise.
- * src/chroot.c (main): Likewise.
- * src/comm.c (main): Likewise.
- * src/cp.c (do_copy): Likewise.
- * src/csplit.c (main): Likewise.
- * src/date.c (main): Likewise.
- * src/dircolors.c (main): Likewise.
- * src/dirname.c (main): Likewise.
- * src/du.c (main): Likewise.
- * src/expr.c (main): Likewise.
- * src/hostid.c (main): Likewise.
- * src/hostname.c (main): Likewise.
- * src/id.c (main): Likewise.
- * src/install.c (main): Likewise.
- * src/join.c (add_file_name, main): Likewise.
- * src/link.c (main): Likewise.
- * src/ln.c (main): Likewise.
- * src/logname.c (main): Likewise.
- * src/md5sum.c (main): Likewise.
- * src/mkdir.c (main): Likewise.
- * src/mkfifo.c (main): Likewise.
- * src/mknod.c (main): Likewise.
- * src/mv.c (main): Likewise.
- * src/nohup.c (main): Likewise.
- * src/od.c (main): Likewise.
- * src/pathchk.c (main): Likewise.
- * src/ptx.c (main): Likewise.
- * src/readlink.c (main): Likewise.
- * src/rm.c (main): Likewise.
- * src/rmdir.c (main): Likewise.
- * src/seq.c (main): Likewise.
- * src/setuidgid.c (main): Likewise.
- * src/shred.c (main): Likewise.
- * src/sleep.c (main): Likewise.
- * src/sort.c (main): Likewise.
- * src/split.c (main): Likewise.
- * src/stat.c (main): Likewise.
- * src/test.c (beyond, main): Likewise.
- * src/touch.c (main): Likewise.
- * src/tr.c (main): Likewise.
- * src/tsort.c (main): Likewise.
- * src/tty.c (main): Likewise.
- * src/uname.c (main): Likewise.
- * src/uniq.c (main): Likewise.
- * src/unlink.c (main): Likewise.
- * src/uptime.c (main): Likewise.
- * src/users.c (main): Likewise.
- * src/who.c (main): Likewise.
- * src/whoami.c (main): Likewise.
-
- * tests/basename/basic: Adjust to new diagnostics.
- * tests/du/files0-from: Likewise.
- * tests/expr/basic: Likewise.
- * tests/mv/diag: Likewise.
- * tests/tsort/basic-1: Likewise.
-
-2004-06-20 Jim Meyering <jim@meyering.net>
-
- * src/ln.c: Remove declaration of yesno.
- Instead, include yesno.h.
- * src/copy.c: Likewise.
-
- * src/remove.c: Remove declaration of yesno.
- Instead, include yesno.h.
- (top_dir): Remove now-unnecessary cast of obstack_base.
- (pop_dir): Likewise.
- (full_filename_): Likewise.
-
-2004-06-19 Paul Eggert <eggert@cs.ucla.edu>
-
- Don't dump core if ctime returns NULL; this is possible on
- hosts with 64-bit time_t and 32-bit int.
- * src/who.c: Include "inttostr.h".
- (time_string): If ctime fails, print the raw time as an integer
- instead of dumping core.
- * src/pinky.c: Likewise, as follows:
- Include "inttostr.h".
- (time_string): New function, copied from who.c.
- (print_entry): Use it.
-
-2004-06-19 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/who.c (print_line): Don't truncate user names at 8 bytes.
- Problem reported by Guido Leenders in:
- http://lists.gnu.org/archive/html/bug-coreutils/2004-06/msg00056.html
- * NEWS: document this.
-
-2004-06-19 Jim Meyering <jim@meyering.net>
-
- * src/system.h (case_GETOPT_VERSION_CHAR): Switch back to
- using GNU_PACKAGE (from PACKAGE) once again. This restores
- `GNU' to the parenthesized package name in --version output.
- Before, the first argument from AC_INIT, `GNU coreutils', would
- be propagated to the PACKAGE variable. Now, `GNU ' is trimmed.
- Reported by Richard Stallman.
-
-2004-06-17 Jim Meyering <jim@meyering.net>
-
- * src/tr.c (to_uchar): Rename function from `uchar'. The latter
- would clash with a typedef in Tru64's <sys/types.h>. From Albert Chin.
-
-2004-06-15 Paul Eggert <eggert@cs.ucla.edu>
-
- * NEWS: Remove more special cases for POSIXLY_CORRECT when POSIX
- allows the GNU behavior. "--" is now supported by chroot, hostid,
- hosname, pwd, sync, yes.
- * doc/coreutils.texi (yes invocation, false invocation,
- true invocation): Document this.
- * src/chroot.c (main): Handle "--".
- * src/hostid.c (main): Likewise.
- * src/hostname.c (main): Likewise.
- * src/pwd.c (main): Likewise.
- * src/sync.c (main): Likewise.
- * src/yes.c (main): Likewise.
- * src/true.c (main): Recognize --help and --version even if
- POSIXLY_CORRECT is set.
- * src/yes.c (main): Likewise.
-
-2004-06-09 Paul Eggert <eggert@cs.ucla.edu>
-
- * NEWS: Remove special cases for POSIXLY_CORRECT when POSIX allows
- the GNU behavior.
- * doc/coreutils.texi (pr invocation, unlink invocation): Document this.
- * src/ls.c (decode_switches): Pay attention to TABSIZE even if
- POSIXLY_CORRECT is set. POSIX reserves upper-case environment
- variables to the implementation, so it's OK for ls to depend on
- TABSIZE.
- * src/pr.c: Include "hard-locale.h".
- (main): When in a non-POSIX locale, ignore POSIXLY_CORRECT, since
- POSIX specifies the behavior only in the POSIX locale.
- * src/printf.c (print_esc): Support \x, \u, \U even if POSIXLY_CORRECT,
- since POSIX says the behavior is unspecified here.
- * src/tail.c (parse_obsolescent_option): Support multiple file operands
- even if POSIXLY_CORRECT, since POSIX does not require a diagnostic.
- * src/printf.c (main): Recognize --help, --version even if
- POSIXLY_CORRECT. POSIX does not specify any options, but it
- does not prohibit options either, so "printf" is like "expr" here.
- * src/unlink.c (main): Likewise.
- * tests/misc/printf: Adjust to the new semantics for \x if
- POSIXLY_CORRECT.
-
-2004-06-14 Jim Meyering <jim@meyering.net>
-
- * tests/misc/pwd: New test, for fix of 2004-04-19.
- * tests/misc/Makefile.am (TESTS): Add pwd.
- (BUILD_SRC_DIR): Define BUILD_SRC_DIR.
-
- * src/copy.c: Remove declaration of euidaccess.
- Instead, include "euidaccess.h".
-
-2004-06-13 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/who.c (PIDSTR_DECL_AND_INIT): Don't assume pid_t fits in int.
- (UT_ID) [!HAVE_STRUCT_XTMP_UT_ID]: Remove bogus comment,
- as (sizeof "??") reliably returns 3.
- (print_line): Guard against idle and pid being too long
- (which is possible when printing headers).
- (print_user): Allocate enough bytes for idlestr. Use IDLESTR_LEN.
- Avoid unnecessary cast of sizeof to int.
- (make_id_equals_comment): Do not assume that UT_ID returns
- a string; it might return a non-null-terminated array.
- Use strncat instead. It's not very often where strncat is
- exactly what you want, but this is one of those rare cases.
-
-2004-06-11 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/who.c (list_entries_who): Don't output a trailing space.
-
-2004-06-09 Jim Meyering <jim@meyering.net>
-
- * src/touch.c (usage): Improve wording in description of the
- --time=WORD option. Reported by Dan Jacobson.
-
- * src/chown-core.c (change_file_owner): Change names of parameters
- old_uid and old_gid to required_uid and required_gid respectively.
-
- * src/chmod.c (mode_changed): Return false, not 0, now that the
- function returns `bool'.
-
-2004-06-08 Paul Eggert <eggert@cs.ucla.edu>
-
- Adjust chmod and chown to be similar if -c or -v are given. In
- particular, a no-op chown is no longer reported as a change; this
- reverts to previous behavior. Also, fix both commands so that -v
- report failures even if the failure is not due to the chmod or
- chown syscalls.
-
- * src/chmod.c (CH_NOT_APPLIED): New constant.
- (describe_change): Handle it.
- (process_file): Use it, if a symlink wasn't changed.
- (mode_changed): Return bool, not int. Accept new argument
- NEW_MODE; all callers changed. This lets us avoid statting the
- file unless the new mode has unusual bits.
- (process_file): Return -1 on error. With -v, report all errors
- verbosely, not just some.
-
- * src/chown-core.c (change_file_owner): Return -1 on error, not
- 1 sometimes and -1 on others. Our caller ORs together our results,
- and (-1 | 1) == 0 on ones-complement hosts.
- With -v report all errors verbosely, not just some.
- Fix bug when chopt->root_dev_ino && !chopt->affect_symlink_referent:
- file_stats wasn't set properly in that case.
-
- * tests/chgrp/basic: Adjust to above changes.
-
-2004-05-20 Paul Eggert <eggert@cs.ucla.edu>
-
- * tests/chgrp/basic: Test that chgrp -h does not fail on
- symlinks, even on hosts where that's not supported.
- Test that if -R is specified without -H or L, -h is assumed.
- Test that chown() is not optimized away.
-
-2004-05-18 Paul Eggert <eggert@cs.ucla.edu>
-
- Several fixes to chgrp and chown for compatibility with POSIX and BSD:
-
- Check for incompatible options. When -R and --dereference are
- both used, then either -H or -L must also be used. When -R and -h
- are both used, then -P must be in effect.
-
- -H, -L, and -P have no effect unless -R is also specified.
- If -P and -R are both specified, -h is assumed.
-
- Do not optimize away the chown() system call when the file's owner
- and group already have the desired value. This optimization was
- incorrect, as it failed to updated the last-changed time and reset
- special permission bits, as POSIX requires.
-
- Do not report an error if the owner or group of a
- recursively-encountered symbolic link cannot be updated because
- the file system does not support it.
-
- * NEWS: Document the above.
-
- * src/chgrp.c (main): Check for incompatible options. -R --dereference
- requires either -H or -L, and -R -h requires -P. If -H, specify
- FTS_PHYSICAL as well as FTS_COMFOLLOW; this is faster. Make this
- file as much like chown.c as possible.
- * src/chown.c (main): Likewise.
-
- * src/chown-core.c (change_file_owner): Use ent->fts_statp only if
- needed. Chown a directory only after chowning its children; this
- avoids problems if the new directory ownership doesn't permit
- access to the children. Dereference symlinks before doing
- ROOT_DEV_INO_CHECK, not after, so that we catch symlinks to /.
- Do not optimize away the chown() system call when the file's owner
- and group already have the desired value. POSIX does not permit
- this optimization. Rely on chown and lchown to do the right
- thing with symlinks and/or -1 arguments, now that we have wrappers
- to do this. Use ENOTSUPP not ENOSYS, and ignore all ENOTSUPP
- errors, not just command-line errors.
- (chown_files): Pass FTS_NOSTAT to xfts_open if we don't need file status.
-
- * src/system.h (ENOTSUP): Remove.
-
- * tests/chgrp/basic: Use chown --from to discover whether the
- group changed, since chgrp now changes unconditionally. This
- complicates the sed script a bit. Do not specify --dereference,
- since it's the default (and we want to test this). Adjust output
- to match the fact that chgrp no longer optimizes the case of
- changing a file's group to the same value as before.
- * tests/chgrp/posix-H: Do not attempt to combine -h and -H; these
- options are incompatible, and their behavior is undefined with POSIX.
- (changed, not_changed): Adjust to match the fact that -h is no longer
- specified. Sort names.
- * tests/chown/deref: Adjust error-diagnostic spelling to match new
- behavior.
-
-2004-06-07 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/uname.c (main): Fix typo introduced on 2003-05-10 that
- prevented a diagnostic of any operands.
-
-2004-06-08 Jim Meyering <jim@meyering.net>
-
- * src/shred.c (direct_mode): Turn it on/off with directio, too.
-
-2004-06-07 Jim Meyering <jim@meyering.net>
-
- Enable direct-mode I/O (bypassing the buffer cache), if possible.
- Prompted by a suggestion from Kalle Olavi Niemitalo
- in http://bugs.debian.org/207035.
- * src/shred.c (direct_mode): New function.
- (do_wipefd): Turn on direct-mode I/O.
- (dopass): If a file's first write fails with EINVAL,
- turn off direct-mode I/O and retry the write.
-
-2004-06-05 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/tr.c (main): "tr -d a b" is now a fatal error even if
- POSIXLY_CORRECT is set. The POSIX SYNOPSIS does not allow this
- option combination.
-
-2004-06-04 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/shred.c (dopass): Don't subtract 1 from the offset after
- a write error. Problem reported by Jon Peatfield in:
- http://lists.gnu.org/archive/html/bug-coreutils/2004-06/msg00020.html
-
-2004-06-02 Paul Eggert <eggert@cs.ucla.edu>
-
- Fix bug reported by Buciuman Adrian in
- <http://mail.gnu.org/archive/html/bug-coreutils/2003-08/msg00105.html>
- where 'dd' created a file that was too large. The bug was that dd
- assumed that the input file offset does not advance after a failed
- read; but POSIX says that the input file offset is undefined after
- a failed read.
-
- * src/dd.c (MAX_BLOCKSIZE): New macro.
- (input_seekable, input_seek_errno, input_offset,
- input_offset_overflow): New vars.
- (scanargs): Reject block sizes greater than MAX_BLOCKSIZE.
- (advance_input_offset): New function.
- (skip_via_lseek): Set errno to zero when reporting our failure,
- so that we don't report based on garbage errno.
- (skip): If fdesc is standard input, advance the input offset.
- Do not quit if reading, and if noerror was specified;
- POSIX seems to require this.
- If read fails on output file, report the earlier lseek failure
- instead; this fixes a FIXME in dd_copy.
- (advance_input_after_read_error): New function.
- (dd_copy): Use it, instead of assuming that failed reads
- do not advance the file pointer. Advance input offset
- after nonfailed reads. Advance only a partial block if
- the previous read (before the failed read) succeeded, and
- do not generate an output block of zeros in this case.
- (main): Determine initial input offset, seekability of input,
- and error if it wasn't seekable.
-
-2004-06-02 Jim Meyering <jim@meyering.net>
-
- rm (without -f) could hang unnecessarily when attempting to
- remove a symlink to a file on an off-line NFS-mounted partition.
- Reported by David Howells in https://bugzilla.redhat.com/124699.
- * src/remove.c (write_protected_non_symlink): New function.
- Don't invoke euidaccess on symlinks.
- (prompt): Use write_protected_non_symlink rather than using
- euidaccess directly, being careful not to call lstat twice for a file.
-
- Fix a bug in how the --output-delimiter=D option works with
- abutting byte or character ranges. Reported by David Krider in
- http://lists.gnu.org/archive/html/bug-coreutils/2004-05/msg00132.html
- * src/cut.c (print_kth): Remove special case for open-ended range.
- (set_fields): Record the range start index for an interval even
- when it abuts another interval on its low side.
- Also record the range start index of the longest right-open-interval.
- * tests/cut/Test.pm: Add tests of --output-delimiter=S with
- abutting and overlapping byte ranges.
-
-2004-06-01 Paul Eggert <eggert@cs.ucla.edu>
-
- Some POSIX-conformance cleanups for tr.
-
- * src/tr.c (posix_pedantic): Remove; no longer needed since
- we need to test this in just one place now.
- (usage): Mention -C.
- (unquote): Note that \055, \n, etc are escaped.
- Do not worry about POSIXLY_CORRECT when warning about ambiguous
- escape sequences.
- \ at end of string stands for itself.
- Do not diagnose invalid backslash escapes: POSIX says the behavior
- is unspecified in this case, so we don't need to diagnose it.
- (main): Add support for -C (currently an alias for -c).
- Do not diagnose 'tr [:upper:] [:upper:], as POSIX does not require
- a diagnostic here.
- * tests/tr/Test.pm: New tests bs-055, bs-at-end, repeat-Compl.
- Fix comment for range-a-a.
-
-2004-05-25 Paul Eggert <eggert@cs.ucla.edu>
-
- Improve the efficiency (and in one case, correctness) of code
- that reads symlinks.
-
- * src/copy.c (copy_internal): Don't use alloca, as it can mess up
- royally if the link length is long (e.g., GNU/Hurd). Use
- xreadlink instead, it's safer. Don't bother to read the link if
- it's the wrong size. Add a FIXME because this area is a bit murky
- and undocumented.
- * src/ls.c (get_link_name): Update use of xreadlink.
- * src/readlink.c (main): Likewise.
- * src/stat.c (print_stat): Likewise.
-
-2004-06-01 Jim Meyering <jim@meyering.net>
-
- * src/env.c (main): Prefer the notation `STREQ (a, b)'
- over `!strcmp (a, b)'.
- * src/sort.c (main, sort_buffer_size): Prefer the notation
- `STREQ (a, b)' over `strcmp (a, b) == 0'.
- * src/date.c (batch_convert): Likewise.
- * src/expr.c (nextarg): Likewise.
- * src/su.c (correct_password, restricted_shell, main): Likewise.
- * src/ptx.c (swallow_file_in_memory, main): Likewise.
- * src/test.c (binary_operator, and, or, main): Likewise.
-
-2004-05-13 Paul Eggert <eggert@cs.ucla.edu>
-
- * NEWS: echo compatibility cleanup.
- * doc/coreutils.texi (echo invocation): Document the changes.
- * src/echo.c (V9_ECHO): Remove; always enabled.
- (DEFAULT_ECHO_TO_XPG): Renamed from V9_DEFAULT, so that
- we use the same naming convention as bash. Now an enum,
- not a macro.
- (usage): Reword to mention -e/-E more accurately.
- Mention \0NNN (the POSIX syntax) rather than \NNN (nonstandard).
- (hextobin): New function.
- (main): Use bool rather than int for local vars when appropriate.
- Do not allow options if POSIXLY_CORRECT, unless we are using
- BSD semantics and the first argument is "-n".
- Don't pass unnecessary extra arg to parse_long_options.
- do_v9 now defaults to DEFAULT_ECHO_TO_XPG, not to allow_options.
- Do not look for options if !allow_options.
- Use size_t rather than int when appropriate.
- Open-code option test rather than using strrchr.
- Use faster test for "-".
- Avoid redundant argc test.
- Add support for \x, for Bash compatibility.
- Use e.g. '\a' rather than '\007', for portability to EBCDIC hosts.
- When '\c' is encountered, stop printing immediately, as POSIX
- requires.
- Add support for \xhh syntax.
- Add support for \0ooo syntax; POSIX requires this.
-
-2004-06-01 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.8b. Regenerate dependent files.
-
-2004-05-31 Jim Meyering <jim@meyering.net>
-
- * tests/Makefile.am.in (TESTS_ENVIRONMENT): Define PATH to include
- the build src/ directory -- at the front.
- ($(srcdir)/$x-tests): Depend on Makefile.am.
- Use $x as the program name, except when it would be `test' (test is
- the sole program tested via mk-script that is also a shell built-in).
- In that case, use the old ../../src/$x.
-
-2004-05-30 Jim Meyering <jim@meyering.net>
-
- Work around HPUX /bin/cc compiler bug that is exposed, now that
- sets are arrays of type `bool'. More details here:
- http://lists.gnu.org/archive/html/bug-gnulib/2004-05/msg00094.html
- FIXME: verify that the above URL points to the right message
-
- * src/tr.c (card_of_complement): Use cleaner `sizeof in_set'
- rather than `N_CHARS * sizeof(in_set[0])'. Using HPUX's /bin/cc
- (aC++/ANSI C B3910B A.05.55 [Dec 04 2003]) on an ia64-hp-hpux11.22
- system, those two expressions are not the same (256 vs. 1024).
- The effect of this problem was that `tr -c x y' would fail:
- tr: when not truncating set1, string2 must be non-empty
- (set_initialize): Remove unnecessary initialization of the `in_set'
- buffer; that initialization triggered the same compiler bug as above.
-
-2004-05-29 Paul Eggert <eggert@cs.ucla.edu>
-
- tr cleanup, mostly having to do with integer type ranges.
- Remove all casts.
-
- * tests/tr/Test.pm: Add a few tests for the below. Alas, most of
- the test cases wouldn't be portable, or would take too much CPU
- time, or both.
-
- * src/tr.c (N_CHARS, N_CHAR_CLASSES): Now an enum, not a macro.
- This is safe since the code already assumes N_CHARS fits in int.
- (Filter): Remove: we want to prototype everything.
- (ORD, CHR): Remove. All uses removed. Some replaced with:
- (uchar): New function. All places where a char must be converted
- to an unsigned char are now done this way, not by ad-hoc methods.
- (count): New type. Use it whenever counts or states are needed.
- (BEGIN_STATE): Increase from INT_MAX - 1 (which was bogus, anyway,
- since we used it in an unsigned int context) to UINTMAX_MAX - 1.
- (REPEAT_COUNT_MAXIMUM): New macro. Use it in place of BEGIN_STATE
- whenever appropriate.
- (NOT_A_CHAR): Remove global macro; now a local enum.
- (UL_LOWER, UL_UPPER, UL_NONE): No longer specify values, since
- the rest of the code no longer depends on them.
- (class_ok): Remove; all uses changed to use inline comparisons.
- (RE_NO_TYPE): Remove; wasn't used or needed.
- (struct List_element): normal_char and equiv_code are now unsigned
- char, not int.
- first_char, last_char, and the_repeated_char are now unsigned char,
- not unsigned int. repeat_count is now count, not size_t.
- All uses changed.
- (struct Spec_list): state is now count, not unsigned int.
- lengthis now count, not size_t.
- n_indefinite_repeats is now size_t, not int.
- has_equiv_class, has_char_class, and has_restricted_char_class
- are now bool, not int. All uses changed.
- (struct E_string): s is now char *, not unsigned char *.
- escaped is now bool *, not int *. All uses changed.
- (ES_MATCH): Remove macro, replacing with:
- (es_match): New inline function. All uses changed.
- (squeeze_repeats, complement, posix_pedantic, truncate_set1,
- translating): Now bool, not int.
- (io_buf): Now char array, not unsigned char.
- (SET_TYPE): Remove. All uses replaced with bool.
- (is_equiv_class_member, unquote, append_range, append_char_class,
- append_equiv_class, find_closing_delim, star_digits_closebracket,
- build_spec_list, parse_str, homogeneous_spec_list):
- Now returns bool, not int. All uses changed.
- (is_equiv_class_member): Now inline.
- (is_equiv_class_member, is_char_class_member, make_printable_str,
- append_normal_char, append_range, append_repeated_char,
- get_s2_spec_stats):
- Args are now of proper integer type.
- (unquote, look_up_char_class, make_printable_str,
- append_equiv_class, build_spec_list, squeeze_filter):
- Avoid unsigned char *p; gently convert *p to unsigned char instead.
- (unquote, get_spec_stats): Do not jump past declarations and then
- use them; C doesn't allow this in portable programs.
- (make_printable_str): Check for overflow in size calculations.
- (xmemdup): Remove. All uses rewritten.
- (find_bracketed_repeat): Args are now of proper pointer-to-integer
- type. Do not reject [c*0]. Use xstrtoumax, not xstrtoul.
- (find_bracketed_repeat, star_digits_closebracket): Check that the
- digits are not escaped.
- (build_spec_list): Don't bother to copy opnd_str; not needed.
- (build_spec_list, get_next): Simplify internal logic a bit.
- (card_of_complement): Fix bug due to char overflow.
- (get_spec_stats): Don't assume len fits into int.
- Check for integer overflow. Use abort() rather than assert(0).
- (string2_extend): Fix subscript error: is_char_class_member (..., 255)
- was being invoked.
- (squeeze_filter): READER is never null now; simplify code.
- READER arg now has a simpler type. Remove unnecessary casts.
- (squeeze_filter, main): Calls to fwrite improperly checked result
- against zero, rather than against requested size.
- (plain_read): New function.
- (read_and_delete, read_and_xlate):
- Remove unused filter arg, and don't worry about hit_eof.
- Simplify by using plain_read.
- (set_initialize): Args are bool and bool *, not int and SET_TYPE *.
- (main): Always pass a non-null procedure to squeeze_filter.
- Rewrite so that class_ok isn't needed.
-
-2004-05-29 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/shred.c (dosync): Ignore EBADF errors, as IRIX 6.5
- fdatasync reports EBADF when syncing (unwritable) directories.
- Problem reported by Albert Chin-A-Young in:
- http://lists.gnu.org/archive/html/bug-coreutils/2004-05/msg00165.html
-
-2004-05-29 Jim Meyering <jim@meyering.net>
-
- * tests/chown/deref: Fix typo: use ls -ldo, not ls -ldg.
- Patch from Albert Chin.
-
- * src/ptx.c (text_buffer_maxend): Remove declaration of unused variable.
-
- * src/remove.c (push_dir): Merge declaration and adjacent assignment
- into a single statement.
-
-2004-05-28 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (AD_mark_helper): Eliminate an unnecessary comparison.
-
-2004-05-22 Jim Meyering <jim@meyering.net>
-
- rm -r would get a failed assertion when run from an inaccessible
- directory and with two or more command line arguments including an
- absolute-named directory followed by a relative-named directory.
-
- * src/remove.h (struct rm_options) [require_restore_cwd]: New member.
- * src/remove.c (struct cwd_state): Define.
- (AD_pop_and_chdir): Redesign interface so that a restore_cwd failure
- can be detected by the caller. Instead of returning a malloc'd
- directory name, communicate it to caller via a new parameter, and
- return an indication of whether restore_cwd failed. Update caller.
- Eliminate an unnecessary call to AC_stack_top.
- (remove_dir): Change type of cwd_state parameter to `struct cwd_state'
- so we can now communicate to caller whether/how functions like
- restore_cwd have failed. Update caller.
- (rm_1): Fail if we've failed to restore the working directory
- and the name of the next file to remove is `.'-relative.
- (rm): Fail if the require_restore_cwd flag is true and we've
- failed to restore the working directory.
- * src/mv.c (rm_option_init): Initialize new member,
- x->require_restore_cwd.
- * src/rm.c (rm_option_init): Likewise.
-
-2004-05-21 Jim Meyering <jim@meyering.net>
-
- * tests/rm/inaccessible: New test for the above fix.
- * tests/rm/Makefile.am (TESTS): Add inaccessible.
-
- * src/remove.c (rm): Use free rather than XFREE.
- (remove_dir): Use xmalloc, not XMALLOC.
- (ds_init): Likewise.
-
-2004-05-20 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_unmarked_diagnostics): Now that the unmarked
- diagnostics in shred.c have been fixed, don't exempt shred.c from
- this check.
-
- * src/shred.c: Use translatable diagnostics, e.g.
- change "%s: remove" to _("%s: failed to remove") and
- change "%s: close" to _("%s: failed to close").
-
-2004-05-17 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/shred.c (names): Bring back lower-case letters, "_", and
- ".". But continue to omit +, =, %, @, #, as they're either
- shell metacharacters (for some shells) or are not in some
- character sets, or (in the case of '%') must be a
- metacharacter somewhere.
-
-2004-05-16 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/cut.c (cut_fields): Adjust to new signature of getndelim2.
-
-2004-05-17 Jim Meyering <jim@meyering.net>
-
- * src/shred.c (incname): Decrement `len' only once per loop iteration.
-
- chgrp and chown now dereference symlinks by default, per POSIX.
- Reported by Michal Politowski as http://bugs.debian.org/249177.
-
- * src/chown-core.c (chopt_init): Affect each symlink referent by default.
- * src/chown.c (usage): Update to reflect this.
- * src/chgrp.c (usage): Likewise.
- * NEWS: Describe the change.
- Adapt tests accordingly.
- * tests/chgrp/basic: Use -h where necessary to retain semantics.
- * tests/chgrp/deref: Likewise.
- * tests/chgrp/posix-H: Likewise.
-
-2004-05-15 Paul Eggert <eggert@cs.ucla.edu>
-
- In shred, check for errors from fdatasync more carefully. If
- fdatasync fails with errno==EINVAL, it means this implementation
- does not support synchronized I/O for this file. Do not report
- this as an error, as (for example) AIX 5.2 fdatasync reports it
- for raw disk devices. Problem reported by Albert Chin in
- <http://mail.gnu.org/archive/html/bug-gnu-utils/2004-05/msg00028.html>.
-
- Check for write errors, though: the old code ignored them.
- Improve error checking in a few other cases, too (e.g., close of a
- directory).
-
- Also, change several 'int' values to 'bool', so that the error
- checking is a bit clearer. Similarly, change unsigned values
- to size_t where appropriate.
-
- * src/shred.c: Include "dirname.h".
- (datasync) [!HAVE_FDATASYNC]: Remove.
- (dosync): New function.
- (dopass): Use it. Return 1 on write error, -1 on other error.
- All callers changed. Report write error if dosync does.
- (do_wipefd, wipefd, wipename, wipefile): Return bool (true/false),
- not int (0/-1). All callers changed. Return false if there's a
- write error.
- (incname): Return bool (true/false), not int (0/1). Accept
- size_t length, not unsigned. All callers changed. Do not
- bother checking for non-digits; it can't happen. Replace
- recursion with iteration.
- (wipename): Use dir_name, base_name, etc. instead of assuming
- Unix file names. Use size_t for length, not unsigned.
- Report error if unlink or close fails.
- (wipename, main): Use bool for booleans.
-
- (names): Use only digits and uppercase letters, for greater
- portability.
-
-2004-05-16 Jim Meyering <jim@meyering.net>
-
- * tests/chown/deref: New test for the yesterday's change.
- * tests/chown/Makefile.am (TESTS): Add deref.
-
-2004-05-15 Jim Meyering <jim@meyering.net>
-
- chown --dereference did nothing when the owner/group of a
- symlink matched the desired owner/group. Reported by David Malone.
- Also reported in 1999 as http://bugs.debian.org/39642.
-
- * src/chown-core.c (change_file_owner): When --dereference has
- been specified, and when processing a symlink, stat it to get the
- owner and group of the referent.
-
-2004-05-14 Jim Meyering <jim@meyering.net>
-
- * man/pwd.x, man/echo.x, man/printf.x: Fix typo:
- s/supercede/supersede/ reported by Andrew Fabbro.
-
-2004-05-13 Paul Eggert <eggert@cs.ucla.edu>
-
- Improve performance of `sort -m' on large files, at the cost of
- making some contrived examples unsafe. POSIX allows this
- optimization. Performance problem reported by Jonathan Baker in
- <http://mail.gnu.org/archive/html/bug-coreutils/2004-05/msg00071.html>.
-
- * src/sort.c (first_same_file): Do not treat input pipes
- differently from other files.
- * doc/coreutils.texi (sort invocation): Document that "sort -m -o F"
- might write F before reading all the input.
- * NEWS: Likewise.
-
-2004-05-12 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/od.c (print_ascii, dump_strings): Use e.g. '\a' rather than
- '\007', for portability to EBCDIC hosts.
- * src/printf.c (print_esc_char): Likewise.
- * src/tr.c (unquote, make_printable_str): Likewise.
-
-2004-05-12 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (AD_pop_and_chdir): Move lstat-`.' into if-block
- where the result is used. This avoids one unnecessary lstat call
- per command line argument.
-
-2004-05-12 Paul Eggert <eggert@cs.ucla.edu>
-
- Don't assume that "make -C" works; Solaris "make" doesn't have -C.
-
- * src/Makefile.am (all_programs.list): New rule, copied from
- man/Makefile.am and tests/Makefile.am, except that we use the
- system tr rather than ./tr and we don't use tr -s.
- * tests/Makefile.am (all_programs): Use it.
- * man/Makefile.am (all_programs): Likewise. Renamed from programs,
- for consistency. All uses changed.
-
-2004-05-11 Jim Meyering <jim@meyering.net>
-
- * tests/rm/unread3: New test, for the above fix and today's
- lib/save-cwd.c improvement.
- * tests/rm/Makefile.am (TESTS): Add unread3.
-
- * src/rm.c: Don't include "save-cwd.h". It's no longer used.
-
-2004-05-10 Jim Meyering <jim@meyering.net>
-
- * tests/install/trap: New file. Test for bug fix of 2004-04-18.
- * tests/install/Makefile.am (TESTS): Add trap.
-
- * src/remove.c (AD_push): Don't use errno in diagnostic about
- `changed dev/ino'.
-
- Remove these generated files from CVS.
- * tests/cut/cut-tests, tests/date/date-tests, tests/join/join-tests:
- * tests/ls/ls-tests, tests/pr/pr-tests, tests/tac/tac-tests:
- * tests/tail/tail-tests, tests/test/test-tests, tests/tr/range-tests:
- * tests/tr/tr-tests, tests/wc/wc-tests:
-
-2004-05-09 Jim Meyering <jim@meyering.net>
-
- * src/tr.c (unquote): Use xcalloc rather than xmalloc and
- a loop initializing the just-allocated memory to zero.
-
-2004-05-08 Jim Meyering <jim@meyering.net>
-
- * tests/rm/no-give-up: New file; check for today's fix.
- * tests/rm/Makefile.am (TESTS): Add no-give-up.
-
-2004-05-08 Paul Eggert <eggert@cs.ucla.edu>
-
- Fix bug where "rm" gave up too easily, reported by Dan Jacobsen in
- <http://mail.gnu.org/archive/html/bug-coreutils/2004-05/msg00013.html>.
-
- * src/remove.c (remove_entry): Check for errno values like ENOENT
- that show the file cannot be directory, instead of for errno
- values like EPERM that show the file might be a directory. This
- is necessary because, when a single unlink() call has multiple
- reasons to fail, it can set errno to any of those reasons; it's
- only the rare errno value like ENOENT that excludes all the other
- possible reasons to fail even when the file is a directory.
- (remove_cwd_entries): Don't attempt chdir if the file is known
- to not be a directory.
- (remove_dir): Use the same method that remove_cwd_entries uses
- (for some reason they differed). Don't assert that saved_errno
- must be EPERM; it might be just about anything.
-
-2004-05-06 Jim Meyering <jim@meyering.net>
-
- * src/id.c (xgetgroups): Use xnmalloc, rather than xmalloc.
- Don't add `1' to the buffer size (it was to protect against malloc
- implementations that fail to allocate a buffer of size zero).
- That is no longer necessary, since we use a malloc wrapper
- on such systems.
-
- * src/wc.c (get_input_fstatus): Use xnmalloc, rather than xmalloc.
- * src/head.c (elide_tail_bytes_pipe): Likewise.
- * src/df.c (main): Likewise.
- * src/shred.c (do_wipefd): Likewise.
- * src/users.c (list_entries_users): Likewise.
- * src/tail.c (main): Likewise.
- * src/md5sum.c (main): Likewise.
-
-2004-04-29 Paul Eggert <eggert@cs.ucla.edu>
-
- * src/df.c (show_disk, show_point): If several filesystems are
- mounted on the same mount point, prefer the last one, not the first.
- Problem reported by Christian Jones in
- <http://mail.gnu.org/archive/html/bug-coreutils/2004-04/msg00200.html>.
- (show_disk): Remove unused statp arg. Return bool, not int.
- (show_point): Rewrite to avoid gotos. Use the same algorithm
- for lofs and dummies for each pass through the mount table,
- rather than subtly different algorithms (which are probably
- inadvertent).
-
-2004-05-03 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (EXTRA_DIST): Add m4/ChangeLog, now that we no longer
- have m4/Makefile*.
-
-2004-05-01 Jim Meyering <jim@meyering.net>
-
- When chown or chgrp is modifying the referent of a symlink,
- use the chown(2) function, if possible.
- * src/chown-core.c (change_file_owner): Don't hard-code the
- open/fchown/close kludge here. Use `chown' instead.
- The chown function works just fine on conforming systems.
- Other systems now go through the new chown wrapper that
- resorts to the old kludge.
-
- * src/chown-core.c (change_file_owner): Add a comment.
-
-2004-04-27 Jim Meyering <jim@meyering.net>
-
- * src/ptx.c: Make over 40 global extern variables `static'.
- (syntax_table, re_syntax_table): Remove declarations of two unused
- variables (they were exposed by the above change).
-
- * src/du.c (G_fail, opt_nul_terminate_output): Declare `static'.
- * src/ln.c (backup_type): Likewise.
-
- * src/remove.c (rm): Add `extern' keyword.
- * src/cp-hash.c (forget_created, remember_created)
- (src_to_dest_lookup, remember_copied, hash_init, forget_all): Likewise.
- * src/copy.c (dest_info_init, src_info_init, copy): Likewise.
- * src/chown-core.c (chopt_init, chopt_free, gid_to_name)
- (uid_to_name, chown_files): Likewise.
-
- * src/Makefile.am (sc_tight_scope): New rule.
- * Makefile.maint (sc_tight_scope): New rule.
- (syntax-check-rules): Add it.
-
-2004-04-26 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.8.4. Regenerate dependent files.
-
- * src/sort.c (limfield): Make a comment clearer.
-
-2004-04-25 Paul Eggert <eggert@twinsun.com>
-
- Fix POSIX-conformance bug: "sort -k 3,3.5b" is supposed to skip
- leading blanks when computing the location of the field end;
- it is not supposed to skip trailing blanks. Solaris 8 "sort"
- does conform to POSIX. Also fix the documentation to clarify
- this and related issues.
-
- * doc/coreutils.texi (sort invocation): Mention -k earlier, so
- that the options are in alphabetical order. Describe how -b works
- more-accurately; this involves fixing some examples, too. Mention
- what happens if the start field falls after an end field or after
- a line end. Warn about using -k without -b, -g, -M, -n, or -t.
- Add an example of how to sort IPv4 addresses and Apache Common
- Log Format dates. Remove a duplicate example.
- (Putting the tools together): Use separate options rather
- than agglomerating them.
- * src/sort.c (limfield): Use skipeblanks, not skipsblanks, to
- decode whether to skip leading blanks.
- (trailing_blanks): Remove.
- (fillbuf, getmonth, keycompare): Don't trim trailing blanks.
-
- * tests/pr/Test.pm: Fix typo in env_default comment.
- * tests/sort/Test.pm: Likewise.
- (18c, 18d): Reverse the order of output lines, so that the
- test cases conform to POSIX.
-
-2004-04-22 Paul Eggert <eggert@twinsun.com>
-
- More signal-handling cleanup for ls.c. Do not allow signals to
- happen between arbitrary output bytes, as the
- restore-default-color sequence can bollix up multibyte chars or
- color-change sequences in the ordinary output. Instead, process
- signals only between printing a file name and changing the color
- back to non_filename_text color. That way, if the signal handler
- changes the color (to the default), 'ls' will change it back when
- 'ls' continues (after being suspended).
-
- Also, do not bother with signal-handling unless stdout is a
- controlling terminal; this lets stdio buffer better when "ls
- --color" is piped or sent to a file.
-
- * src/ls.c (sigprocmask, sigset_t) [!defined SA_NOCLDSTOP]: New macros.
- Do not include "full-write.h"; no longer needed.
- (tcgetpgrp) [! HAVE_TCGETPGRP]: New macro.
- (put_indicator_direct): Remove. All callers changed to use
- put_indicator.
- (caught_signals, interrupt_signal, stop_signal_count): New vars.
- (restore_default_color): Don't bother checking for put_indicator
- failure.
- (sighandler): Don't handle SIGTSTP; that's another handler now.
- Simply set interrupt_signal to the signal, then exit.
- (stophandler, process_signals): New functions.
- (main): Don't output any color changes until _after_ the signal
- handlers are set up. This fixes a race condition where 'ls'
- could be interrupted while initializing colors, and leaving the
- terminal in an undesirable state.
- Don't mess with signal-handling if standard output is not a
- controlling terminal.
- When exiting, restore the default color, then restore the
- default signal handling, then act on any signals that weren't
- acted on yet.
- Do not print //DIRED// etc. in colors; this avoids the need
- to catch signals when printing them.
- (print_name_with_quoting): Process signals just before switching
- color back to non_filename_text.
-
-2004-04-23 Jim Meyering <jim@meyering.net>
-
- Avoid segfault on systems for which SIZE_MAX != (size_t) -1.
- * src/ls.c (quote_name): Use SIZE_MAX, not -1, in calls
- of quotearg_buffer. Patch by Mikulas Patocka.
-
-2004-04-18 Paul Eggert <eggert@twinsun.com>
-
- tee ignored SIGPIPE, but POSIX doesn't allow this.
-
- * src/tee.c (main): Do not ignore SIGPIPE, as POSIX 1003.1-2001
- does not allow this. This undoes the 1996-10-24 patch.
-
-2004-04-18 Paul Eggert <eggert@twinsun.com>
-
- Signal-handling cleanup for coreutils. Here are the highlights:
-
- - csplit sometimes failed to remove files when interrupted.
- - csplit didn't clean up if two signals arrived nearly simultaneously.
- - install -s would infloop on System V if SIGCHLD was ignored.
- - ls could incorrectly restore color if multiple signals
- arrived nearly simultaneously.
-
- * src/csplit.c (sigprocmask, sigset_t) [!defined SA_NOCLDSTOP]:
- Define.
- (filename_space, prefix, suffix, digits, files_created, remove_files):
- Now volatile.
- (caught_signals): New var.
- (cleanup): Block signals while deleting all files.
- (cleanup_fatal, handle_line_error, regexp_error):
- Mark with ATTRIBUTE_NORETURN.
- (create_output_file, close_output_file, interrupt_handler):
- Block signals while changing the number of output files,
- to fix some race conditions.
- (delete_all_files): Do nothing if remove_files is zero.
- Clear files_created.
- (main): Don't mess with signals until after argument processing
- is done.
-
- * src/csplit.c (main): Rewrite signal-catching code to make it
- similar to other coreutils programs. When processing signals,
- block all signals that we catch, but do not block signals that we
- don't catch. Avoid problems with unsigned int warnings.
- * src/ls.c (main): Likewise.
- * src/sort.c (main): Likewise.
-
- * src/csplit.c (interrupt_handler):
- Use void, not (obsolete) RETSIGTYPE.
- * src/shred.c (sigill_handler, isaac_seed_machdep): Likewise.
-
- * src/csplit.c (interrupt_handler) [defined SA_NOCLDSTOP]:
- Use simpler "signal (sig, SIG_DFL)" rather than sigaction equivalent.
- * src/ls.c (sighandler) [defined SA_NOCLDSTOP]: Likewise.
- * src/sort.c (sighandler) [defined SA_NOCLDSTOP]: Likewise.
- * src/nohup.c (main) [!defined _POSIX_SOURCE]: Likewise, except
- for SIG_IGN.
- * src/tee.c (main) [!defined _POSIX_SOURCE]: Likewise.
-
- * src/install.c: Include <signal.h>.
- (main) [defined SIGCHLD]: Set SIGCHLD handler to the default, if -s is
- given, since System V fork+wait does not work if SIGCHLD is ignored.
-
- * src/ls.c (sighandler) [!defined SA_NOCLDSTOP]: Reset signal
- handler to self, not to SIG_IGN, since SIGTSTP can be received
- more than once.
- (main): Use SA_RESTART, as that is simpler than checking for EINTR
- failures all over the place.
-
-2004-04-20 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (is_empty_dir): Clarify comment.
-
- * man/help2man: Accept new option: --program-name=NAME, so that we
- can override the one in --version output. This is needed solely
- so that test.1 doesn't refer to `[' as the program name.
- Reported by Benjamin Cutler as http://bugs.debian.org/205251.
- * man/Makefile.am (.x.1): Use help2man's new --program-name option.
-
- * src/pwd.c: Don't include pathmax.h; system.h already does it.
-
- * src/cut.c (cut_fields): Free buffer upon getndelim2 failure.
-
-2004-04-19 Jim Meyering <jim@meyering.net>
-
- * src/shred.c (isaac_seed_start) [AVOID_USED_UNINITIALIZED_WARNINGS]:
- Initialize a buffer to avoid warnings from tools like valgrind.
-
- * Makefile.maint (sc_trailing_blank): New rule.
- (syntax-check-rules): Add it.
- * .x-sc_trailing_blank: New file.
-
- Make pwd work even if the resulting name is so long that getcwd fails.
- * src/pwd.c: (path_free, path_init, path_prepend): New functions.
- (nth_parent, find_dir_entry, robust_getcwd): New functions.
- (main): First try getcwd, then, upon failure, robust_getcwd.
-
-2004-04-18 Jim Meyering <jim@meyering.net>
-
- * src/who.c (print_user): Use xrealloc here, rather than
- unchecked realloc. Remove anachronistic casts.
-
- * src/remove.c (full_filename_): Don't leak upon failed realloc.
-
- * src/system.h (readdir_ignoring_dot_and_dotdot): New inline function,
- from remove.c.
- * src/remove.c (readdir_ignoring_dotdirs): Move function to system.h,
- renaming it. Update uses.
-
-2004-04-17 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Depend on automake-1.8.3.
-
- * src/join.c (add_file_name): Declare function to be `static'.
- (string_to_join_field): Likewise.
- * src/remove.c (ds_init, ds_free): Likewise.
-
- * Makefile.maint (sc_prohibit_jm_in_m4): New rule.
- (syntax-check-rules): Add to the list.
-
-2004-04-13 Paul Eggert <eggert@twinsun.com>
-
- Use page-aligned buffers whenever we bother to do I/O using buffer
- sizes that are tailored for the files.
-
- * src/cat.c: Include getpagesize.h.
- * src/copy.c: Likewise.
- * src/shred.c: Likewise.
- * src/split.c: Likewise.
- * src/cat.c (main): Align I/O buffers to page boundaries.
- * src/copy.c (copy_reg): Likewise.
- * src/shred.c (dopass): Likewise.
- * src/split.c (main): Likewise.
- * src/dd.c (ROUND_UP_OFFSET, PTR_ALIGN): Remove.
- All uses replaced by ptr_align.
- * src/od.c (gcd, lcm): Remove; now in system.h.
- * src/system.h (gcd, lcm, ptr_align): New functions, moved from od.c.
-
-2004-04-14 Jim Meyering <jim@meyering.net>
-
- Remove m4/Makefile.am: it's no longer needed, with newer automake
- * configure.ac (AC_CONFIG_FILES): Remove m4/Makefile.in from the list.
- * Makefile.am (SUBDIRS): Remove `m4' from the list.
-
-2004-04-13 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Change `jm_' in AC_DEFINE'd names to `gl_'.
-
-2004-03-27 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: cp -pu and mv -u (when copying) now take the destination
- file system time stamp resolution into account.
- * doc/coreutils.texi (mv invocation): Document this.
- (cp invocation): Document -u (it was missing!) with new behavior.
-
- * src/copy.c: Include "utimecmp.h".
- (copy_internal): Compare time stamps using utimecmp rather than
- MTIME_CMP.
-
-2004-04-09 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (.re-list): New rule/file, to replace
- hard-coded list of header file names.
- (sc_system_h_headers): Use the new file.
- Don't look for sys2.h anymore.
-
- * src/system.h: Include new "stat-macros.h" rather than hard-coding
- all of its macro definitions -- the list was slightly out of date.
- Suggestion from Dmitry V. Levin.
-
-2004-04-08 Paul Eggert <eggert@cs.ucla.edu>
-
- * NEWS: Remove noctty flag from dd. Suggested by Philippe Troin.
- * doc/coreutils.texi (dd invocation): Likewise.
- * src/shred.c (O_NOCTTY): Remove redundant decl.
- * src/dd.c (flags, usage): Remove noctty flag.
- (main): Always use O_NOCTTY when opening files.
-
-2004-04-08 Jim Meyering <jim@meyering.net>
-
- * src/dd.c (dd_copy): Mark two diagnostics for translations.
- (set_fd_flags): Undo part of today's change: it's a little
- cleaner -- and more efficient in the common case -- to go
- ahead and OR in the -1 when fcntl fails.
-
- * Makefile.maint (sc_dd_max_sym_length): New target.
- (syntax-check-rules): Add it.
-
- * src/md5sum.c (PROGRAM_NAME) [algorithm == ALG_SHA1]:
- Correct spelling: s/shasum/sha1sum. Reported by Jesse Kornblum.
-
- * src/dd.c (set_fd_flags): Don't OR in -1 when fcntl fails.
- Rename parameter, flags, to avoid shadowing global.
- (LONGEST_SYMBOL): Tweak comment.
-
-2004-04-07 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: New dd conv= symbols nocreat, excl, fdatasync, fsync,
- and new dd options iflag= and oflag=.
- * src/dd.c (usage): Likewise.
- * src/Makefile.am (dd_LDADD, shred_LDADD): Add fdatasync's lib.
- * src/dd.c (fdatasync) [!HAVE_FDATASYNC]: New macro.
- (C_NOCREAT, C_EXCL, C_FDATASYNC, C_FSYNC): New macros.
- (input_flags, output_flags): New vars.
- (LONGEST_SYMBOL): New macro.
- (struct symbol_value): Renamed from struct conversion. Members
- symbol and value renamed from convname and conversion. The
- symbol value is now an array instead of a pointer; this saves
- a bit of space and time in practice. All uses changed.
- (conversions): Add nocreat, excl, fdatasync, fsync. Now const.
- (flags): New constant array.
- (iflag_error_msgid, oflag_error_msgid): New constants.
- (parse_symbols): Renamed from parse_conversion and generalized
- to handle either conversion or flag symbols.
- (scanargs): Adjust uses of parse_symbols accodingly. Add
- support for iflag= and oflag=. Reject attempts to use
- both excl and nocreat.
- (set_fd_flags): New function.
- (dd_copy): Just return X rather than calling quit (X), since our
- caller invokes quit with the returned value. Add support for
- fdatasync and fsync.
- (main): Add support for iflag=, oflag=, and new conv= symbols.
- * src/system.h (O_DIRECT, O_DSYNC, O_NDELAY, O_NOFOLLOW,
- O_RSYNC, O_SYNC): Define to 0 if not already defined.
-
- * NEWS: Remove duplicate mention of BLOCKSIZE.
-
-2004-04-02 Andreas Schwab <schwab@suse.de>
-
- * src/stty.c: Add support for IUTF8 input flag.
-
-2004-04-06 Jim Meyering <jim@meyering.net>
-
- * src/system.h (makedev) [mkdev && !makedev]: Define in terms of mkdev.
- Interix spells it `mkdev'. Reported by Mark Funkenhauser.
-
-2004-04-04 Jim Meyering <jim@meyering.net>
-
- A specified format is no longer automatically newline terminated.
- If you want a newline at the end of your format, use `\n'.
- * src/stat.c (print_it): Don't print a newline at the end of
- every format.
- (do_statfs): Add a newline at end of each default format string.
-
-2004-03-30 Paul Eggert <eggert@twinsun.com>
-
- * src/nohup.c (main): Adjust to new calling convention
- for set_cloexec_flag.
-
-2004-03-31 Jim Meyering <jim@meyering.net>
-
- * tests/Fetish.pm (run_tests): Remove `.orig' file.
- Remove debugging diagnostic.
-
- Specifying an invalid --width=N (-w) or --gap-size=N (-g)
- would not elicit an error.
- * src/ptx.c: Include "xstrtol.h" and "quotearg.h".
- (main): Don't use atoi. Use xstrtoul instead.
-
-2004-03-30 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_prohibit_atoi_atof): New rule.
- (syntax-check-rules): Add it.
- * .x-sc_prohibit_atoi_atof: New file.
-
-2004-03-29 Jim Meyering <jim@meyering.net>
-
- * tests/du/files0-from: Use new OUT_SUBST directive, so that this
- test is not sensitive to system-dependent block size differences.
- Prompted by a report of Solaris 8 differences from Paul Eggert.
-
- * tests/Fetish.pm: Accept new directives: OUT_SUBST, ERR_SUBST.
- Rename `%tmp' to `%actual'. Reverse order of last two args to
- _compare_files (to $actual, $expected) so as to match declaration.
-
-2004-03-28 Paul Eggert <eggert@twinsun.com>
-
- Fix some gotchas encountered when porting to Solaris 8, using
- the Forte 6u2 compiler.
-
- * src/hostname.c [HAVE_SETHOSTNAME && !defined sethostname]:
- Declare sethostname, since no Solaris header does it.
- * src/who.c: Include "vasprintf.h", for asprintf.
-
-2004-03-28 Jim Meyering <jim@meyering.net>
-
- Minor optimization:
- * src/du.c (process_file): Don't record dev/inode for directories.
-
- Under some circumstances, without -c, du would mistakenly count the
- space of hard-linked files, not just the first one it encountered.
- Reported by Anthony Thyssen.
- * src/du.c (du_files): Don't ever clear the set of `seen' dev/inodes.
-
- * src/du.c: Rename global `print_totals' to `print_grand_total'.
-
- * src/du.c (main): Rearrange filtering loop to be a tiny bit
- more efficient.
-
- * src/chown-core.c: Don't include savedir.h -- no longer needed.
- * src/chmod.c: Likewise.
-
-2004-03-25 Jim Meyering <jim@meyering.net>
-
- * src/du.c (main): Remove now-unused declaration of `i'.
-
-2004-03-24 Paul Eggert <eggert@twinsun.com>
-
- * src/du.c (main): Filter out file names of length zero before
- invoking fts, so that they don't cause fatal errors.
-
-2004-03-25 Jim Meyering <jim@meyering.net>
-
- * tests/du/files0-from (zero-len): Add a test for the above.
-
-2004-02-25 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: New environment var BLOCKSIZE.
- * lib/human.c (humblock): Support BLOCKSIZE as well as BLOCK_SIZE.
- * tests/envvar-check: Test for it. Factor the code to simplify it.
-
-2004-03-23 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: Shorten the du --files0-from announcement, and say
- "NUL-terminated" rather than "NUL-separated".
- * src/du.c (EXPECTED_BYTES_PER_FILE_NAME, DEFAULT_PROJECTED_N_FILES):
- Remove: not used.
- (usage): Say "NUL-terminated", not "NUL-separated".
- (main): Check for I/O error when istream is closed.
- Allow --files0-from=F even if F is empty; this specifies no files.
- (du_files): Now that we allow the list of files to be empty,
- handle that case.
- * tests/du/files0-from: Adjust to above changes to src/du.c.
-
-2004-03-24 Jim Meyering <jim@meyering.net>
-
- * tests/tail-2/assert: Avoid race condition that could cause
- spurious failure. Based on a patch from Andreas Schwab.
-
-2004-03-23 Jim Meyering <jim@meyering.net>
-
- * src/du.c (main): Free the hash table, too.
-
-2004-03-22 Jim Meyering <jim@meyering.net>
-
- * man/Makefile.am (.x.1): Remove --info-page= option, reverting
- the change of 2004-01-22. I can no longer reproduce the problem
- that prompted that change, and `info coreutils pr' would display the
- `printing text' section of the manual, not the one on `pr invocation'.
-
- * tests/du/files0-from (nul-1, nul-2): Adjust expected diagnostics
- to match corrected output.
-
- * src/du.c: Include "readtokens0.h" rather than "readtokens.h".
- (main): Use readtoken0 functions rather than readtokens.
- Don't use errno when diagnosing readtokens0 failure.
- Fix off-by-one error in the token number reported in a diagnostic.
- (du_files): Return bool, rather than int.
- (main): Call readtokens0_free.
-
-2004-03-21 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (ds_free): Plug a small leak.
-
- * tests/Fetish.pm: Fix typo in comment.
-
-2004-03-07 Jim Meyering <jim@meyering.net>
-
- * NEWS: du accepts a new option --files0-from=FILE, where FILE
- contains a list of NUL-separated file names.
-
- * src/du.c: Include "readtokens.h".
- (usage): Describe the new option, and adjust the `Usage':
- with this option, no FILE may be specified on the command line.
- (main): Handle the new option.
-
- * tests/du/files0-from: New tests, for the above.
- * tests/du/Makefile.am (TESTS): Add files0-from.
-
- * src/factor.c (do_stdin): Reflect changes in use of readtoken.
- * src/tsort.c (tsort): Likewise.
-
-2004-02-29 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: Add support for a new notation @N to get_date to represent
- the time stamp with numeric value N. Improve support for
- fractional time stamps. date's -d and -f options now accept them.
- Likewise for touch -t. date has a new option --iso-8601=ns.
-
- * doc/coreutils.texi (touch invocation):
- Describe use of fractional seconds.
- (date invocation, Options for date): Likewise.
- * doc/getdate.texi (General date syntax, Time of day items): Likewise.
- * doc/coreutils.texi (date invocation): Mention effect of LC_TIME.
- (Options for date): Describe new --iso-8601=ns option.
-
- * doc/getdate.texi: Add copyright notice. Change getdate to
- get_date when talking about the function name.
- (Seconds since the Epoch): New section, containing the time_t
- info moved from Date input formats section, along with new
- info about the @ syntax. Mention negative time stamps,
- fractional time stamps, and leap seconds.
- (General date syntax): Modernize examples a bit to reflect new
- features.
- (General date syntax, Relative items in date strings):
- Use ' rather than " to quote formats.
- (Time of day items): Add an example with fractional seconds.
- Describe fractional-second syntax.
-
- * src/Makefile.am (touch_LDADD): New macro, since `touch' now
- needs clock_gettime.
-
- * src/date.c (enum Time_spec): New enum TIME_SPEC_NS.
- (time_spec_string, time_spec, show_date): Support it.
- (usage): Remove description of -ITIMESPEC, as it's obsolete and
- confusing. Mention --iso-8601=ns.
- (batch_convert): getline returns ssize_t, not int.
-
- * src/touch.c (newtime): Now an array of two timespecs, one
- for access and one for modification.
- (ref_stats): Remove.
- (get_reldate): Use get_date's parameter profile.
- (touch, main): Adjust to above changes.
- (main): Work even if tm_year == INT_MAX (so long as long int is wider).
- Use gettime instead of gettimeofday, for new get_date signature.
-
- * tests/date/Test.pm (test_vector): New tests epoch, ns-10, ns-max32,
- ns-relative.
-
-2004-03-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (alpha beta major): `Make' the emit_upload_commands
- target before updating $(prev_version_file).
-
- * tests/misc/date-sec: New file, to test for just-fixed bug in date.
- See today's change in lib/getdate.y.
- * tests/misc/Makefile.am (TESTS): Add date-sec.
-
-2004-03-14 Jim Meyering <jim@meyering.net>
-
- * announce-gen (print_changelog_deltas): Use `.sig' suffix for
- signature files, not `.asc'. Reported by angico@yahoo.com.
-
-2004-03-13 Jim Meyering <jim@meyering.net>
-
- * src/cp.c (do_copy): Tweak wording in a diagnostic.
- Suggestion from Karl Berry.
- Include "quoatearg.h".
- (do_copy): Use quotearg_colon (not quote) for diagnostics
- that begin with `"%s:'.
-
- * src/nl.c (usage): Specify that nl uses _basic_ regular expressions.
- Suggestion from Dan Jacobson.
-
-2004-03-12 Jim Meyering <jim@meyering.net>
-
- * Version 5.2.1.
-
- Sometimes, when source and destination partition are different,
- mv mistakenly fails to preserve a hard link. Reported by IIDA Yosiaki.
-
- * src/copy.c: When moving a set of N hard-linked files between
- partitions, via two or more command line arguments where the
- command line argument containing the Nth link contains no other
- link to that same file, mv would mistakenly copy the file, rather
- than hard-linking it to the other(s). That happens because when the
- final link is processed, its link count has been reduced to 1 since
- the other links have been `copied' to the destination partition
- and the source links have been removed.
- (copy_internal): When in move mode, use the source dev/inode
- pair to look up destination name even when st_nlink == 1.
- * src/cp-hash.c (src_to_dest_lookup): New function.
- * src/cp-hash.h (src_to_dest_lookup): Add prototype.
- * tests/mv/part-hardlink: New file. Test for the above fix.
- * tests/mv/Makefile.am (TESTS): Add part-hardlink.
-
- * announce-gen: Sync with autoconf.
-
- * tests/ls/time-1: Exit 77 (not 1) if we can't set up for the test.
- This was triggered on a Linux-2.2.19 system using a file system
- NFS-mounted from some sort of Sun.
-
-2004-03-11 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.8.3. Regenerate dependent files.
-
-2004-03-10 Jim Meyering <jim@meyering.net>
-
- * tests/du/deref-args: Also convert sizes in the 70-79 kB range,
- so that this test works with SELinux-enabled systems.
- Based on a patch from Tim Waugh.
-
- `join -1 x' would give a misleading diagnostic
- * src/join.c (string_to_join_field): Report that a non-numeric field
- number is invalid, rather than `so large that it is not representable'.
- * tests/join/Test.pm (invalid-j): New partial test for the above fix.
-
-2004-03-06 Jim Meyering <jim@meyering.net>
-
- cp --sparse=always sparse-image-file.img /dev/hda1 could
- produce an invalid copy on the destination device.
-
- * src/copy.c (copy_reg): Even with --sparse=always, try to
- make `holes' only if the destination is a regular file.
- Reported by Szakacsits Szabolcs.
-
-2004-03-03 Paul Eggert <eggert@twinsun.com>
-
- * src/nohup.c (main): Don't invoke set_cloexec_flag with
- a file descriptor of -1.
-
-2004-03-02 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/nohup.c: Include "cloexec.h".
- (main): Set the copy of stderr to close on exec.
-
-2004-03-01 Paul Eggert <eggert@twinsun.com>
-
- * configure.ac: Include <signal.h> when checking for strsignal,
- sys_siglist, and friends. Problem reported by Tony Leneis in
- <http://mail.gnu.org/archive/html/bug-coreutils/2004-02/msg00136.html>.
-
-2004-02-25 Paul Eggert <eggert@twinsun.com>
-
- * tests/du/deref-args, tests/du/exclude, tests/du/slash:
- * tests/du/trailing-slash: Run envvar-check in case BLOCK_SIZE
- etc. are set.
-
-2004-02-23 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: Document how chown's USER.GROUP argument is now parsed.
-
-2004-02-23 Jim Meyering <jim@meyering.net>
-
- * src/seq.c (usage): Remove stray space after \n in --help output.
-
-2004-02-22 Jim Meyering <jim@meyering.net>
-
- * src/du.c (usage): Separate -H and --si. Say that the meaning
- of -H will soon change to that of --dereference-args (-D).
-
-2004-02-21 Jim Meyering <jim@meyering.net>
-
- * src/comm.c (usage): Tell what comm does when there are no options.
- Reword in terms of FILE1 and FILE2 rather than `left file' and
- `right file'. Suggestion from Dan Jacobson.
-
-2004-02-15 Paul Eggert <eggert@twinsun.com>
-
- Fix some POSIX-conformance bugs in expr.
-
- * NEWS: document the following changes to src/expr.c.
- * doc/coreutils.texi (expr invocation): Likewise.
- Document what forms integers may take, and say "integer"
- consistently instead of "number". Warn about operands
- that "expr" can misinterpret, and how to work around the
- problem.
- * src/expr.c (eval, eval7, eval6, eval5, eval4, eval3, eval2, eval1):
- Accept a bool argument specifying whether to evaluate the
- expression. This is to allow short-circuit evaluation. All
- callers changed.
- (null): Report that a string is zero even if it has
- a form like "-0" or "00".
- (eval1, eval): Use short-circuit evaluation for | and &.
- (eval): Return 0 if both arguments are null or zero, instead
- of returning the first argument.
- * tests/expr/basic: Add some tests for the above.
-
-2004-02-17 Jim Meyering <jim@meyering.net>
-
- * Version 5.2.0.
-
- `make check' from a build inside a chroot environment would fail
- * tests/help-version: Specify an argument (`/') for df, in the
- unusual event that there is no valid entry in /etc/mtab.
- Likewise for id: add the -u option, so we don't get spurious
- failures when there are no user or group names.
- Patch by Tim Waugh.
-
- * src/sort.c (usage) [-u]: Add punctuation so that the description in
- the help2man-generated (line-joined) man page is more readable.
- Reported by Tim Waugh.
- [-T]: Add a semicolon, for the same reason.
-
-2004-02-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (dist-hook): Qualify target with $(srcdir)/ prefix.
-
-2004-02-11 Jim Meyering <jim@meyering.net>
-
- * tests/Makefile.am.in ($(srcdir)/Makefile.am): Use more portable
- $(srcdir)/../Makefile.am.in, rather than $<.
- Suggestion from Michael Elizabeth Chastain.
-
-2004-02-10 Jim Meyering <jim@meyering.net>
-
- * config/install-sh: Make this script executable.
- * Makefile.am (dist-hook): New target, to ensure that config/install-sh
- is executable. Otherwise, on systems that lack a suitable install
- binary, `make install' would fail, because of the way this script
- is invoked (without `$SHELL ' prefix).
- Reported by Bob Proulx.
-
-2004-02-08 Jim Meyering <jim@meyering.net>
-
- * Version 5.1.3.
-
- * tests/rm/rm5: Avoid triggering a bug in OSF/Tru64's sed
- that would cause an unwarranted test failure.
- * tests/rm/rm3: Likewise.
-
-2004-02-07 Jim Meyering <jim@meyering.net>
-
- Remove xstat function pointer member. The way it was used was not
- portable, since some systems (OSF V5.1, Solaris 2.5.1) provide static
- inline `stat' and `lstat' functions, thus making the tests of
- `xstat == lstat' in copy.c always fail.
- * src/copy.h (struct cp_options) [xstat]: Remove member.
- (XSTAT): New macro.
- * src/copy.c (copy_dir): Set `.dereference' member, not .xstat.
- (copy_internal): Use `XSTAT (x, ...)' in place of `*(x->xstat) (...)'.
- Use `x->dereference == DEREF_NEVER' in place of `x->xstat == lstat'.
- (valid_options): Remove now-obsolete FIXME comments.
-
- * src/cp.c (re_protect): Use `XSTAT (x, ...)' in place of
- `*(x->xstat) (...)'.
- (do_copy): Declare/use local xstat rather than x->xstat.
- (main): Remove code that set x.xstat.
- * src/mv.c (cp_option_init): Don't initialize xstat member.
- * src/install.c (cp_option_init): Likewise.
-
- * Makefile.cfg (gnu_ftp_host-alpha, etc.): Un-factor .gnu.org suffix,
- so that emit_upload_commands can use these variables, too.
-
-2004-02-06 Jim Meyering <jim@meyering.net>
-
- * tests/rm/deep-1: Remove `du' stack space test.
- Apparently, `ulimit -s N' isn't portable enough.
- This test will be restored (with a guard against losing ulimit)
- in its own file later.
-
- * tests/rm/deep-1 (deep): Remove progress-style diagnostics,
- since this test doesn't take long enough to merit them.
- Run du on $tmp (the containing dir), not $deep, the full path to leaf.
-
- * Makefile.maint (signatures): Remove definition.
- Now, automake's gnupload handles this.
- (%.sig: %): Remove now-unused rule.
- (rel-files): Use automake's $(DIST_ARCHIVES), rather than
- `$(distdir).tar.bz2 $(distdir).tar.gz'.
- (emit-upload-commands): Adjust to use gnupload.
-
-2004-02-05 Jim Meyering <jim@meyering.net>
-
- * src/system.h (ST_TIME_CMP_NS, ST_TIME_CMP): Remove definitions.
- (ATIME_CMP, CTIME_CMP, MTIME_CMP, TIMESPEC_NS): Likewise.
- Now, those are all defined in timespec.h.
- Include timespec.h.
-
- * src/date.c: Don't include timespec.h, now that system.h does it.
-
-2004-02-02 Paul Eggert <eggert@twinsun.com>
-
- Don't dump core if localtime returns NULL (possible on
- hosts with 64-bit time_t and 32-bit int).
- * src/date.c: Include "inttostr.h".
- (batch_convert, main):
- If time conversion fails, exit with nonzero status.
- (show_date): Return int to report conversion failure.
- Print the time as an int if localtime fails.
- * src/uptime.c: Print "??" if the current clock can't
- be converted by localtime. This won't happen until the year
- 2*31 + 1900, but we don't want to dump core even if the current
- clock has the wrong value.
-
- * src/stat.c: Include "inttostr.h".
- (human_time): Print the date/time as a number of seconds since the
- epoch if it can't be converted by localtime. This is better than
- just saying "invalid", and is consistent with what "ls" does.
- Don't dump core if the year has more than 48 digits; this isn't
- possible on any contemporary host, but we might as well do it right.
-
-2004-01-31 Paul Eggert <eggert@twinsun.com>
-
- * src/stat.c (human_time): Accept time rather than
- pointer-to-const-time parameter, for clarity. All callers changed.
-
-2004-02-02 Jim Meyering <jim@meyering.net>
-
- * src/stat.c (do_stat): Remove extra trailing newline from
- default formats. Reported by Nelson H. F. Beebe.
-
- Print actual fractional seconds in time stamps, not just `.00000000'.
- * src/stat.c (human_time): Add and use new parameter, t_ns.
- (print_stat): Update callers.
- * src/ls.c (TIMESPEC_NS): Remove definition.
- * src/system.h (TIMESPEC_NS): Define here, instead, now that stat.c
- also uses this macro.
- Nelson H. F. Beebe noticed that ls --full-time printed nonzero
- fractional seconds for files on an XFS file system, but that stat's
- fractional seconds were always zero.
-
-2004-01-28 Paul Eggert <eggert@twinsun.com>
-
- * src/seq.c (print_numbers): Use 'double' for loop index, not
- 'int', to avoid problems with integer overflow. On almost all
- machines 'double' works in every case where 'int' works, and
- it works on other cases besides.
-
-2004-01-27 Jim Meyering <jim@meyering.net>
-
- * src/seq.c (usage): Mention that if INCREMENT is omitted,
- it defaults to 1, even when FIRST is larger than LAST.
- Reword so as not to exclude the possibility that INCREMENT be zero.
-
-2004-01-25 Jim Meyering <jim@meyering.net>
-
- * Version 5.1.2.
-
- * Makefile.maint (signatures): Comment out definition.
-
-2004-01-23 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (header_regexp): Add exitfail.
-
- * man/Makefile.am (EXTRA_DIST): Add help2man.
- Reported by Nelson H. F. Beebe.
-
- * man/Makefile.am (.x.1): Prefix help2man invocation with `$(PERL) --'
- so it works on systems with Perl installed somewhere other than in
- /usr/bin.
-
- * src/paste.c (paste_parallel): Declare local, chr, to be of type
- `int', not `char', since it must hold EOF. This bug would make
- paste infloop on some systems. Test failures reported by
- Nelson H. F. Beebe and Christian Krackowizer.
-
-2004-01-22 Jim Meyering <jim@meyering.net>
-
- * tests/rmdir/fail-perm: New file. Test for just-fixed rmdir bug.
- * tests/rmdir/Makefile.am (TESTS): Add fail-perm.
-
- * man/help2man: Fix it so using --info-page='coreutils PROG' works.
- * man/Makefile.am (.x.1): Invoke our own (tweaked) copy of help2man.
- Use --info-page='coreutils PROG' option.
- Now, readlink.1 refers the user to `info coreutils readlink'
- rather than to `info readlink'. Reported by Matt Swift.
-
-2004-01-21 Paul Eggert <eggert@twinsun.com>
-
- Exit status cleanup.
-
- * src/basename.c (usage): Use EXIT_SUCCESS, not 0, for clarity.
- * src/cat.c, src/chgrp.c, src/chmod.c, src/chown.c, src/chroot.c,
- * src/cksum.c, src/comm.c, src/cp.c, src/csplit.c, src/cut.c,
- * src/date.c, src/dd.c, src/df.c, src/dircolors.c, src/dirname.c,
- * src/du.c, src/echo.c, src/env.c, src/expand.c, src/expr.c,
- * src/factor.c, src/fmt.c, src/fold.c, src/head.c, src/hostid.c,
- * src/hostname.c, src/id.c, src/install.c, src/join.c, src/kill.c,
- * src/link.c, src/ln.c, src/logname.c, src/ls.c, src/md5sum.c,
- * src/mkdir.c, src/mkfifo.c, src/mknod.c, src/mv.c, src/nice.c,
- * src/nl.c, src/nohup.c, src/od.c, src/paste.c, src/pathchk.c,
- * src/pinky.c, src/pr.c, src/printenv.c, src/printf.c, src/pwd.c,
- * src/rm.c, src/rmdir.c, src/seq.c, src/setuidgid.c, src/shred.c,
- * src/sleep.c, src/sort.c, src/split.c, src/stat.c, src/stty.c,
- * src/su.c, src/sum.c, src/sync.c, src/tac.c, src/tail.c, src/tee.c,
- * src/test.c, src/touch.c, src/tr.c, src/tsort.c, src/tty.c,
- * src/uname.c, src/unexpand.c, src/uniq.c, src/unlink.c, src/uptime.c,
- * src/users.c, src/wc.c, src/who.c, src/whoami.c, src/yes.c: Likewise.
-
- * src/cat.c (usage): Don't bother normalizing exit status
- since the arg is already the correct exit status now.
- * src/cksum.c, src/comm.c, src/csplit.c, src/cut.c,
- * src/dircolors.c, src/expand.c, src/fmt.c, src/fold.c, src/head.c,
- * src/join.c, src/md5sum.c, src/nl.c, src/od.c, src/paste.c,
- * src/pr.c, src/split.c, src/sum.c, src/tac.c, src/tail.c, src/tr.c,
- * src/tsort.c, unexpand.c, src/src/uniq.c, src/src/wc.c: Likewise.
-
- * src/chown.c (main): Removed unused local 'fail'.
-
- * src/chroot.c (CHROOT_FOUND_BUT_CANNOT_INVOKE, CHROOT_FAILURE):
- Remove.
-
- * src/chroot.c (main): Initialize exit_failure to EXIT_FAIL.
- * src/env.c, src/nice.c, src/su.c: Likewise.
- * src/nohup.c (main): Likewise, to NOHUP_FAILURE.
- * src/setuidgid.c (main): Likewise, to SETUIDGID_FAILURE.
- * src/expr.c (main): Use initialize_exit_failure rather than
- setting exit_failure directly; this optimizes away redundant
- assignments.
- * src/printenv.c, src/sort.c, src/test.c, src/tty.c: Likewise.
-
- * src/chroot.c (main): Exit with status 1 rather than 127
- if chroot itself fails, as per documentation.
-
- * src/chroot.c (main): Use EXIT_ENOENT and EXIT_CANNOT_INVOKE
- rather than roll-your-own symbols or integers.
- * src/env.c (main): Likewise.
- * src/nohup.c (main): Likewise.
- * src/su.c (run_shell): Likewise.
-
- * src/cp.c (exit_status): Remove static var....
- (main): Making it local here instead. Use =, not |=, to set it.
-
- * src/cut.c (FATAL_ERROR, main): Exit with status EXIT_FAILURE,
- not 2, on errors.
- * src/date.c (batch_convert, main): Likewise.
- * src/dd.c (dd_copy): Likewise.
- * src/pr.c (first_last_page, main, getoptarg): Likewise.
- * src/tr.c (main): Likewise.
- * src/date.c (main): Don't assume EXIT_FAILURE == 1, as
- POSIX doesn't require it.
- * src/dd.c (write_output, skip, dd_copy): Likewise.
- * src/df.c (main): Likewise.
- * src/id.c (main): Likewise.
- * src/install.c (main): Likewise.
- * src/ln.c (main): Likewise.
- * src/ls.c (main): Likewise.
- * src/mv.c (main): Likewise.
- * src/shred.c (main): Likewise.
-
- * src/env.c (main): Exit with status 1, not 2, on errors detected
- by env proper.
- * src/hostname.c (main): Likewise.
- * src/nl.c (main): Likewise.
- * src/stty.c (main): Likewise.
-
- * src/expr.c (EXPR_FAILURE): Renamed from EXPR_ERROR, for
- consistency with the other programs' naming conventions.
- All uses changed.
-
- * src/factor.c (main): Do not report a usage error simply
- because stdin has bad numbers.
-
- * src/id.c (problems): Now a boolean int, not a counter,
- so that we don't have to worry about int overflow. All uses changed.
- * src/touch.c (err): Likewise.
-
- * src/md5sum.c (main): Use int, not size_t, to store boolean int.
-
- * src/mkfifo.c (main): Exit with status 1, not 4, if not implemented.
- * src/mknod.c: Likewise.
-
- * src/nice.c (main): Exit with status EXIT_FAIL, not EXIT_FAILURE,
- on error; this is in case EXIT_FAILURE is unusual.
- * src/su.c (main): Likewise.
-
- * src/nohup.c (NOHUP_FOUND_BUT_CANNOT_INVOKE): Remove; all uses
- changed to EXIT_CANNOT_INVOKE.
-
- * src/printenv.c (PRINTENV_FAILURE): New constant.
- (main): Exit with status PRINTENV_FAILURE, not EXIT_FAILURE, on
- command-line syntax problems.
-
- * src/rmdir.c (remove_parents): Don't set 'fail' to a negative number.
- (main): Avoid integer overflow when seeing whether errors occurred.
-
- * src/seq.c (print_numbers): Now returns void, not (zero) int.
- All callers changed.
- (main): Remove unused local variable 'errs'. Always exit successfully
- if we reach the end.
-
- * src/setuidgid.c (SETUIDGID_FAILURE): Renamed from FAIL_STATUS,
- for consistency with other programs here. All uses changed.
- (main): Use 'error' to exit rather than invoking 'exit' here.
-
- * src/sort.c: Don't include <assert.h>.
- (SORT_OUT_OF_ORDER, SORT_FAILURE): Now enums, not macros.
- (usage): Don't use 'assert'.
- (main): Remove redundant assignment to exit_failure.
-
- * src/system.h (EXIT_FAIL, EXIT_CANNOT_INVOKE, EXIT_ENOENT):
- New enum values.
- (initialize_exit_failure): New inline function.
- Include exitfail.h here, since we refer to exit_failure.
- All callers changed to not include exitfail.h.
-
- * src/tty.c (TTY_FAILURE, TTY_WRITE_ERROR): New enum values;
- substitute them for the corresponding integer constants.
-
- * tests/help-version (expected_failure_status_date): Remove, as
- 'date' is now normal.
- (expected_failure_status_nohup): New var.
-
-2004-01-21 Jim Meyering <jim@meyering.net>
-
- * tests/touch/relative: Remove `command' syntax.
- Thanks to Nelson H. F. Beebe and Paul Eggert.
-
- * tests/touch/relative: Test only year/month/day, not hours/min/sec,
- so as to avoid problems with systems using TAI clocks.
- Although it's no longer necessary, set TZ=UTC0 also for the
- initial touch command. Reported by Paul Jarc here:
- http://article.gmane.org/gmane.comp.gnu.core-utils.bugs/1504
-
-2004-01-20 Diego Biurrun <diego@biurrun.de>
-
- * src/dircolors.hin: Add .mov to the list of media files.
-
-2004-01-19 Paul Eggert <eggert@twinsun.com>
-
- * tests/touch/relative: Use TZ=UTC0, not TZ=utc (which isn't
- portable). Problem reported by Christian Krackowizer. Also, use
- +0000 rather than +0 to specify a time zone, as the documentation
- requires four digits.
-
-2004-01-19 Jim Meyering <jim@meyering.net>
-
- * tests/mv/hard-4: Run envvar-check in case SIMPLE_BACKUP_SUFFIX is set.
- * tests/mv/backup-is-src: Likewise.
- Problem reported by Peter Horst
-
-2004-01-17 Jim Meyering <jim@meyering.net>
-
- * announce-gen (print_changelog_deltas): Use .sig suffix, not .asc.
-
- * Version 5.1.1.
-
-2003-12-15 Paul Eggert <eggert@twinsun.com>
-
- * NEWS, doc/coreutils.texi: touch -r and -d can now both be specified,
- with -r specifying the origin for -d.
- * src/touch.c (flexible_date): Remove static var.
- (get_reldate): New function.
- (main): Use it, to implement this new behavior.
-
-2004-01-16 Jim Meyering <jim@meyering.net>
-
- * tests/touch/relative: New test for the above.
- * tests/touch/Makefile.am (TESTS): Add relative.
-
-2004-01-13 Jim Meyering <jim@meyering.net>
-
- * src/system.h: Include contents of sys2.h.
- * src/sys2.h: Remove file.
- * src/Makefile.am (noinst_HEADERS): Remove sys2.h.
-
- * Use automake-1.8.2. Regenerate dependent files.
-
- * Update to gettext-0.13.1.
- * configure.ac: Use gettext-0.13.1.
- * .x-sc_space_tab: Add m4/po.m4 to the list of exceptions.
-
-2004-01-12 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (%.sig): Use .sig suffix rather than .asc.
-
- * Makefile.maint (po-check): Ensure that cvsu works before using it.
- Reported by Alexandre Duret-Lutz.
-
- * src/tail.c (main): Warn about following stdin only when it's a tty.
-
- * configure.ac: Use gl_DEFAULT_POSIX2_VERSION.
-
-2004-01-10 Jim Meyering <jim@meyering.net>
-
- * tests/misc/stat-fmt: Use backticks, not `$()' notation.
-
-2004-01-09 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Quote underquoted `jm_DUMMY_1' to avoid new warning.
-
-2004-01-08 Jim Meyering <jim@meyering.net>
-
- * src/stat.c (human_fstype): Use %lx, not %x format for `unsigned long'.
- From Andreas Schwab.
-
- * tests/Makefile.am (TESTS_ENVIRONMENT): Remove `/vg' (prerelease test
- remnant) from PATH component. That would cause tests in this directory
- not to run the just-built binaries, but rather whatever happened
- to be in one's PATH. Reported by Christian Krackowizer.
-
-2004-01-04 Jim Meyering <jim@meyering.net>
-
- * src/csplit.c (new_control_record): Use x2nrealloc
- rather than xrealloc.
-
- * src/cp.c (re_protect): Use ASSIGN_STRDUPA rather than
- alloca and strcpy.
- (make_path_private): Likewise.
-
-2004-01-03 Jim Meyering <jim@meyering.net>
-
- * src/paste.c: Use `bool' (not int) as the type for a few
- global variables.
- (collapse_escapes): Rewrite to set globals rather than modifying
- its parameter.
- Use size_t (not int) for all counters and related index variables.
- (paste_parallel): Remove needless complexity of
- using xrealloc in the loop; just allocate the buffers up front.
- Free the two temporary buffers.
- Move declarations of locals `down' into scope where used.
- (paste_serial): Remove `register' attributes.
- (main): Simplify delim-related code.
- Free `delims', now that it's malloc'd.
-
-2004-01-02 Jim Meyering <jim@meyering.net>
-
- * src/chroot.c: Include "quote.h".
- (CHROOT_FOUND_BUT_CANNOT_INVOKE, CHROOT_FAILURE): Define.
- (main): Exit with status of 127, not 1, for too-few-args,
- chroot failure, or chdir failure.
- Give a better diagnostic upon execvp failure.
-
- * src/du.c (usage): Mention that, with its current meaning,
- -H is deprecated.
-
- * src/tail.c (main): Warn about following stdin when it's a tty.
- Fail when following by name but no names are specified.
-
-2003-12-30 Jim Meyering <jim@meyering.net>
-
- * src/fold.c (main): Use memcpy, not strcpy.
-
- * src/copy.c (copy_internal): Use ASSIGN_STRDUPA rather than
- alloca and strcpy.
-
-2003-12-28 Jim Meyering <jim@meyering.net>
-
- * src/unexpand.c (n_tabs_allocated): New global.
- (add_tabstop): Use x2nrealloc rather than xrealloc.
- * src/expand.c: Likewise.
-
- * tests/misc/expand: New file.
- * tests/misc/Makefile.am (TESTS): Add expand.
-
- * src/sort.c (add_temp_dir): Use x2nrealloc rather than xrealloc.
- (fillbuf): Use x2nrealloc rather than xrealloc.
- (sort): Use xnmalloc rather than xmalloc.
- (main): Likewise.
-
-2003-12-27 Jim Meyering <jim@meyering.net>
-
- * src/tee.c (tee): Use xnmalloc rather than xmalloc.
-
-2003-12-29 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: Remove support for join -j1 FIELD, -j2 FIELD, and -o LIST1
- LIST2 in POSIX 1003.1-2001 hosts, as required by POSIX.
-
- * doc/coreutils.texi (join invocation): Remove documentation
- accordingly. Document that -t makes all separators significant.
-
- * src/join.c: Include posixver.h.
- (obsolete_usage): New var.
- (longopts): Put obsolete options first.
- (OBSOLETE_LONG_OPTIONS): New constant.
- (get_option, add_file_name): New functions.
- (main): Use them to support new behavior.
- (usage): Remove documentation for -j1 FIELD and -j2 FIELD.
- Do not mark -j FIELD as obsolescent; it is longstanding
- UNIX tradition and is a valid extension to POSIX.
-
- * tests/join/Test.pm (tv): Avoid obsolete -o usage.
-
-2003-12-28 Paul Eggert <eggert@twinsun.com>
-
- * src/join.c (add_field_list): Don't use alloca with unbounded
- size; just modify the argument, which is no longer const *.
-
- Various other minor cleanups, mostly to avoid the need for casts.
-
- (extract_field): Renamed from ADD_FIELD, as it's now a function.
-
- (struct field.beg): Now char *, not unsigned char const *. All
- uses changed. It shouldn't be const since xmemcoll writes on its
- arguments.
- (extract_field): Likewise, for 2nd arg.
- (keycmp): Remove now-unnecessary cast of xmemcoll args.
-
- (is_blank): New function, to avoid need to cast arg to unsigned char.
- (extract_field): Use it.
-
- (xfields): Rewrite pretty much from scratch.
-
- (hard_LC_COLLATE): Now bool, not int.
- (get_line, getseq, add_field_list): Now returns bool, not int.
- (decode_field_spec, add_field_list): Return true on success (not
- false), for consistency with the rest of the code. All uses changed.
-
- (tab): Now char, not unsigned char. This wasn't 100% necessary
- but is slightly cleaner.
- (prjoin): Hoist (tab ? tab : ' ') expression, to help the compiler.
-
- (empty_filler): Now const *.
-
- (make_blank): Remove; wasn't needed. Remove all calls.
- (main): Don't set uni_blank.nfields; zero is fine.
-
-2003-12-27 Jim Meyering <jim@meyering.net>
-
- * src/join.c: Include "quote.h".
- (min, max): Remove definitions.
- Make a few function parameters and corresponding
- locals `const'. Use bool for boolean variables.
- Use size_t (not int) for all counters and related index variables.
- (prjoin): Remove now-useless assertion.
- (string_to_join_field): New function.
- (main): Accept join fields as large as SIZE_MAX.
- (keycmp): Rename `min' to MIN and max to MAX.
-
-2003-12-26 Jim Meyering <jim@meyering.net>
-
- fold -s didn't work on e.g., alpha-based systems.
- * src/fold.c (fold_file): Adjust types (int->size_t) so that using
- x2nrealloc works properly on systems with differing sizes for int
- and size_t. Reported by Nelson Beebe.
-
- * src/fold.c: Use `bool' (not int) as the type for a few
- global variables.
-
-2003-12-23 Paul Eggert <eggert@twinsun.com>
-
- * src/ls.c (length_of_file_names_and_frills):
- Remove forward decl; not needed.
- (print_file_name_and_frills, length_of_file_name_and_frills):
- With -m, don't output spaces before inum or size.
- (print_with_commas): Don't output space just before newline.
-
-2003-12-24 Jim Meyering <jim@meyering.net>
-
- * tests/ls/Makefile.am (TESTS): Add m-option.
- * tests/ls/m-option: New file. Test for above fixes.
-
-2003-12-20 Jim Meyering <jim@meyering.net>
-
- * Version 5.1.0.
-
- * src/pr.c: Change type of global, buff_allocated, to size_t.
-
- * src/join.c [struct seq]: Change types of members count and alloc
- from `int' to `size_t'.
-
- * tests/Makefile.am (root-hint): Tweak wording.
-
- * src/du.c: Accept new option (-0, --null) that makes it so each
- output line is NUL-terminated rather than newline-terminated.
-
- * src/dd.c (apply_translations): Don't prohibit conv=unblock,sync.
- Reported by Volker Paul.
- * tests/dd/Makefile.am (TESTS): Add unblock-sync.
- * tests/dd/unblock-sync: New test for the above.
-
-2003-12-19 Jim Meyering <jim@meyering.net>
-
- * tests/misc/nohup: Double quote back-ticked expression,
- in case it ends up having an unexpected value.
-
- * tests/ls/no-arg: Use ls's -1 option in both runs.
-
- * src/du.c (fts_debug): New global.
- (FTS_CROSS_CHECK, DEBUG_OPT): Define.
- (main): Make fts use FTS_TIGHT_CYCLE_CHECK.
- (main) [DU_DEBUG]: Accept -d option.
-
-2003-12-18 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (format_user): Increment dired_pos via two statements,
- `dired_pos += width; dired_pos++;' rather than one,
- `dired_pos += width + 1;' since the latter could conceivably overflow.
- (format_group): Likewise.
- From Paul Eggert.
-
- * configure.ac: Require automake-1.8.
-
-2003-12-12 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.8. Regenerate dependent files.
-
-2003-12-08 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (news-date-check): New rule.
- (alpha beta major): Depend on it.
-
-2003-12-03 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: ls -l (and similar options) now adjust all columns to
- fit the data. Generalized from a suggestion by Leah Q for file sizes.
- * src/ls.c (INODE_DIGITS, LOGIN_NAME_MAX, ID_LENGTH_MAX): Remove.
- (format_user_width, format_group_width, unsigned_file_size,
- format_group): New functions.
- (block_size_width): Renamed from block_size_size.
- (inode_number_width, nlink_width, owner_width, group_width,
- author_width, major_device_number_width, minor_device_number_width,
- file_size_width): New vars.
- (clear_files): Initialize them.
- (gobble_file): Set them. Don't ceiling block_size_width to 7.
- (print_long_file): Use them.
- (gobble_file): Use a new local variable 'f' to make the code
- smaller and more consistent with other functions.
- (format_user): Output to stdout, not to a buffer, so that we
- don't have to worry about buffer overrun. Update dired_pos.
- (print_long_file): Don't put owner, group, author into buffer;
- just print them directly. Don't assume link counts and
- major and minor numbers fit into unsigned long int.
- * tests/cp/same-file, tests/mv/part-symlink: Don't assume that
- 'ls' output is fixed-width.
-
-2003-12-02 Jim Meyering <jim@meyering.net>
-
- * src/md5sum.c: Include sha1.h (reflect renaming: sha.h -> sha1.h.
-
-2003-11-27 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.7f. Regenerate dependent files.
-
-2003-11-24 Paul Eggert <eggert@twinsun.com>
-
- Parse floating-point operands and options in the C locale.
- POSIX requires this for printf, and we might as well be
- consistent elsewhere (tail, sleep, seq).
-
- * src/printf.c: Remove decls of strtod, strtol, strtoul; no longer
- needed now that we assume C89. Include "c-strtod.h".
- (xstrtod): Call c_strtod, not strtod.
- * src/sleep.c: Include "c-strtod.h".
- (main): Update xstrtod call to include new argument, c_strtod.
- * src/seq.c (scan_double_arg): Likewise.
- * src/tail.c (parse_options): Likewise.
-
-2003-11-24 Jim Meyering <jim@meyering.net>
-
- * tests/rm/fail-2eperm: Handle another errno variant (HPUX, EPERM).
- Reported by Mark Conty.
-
-2003-11-22 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_xalloc_h_in_src): Remove rule. Subsumed by...
- (sc_system_h_headers): Do this test only if sys2.h exists.
-
-2003-11-20 Jim Meyering <jim@meyering.net>
-
- * tests/help-version: Ensure that the bug-reporting address is
- included in the --help output for every program.
- * tests/Makefile.am (TESTS_ENVIRONMENT): Add $PACKAGE_BUGREPORT.
-
- * src/ptx.c (usage): Output bug-reporting address.
- Reported by Dan Jacobson.
-
-2003-11-19 Jim Meyering <jim@meyering.net>
-
- * src/join.c (usage): Mention that FILE1 and FILE2 must be sorted
- on the join fields. Suggestion from Bruce Robertson.
-
-2003-11-18 Jim Meyering <jim@meyering.net>
-
- `od -c -w9999999' could segfault
- * src/od.c (dump): Use xnmalloc/free, not alloca.
-
-2003-11-16 Jim Meyering <jim@meyering.net>
-
- * Use autoconf-2.59. Regenerate dependent files.
-
- * tests/du/hard-link: Minor tweak: use mkdir -p.
-
- Fix read-from-free'd-buffer error detected by valgrind.
- * src/csplit.c (remove_line): Don't return a pointer to data in
- a freed buffer. Instead, arrange to free the buffer on the
- subsequent call.
-
- * tests/misc/csplit: New test for above fix.
-
-2003-11-11 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (extract_dirs_from_files): Avoid useless copy operations.
- This avoids a warning from valgrind about memcpy with overlapping
- source and destination.
-
- * configure.ac: Require automake-1.7.8.
-
-2003-11-09 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.7.9. Regenerate dependent files.
-
- * src/rm.c: Support new options: --preserve-root and --no-preserve-root.
- * src/chown.c: Likewise.
-
- * src/chown-core.c: Include "root-dev-ino.h".
- (chopt_init): Initialize new member.
- (change_file_owner): Support rm's new --preserve-root option.
-
- * src/remove.c: Include "root-dev-ino.h".
- (remove_cwd_entries): Remove now-obsolete FIXME comment.
- (remove_dir): Support rm's new --preserve-root option.
-
- * src/chown.c: Include "root-dev-ino.h".
- Add new options: --preserve-root and --no-preserve-root.
-
- * src/chmod.c: Include "root-dev-ino.h".
- (process_file): Use newly-factored-out ROOT_DEV_INO_CHECK and
- ROOT_DEV_INO_WARN macros.
- (get_root_dev_ino): Remove function definition, now that it's
- been moved to a separate file.
- (usage): Describe new options.
-
- * src/mv.c (rm_option_init): Initialized new member.
-
- * src/remove.h: Include "dev-ino.h".
- (struct rm_options): Add new member: root_dev_ino.
- * src/chown-core.h: Include "dev-ino.h".
- (struct Chown_option): Add new member: root_dev_ino.
-
-2003-11-06 Jim Meyering <jim@meyering.net>
-
- * src/paste.c (paste_parallel): Use `sizeof *var' rather than
- hard-coding `sizeof FILE*'.
-
-2003-11-05 Dennis Smit <ds@nerds-incorporated.org>
-
- * src/wc.c (main): Free `fstatus' so there is no confusion about
- whether it's leaked or not.
- * src/who.c (who): Likewise for `utmp_buf'.
-
-2003-11-05 Paul Eggert <eggert@twinsun.com>
-
- Fix 'cut' problems with size_t overflow and unsigned int.
- More generally, resize integer variables to fit use more precisely.
- * src/cut.c (ADD_RANGE_PAIR): Remove unnecessary parens.
- (struct range_pair): Make members to be of type size_t, not unsigned.
- (max_range_endpoint, eol_range_start): Now size_t, not unsigned.
- (suppress_non_delimited, output_delimiter_specified,
- have_read_stdin, print_kth, set_fields): Now bool, nt int.
- (delim): Now unsigned char, not int.
- (mark_printable_field, is_printable_field, is_range_start_index,
- set_fields, set_fields, cut_bytes, cut_fields):
- Use size_t, not unsigned, for field and byte counts.
- (hash_int): Use uintptr_t, not unsigned, for pointers converted
- to integers. This squeezes more info out of them.
- (set_fields, cut_bytes, cut_fields, main):
- Use bool, not int, for booleans.
- (set_fields): Allocate zeroed byte array with xzalloc, not xcalloc.
-
-2003-11-05 Paul Eggert <eggert@twinsun.com>
-
- * man/Makefile.am (check-programs-vs-x):
- Work even if $(programs) contains '$'.
- Work even if 'missing=1' in environment.
- Don't report an error simply because $(programs) outputs nothing.
-
-2003-11-05 Jim Meyering <jim@meyering.net>
-
- * Use autoconf-2.58. Regenerate dependent files.
-
- * src/tr.c (spec_init): Fix typo in last change.
-
- * src/sys2.h (case_GETOPT_VERSION_CHAR): Cast NULL to `(char *)' in
- call to variadic version_etc function, so that it works even on systems
- for which sizeof char* != sizeof int.
- * src/true.c (main): Likewise.
- * basename.c, chroot.c, cksum.c, dd.c, dirname.c, echo.c, expr.c:
- * factor.c, hostid.c, hostname.c, link.c, logname.c, nice.c, nohup.c:
- * pathchk.c, printenv.c, printf.c, pwd.c, setuidgid.c, sleep.c, stty.c:
- * sync.c, test.c, tsort.c, unlink.c, uptime.c, users.c, whoami.c, yes.c:
- Similarly, cast NULL to `(char *)' in call to variadic function,
- parse_long_options, so that it works even on systems for which
- sizeof char* != sizeof int.
- A similar problem was reported by Harti Brandt in
- http://mail.gnu.org/archive/html/bug-gnu-utils/2003-10/msg00320.html.
-
- * src/users.c (users): Free `utmp_buf' explicitly so that people
- don't mistake this for a real leak.
- Patch by Dennis Smit <ds@nerds-incorporated.org.
-
-2003-11-04 Paul Eggert <eggert@twinsun.com>
-
- * README: Document _POSIX2_VERSION.
-
-2003-11-04 Jim Meyering <jim@meyering.net>
-
- * src/tac.c (memrchr): Remove #if-0'd function.
- (tac_stdin_to_mem): Clean up #if-0'd code.
-
- * src/od.c (decode_format_string): Remove unnecessary casts.
- Use more maintainable `sizeof *var'.
- (main): Call decode_format_string rather than decode_one_format,
- now that `spec' may be NULL.
-
- * src/chmod.c (AUTHORS): Add my name.
-
- * src/split.c (next_file_name): Use `sizeof *var' rather than
- hard-coding `sizeof size_t'.
-
- * src/sort.c (new_key): Use xzalloc, not xcalloc (1, ...).
-
- * src/cut.c (ADD_RANGE_PAIR): Use x2nrealloc rather than xrealloc,
- to avoid potential overflow in pointer arithmetic.
- (set_fields): Use not `1', but rather `sizeof *printable_field' as
- second argument to xcalloc.
- * src/od.c (decode_format_string, dump_strings): Use x2nrealloc
- rather than xrealloc.
- * src/date.c (show_date): Likewise.
- * src/join.c (ADD_FIELD, initseq, getseq): Likewise.
- * src/pr.c (store_char): Likewise.
- * src/fold.c (fold_file): Likewise.
-
- * src/copy.c (triple_hash, triple_hash_no_name): Adjust to reflect
- type changes (unsigned int -> size_t) in hash.c.
- * src/cp-hash.c (src_to_dest_hash): Likewise.
- * src/du.c (entry_hash): Likewise.
- * src/ls.c (dev_ino_hash): Likewise.
- * src/cut.c (hash_int): Likewise. Declare function as static.
-
-2003-11-03 Jim Meyering <jim@meyering.net>
-
- * tests/misc/Makefile.am (TESTS_ENVIRONMENT): Define PACKAGE_VERSION.
- * tests/misc/fold: Fail the test immediately if we're not running
- the expected version of fold.
-
-2003-11-02 Jim Meyering <jim@meyering.net>
-
- * src/tr.c (append_normal_char, append_range, append_char_class)
- (append_repeated_char, append_equiv_class, spec_init): Use `sizeof *var'
- rather than `sizeof EXPLICIT_TYPE'. The former is more maintainable
- and usually shorter.
- * src/copy.c (copy_internal): Likewise.
- * src/join.c (initseq, add_field, make_blank): Likewise.
- * src/od.c (main): Likewise.
- * src/cp.c (make_path_private): Likewise.
- * src/tsort.c (new_item, record_relation): Likewise.
-
- * src/df.c (add_fs_type, add_excluded_fs_type, main): Likewise.
- (main): Also remove anachronistic cast of xmalloc return value.
- * src/ptx.c (alloc_and_compile_regex, main): Likewise.
- (main): Also remove anachronistic cast of xmalloc return value.
- * src/sort.c (inittables): Likewise.
- (sort): Also Split a long line.
-
-2003-10-25 Jim Meyering <jim@meyering.net>
-
- * src/copy.c (triple_hash, triple_hash_no_name): Adjust to reflect
- type changes (unsigned int -> size_t) in hash.c.
- * src/cp-hash.c (src_to_dest_hash): Likewise.
- * src/du.c (entry_hash): Likewise.
- * src/ls.c (dev_ino_hash): Likewise.
- * src/cut.c (hash_int): Likewise. Declare function as static.
-
-2003-10-21 Jim Meyering <jim@meyering.net>
-
- Don't fail when run with VERBOSE=yes.
- * tests/chgrp/basic: Do `set +x' before starting the subshell
- from which we invoke chgrp. Otherwise, the output from the
- VERBOSE=yes-induced `set -x' would result in spurious differences.
- Reported by Russel Coker via Michael Stone.
-
-2003-10-19 Jim Meyering <jim@meyering.net>
-
- chmod now uses fts to perform a directory traversal when -R is
- specified. Before, it operated on full path names, and as such
- would encounter the PATH_MAX (often 4096) limit.
-
- * src/chmod.c: Include "xfts.h".
- (process_file): Rename from change_file_mode.
- Adapt to be used with fts.
- (process_files): New function.
-
-2003-10-18 Jim Meyering <jim@meyering.net>
-
- * tests/du/deref-args: Ensure that du -D now dereferences all
- symlinks specified on the command line, not just those that
- reference directories.
-
- * basename.c, cat.c, chroot.c, cksum.c, comm.c, cp.c, csplit.c, cut.c:
- * dd.c, df.c, dirname.c, du.c, echo.c, env.c, expr.c, factor.c, head.c:
- * hostid.c, hostname.c, id.c, link.c, ln.c, logname.c, ls.c, md5sum.c:
- * mv.c, nice.c, nl.c, nohup.c, paste.c, pathchk.c, pinky.c, pr.c:
- * printenv.c, printf.c, pwd.c, rm.c, setuidgid.c, sleep.c, sort.c:
- * split.c, stty.c, sum.c, sync.c, tac.c, tail.c, tee.c, test.c:
- * touch.c, tsort.c, uniq.c, unlink.c, uptime.c, users.c, wc.c:
- * who.c, whoami.c, yes.c (AUTHORS): Revert the WRITTEN_BY/AUTHORS change
- of 2003-09-19. Now, AUTHORS is a comma-separated list of strings.
- Update the call to parse_long_options so that `AUTHORS, NULL' are the
- last parameters.
- * src/true.c (main): Append NULL to version_etc argument list.
- * src/sys2.h (case_GETOPT_VERSION_CHAR): Likewise.
-
-2003-10-17 Andreas Schwab <schwab@suse.de>
-
- * tests/mk-script: Get $srcdir from first parameter instead of
- hardcoding it.
- (main): Update usage.
-
- * tests/Makefile.am.in ($(srcdir)/$x-tests): Pass $(srcdir) as
- first argument of mk-script.
- ($(srcdir)/Makefile.am): Likewise. Prepend $(srcdir) to target.
-
-2003-10-17 Jim Meyering <jim@meyering.net>
-
- * src/mv.c (usage): Tweak descriptions of -i and -f so that the
- generated `man' page is more readable. Suggestion from Dan Jacobson.
-
- * src/chown-core.c (change_file_owner): Handle the cases in
- which fts_info indicates an error with the given entry.
-
- * src/du.c (main): Simply assign to bit_flags.
- Don't bother with bit arithmetic.
-
- * tests/chmod/no-x: New file.
- * tests/chgrp/no-x: New file.
- * tests/chmod/Makefile.am (TESTS): Add no-x.
- * tests/chgrp/Makefile.am (TESTS): Likewise.
-
- * src/du.c: Include "xfts.h".
- (du_files): Use xfts_open, rather than fts_open.
- * src/chown-core.c (chown_files): Likewise.
-
-2003-10-16 Jim Meyering <jim@meyering.net>
-
- * src/chgrp.c (main): Simply assign to bit_flags.
- Don't bother with bit arithmetic.
- * src/chown.c (main): Likewise.
- Rename a couple of local variables.
- Remove unnecessary casts.
-
- * src/tail.c (start_bytes): Rename local, remainder, to avoid
- gcc's warning about shadowing a global.
-
-2003-10-15 Jim Meyering <jim@meyering.net>
-
- chown and chgrp now accept POSIX-mandated -H, -L, -P options and
- use fts to perform a directory traversal when -R is specified.
- Before, they operated on full path names, and as such would
- encounter the PATH_MAX (often 4096) limit.
- They are more efficient. For example, before, chgrp -R would
- take almost 5 seconds to change about 2000 directories and fail
- (with `File name too long'), while now it succeeds on a hierarchy
- of depth 20,000 in 1/10 the time.
-
- * src/chown.c: Include "userspec.h" and "fts_.h".
- (WRITTEN_BY): Add my name.
- (getpwnam, getgrnam, getgrgid): Remove declarations.
- (endpwent): Remove definition.
- (usage): Update.
- (main): Handle new options.
- Call new function, chown_files rather than change_file_owner.
-
- * src/chgrp.c: Include "fts_.h".
- (WRITTEN_BY): Add my name.
- (MAXUID, MAXGID): Remove definitions. Use GID_T_MAX instead of
- the latter.
- (usage): Update.
- (main): Handle new options.
- Call new function, chown_files rather than change_file_owner.
-
- Rewrite to iterate through hierarchies using fts rather than
- via explicit recursion.
- * src/chown-core.c: Include "fts_.h"
- (change_file_owner): Rewrite to use FTS* and FTSENT* and to operate
- on a single file at a time.
- (chown_files): New function.
- * src/chown-core.h [enum Dereference_symlink]: Remove declaration.
- [struct Chown_option] (recurse, force_silent): Change type to `bool'.
- [struct Chown_option] (dereference): Remove member with ambiguous name.
- [struct Chown_option] (affect_symlink_referent): New member.
- (chown_files): New prototype.
-
- * tests/chgrp/recurse: Update tests accordingly.
- * tests/chgrp/posix-H: New tests for the above.
- * tests/chgrp/Makefile.am (TESTS): Add posix-H.
-
- * src/ln.c (usage): Clarify that --directory, -d, -F probably won't
- work even for superuser. Suggestion from Dan Jacobson.
-
-2003-10-14 Paul Eggert <eggert@twinsun.com>
-
- Fix some number-parsing bugs, e.g., "head -n 100k@" wasn't
- properly diagnosed.
- * lib/human.c, lib/xstrtoimax.c, lib/xstrtol.c, lib/xstrtol.h,
- lib/xstrtoul.c, lib/xstrtoumax.c: Sync with gnulib.
- * src/sort.c (parse_field_count): Handle the case where overflow
- and invalid suffix char are both reported.
-
-2003-10-14 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (decode_switches) [TIOCGWINSZ]: Comment out the
- warning-inducing test, ws.ws_col <= SIZE_MAX, since it was always
- true on Linux.
-
-2003-10-13 Paul Eggert <eggert@twinsun.com>
-
- Fix to avoid a denial-of-service attack if the display width is
- enormous. Also, clean up the code a bit by removing duplicate code.
-
- * src/ls.c (init_column_info): Remove forward decl; no longer needed.
- (calculate_columns): New function, that contains code that used
- to be common to print_many_per_line and print_horizontal.
- (print_many_per_line, print_horizontal): Use it.
- (decode_switches): Set max_idx here, not in calculate_columns.
- (print_current_files): Don't call init_column_info; calculate_columns
- now does that.
- (init_column_info): Don't allocate a lot more space than is needed
- to represent the current set of files. Allocate all the new
- size_t cells in one call to xnmalloc, rather than a row at a time.
-
-2003-10-13 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (init_column_info): Add another FIXME comment.
-
-2003-10-13 Paul Eggert <eggert@twinsun.com>
-
- Fix address-arithmetic bug in 'ls', reported by Georgi Guninski.
- Remove several arbitrary limits on hosts where int cannot represent
- all size_t values.
-
- * src/ls.c (struct bin_str.len, length_of_file_name_and_frills, indent,
- nfiles, files_index, tabsize, line_length, struct column_info.line_len,
- struct column_info.col_arr[0], max_idx):
- Now size_t, not int.
- (get_funky_string): Return bool indicating success, instead of
- a negative count to indicate failure. Store number of columns
- through new parameter OUTPUT_COUNT; that way, they can never
- go negative. Change equals_end from int to bool. All uses
- changed.
- (struct column_info.valid_len): Now bool, not int. All uses changed.
- (dired_dump_obstack, get_funky_string, clear_files,
- extract_dirs_from_files, print_current_files,
- print_many_per_line, print_horizontal, init_column_info,
- put_indicator, length_of_file_name_and_frills,
- print_with_commas): Use size_t, not int, for local variables
- that count sizes.
- (decode_switches): Decode sizes using xstrtoul, not xstrtol.
- Check for TIOCGWINSZ returing negative values (or values greater
- than SIZE_MAX!).
- (visit_dir, main, parse_ls_color, queue_directory, add_ignore_pattern,
- init_column_info):
- Use xmalloc and xnmalloc, not XMALLOC.
- (gobble_file): Use xnrealloc, not XREALLOC.
- (print_color_indicator): Remove now-unnecessary cast to size_t.
-
-2003-10-12 Paul Eggert <eggert@twinsun.com>
-
- * tests/du/no-x: Change wording of diagnostic to match latest du.c.
- * tests/sort/sort-tests: Remove from CVS; assume that people
- brave enough to check coreutils out from CVS can rebuild it.
-
-2003-10-12 Jim Meyering <jim@meyering.net>
-
- New options: --preserve-root and --no-preserve-root.
- * src/chmod.c (change_file_mode): Honor new option.
- (change_file_mode): Strip trailing slashes on directory
- argument passed to change_dir_mode.
- (get_root_dev_ino): New function.
- (main): Initialize global, root_dev_ino.
-
- * src/copy.c (copy_internal): Don't #ifdef-out simple uses of
- S_ISLNK or S_ISSOCK. The S_IS* macros are guaranteed to be defined
- via system.h.
- * src/chmod.c (change_file_mode): Likewise.
-
-2003-10-08 Jim Meyering <jim@meyering.net>
-
- * src/csplit.c (main): Remove obsolete FIXME.
-
-2003-10-07 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.7.8. Regenerate dependent files.
-
-2003-09-29 Paul Eggert <eggert@twinsun.com>
-
- csplit cleanup.
-
- * doc/coreutils.texi (csplit invocation):
- The regexp offset need not have a sign; POSIX requires support
- for signless offets.
-
- Be more careful about int widths. For example, remove some
- arbitrary limits by replacing 'unsigned' with 'size_t',
- 'uintmax_t', etc. Use standard bool rather than a homegrown type.
- * lib/Makefile.am (libfetish_a_SOURCES): Add xstrtoimax.c.
- * src/csplit.c (FALSE, TRUE, boolean): Remove. All uses changed
- to <stdbool.h> usage.
- (struct control): offset is now intmax_t, not int.
- repeat_forever is now bool, not int.
- (struct cstring): len is now size_t, not unsigned int.
- (struct buffer_record): bytes_alloc, bytes_used, num_lines are now
- size_t, not unsigned. start_line, first_available are now
- uintmax_t, not unsigned.
- (hold_count, control_used): Now size_t, not unsigned.
- (last_line_number, current_line, bytes_written):
- Now uintmax_t, not unsigned.
- (save_to_hold_area, red_input, keep_new_line, record_line_starts,
- create_new_buffer, get_new_buffer, load_buffer, find_line,
- process_regexp, split_file, new_control_record, extract_regexp,
- get_format_width, get_format_prec, max_out):
- size args, locals, and returned values are now size_t, not unsigned
- or int.
- (get_first_line_in_buffer, find_line, write_to_file,
- handle_line_error, process_line_count, regexp_error, process_regexp,
- split_file):
- File line, byte, and repetition counts are now uintmax_t, not unsigned.
- (check_for_offset): Don't require a sign before the offset.
- Use xstrtoimax to do the real work.
- (extract_regexp): Remove harmful cast of size to unsigned.
- 256 -> 1<<CHAR_BIT, for clarity.
- (get_format_flags): Return at most 3, to avoid worries about overflow.
-
- (bytes_to_octal_digits): Remove.
-
- (cleanup): Don't check whether output_stream is NULL, since
- close_output_file does that for us.
-
- (new_line_control, create_new_buffer): Use "foo *p = xmalloc
- (sizeof *p);" instead of the more long-winded alternatives.
-
- (get_new_buffer): Use O(1) algorithm for resizing a buffer
- to a much larger size, instead of an O(N) algorithm.
-
- (process_regexp): Use plain NULL rather than casted 0.
-
- (make_filename): Use %u, not %d, to format unsigned file number.
-
- (new_control_record): Use xrealloc exclusively, since it handles
- NULL reliably.
-
- (extract_regexp): Change misspelled word in diagnostic.
-
- (get_format_width): Even if a minimum field width is specified,
- allow room for enough octal digits to represent the value of
- the maximum representible integer. This fixes a potential
- buffer overrun. Calculate this room at compile-time, not
- at run-time; this removes the need for bytes_to_octal_digits.
- Check for overflow; this removes a FIXME.
-
- (get_format_prec): Don't allow precision to be signed; it's
- not ANSI. Check for overflow. Remove hardcoded "11" as
- default precision; this fixes a potential buffer overrun
- on hosts with wider size_t.
-
- (get_format_conv_type): Change local variable to be of type
- unsigned char, not int; this removes a potential subscript
- violation on hosts where char is signed.
-
- (max_out): Replace "for (;*p;)" with more-standard "while (*p)".
- Allow "%%" in format. Don't overflow when
- counting lots of percents.
-
- (usage): Default sprintf format is %02u, not %d.
-
-2003-10-05 Jim Meyering <jim@meyering.net>
-
- * src/chown-core.c (change_file_owner): Remove set-but-not-used local.
-
- * src/du.c (du_files): Mark diagnostic for translation.
-
-2003-10-04 Jim Meyering <jim@meyering.net>
-
- * src/du.c (du_files): Ignore any failure of fts_close.
- Give better diagnostics for failed fts_open.
-
- * src/du.c (MAX_N_DESCRIPTORS): Remove now-unused definition.
-
- Deprecate existing use of -H (aka --si).
- * src/du.c (enum) [HUMAN_SI_OPTION]: New member.
- [long_options]: Use HUMAN_SI_OPTION, not 'H'.
- (main): Warn that the meaning of -H will soon change to be
- POSIX compliant.
-
-2003-10-03 Jim Meyering <jim@meyering.net>
-
- * src/du.c: Accept --no-dereference (-P).
-
-2003-10-02 Jim Meyering <jim@meyering.net>
-
- * tests/du/trailing-slash: Adjust for slightly different output.
-
- Rewrite du.c to use fts.
- * src/du.c: Include "fts_.h", not ftw.h.
- (opt_dereference_arguments, arg_length, suffix_length): Remove globals.
- (IS_FTW_DIR_TYPE): Remove definition.
- (IS_DIR_TYPE): Define.
- (is_symlink_to_dir): Remove now-unnecessary function.
- (process_file, du_files): Rewrite to use fts.
-
- * tests/du/inaccessible-cwd: Ensure that even when run from an
- inaccessible directory, du can still operate on accessible
- directories elsewhere.
- * tests/du/Makefile.am (TESTS): Add inaccessible-cwd.
-
- * tests/rm/deep-1: Ensure that du can process a hierarchy
- of depth 400 while using no more than 50KB of stack space.
-
-2003-10-01 Akim Demaille <akim@epita.fr>
-
- * announce-gen (print_news_deltas): New function, extracted from main.
- (main): Make `news_file' an array.
- Use '...=s' => \@var for --news and --url-directory specs.
- Before there were a couple of portability problems.
-
-2003-09-28 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_cast_of_alloca_return_value): New rule.
- (syntax-check-rules): Add it.
-
- * src/copy.c: Remove unnecessary cast of alloca, since now it's
- guaranteed to be (void *).
- * src/cp.c: Likewise.
- * src/join.c: Likewise.
- * src/ln.c: Likewise.
- * src/ls.c: Likewise.
- * src/od.c: Likewise.
- * src/sys2.h (ASSIGN_STRDUPA): Likewise.
-
-2003-09-27 Jim Meyering <jim@meyering.net>
-
- Don't exhaust virtual memory when processing large inputs.
- Fix this by removing csplit's internal free-list management;
- instead rely on malloc for that.
-
- * src/csplit.c (free_list): Remove global.
- (clear_all_line_control): Remove function.
- (get_new_buffer): Always use create_new_buffer to obtain a
- new buffer, rather than searching free_list.
- (free_buffer): Just call free.
- Reported by Nikola Milutinovic.
-
-2003-09-26 Jim Meyering <jim@meyering.net>
-
- * man/rm.x: Also list `chattr' in SEE ALSO section.
- Suggestion from Mark Hubbart.
-
-2003-09-25 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Don't invoke AC_AIX or AC_MINIX explicitly, now
- that we use gl_USE_SYSTEM_EXTENSIONS, since it AC_REQUIREs them.
-
- * Use autoconf-2.57d. Regenerate dependent files.
-
-2003-09-24 Jim Meyering <jim@meyering.net>
-
- Minor efficiency tweak.
- * src/ln.c (PATH_BASENAME_CONCAT): Use memcpy rather than strcpy.
- (do_link): Likewise.
-
-2003-09-23 Jim Meyering <jim@meyering.net>
-
- * src/paste.c (paste_serial): Save errno after input error,
- to report proper errno value.
- Based on a patch from Paul Eggert.
-
- * src/tee.c (tee): Adjust fwrite arguments so that the return
- value is the number of bytes written.
-
-2003-09-16 Paul Eggert <eggert@twinsun.com>
-
- Don't assume ferror sets errno. Bug reported by Bruno Haible.
-
- * src/comm.c (compare_files): Save errno after input error,
- to report proper errno value.
- * src/fold.c (fold_file): Likewise.
- * src/od.c (check_and_close, skip, read_char, read_block): Likewise.
- * src/unexpand.c (unexpand): Likewise.
-
- * src/csplit.c (close_output_file): Don't report bogus errno value
- after ferror discovers an output error. We don't know the proper
- errno value, since it might have been caused by any of a whole
- bunch of calls, and it might have been trashed in the meantime.
- Fixing this problem will require much more extensive changes;
- in the meantime just say "write error".
- * src/od.c (check_and_close, dump, dump_strings): Likewise.
- * src/uniq.c (check_file): Likewise.
-
- * src/join.c (get_line): Report error right away if I/O fails,
- so that the proper errno value is used.
- * src/tac.c (tac_seekable, tac_file, save_stdin): Likewise.
- * src/tee.c (tee): Likewise.
- * src/uniq.c (check_file): Likewise.
-
- * src/od.c (skip): If a read fails, don't retry it later, so
- that we report the proper errno.
-
- * src/tac.c (tac_mem): Don't return a value; nobody uses it.
-
- * src/tee.c (tee): Once a write failure has occurred, don't bother
- writing anything more to that stream.
-
- * src/uniq.c (check_file): Check for ferror (stdout) even if
- ostream == stdout.
-
- * src/yes.c (UNROLL): Remove.
- (main): Exit immediately when write failure is detected.
- Simplify code by assigning to argv when argc == 1.
-
-2003-09-21 Paul Eggert <eggert@twinsun.com>
-
- * src/ptx.c: Switch encoding from Latin-1 to UTF-8.
- (WRITTEN_BY): Change "Franc,ois" (actually using
- c-with-cedilla in Latin-1) to "F.", so that it's ASCII, as
- xgettext requires.
-
-2003-09-19 Jim Meyering <jim@meyering.net>
-
- `du -D symlink-to-dir' would mistakenly omit the slash in
- lines like this: 24 symlink-to-dir/subdir
- * src/du.c (process_file): Fix offset calculation.
- Reported by Jeff Sheinberg as Debian bug #211591;
- http://bugs.debian.org/205251
-
- * tests/du/deref-args: New file/test for the above.
- * tests/du/Makefile.am (TESTS): Add deref-args.
-
- * src/du.c (process_file): Remove useless disjunct.
-
- * src/sys2.h (case_GETOPT_VERSION_CHAR): Rename parameter, Authors,
- to Written_by.
- * nearly all src/*.c files (WRITTEN_BY): Rename from AUTHORS.
- Begin each WRITTEN_BY string with `Written by ' and end it with `.'.
- Mark each WRITTEN_BY string as translatable.
-
- * basename.c, cat.c, chroot.c, cksum.c, comm.c, cp.c, csplit.c, cut.c:
- * dd.c, df.c, dirname.c, du.c, echo.c, env.c, expr.c, factor.c, head.c:
- * hostid.c, hostname.c, id.c, link.c, ln.c, logname.c, ls.c, md5sum.c:
- * mv.c, nice.c, nl.c, nohup.c, paste.c, pathchk.c, pinky.c, pr.c:
- * printenv.c, printf.c, pwd.c, rm.c, setuidgid.c, sleep.c, sort.c:
- * split.c, stty.c, sum.c, sync.c, tac.c, tail.c, tee.c, test.c:
- * touch.c, tsort.c, uniq.c, unlink.c, uptime.c, users.c, wc.c:
- * who.c, whoami.c, yes.c: Revert yesterday's changes.
- Instead, a subsequent change will embed `Written by ' in
- each string along with the author names.
-
- * src/true.c: Revert yesterday's changes.
- * src/sys2.h: Likewise.
-
-2003-09-18 Jim Meyering <jim@meyering.net>
-
- * basename.c, cat.c, chroot.c, cksum.c, comm.c, cp.c, csplit.c, cut.c:
- * dd.c, df.c, dirname.c, du.c, echo.c, env.c, expr.c, factor.c, head.c:
- * hostid.c, hostname.c, id.c, link.c, ln.c, logname.c, ls.c, md5sum.c:
- * mv.c, nice.c, nl.c, nohup.c, paste.c, pathchk.c, pinky.c, pr.c:
- * printenv.c, printf.c, pwd.c, rm.c, setuidgid.c, sleep.c, sort.c:
- * split.c, stty.c, sum.c, sync.c, tac.c, tail.c, tee.c, test.c:
- * touch.c, tsort.c, uniq.c, unlink.c, uptime.c, users.c, wc.c:
- * who.c, whoami.c, yes.c: Update AUTHORS definition to be a
- comma-separated list of strings and/or update the call to
- parse_long_options so that `AUTHORS, NULL' are the last parameters.
- * src/true.c (main): Append NULL to version_etc argument list.
- * src/sys2.h (case_GETOPT_VERSION_CHAR): Likewise.
-
- * src/sort.c (numcompare): Rename local, logb, to log_b to avoid
- shadowing the math function name. Also rename loga to log_a.
-
-2003-09-14 Jim Meyering <jim@meyering.net>
-
- * src/factor.c (print_factors): Give a separate diagnostic
- for numbers that are too large, but otherwise valid.
- Reported by Dániel Varga.
-
-2003-09-10 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.7.7. Regenerate dependent files.
-
- * tests/Makefile.am (all_programs): Use ../src/tr -s ' ' '\n' in place
- of `fmt -1'. Using the just-built tr is a little cleaner.
- Christian Krackowizer reported that HPUX 10.20 doesn't have fmt.
- * man/Makefile.am (programs, check-x-vs-1): Likewise.
-
-2003-09-09 Jim Meyering <jim@meyering.net>
-
- * src/copy.c: Alphabetize includes.
- Remove duplicate inclusion of "same.h".
-
-2003-09-08 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (GZIP_ENV): Remove --rsyncable.
- Didn't give enough of a benefit, mainly because it's not yet
- in wide enough use.
-
- * Version 5.0.91.
-
- * man/Makefile.am (programs): Use ../src, not $(srcdir)/../src.
- (check-programs-vs-x): Fail if $(programs) is empty.
-
- * src/remove.c: Add a comment.
-
-2003-09-07 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (D_INO, ENABLE_CYCLE_CHECK) [D_INO_IN_DIRENT]:
- Don't define. These symbols are no longer used.
-
- * tests/misc/tty-eof: Write ^D as \cD.
- Complete the change of 2003-08-02.
-
- * Makefile.maint (po-check): Use cvsu, so that a temporary source
- file in lib/ or src/ doesn't induce an unwarranted failure.
- Add a kludge to filter out the sole generated source file that
- also has translatable messages: src/false.c.
-
-2003-09-06 Jim Meyering <jim@meyering.net>
-
- * src/tail.c (enum): Add ALLOW_MISSING_OPTION.
- (parse_options): Give a diagnostic for (but still accept) the
- deprecated --allow-missing option.
-
-2003-09-04 Paul Eggert <eggert@twinsun.com>
-
- Don't ignore -S if input is a pipe. Bug report by Michael McFarland in
- <http://mail.gnu.org/archive/html/bug-coreutils/2003-09/msg00008.html>.
-
- * src/sort.c (sort_buffer_size): Omit SIZE_BOUND arg. Compute the
- size_bound ourselves. if an input file is a pipe and the user
- specified a size, use that size instead of trying to guess the
- pipe size. This has the beneficial side effect of avoiding the
- overhead of default_sort_size in that case. All callers changed.
- (sort): Remove static var size; now done by sort_buffer_size.
-
-2003-09-05 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.7.6b and autoconf-2.57b. Regenerate dependent files.
-
- * tests/tail-2/tail-n0f: Wait .5 seconds for backgrounded process
- to start, rather than just .1. Upon failure, print unexpected state.
-
-2003-09-04 Paul Eggert <eggert@twinsun.com>
-
- * src/head.c (elide_tail_lines_pipe): Don't assign 0 or
- SAFE_READ_ERROR to tmp->nbytes.
- * src/tail.c (pipe_lines, pipe_bytes): Likewise.
-
- * src/head.c (struct linebuffer): Change nbytes and nlines
- from unsigned int to size_t. unsigned int is safe (after the
- 2003-09-03 patch) but size_t is cleaner.
- * src/tail.c (struct linebuffer, struct charbuffer): Likewise.
- (pipe_bytes): Likewise for local variable 'i', which was 'int'.
-
- Standardize on BUFSIZ as opposed to other macro names and values.
- * src/head.c (BUFSIZE): Remove. All uses changed to BUFSIZ.
- * src/tail.c (BUFSIZ) [!defined BUFSIZ]: Remove.
- stdio.h has always defined it,
- and other code already assumes it's defined.
- * src/tr.c (BUFSIZ) [!defined BUFSIZ]: Likewise.
- (IO_BUF_SIZE): Remove; replace all uses with sizeof io_buf.
- (io_buf): IO_BUF_SIZE -> BUFSIZ.
-
-2003-09-04 Paul Eggert <eggert@twinsun.com>
-
- * src/seq.c (step): Default to 1.
- (print_numbers): Allow the output to be empty.
- (main): The default step is 1, even if LAST < FIRST;
- as per documentation.
- * tests/seq/basic (onearg-2): Output should be empty.
-
-2003-09-05 Jim Meyering <jim@meyering.net>
-
- * Makefile.cfg (wget_files): Temporarily disable, until master
- versions are restored to ftp.gnu.org.
-
- * configure.ac (AM_INIT_AUTOMAKE): Specify automake-1.7.6.
-
- Make seq's --width (-w) option work properly even when the
- endpoint requiring the larger width is negative and smaller than
- the other endpoint.
- * src/seq.c (get_width_format): Include `-' in the set of bytes
- allowed in a `simple' number (no decimal point, no exponent).
- Reported by Patrick Mauritz.
-
-2003-09-02 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: sort -t '\0' now uses a NUL tab.
- sort option order no longer matters, unless POSIX requires it.
- * src/sort.c (usage): Say "blanks" instead of "whitespace",
- Similar fixes for many comments.
- (TAB_DEFAULT): New constant, so that we can support NUL as
- the field separator.
- (tab): Now int, not char. Initialize to TAB_DEFAULT.
- (specify_sort_size): If multiple sizes are specified, use the largest.
- (begfield, limfield): Support NUL tab char.
- (set_ordering): Do not let -i override -d.
- (main): Report an error if incompatible -o or -t options are given.
- Report an error for "-t ''". Allow "-t '\0'" to specify a NUL tab.
-
-2003-09-05 Jim Meyering <jim@meyering.net>
-
- * tests/sort/Test.pm [o2, nul-tab]: New tests for the above.
-
-2003-09-03 Andreas Schwab <schwab@suse.de>
-
- Bug report and patch here:
- <http://mail.gnu.org/archive/html/bug-coreutils/2003-09/msg00009.html>
- * src/tail.c (pipe_lines): Don't truncate return value from safe_read.
- * src/head.c (elide_tail_lines_pipe): Likewise.
-
-2003-09-03 Jim Meyering <jim@meyering.net>
-
- * src/du.c (AUTHORS): Remove Larry McVoy's name, since the relatively
- small amount of code from him was first moved to lib/human.c, and was
- subsequently rewritten entirely.
- * src/df.c (AUTHORS): Likewise.
-
-2003-08-22 Lawrence Teo <lcteo@uncc.edu>
-
- * src/md5sum.c (split_3): Accept the BSD format for generic
- message digest modes. Currently works with BSD's MD5 and SHA1
- formats since these are the two algorithms presently used in
- coreutils. Updated comments to reflect this change.
- (bsd_split_3): Updated comments.
-
- * tests/md5sum/basic-1: New test to make sure that
- `md5sum --check' doesn't accept the BSD SHA1 format (adapted
- from `check-bsd' test in tests/sha1sum/basic-1).
-
- * tests/sha1sum/basic-1 (check-bsd2, check-bsd3): New tests for
- --check exit status and BSD SHA1 format (adapted from tests
- in tests/md5sum/basic-1).
-
-2003-08-30 Jim Meyering <jim@meyering.net>
-
- * src/ln.c (do_link): Use SAME_INODE rather than open-coding it.
-
- When source and destination arguments refer to the same file, reside
- on a partition (e.g. VFAT) on which distinct names may refer to the
- same directory entry (often due to variations in case), and when the
- link count for the file is 1, mv no longer unlinks the file. Instead,
- it gives the expected diagnostic that the source and destination are
- the same. WARNING: this is an incomplete fix. If the file happens
- to have a link count of 2 or greater, such an erroneous mv command
- will still unlink it.
- Although that is not possible on vfat or umsdos, it is possible on
- other file system types, e.g., ntfs, and hpfs.
- * src/copy.c (same_file_ok): Invoke same_name (which might still
- return false for names that refer to the same directory entry)
- only if the link count is 2 or more.
- * tests/mv/vfat: Show how to demonstrate the above problem.
- This test is not run.
- * tests/mv/Makefile.am (EXTRA_DIST): Add vfat.
-
-2003-08-27 Jim Meyering <jim@meyering.net>
-
- * src/who.c: Change meaning of -l from --lookup to --login, per POSIX.
- who's -l option has been eliciting an unconditional warning about
- this impending change since sh-utils-2.0.12 (April 2002).
-
- * src/paste.c (paste_parallel): Don't output `EOF' (aka -1) as a `char'.
- This would happen for nonempty files not ending with a newline.
- Reported by Dan Jacobson.
- * tests/misc/paste-no-nl: New file. Test for above-fixed bug.
- * tests/misc/Makefile.am (TESTS): Add paste-no-nl.
-
- * src/stat.c (print_it): Avoid buffer overrun that would
- occur when the user-specified format string ends with `%'.
- Patch by Tommi Kyntola.
- * tests/misc/stat-fmt: New file. Test for above-fixed bug.
- * tests/misc/Makefile.am (TESTS): Add stat-fmt.
-
-2003-08-26 Jim Meyering <jim@meyering.net>
-
- Apply changes from bison.
- * GNUmakefile (SHELL): Define to `sh', if necessary.
- Add copyright.
- * Makefile.maint (WGETFLAGS): Define to `-C off'.
- Update all uses of $(WGET).
-
-2003-08-22 Akim Demaille <akim@epita.fr>
-
- * Makefile.cfg (local-checks-to-skip): New.
- * Makefile.maint (local-check): Rename as...
- (local-checks-available): this.
- (local-check): New.
-
-2003-08-26 Akim Demaille <akim@epita.fr>
-
- * announce-gen (print_changelog_deltas): Neutralize "<#" as
- "<\#" to avoid magic from Gnus when posting parts of this script.
-
-2003-08-25 Jim Meyering <jim@meyering.net>
-
- * src/stat.c (main): Warn about use of deprecated `-l' option.
-
-2003-08-22 Jim Meyering <jim@meyering.net>
-
- * src/stat.c (do_stat): For link count at end of line, use %h format,
- instead of %-5h. The latter would make stat emit trailing spaces.
- Reported by Dan Jacobson.
-
-2003-08-20 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (EXTRA_DIST): Add .x-sc_space_tab .x-sc_sun_os_names
-
-2003-08-19 Jim Meyering <jim@meyering.net>
-
- * src/system.h: Include stdlib.h unconditionally,
- as we're now assuming that part of hosted C89.
-
-2003-08-18 Jim Meyering <jim@meyering.net>
-
- * src/sys2.h (textdomain, bindtextdomain) [! ENABLE_NLS]: Define away,
- to avoid warnings from gcc.
-
-2003-08-17 Jim Meyering <jim@meyering.net>
-
- Avoid unnecessary and sometimes time-consuming hostname lookups.
- * src/who.c (print_user): Use strchr, not strrchr.
- * src/pinky.c (print_entry): Likewise.
- Patch by Michael Stone.
- This fixes a typo I introduced in who-users.c on 1996-02-23.
-
- * Makefile.maint (makefile-check): Add 0-9 to the range of characters
- disallowed between `@...@'.
-
-2003-08-16 Paul Eggert <eggert@twinsun.com>
-
- * configure.ac (fu_cv_sys_truncating_statfs): Remove; now
- done by gnulib .m4 files.
- (jm_DUMMY_1): Require gl_READUTMP, not jm_PREREQ_READUTMP.
- * src/sys2.h (strtoull): Remove unused declaration.
-
-2003-08-16 Jim Meyering <jim@meyering.net>
-
- * man/Makefile.am (.x.1): Ensure that generated PROGRAM.1 files
- are read-only.
-
- * src/tail.c (tail_lines): Fix a potential (but very hard to exercise)
- race condition bug. The bug would be triggered when tailing a file
- with file pointer not at beginning of file, and where the file was
- truncated to have a length of less than the initial offset at just
- the right moment (between the two lseek calls in this function).
-
- An invalid initial value for *read_pos would result in
- `tail -n0 -f FILE' and `tail -c0 -f FILE' doing what amounted to a
- busy-wait rather than sleeping between iterations. The bug manifests
- itself only when tailing regular files that are initially nonempty.
- * src/tail.c (tail_bytes): Set *read_pos to new file offset after
- each xlseek call.
- (tail_lines): Likewise, after lseek calls.
- Reported by Nick Estes. See http://bugs.debian.org/205251 for details.
- * tests/tail-2/tail-n0f: New file. Test for above fix.
- * tests/tail-2/Makefile.am (TESTS): Add tail-n0f.
-
-2003-08-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_space_tab): Use exclusion list in separate file.
- (sc_sun_os_names): Likewise.
- * .x-sc_space_tab, .x-sc_sun_os_names: New files.
-
- * man/help2man: Remove some SPACEs before TAB.
-
-2003-08-14 Paul Eggert <eggert@twinsun.com>
-
- * Makefile.maint (LC_ALL): Set to C.
- * man/Makefile.am (ASSORT): New var.
- (check-x-vs-1, programs): Use it.
- * src/Makefile.am (ASSORT, check-README, ../AUTHORS): Likewise.
- * tests/Makefile.am (ASSORT, all_programs): Likewise.
-
-2003-08-11 Jim Meyering <jim@meyering.net>
-
- fold -s -wN would infloop for N < 8 with TABs in the input.
- E.g., this would not terminate: printf 'a\tb' | fold -w2 -s
- * src/fold.c (fold_file): Move contents of `else'-block
- out of conditional so it's used also for --spaces (-s).
- * tests/misc/fold: Test for the above fix.
- * tests/misc/Makefile.am (TESTS): Add fold.
-
-2003-08-10 Jim Meyering <jim@meyering.net>
-
- * src/nice.c [!NICE_PRIORITY]: Include <sys/resource.h> after
- system.h so the types from time.h and sys/time.h are available.
- It appears that this is necessary for OpenBSD, NetBSD, and
- Darwin 6.5 (MacOS 10.2.5). Reported by Nelson Beebe.
-
-2003-08-06 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: Add support for setting file timestamps to microsecond
- resolution, on hosts that support this.
- * src/copy.c, src/cp.c, src/install.c, src/touch.c: Include utimens.h.
- * src/copy.c (copy_internal):
- Set file timestamps with utimens, not utime.
- * src/cp.c (re_protect): Likewise.
- * src/install.c (change_timestamps): Likewise.
- * src/touch.c (newtime, touch, main): Likewise.
-
-2003-08-09 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_sun_os_names): New rule based on a regexp
- from Paul Eggert.
- (syntax-check-rules): Add it.
-
- * src/tail.c (main): Tweak Solaris OS version number in comment.
- * src/wc.c (wc): Likewise
- * tests/tail-2/fflush: Likewise.
-
- * src/tail.c: Add new undocumented option, --presume-input-pipe.
- (pipe_lines): Use memchr to skip lines, rather than an explicit loop.
-
-2003-08-08 Paul Eggert <eggert@twinsun.com>
-
- Use new gnulib 'extensions' module.
- * configure.ac: Invoke gl_USE_SYSTEM_EXTENSIONS instead of
- AC_GNU_SOURCE.
-
-2003-08-08 Paul Eggert <eggert@twinsun.com>
-
- * tests/du/basic: Ensure that a/b/F has at least 65 bytes too.
-
-2003-08-09 Jim Meyering <jim@meyering.net>
-
- * tests/misc/split-fail: Reflect that `split -a 0' is now accepted.
- For tests of obsolete behavior, don't presume that unsetting
- _POSIX2_VERSION is equivalent to _POSIX2_VERSION=199209.
-
-2003-08-07 Paul Eggert <eggert@twinsun.com>
-
- * doc/coreutils.texi (split invocation):
- Add -d or --numeric-suffixes option to 'split'.
- From a suggestion by Jesse Kornblum.
- * src/split.c (suffix_alphabet): New var.
- (longopts, usage, next_file_name, main): Support -d.
- (next_file_name, main): Allow -a0, as POSIX requires.
- (next_file_name): Don't assume ASCII-like encoding;
- 'a' through 'z' are not contiguous in EBCDIC.
-
-2003-08-05 Paul Eggert <eggert@twinsun.com>
-
- Merge getline from gnulib.
- * lib/getline.h, lib/getline.c, m4/getline.m4: Merge from gnulib.
- * lib/getndelim2.h, lib/getndelim2.c, m4/getndelim2.m4, m4/ssize_t.m4:
- New files, from gnulib.
- * lib/getdelim2.c, lib/getdelim2.h: Remove.
- * lib/Makefile.am (libfetish_a_SOURCES): Change getdelim2.c and
- getdelim2.h to getndelim2.c and getndelim2.h.
- * m4/jm-macros.m4 (jm_MACROS): Use gl_GETNDELIM2 rather than
- checking for getdelim.
- (jm_CHECK_ALL_TYPES): Use gt_TYPE_SSIZE_T for ssize_t rather
- than rolling our own.
- * src/cut.c: Include getndelim2.h rather than getdelim2.h.
- (cut_fields): Invoke getndelim2 rather than getdelim2.
-
-2003-08-04 Jim Meyering <jim@meyering.net>
-
- * src/sort.c (main): Use unsigned int instead of int for `nsigs'
- and for the indices to iterate through nsigs.
-
-2003-08-02 Paul Eggert <eggert@twinsun.com>
-
- * src/sort.c: Minor code cleanups, mostly to use more accurate
- types and to remove unnecessary casts.
- (min, max): Remove. All uses changed to MIN and MAX.
- (hard_lc_collate, hard_LC_TIME, struct buffer.eof, struct
- keyfield.skipsblanks, struct keyfield.skipeblanks, struct
- keyfield.numeric, struct keyfield.general_numeric, struct
- keyfield.month, struct keyfield.reverse, reverse, unique,
- have_read_stdin): Now bool, not int. All uses changed.
- (eolchar): Now char, not int.
- (struct keyfield.ignore): Now bool const *, not int *.
- (struct keyfield.translate): Now char const *, not char *.
- (struct month.name): Likewise.
- (blanks, nonprinting, nondictionary): Now bool[], not int[].
- (cleanup, inittables, keycompare, check, mergefps, first_same_file,
- check, sort, main): Use const * pointers when possible.
- (month_cmp): Rewrite to avoid casts.
- (inittables): Initialize tables unconditionally, to avoid branches.
- (fillbuf): Return bool, not int. All uses changed.
- (fillbuf, keycompare, new_key, main):
- Use SIZE_MAX rather than (size_t) -1.
- (trailing_blanks): Renamed from trim_trailing_blanks.
- Return the number of blanks to trim. All uses changed.
- (getmonth): Use trailing_blanks rather than open code.
- (keycompare): Do not cast char * to unsigned char *; not needed.
- CMP_WITH_IGNORE converts args to UCHAR, so no need to convert it
- ourselves.
- (compare, main): Use | rather than || to avoid jumps.
- Replace "diff = NONZERO (alen)" with "diff = 1", since alen must
- be nonzero there.
- (check, first_same_file, sort, main):
- Use bool instead of int local vars when possible.
- (check): Merge the old 'checkfp' and 'check' into a single function,
- that returns a boolean (true if the file was ordered).
- All uses changed.
- (main): Use int instead of unsigned for iterating through nsigs.
- Rename local var "posix_pedantic" to "posixly_correct".
-
-2003-08-02 Jim Meyering <jim@meyering.net>
-
- * src/nice.c [!NICE_PRIORITY]: Include <time.h> before <sys/resource.h>
- to avoid compilation error on Ultrix. Reported by Christian Krackowizer.
-
- * src/cut.c (cut_fields): Don't read again after encountering an
- initial EOF. E.g., `cut -f2' would do so.
- * tests/misc/tty-eof: Add a test for the above fix.
-
- * src/sort.c (sortlines): Add description and references.
- From Paul Eggert.
-
- * tests/Makefile.am (TESTS_ENVIRONMENT): Set PATH so that
- the tests in help-version will use the just-built binaries.
- Reported by Christian Krackowizer.
-
-2003-07-31 Paul Eggert <eggert@twinsun.com>
-
- * NEWS: Add --rfc-2822 option to GNU date.
- * doc/coreutils.texi (Time directives, Options for date, Examples
- of date): Likewise.
- * src/date.c (long_options, usage, main): Likewise.
- * doc/getdate.texi (General date syntax): Likewise.
- * doc/coreutils.texi (Options for date): Fix a typo in format:
- it's now %d not %_d. Add URLs.
-
-2003-08-01 Jim Meyering <jim@meyering.net>
-
- * tests/shred/remove: Ensure that $? is 0 for the final `exit 0'.
- Otherwise, with at least the /bin/sh from HPUX 10.20,
- the trap code would end up converting that to exit 1 and thus an
- unexpected test failure. Reported by Christian Krackowizer.
-
-2003-07-31 Paul Eggert <eggert@twinsun.com>
-
- * src/ptx.c: Do not include bumpalloc.h.
- (WORD_TABLE): New member alloc.
- (ALLOC_NEW_WORD): Remove.
- (occurs_alloc): New var.
- (digest_word_file, find_occurs_in_text): Check for arithmetic
- overflow when computing table size. Use xrealloc rather than
- bumpalloc primitives.
-
-2003-07-29 Jim Meyering <jim@meyering.net>
-
- * Version 5.0.90.
-
- * README: When running tests as root, suggest using
- sudo with NON_ROOT_USERNAME=$USER.
-
- * tests/Makefile.am (all_programs): Makefile is in ../src, not
- $(srcdir)/../src.
-
-2003-07-28 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (GZIP_ENV): Try Debian/gzip's new --rsyncable option.
-
-2003-07-28 Paul Eggert <eggert@twinsun.com>
-
- * lib/stdbool.hin (_Bool): Make it signed char, instead of
- an enum type, so that it's guaranteed to promote to int.
- * src/sort.c (sortlines_temp): Undo previous change.
-
-2003-07-28 Jim Meyering <jim@meyering.net>
-
- * src/sort.c (sortlines_temp): Declare local `swap' to be `int', not
- `bool'. Otherwise, at least one buggy compiler (alpha gcc-2.95.4)
- would cause lines[-1 - swap] (with swap = false) to evaluate to
- lines[4294967295].
-
-2003-07-27 Jim Meyering <jim@meyering.net>
-
- * tests/priv-check (my_uid): Use `!', not `^' in case pattern `[!0-9]',
- since /bin/sh of at least NetBSD 1.6 and OpenBSD 3.2 don't accept `^'.
-
- * src/remove.c (prompt) [! recursive]: Don't prompt about unwritable
- directories, as required by POSIX. Reported by Karl Berry.
- * tests/rm/dir-no-w: New file. Test for the above fix.
- * tests/rm/Makefile.am (TESTS): Add dir-no-w.
-
- * tests/mk-script: Emit `$xx', not its expansion.
-
-2003-07-27 Paul Eggert <eggert@twinsun.com>
-
- This change was inspired by a similar proposal by Stepan Kasal.
- * src/sort.c (mergelines, sortlines_temp): New functions.
- (sortlines): Use them, to reduce the number of times that
- we need to copy 'struct line' values. This improved CPU
- performance by about 30% on one 18 MB test.
- (sort): Don't invoke sortlines unless we have 2 or more lines.
-
-2003-07-26 Stepan Kasal <kasal@ucw.cz>
-
- * src/sort.c (sort): Don't require two `struct line's per text line,
- the new sort algorithm requires just 1.5.
-
-2003-07-27 Jim Meyering <jim@meyering.net>
-
- * src/pathchk.c (validate_path): Use %lu, not %ld.
- From Paul Eggert.
- * src/cut.c (is_printable_field): Simplify bit arithmetic.
- From Paul Eggert.
- * src/ls.c (sort_files): Put `volatile' in the right place.
- From Paul Eggert.
-
-2003-07-26 Jim Meyering <jim@meyering.net>
-
- Use only one bit per field/offset in array, not one `int'.
- * src/cut.c (printable_field): Change type to `unsigned char'.
- (mark_printable_field, is_printable_field): New functions.
- Use them in place of all direct accesses of `printable_field'.
-
- * src/expand.c (parse_tabstops): Detect overflow properly.
- * src/cut.c (set_fields): Likewise.
-
- * src/rm.c: Include "dirname.h".
- (usage): Use base_name (program_name) in body of --help output.
- This lets me...
- * man/Makefile.am (.x.1): ...back out the kludge of 2003-07-22.
- Idea from Brendan O'Dea, who suggested using
- `program_name = basename (argv[0]);' everywhere --
- can't do that, but using base_name works just fine here.
-
- * src/Makefile.am (AM_INSTALLCHECK_STD_OPTIONS_EXEMPT): Exempt test.
-
-2003-07-24 Paul Eggert <eggert@twinsun.com>
-
- Fix some POSIX-compliance problems with 'test'. This makes
- 'test' more compatible with Bash.
-
- * NEWS, doc/coreutils.texi: Document the following.
- * src/test.c: Include exitfail.h.
- (TEST_FAILURE): New constant, used for exit status if 'test' fails.
- (test-syntax_error): Use it.
- (binary_operator): Now takes bool arg specifying whether left operand
- is -l ARG, so that caller determines this rather than us.
- All uses changed.
- (term): Use posixtest to evaluate parenthesized subexpressions.
- (unary_operator, one_argument): Remove support for -t without operand.
- (one_argument): Take argument from argv[pos].
- (one_argument, two_arguments, three_arguments): Advance pos.
- All callers changed.
- (three_arguments): Look for binary ops before "!". Then look
- for parenthesized one_argument expressions, instead of trusting
- expr () to do the right thing.
- (posixtest): Now takes number of args. All callers changed.
- Treat "( A B )" like "A B".
- (main): Set exit_failure to TEST_FAILURE. Don't depend on
- POSIXLY_CORRECT, as we now conform to POSIX by default.
- (main) [!LBRACKET]: Do not recognize "--help" or "--verbose" unless.
- * tests/test/Test.pm (test_vector): Add several tests to check
- the above. Syntax errors now exit with status 2, not 1.
- * man/Makefile.am (mapped_name): Use `../src/[' binary to create test.1.
-
-2003-07-26 Jim Meyering <jim@meyering.net>
-
- * tests/help-version: Adjust for above change in test behavior:
- `[' exits with 2, not 1, and test doesn't accept --help or --version.
-
- * Makefile.maint (ME): Don't use trick suggested in Make manual.
- It doesn't work for make-3.79.1. Reported by Christian Krackowizer.
-
- * Makefile.maint (sc_system_h_headers): Another syntax check.
- (syntax-check-rules): Add it to the list.
-
- * src/pathchk.c (validate_path): Cast strlen value to `unsigned long'
- so it matches `%ld' format even on 32-bit systems.
-
- * src/fmt.c (flush_paragraph): Cast field width to `int' to
- avoid warning on 64-bit systems.
-
- * src/ls.c (sort_files): Make `func' volatile, so it can't be
- clobbered by a `longjmp' into this function.
-
-2003-07-25 Jim Meyering <jim@meyering.net>
-
- * src/pathchk.c (validate_path): Use %ld format (not %d) for size_t
- value.
-
- * tests/misc/split-fail: Disable the --line-bytes=$_4gb test,
- because it'd evoke spurious failure on 64-bit systems.
-
-2003-07-24 Jim Meyering <jim@meyering.net>
-
- * src/dd.c (usage): Document the fact that SIGUSR1 makes dd
- output its current record counts. Reported by Jurriaan.
-
- * tests/wc/Test.pm (test_vector): Disable the `PIPE' tests when running
- `wc' with no options. This goes along with the change of 2003-07-20.
-
-2003-07-23 Jim Meyering <jim@meyering.net>
-
- Don't include headers already included by system.h:
- * src/tr.c: Don't include errno.h.
- * src/true.c: Don't include version-etc.h.
- * src/test.c: Don't include limits.h or error.h.
- * src/stat.c: Don't include unistd.h or time.h.
- * src/readlink.c: Don't include stdlib.h, unistd.h, or limits.h.
- * src/pr.c: Don't include time.h.
- * src/pathchk.c: Don't include errno.h.
- * src/nice.c: Don't include sys/time.h.
- * src/ls.c: Don't include stdlib.h.
-
- * basename.c, cat.c, chroot.c, cksum.c, comm.c, csplit.c, cut.c, date.c:
- * dd.c, dirname.c, echo.c, env.c, expand.c, expr.c, factor.c, fmt.c:
- * fold.c, head.c, hostid.c, hostname.c, id.c, join.c, kill.c, logname.c:
- * md5sum.c, nice.c, nl.c, nohup.c, od.c, paste.c, pathchk.c, pinky.c:
- * pr.c, printenv.c, printf.c, ptx.c, pwd.c, seq.c, setuidgid.c, shred.c:
- * sleep.c, sort.c, split.c, stat.c, stty.c, su.c, sum.c, tac.c, tail.c:
- * tee.c, test.c, tr.c, true.c, tsort.c, tty.c, uname.c, unexpand.c:
- * uniq.c, uptime.c, users.c, wc.c, who.c, whoami.c, yes.c:
- Don't include closeout.h.
-
- * tests/rm/fail-2eperm: Add a check for whether $NON_ROOT_USERNAME
- can access the required version of rm.
- * tests/rm/Makefile.am (TESTS_ENVIRONMENT): Define PACKAGE_VERSION.
-
- * tests/cut/Test.pm (out-delim3a): New test.
-
- * man/help2man: Update to version 1.33.
-
- * src/expand.c (parse_tabstops): Detect overflow in tabstop sizes.
-
- * src/dircolors.c: Include xstrndup.h.
- (xstrndup): Remove function, now that it's been factored out into
- it's own file.
-
-2003-07-22 Paul Eggert <eggert@twinsun.com>
-
- * src/wc.c (wc): Fix typo in computation of file from file_x,
- which caused the former to be used uninitialized if file_x was
- nonzero.
-
-2003-07-22 Jim Meyering <jim@meyering.net>
-
- * src/cut.c (set_fields): Use xcalloc in place of xmalloc+memset.
-
- * man/Makefile.am (.x.1): Substitute 's,$t/$*,$*,' on output of
- help2man, to avoid having `rm.td/rm' appear in rm.1. Reported by
- Thomas Luzat. See http://bugs.debian.org/202413 for details.
-
- * src/cut.c (main) [lint]: Initialize spec_list_string to avoid warning.
-
- * src/hostid.c: Don't include <unistd.h>. system.h already does that.
-
- * src/cut.c (set_fields): Mark all selected indices before trying to
- determine range endpoints.
- * tests/cut/Test.pm: New test for the above fix.
-
- Begin to address this comment: What if someone wants to
- extract the 1,000,000-th field of some huge input file?
- The first step is to rearrange things so that the values
- in the printable_field array are all 0/1 rather than 0/1/2.
- * src/cut.c (RANGE_START_SENTINEL): Remove.
- Store range-start indices in a hash table, rather than
- overloading the `printable_field' array.
- (range_start_ht): New global.
- (hash_int, hash_compare_ints, is_range_start_index): New functions.
- (print_kth): Use is_range_start_index; don't test printable_field.
- (set_fields): Detect overflow.
- (set_fields): Insert each range-start index into range_start_ht.
- (main): Call set_fields only once, and only after
- output_delimiter_specified and (if required) range_start_ht have
- been defined.
-
-2003-07-20 Paul Eggert <eggert@twinsun.com>
-
- * src/wc.c (get_input_fstatus): Fix typo: `stat' was being
- invoked with a null pointer when there were no file arguments.
-
-2003-07-20 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (sc_changelog): Add another nit-picky check.
-
- * src/wc.c (write_counts): Add a comment.
- (wc): Rename `file' parameter.
- Set new local, `file', to be the file name, or (when it's NULL)
- _("standard output") so that all uses of `file' use the proper value.
- Use STREQ, not strcmp.
-
-2003-07-20 Paul Eggert <eggert@twinsun.com>
-
- wc count field widths now are heuristically adjusted depending
- on the input size, if known. If only one count is printed, it
- is guaranteed to be printed without leading spaces.
-
- Previously, wc did not align the count fields if
- POSIXLY_CORRECT was set, but POSIX did not actually require
- this undesirable behavior, so it has been removed.
-
- * NEWS: Document this.
- * doc/coreutils.texi (wc invocation): Likewise.
-
- * src/wc.c (number_width): New var.
- (posixly_correct): Remove.
- (struct fstatus): New struct.
- (write_counts): Output fields of width number_width.
- Do not worry about POSIXLY_CORRECT.
- Use null file, not empty-string file, to denote stdin,
- since "" is a valid file name on some hosts.
- (wc, wc_file): New arg fstatus. Use it to avoid invoking fstat
- if possible.
- (wc): Avoid problems if end_pos - current_pos overflows.
- Do not print odd message if stdin has a read error.
- (get_input_fstatus, compute_number_width): New functions.
- (main): Use them to implement the new behavior.
- Ignore POSIXLY_CORRECT.
-
- * tests/wc/Test.pm: Adjust to the new output widths.
-
-2003-07-19 Jim Meyering <jim@meyering.net>
-
- * tests/rm/fail-eperm: Don't create temporary directory --
- we don't use it.
-
- * tests/shred/remove: Don't open-code test for UID != 0.
- Use priv-check's require-non-root instead.
- Update to use newer framework.
-
- * tests/help-version (expected_failure_status_expr): Record that
- expr exits with status of 3 for e.g., a write error.
-
- * tests/priv-check: Use `id -u' to see if we're running as root,
- rather than trying go write to an write-protected file.
- When running as root, ensure $NON_ROOT_USERNAME is valid.
- When running as root with `require-non-root', ensure that `.'
- is writable by $NON_ROOT_USERNAME, then reinvoke $0 set-user-ID
- to $NON_ROOT_USERNAME. If `.' is not writable, then skip the test.
-
- * src/printenv.c: Include "exitfail.h".
- (main): Set exit_failure rather than calling close_stdout_set_status.
- * src/date.c: Likewise.
- * src/sort.c: Likewise.
- * src/tty.c: Likewise.
-
-2003-07-18 Jim Meyering <jim@meyering.net>
-
- * tests/touch/not-owner: Update to use newer framework.
-
- * tests/rm/fail-eperm: Use $srcdir/../priv-check, create a temporary
- directory, and remove Perl-coded `you may not run as root' test.
- * tests/cp/fail-perm: Use $srcdir/../priv-check, rather than
- hard-coding something not quite equivalent.
- Paul Jarc reported the inconsistent diagnostics.
-
- * src/sort.c (main): Use close_stdout via atexit.
- Now `sort --version' and `sort --help' fail, as they should
- when their output is redirected to /dev/full.
-
- * src/su.c (usage): Don't call close_stdout here.
- (main): Use close_stdout via atexit.
- Now `su --version > /dev/full' fails, as it should.
- Somehow, the change of 2000-05-07 that purports to fix this
- was not checked in.
-
- * tests/help-version (--help/--version vs. /dev/full): Special-case
- `[' to protect it from expected_failure_status-`eval'.
-
- * src/uniq.c (writeline): Use a SPACE, not a TAB between the
- count and the corresponding line, as required by POSIX.
- Reported by Clement Wang.
- * tests/uniq/Test.pm (101, 102): Update tests of -c accordingly.
-
- * tests/expr/basic: Add tests for when exit status is 2.
-
- * src/nohup.c (NOHUP_FOUND_BUT_CANNOT_INVOKE, NOHUP_FAILURE):
- Use an anonymous `enum', rather than #define.
-
-2003-07-17 Paul Eggert <eggert@twinsun.com>
-
- * src/expr.c: Include "exitfail.h", "quotearg.h".
- (EXPR_INVALID, EXPR_ERROR): New constants.
- (nomoreargs, null, toarith, nextarg): Return bool, not int.
- (syntax_error): New function, exiting with status 2. Use it
- insteading of printing "syntax error" ourselves.
- (main): Initialize exit_failure to EXPR_ERROR.
- Exit with EXPR_INVALID on syntax error (too few arguments).
- (nextarg): Use strcmp, not strcoll; strcoll might return
- an undesirable 0, or might fail.
- (docolon, eval4, eval3): Exit with status 3 on invalid argument type
- or other such error.
- (eval2): Report an error if strcoll fails in a string comparison.
- * src/sort.c: Include "exitfail.h".
- (main): Set exit_failure, not xalloc_exit_failure and
- xmemcoll_exit_failure.
- * tests/expr/basic: Invalid value exits with status 3, not 2.
-
-2003-07-16 Jim Meyering <jim@meyering.net>
-
- * configure.ac (AC_INIT): Use 5.0.90 as the version, rather than 5.0.2,
- per GNU maintainer guidelines. The next non-beta release will be 5.1.
-
- This script would have caught at least two recent bugs:
- those in [ and kill.
- * tests/help-version: Revive this script.
- It wasn't doing anything useful, since $all_programs wasn't being
- defined by the invoking Makefile.am.
- Reflect that nohup is no longer a script, so don't exclude it.
- Add framework to handle the programs added since it was last run:
- kill, stat, unlink, [, link, readlink.
- Fix path-related problems deriving from the move of this script
- from src/ to its present location.
- * tests/Makefile.am (all_programs): Define.
- (TESTS_ENVIRONMENT): Use it.
-
- * src/kill.c (main): Fix bug introduced on 2003-05-10 (for 5.0.1)
- whereby kill would always attempt to operate on argv[0] and fail.
-
- * src/test.c (integer_expected_error): Improve diagnostic -- now,
- it also matches the one from bash's builtin test.
- (binary_operator): Add \n at end of diagnostic.
-
- * tests/rm/fail-2eperm: Remove setuidgid-related code. Move it to ...
- * tests/priv-check: Move setuidgid-related and
- NON_ROOT_USERNAME-checking code to this file.
-
- * README: Update section on testing as `root'.
- Suggestion from Paul Jarc.
-
- * src/test.c (AUTHORS): Replace 3-letter usernames with the actual
- names of authors that I just found in bash's builtins/test.def.
-
- Running `[' with no arguments would evoke a segfault.
- * src/test.c (main) [LBRACKET]: Move initialization of argv to
- precede potential use via test_syntax_error.
-
- * src/Makefile.am (AM_CPPFLAGS): Rename from `INCLUDES', to avoid
- warning from automake -Wall.
-
-2003-07-15 Jim Meyering <jim@meyering.net>
-
- * Version 5.0.1.
-
- * Makefile.maint (%.asc): Remove target first, so gpg doesn't
- prompt us about it.
-
- * announce-gen (print_changelog_deltas): Relax tests for matching
- version-number line in NEWS.
- Change the .sig suffix to .asc here, too.
-
-2003-07-14 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (%.asc): Renamed from %.sig.
- Generate and use ascii-armored signatures.
- Use gpg's -o option.
-
-2003-07-13 Jim Meyering <jim@meyering.net>
-
- * src/nohup.c (NOHUP_FAILURE, NOHUP_FOUND_BUT_CANNOT_INVOKE): Define.
- (main): Use them.
-
- * Makefile.maint (syntax-check): Move each individual check into
- its own target.
- (syntax-check-rules): This is the list of syntax-check targets.
- (sc_unmarked_diagnostics, sc_cast_of_argument_to_free):
- (sc_cast_of_x_alloc_return_value, sc_space_tab):
- (sc_error_exit_success, sc_xalloc_h_in_src): New targets.
-
-2003-07-12 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Remove uses of OPTIONAL_BIN_ZCRIPTS and last
- traces of the nohup script.
-
- * src/Makefile.am (bin_SCRIPTS): Remove use of just-removed
- $(OPTIONAL_BIN_ZCRIPTS).
-
- * src/Makefile.am (localedir.h): Put the `2>&1' after the redirect
- target, not before the `>'.
-
- * src/remove.c (remove_dir): Give a diagnostic upon failed save_cwd,
- now that that function no longer calls `error'.
-
- * src/df.c (find_mount_point): Emit a diagnostic for each
- failed syscall, rather than relying on caller to do that.
- The caller couldn't do a good job, anyhow -- too many different
- ways to fail (each with a different referent).
- Give a diagnostic upon failed save_cwd, now that that function
- no longer calls `error'.
- (show_point): Don't diagnose find_mount_point's errors, now that
- it handles them itself.
-
- * src/df.c (find_mount_point): Don't let free clobber errno upon
- failed chdir.
-
- * src/sys2.h: Remove alloca-related block.
- * src/system.h: Include <alloca.h> here, instead.
-
- It appears that the `#pragma alloca' included via "system.h" is
- adequate, since join.c uses alloca, yet lacked an in-file #pragma.
- * src/copy.c, src/cp.c, src/df.c, src/install.c, src/ln.c:
- * src/ls.c, src/mv.c, src/remove.c: Remove `#pragma alloca'.
-
- * src/chown-core.c (change_file_owner): Do not restore any special
- permission bits (e.g., set-user-ID, set-group-ID) that are reset
- by chown(2) on some systems. Suggestion and insistence :-) from
- Michael Stone.
-
- * tests/input-tty: Also check `test -t 1'.
- This is necessary on linux-2.4.21. Otherwise, the stty/basic-1
- test would block when run in the background.
-
-2003-07-11 Jim Meyering <jim@meyering.net>
-
- * tests/sample-test: Also fail if cat-to-create-expected-output
- fails. Otherwise, if both `exp' and `out' were to end up empty
- because of e.g., a full disk, they would mistakenly compare equal.
-
- * src/nohup.c: New file. Rewrite of nohup.sh in C.
- This solves a portability problem: on at least Solaris systems,
- when nohup.sh used the vendor /bin/sh, it would exit with status
- of `1' rather than the required 126 or 127 upon failure to exec
- the specified program.
-
- * src/Makefile.am (EXTRA_SCRIPTS): Remove definition.
- (bin_PROGRAMS): Add nohup.
- (EXTRA_DIST): Remove nohup.sh.
- (all_programs): Remove use of $(EXTRA_SCRIPTS).
- * src/nohup.sh: Remove file.
- * man/Makefile.am (nohup.1): Depend on nohup.c, rather than nohup.sh.
-
- * tests/misc/nohup: Tests for the above.
- * tests/misc/Makefile.am (TESTS): Add nohup.
-
- * src/head.c (diagnose_copy_fd_failure): New function, renamed from
- the macro, COPY_FD_DIAGNOSE.
- (diagnose_copy_fd_failure): Enclose diagnostic in _(...).
- (head_file): Likewise.
-
- * src/date.c: Include "quote.h".
- (batch_convert): Use the quote function rather than using literal `...'
- in a diagnostic.
-
- * src/setuidgid.c (main): Enclose diagnostic in _(...).
- * src/fmt.c (main): Likewise.
- * src/mknod.c (main): Likewise.
- * src/tac.c (tac_seekable): Likewise.
- * src/yes.c (main): Likewise.
- * src/od.c (main): Likewise.
- * src/install.c (change_attributes): Likewise.
-
-2003-07-10 Jim Meyering <jim@meyering.net>
-
- * src/head.c (usage): Use 1024*1024 in place of 1048576.
- * src/tail.c (usage): Likewise.
-
- * tests/rm/fail-2eperm: Now that we have setuidgid, use it in
- place of the kludge in this test. Suggestion from Paul Jarc.
-
- * src/Makefile.am (noinst_PROGRAMS): Define to setuidgid.
- * src/setuidgid.c: New program, solely for testing (not installed).
-
- * src/chown-core.c (change_file_owner): Don't leak file descriptors
- when dereferencing symlinks.
-
-2003-07-09 Jim Meyering <jim@meyering.net>
-
- * tests/du/slash: New file/test for today's lib/ftw.c fix.
- * tests/du/Makefile.am (TESTS): Add slash
-
- * src/tail.c (xlseek): Avoid warning about ``return without value
- from function returning non-void''.
-
-2003-07-08 Jim Meyering <jim@meyering.net>
-
- * man/help2man: Update to version 1.29.
-
- * man/help2man: Add END handler to close STDOUT and check for errors.
-
-2003-06-30 Paul Eggert <eggert@twinsun.com>
-
- Add support for a "[" that conforms to the GNU coding standards,
- i.e., that does not depend on its name.
- * src/lbracket.c: New file.
- * README: Add "[".
- * man/Makefile.am (programs): Ignore "[", since it doesn't have
- a separate man page.
- * src/Makefile.am (bin_PROGRAMS): Add "[".
- (__SOURCES): New var.
- * src/test.c (LBRACKET): Define to 0 if not defined.
- (main): Use LBRACKET rather than argv[0].
-
- * src/test.c (one_argument): Do not check for -t if POSIXLY_CORRECT.
- Reported by Paul Jarc and Dan Jacobson.
-
- * src/test.c (main): Do not recognize --help or --version if
- POSIXLY_CORRECT, when invoked as "test". Handle "[ ]" correctly.
- Do not bother testing that margv[margc] is non-null.
-
-2003-07-04 Jim Meyering <jim@meyering.net>
-
- * src/who.c (print_line): Rewrite to use asprintf, in order to be
- able to avoid emitting trailing spaces. Reported by Dan Jacobson.
-
- * tests/misc/head-elide-tail: Add tests of head's new --lines=-N
- option, and perform the +1600 invocations of head IFF the envvar
- RUN_EXPENSIVE_TESTS is set.
-
-2003-07-03 Jim Meyering <jim@meyering.net>
-
- * src/cp.c (do_copy): Give a better diagnostic when failing due
- to nonexistent destination directory. Reported by Dmitry Rutsky.
- See http://bugs.debian.org/199730 for details.
-
-2003-06-27 Jim Meyering <jim@meyering.net>
-
- split's --verbose option did nothing [broken in 4.5.10 and 5.0]
- * src/split.c (longopts): Use `1', not `0' as the value for
- for &verbose. Reported by Keith Thompson.
-
- Test for the above fix.
- * tests/misc/split-a: Also use --verbose and compare stderr
- output with what we'd expect.
-
-2003-06-20 Jim Meyering <jim@meyering.net>
-
- * src/copy.c (copy_internal) [HAVE_STRUCT_STAT_ST_AUTHOR]:
- Use `error_t' (rather than int) as type for local `err'.
- From Alfred M. Szmidt.
-
-2003-06-19 Marcus Brinkmann <marcus@gnu.org>
-
- * src/copy.c (copy_internal) [HAVE_STRUCT_STAT_ST_AUTHOR]:
- Fix author preservation code.
-
-2003-06-19 Jim Meyering <jim@meyering.net>
-
- * src/ln.c (ENABLE_HARD_LINK_TO_SYMLINK_WARNING): Define to 0.
- (do_link): Don't warn about hard link to symlink.
-
-2003-06-18 Jim Meyering <jim@meyering.net>
-
- * src/cut.c: Include "getdelim2.h", not "getstr.h".
- Reflect renaming: getstr -> getdelim2.
-
- * src/comm.c, src/join.c, src/nl.c, src/uniq.c: Reflect renaming:
- readline -> readlinebuffer.
-
-2003-06-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- * src/readlink.c: Include <sys/types.h> before system.h (because
- the latter includes <sys/stat.h>). Required on Ultrix 4.3.
-
-2003-06-17 Jim Meyering <jim@meyering.net>
-
- * src/system.h (initialize_main): Define.
- Use it in every `main'. Applied via this:
- p='initialize_main (&argc, &argv);'
- perl -ni -e '/program_name.=.argv.0/ and print " '"$p"'\n"; print' \
- $(grep -l program_name.=.argv.0 *.c)
- test.c uses margc/margv, so I made the change manually for that file.
- Based on a patch from Bernard Giroud.
-
-2003-06-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- Fix for build failure on Ultrix 4.3.
- * src/stat.c: Include sys/statvfs.h in preference to sys/vfs.h.
- Include sys/param.h and sys/mount.h on ultrix.
-
-2003-06-16 Jim Meyering <jim@meyering.net>
-
- * src/touch.c (O_NDELAY, O_NONBLOCK, O_NOCTTY, EISDIR): Remove
- definitions.
- * src/system.h (O_NDELAY, O_NONBLOCK, O_NOCTTY, EISDIR): Define
- them here instead, but with one change: define EISDIR to -1, not 0.
-
- * src/cat.c (cat): Remove `#ifndef ENOSYS', now that it's
- guaranteed to be defined.
- * src/system.h (ENOSYS, ENOTSUP): Define to -1 if not defined.
-
- * README: Mention the CVS repository.
- Encourage addition of test cases.
-
-2003-06-12 Jim Meyering <jim@meyering.net>
-
- * src/touch.c (touch): Call close only if necessary.
- From Bruno Haible.
-
- * src/wc.c (usage): Correct wording: wc prints counts in the order
- `newline, word, byte'. Reported by Keith M. Briggs.
- * man/wc.x: Fix it here, too. And change `lines' to `newlines'.
-
-2003-06-10 Jim Meyering <jim@meyering.net>
-
- * tests/date/Test.pm: Add a test for the new format, e.g., May-23-2003.
-
-2003-06-07 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (syntax-check): Add commented-out (over-aggressive)
- rule.
-
-2003-06-06 Jim Meyering <jim@meyering.net>
-
- * src/extract-magic (main): Avoid newer 3-arg form of open,
- so this script works also with e.g., perl5.005_03.
- Patch by John David Anglin.
-
-2003-06-04 Paul Eggert <eggert@twinsun.com>
-
- * src/system.h: Include <stdbool.h> unconditionally.
-
-2003-06-04 Jim Meyering <jim@meyering.net>
-
- * man/Makefile.am (check-programs-vs-x): Rename target
- from check-programs-vs-1. Adjust rule to check for the
- primary (.x) file, not the generated one (.1).
-
-2003-06-03 Tim Mooney <mooney@dogbert.cc.ndsu.NoDak.edu>
-
- * man/kill.x: New file.
- * man/Makefile.am (dist_man_MANS): Add kill.1.
- (kill.1): New rule.
-
-2003-06-04 Jim Meyering <jim@meyering.net>
-
- Ensure that the .x file for a new program is never forgotten again.
- * man/Makefile.am (programs): Define.
- (check-programs-vs-1): New phony target.
- (check-local): Depend on it.
-
-2003-06-03 Jim Meyering <jim@meyering.net>
-
- Avoid unnecessary copying of environment.
- * src/env.c (main): Rather than clearing the environment and --
- unless told to ignore environment -- copying all settings from
- the saved, original environment, clear the environment only when
- that is requested. Suggested by Jens Elkner.
-
-2003-06-02 Jim Meyering <jim@meyering.net>
-
- * src/system.h: Always include <string.h>, since we assume C89.
- Include <limits.h> without checking for HAVE_LIMITS_H.
-
- * src/test.c [!TEST_STANDALONE]: Remove #if-0'd block.
- (STREQ, S_IXUGO): Remove redundant (in system.h) definitions.
-
-2003-06-01 Jim Meyering <jim@meyering.net>
-
- Avoid a race condition in `tail -f' described by Ken Raeburn in
- http://mail.gnu.org/archive/html/bug-textutils/2003-05/msg00007.html
- * src/tail.c (file_lines): Add new parameter, *read_pos, and set it.
- (pipe_lines, pipe_bytes, start_bytes, start_lines): Likewise.
- (tail_bytes, tail_lines, tail): Likewise.
- (tail_file): Use the new `read_pos' value as the size,
- rather than stats.st_size from the fstat call.
-
-2003-05-28 Jim Meyering <jim@meyering.net>
-
- * src/extract-magic: Allow expansion of `$file' in the here-
- document corresponding to the comment at the top of fs.h.
-
-2003-05-26 Jim Meyering <jim@meyering.net>
-
- * src/stat.c: Fix portability problem on FreeBSD5.0: don't include
- <sys/statvfs.h> on systems without HAVE_STRUCT_STATVFS_F_BASETYPE.
- Use #if/#elif/... cascade so we get only one set of include files.
- Reported by Nelson Beebe.
-
-2003-05-24 Jim Meyering <jim@meyering.net>
-
- * src/md5sum.c (split_3): Accept the BSD format only when in MD5 mode.
- * tests/sha1sum/basic-1: Make sure `sha1sum --check' doesn't
- accept the BSD format.
-
-2003-03-28 Joe Orton <jorton@redhat.com>
-
- * src/md5sum.c (bsd_split_3): New function.
- (split_3): Detect checksums from BSD 'md5' command and handle them
- using bsd_split_3.
-
- * tests/md5sum/basic-1: New tests for --check exit status, and for
- BSD-style checksum files.
-
-2003-05-21 Jim Meyering <jim@meyering.net>
-
- * src/head.c (elide_tail_lines_pipe): Fix a thinko.
- This sort of thing is why it'd be *Really Good* to factor
- out the common code used here and in tail.c.
-
-2003-05-14 Jim Meyering <jim@meyering.net>
-
- * src/head.c (usage): Document new feature: --bytes=-N and --lines=-N.
-
- * tests/du/slink: Skip this test if `.' is on an XFS file system.
-
- * tests/du/fd-leak: New file. Test for the bug in du that
- was fixed by the 2003-05-12 change to lib/ftw.c.
- * tests/du/Makefile.am (TESTS): Add fd-leak.
-
- * src/head.c (AUTHORS): Enclose string in N_(...), now that it
- includes a translatable word, `and'.
-
- * src/dd.c (usage): Don't use `,' as the thousands separator
- in e.g. 1,000,000 and 1,048,576. Instead, do this:
- `SIZE may be ..., MB 1000*1000, M 1024*1024 and so on...'
- * src/df.c (usage): Likewise.
- * src/du.c (usage): Likewise.
- * src/ls.c (usage): Likewise.
-
- * Makefile.maint (syntax-check): Add another check.
-
-2003-05-13 Paul Eggert <eggert@twinsun.com>
-
- Fix uniq to conform to POSIX, which requires that "uniq -d -u"
- must output nothing. Problem reported by Josh Hyman.
-
- * src/uniq.c (enum output_mode, mode): Remove, replacing with:
- (output_unique, output_first_repeated, output_later_repeated):
- New vars. All uses of "mode" changed to use these variables,
- which are not mutually exclusive as "mode" was.
- (writeline): New arg "match", used to control whether to
- obey output_first_repeated or output_later_repeated.
- All callers changed.
- (check_file, main): Adjust to above changes.
-
- * tests/uniq/Test.pm: Test that 'uniq -d -u' outputs nothing.
-
-2003-05-14 Jim Meyering <jim@meyering.net>
-
- * tests/rm/rm3: Use tr's \n notation rather than \012.
- This package can afford to do that, since its tests are guaranteed use
- GNU tr, which has accepted the more modern notation for 10 years.
- * tests/rm/rm5: Likewise.
- * tests/cp/same-file: Likewise.
- * tests/stty/row-col-1: Likewise.
- * tests/stty/basic-1: Likewise.
- * tests/rm/deep-1: Likewise.
- * tests/mv/part-symlink: Likewise.
- * tests/mkdir/perm: Likewise.
- * tests/misc/nice: Likewise.
-
-2003-05-13 Jim Meyering <jim@meyering.net>
-
- * src/copy.c (struct F_triple) [name]: Remove const attribute.
- (triple_free): Don't apply cast to argument of free.
- (seen_file): Add cast here instead.
-
- * src/cp-hash.c (struct Src_to_dest) [name]: Remove const attribute.
- (src_to_dest_free): Don't apply cast to argument of free.
-
- * src/sort.c (zaptemp): Don't apply cast to argument of free.
- * src/pr.c (init_fps, init_store_cols): Likewise.
- * src/join.c (delseq, freeline): Likewise.
- * src/expr.c (OLD): Likewise.
- * src/sort.c (sort): Likewise.
- * src/head.c (elide_tail_lines_pipe): Likewise.
-
- * src/tail.c: Include "quote.h".
- Use quote in diagnostics. Change many error format strings
- from just `%s' to e.g., `error reading %s'.
- (pipe_lines): Change type of parameter, n_lines, to uintmax_t.
- Rewrite newline-counting loop to use memchr.
-
- * src/head.c (elide_tail_lines_pipe): Use `if', not assert.
- Now that assert is no longer used, don't include <assert.h>.
-
-2003-05-12 Jim Meyering <jim@meyering.net>
-
- * src/head.c: Include <assert.h>.
- (AUTHORS): Add my name.
- (elide_tail_lines_pipe): New function.
-
-2003-05-10 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (syntax-check): Check for `error (EXIT_SUCCESS,'.
-
- * src/readlink.c (main): Set program_name before first use.
- Remove that (redundant) first use.
- Don't exit successfully just because --verbose was specified.
- Pass 0, not EXIT_SUCCESS, as first argument to error; when that
- parameter is 0, error does not exit.
-
- * src/uname.c (main): When failing due to too many arguments, also say
- that, rather than just "Try `uname --help' for more information.".
- * src/comm.c (main): Likewise, but for too few arguments.
- * src/logname.c: Include error.h.
- (main): Say why we're failing.
-
- * src/uniq.c (main): Don't segfault when argc < optind.
- * src/who.c (main): Handle argc < optind.
- * src/df.c (main): Likewise.
- * src/install.c (main): Likewise.
- * src/mv.c (main): Likewise.
- * src/pwd.c (main): Likewise.
- * src/tty.c (main): Likewise.
- * src/chroot.c (main): Likewise.
- * src/hostname.c: Likewise.
- * src/du.c (main): Likewise.
- * src/expand.c (main): Likewise.
- * src/env.c (main): Likewise.
- * src/unexpand.c (main): Likewise.
- * src/printenv.c (main): Likewise.
- * src/sync.c (main): Handle argc == 0.
- * src/expr.c (main): Likewise.
- * src/printf.c (main): Likewise.
- * src/basename.c (main): Likewise.
- * src/ln.c (main): Test for `missing argument' before computing n_files.
- * src/tail.c (main): Test for the case of no arguments before
- computing n_files.
-
- * src/kill.c (send_signals): Don't check command line arguments here.
- (main): Check them here instead. Handle argc < optind.
-
- * src/logname.c (main): Use error, rather than fprintf, for the sake
- of consistency.
-
- * src/rm.c (main): Don't overrun array bound if argc is 0.
-
-2003-05-09 Jim Meyering <jim@meyering.net>
-
- * src/sort.c (main): Don't overrun array bound if argc is 0.
- That would happen when invoked via: execl ("/usr/bin/sort", NULL);
- Reported by Wartan Hachaturow.
-
-2003-05-07 Jim Meyering <jim@meyering.net>
-
- Implement support so that `head --lines=-N' works on seekable files.
- * src/head.c (enum Copy_fd_status): Define.
- (COPY_FD_DIAGNOSE): New macro.
- (elide_tail_lines_seekable): New funtion.
- (elide_tail_lines_file): Call it here.
-
-2003-05-06 Jim Meyering <jim@meyering.net>
-
- * src/sys2.h (CHAR_BIT): Remove duplicate definition.
-
-2003-05-04 Jim Meyering <jim@meyering.net>
-
- * tests/head/Test.pm: Remove tests of --bytes=-N; using that framework
- caused the addition of thousands of small files to the tar archive.
- * tests/misc/head-elide-tail: New file. Add them here instead.
- * tests/misc/Makefile.am (TESTS): Add head-elide-tail.
-
-2003-05-04 Paul Eggert <eggert@twinsun.com>
-
- * src/remove.c (HAVE_WORKING_READDIR): Define to 0 if not defined.
- (IF_READDIR_NEEDS_REWINDDIR): Remove.
- (remove_cwd_entries): Rewrite to avoid IF_READDIR_NEEDS_REWINDDIR,
- which was a bit weird because it couldn't be emulated by a function.
-
-2003-05-03 Jim Meyering <jim@meyering.net>
-
- Extend head to accept --lines=-N (--bytes=-N) and to print all
- but the N lines (bytes) at the end of the file.
- * src/head.c: Include full-write.h, full-read.h, inttostr.h, quote.h.
- Use quote() in diagnostics, rather than literal `' marks.
- (copy_fd, elide_tail_bytes_pipe, elide_tail_bytes_file):
- New functions.
- (elide_tail_lines_pipe, elide_tail_lines_file): New functions.
- (head_file): Reorganize so as to call head from only one place.
- (main): Likewise, for head_file.
- Handle new, undocumented option, --presume-input-pipe.
- Handle negative line and byte counts.
- * tests/head/Test.pm: Add lots of tests to exercise --bytes=-N.
-
- * tests/du/8gb: Skip test if the file system of `.' doesn't support
- sparse files -- otherwise it'd create a file of size 8GB.
-
-2003-05-02 Jim Meyering <jim@meyering.net>
-
- * src/fmt.c (usage): Don't mention obsolescent -WIDTH option.
- Instead explain about `-' and standard input.
- (main): Give a proper diagnostic for e.g., `fmt -c -72'.
- Reported by Keith Thompson.
- * tests/fmt/basic: Add test for the above fix.
-
- * src/fmt.c: Include "quote.h".
- Use quote() in diagnostics, rather than literal `' marks.
- (main): Exit nonzero when unable to open an input file.
- * tests/fmt/basic: Add test for the above fix.
-
- * src/fmt.c (main): Diagnose invalid suffix on obsolescent width
- specifications like `-72x'.
- * tests/fmt/basic: Add test for the above fix.
-
- Work around nasty readdir bug on Darwin6.5.
- * src/remove.c (IF_READDIR_NEEDS_REWINDDIR): Define.
- [! HAVE_WORKING_READDIR] (remove_cwd_entries): If readdir has just
- returned NULL and there has been at least one successful unlink or
- rmdir call since the opendir or previous rewinddir, then call
- rewinddir and reiterate the loop.
-
- Factor out common code.
- * src/remove.c (readdir_ignoring_dotdirs): New function.
- (is_empty_dir): Use it here.
- (remove_cwd_entries): Use it here.
-
-2003-05-01 Jim Meyering <jim@meyering.net>
-
- * tests/rm/r-3: Create 500 rather than just 300 files.
- There's a bug in Darwin6.5's readdir that shows up only with
- 338 or more files.
- Fix a bug in this test: `cd $pwd' (not to `..'), now that $tmp
- has two components.
-
- * src/tail.c:
- Change type of n_units, n_bytes, n_lines to be `uintmax_t'.
- (dump_remainder): Move two declarations `down' into the scope
- where they are used.
- (xlseek): Return the resulting offset.
- (file_lines): Rename parameter, file_length, to end_pos.
- (pipe_lines): Don't coerce safe_read return value to `int'.
- Adapt tests accordingly.
- (pipe_bytes) [struct charbuffer] (nbytes): Change type from `int'
- to `unsigned int'.
- Change type of `total_bytes' from `int' to `size_t',
- since the former wouldn't always be wide enough.
- Don't coerce safe_read return value to `int',
- and adapt tests accordingly.
- Now that testing for a read error no longer involves
- using `tmp', handle that case *after* freeing `tmp'.
- (start_bytes): Clean up.
- (tail_bytes): Now that `n_bytes' may be larger than
- OFF_T_MAX, test for that condition and, if it's true, don't
- use lseek optimizations.
- (parse_options): Don't fail just because N_UNITS is larger than
- the maximum size of a file -- tail may be applied to an input
- stream (e.g., a pipe) with more data than that.
-
- * Makefile.maint (syntax-check): Rename from alloc-check.
- Also check for SPACE-TAB sequences.
- Also check for malloc/calloc/realloc casts.
-
-2003-05-01 Jim Meyering <jim@meyering.net>
-
- * src/tail.c (start_lines): Rewrite to use memchr. Clean up.
-
-2003-04-28 Jim Meyering <jim@meyering.net>
-
- * tests/misc/tty-eof: Send two tokens, not just one, so we don't
- make the now-more-picky tsort fail.
-
-2003-04-24 Jim Meyering <jim@meyering.net>
-
- * src/tsort.c (tsort): Remove unnecessary test of have_read_stdin.
- (main): Minor syntactic clean-up.
-
- * src/tsort.c (tsort): Fail if the input contains an odd number of
- tokens. Reported by junkio@cox.net.
-
- * tests/tsort/basic-1: Test for the above fix.
-
-2003-04-21 Jim Meyering <jim@meyering.net>
-
- * tests/misc/printf: Add tests for the printf fixes below.
-
- * Makefile.cfg (cvs_files): Add $(srcdir)/config/depcomp to the list.
-
-2003-04-20 Paul Eggert <eggert@twinsun.com>
-
- Fix printf POSIX compatibility bug reported by Ben Harris in
- <http://mail.gnu.org/archive/html/bug-coreutils/2003-04/msg00070.html>.
- * doc/coreutils.texi (printf invocation): It's \NNN in the format,
- \0NNN in the %b operand.
- * src/printf.c (usage): Likewise.
- (print_esc): New arg OCTAL0 to specify whether \0NNN or \NNN
- is desired. All uses changed. Behave like Bash printf if %b
- operand uses \NNN where the initial N is not 0.
-
-2003-04-17 Jim Meyering <jim@meyering.net>
-
- * src/stty.c: Remove uses of PROTOTYPE macro.
-
-2003-04-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint: Remove (or replace-with-TAB(s) to retain alignment)
- each sequence of spaces before a TAB character.
-
-2003-04-13 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (is_empty_dir): Don't closedir (NULL).
-
-2003-04-12 Jim Meyering <jim@meyering.net>
-
- Giving nl an invalid STYLE argument (in --header-numbering=STYLE (-h),
- --body-numbering=STYLE (-b), or --footer-numbering=STYLE (-f)) or
- FORMAT (--number-format=FORMAT (-n)) would not give a useful diagnostic.
- * src/nl.c (main): Fix those problems and remove literal quote marks
- (e.g., "`%s'") from format string; instead use "%s" in each format
- string and `quote (optarg)' as the corresponding argument.
- Also, diagnose all invalid command line options before failing.
-
- * src/nl.c (proc_text): Fix a bug that would make nl output extra
- newlines in some cases. Details here: http://bugs.debian.org/177256.
- This bug was introduced on 2001-11-10 for textutils-2.0.17.
- * tests/misc/nl: Add test for the above-fixed bug.
-
- * tests/misc/readlink: New file. Test the --canonicalize option.
- * tests/misc/Makefile.am (TESTS): Add readlink.
-
-2003-04-11 Jim Meyering <jim@meyering.net>
-
- Clean up.
- * src/chown.c, src/cp.c, src/dircolors.hin, src/du.c, src/ln.c:
- * src/mkfifo.c, src/ptx.c, src/spline.c, src/stty.c, src/tail.c:
- * src/test.c, src/unexpand.c: Remove (or replace-with-TAB(s) to
- retain alignment) each sequence of spaces before a TAB character.
-
- * src/ls.c: Include <stdlib.h> unconditionally.
-
- * Makefile.maint (xalloc-check): Rename from header-check.
-
- * src/yes.c: Include error.h after system.h, not before.
-
- Clean up.
- * src/copy.c, src/cp-hash.c, src/cp.c, src/csplit.c, src/cut.c:
- * src/date.c, src/df.c, src/du.c, src/expand.c, src/expr.c, src/id.c:
- * src/join.c, src/md5sum.c, src/nl.c, src/od.c, src/paste.c, src/pr.c:
- * src/ptx.c, src/sort.c, src/split.c, src/su.c, src/tail.c, src/tee.c:
- * src/tr.c: * src/unexpand.c, src/users.c:
- Remove anachronistic casts of xmalloc, xrealloc, and xcalloc
- return values and of xrealloc's first argument.
- Fix the former with this:
- perl -pi -e 's/\([^(]*?\*\) *(x(m|c|re)alloc)\b/$1/'
-
-2003-04-10 Jim Meyering <jim@meyering.net>
-
- * src/stty.c (wrapf): Declare with format attribute.
-
- The S_MAGIC_... names shouldn't be maintained in two places (prior
- to this change, one would have to keep stat.c and fs.h in sync).
- This change makes it so those names and the corresponding
- hexadecimal constants all reside in stat.c. fs.h is now generated.
- * src/Makefile.am (fs.h): New rule to generate fs.h from stat.c.
- (BUILT_SOURCES): Add fs.h, now that it's generated.
- (EXTRA_DIST): Add extract-magic.
- * src/extract-magic: New script to extract fs.h definitions from stat.c.
- * src/stat.c (human_fstype) [__linux__]: Append each hex constant from
- fs.h in a comment after the corresponding `case S_MAGIC_...:' statement.
-
- * tests/tail-2/big-4gb: Skip this test (don't fail) if creating a
- file with nominal length > 4GB fails. Reported by Michael Deutschmann.
-
- * man/unexpand.x: Add `SEE ALSO' reference to expand.
- * man/expand.x: Add `SEE ALSO' reference to unexpand.
- Suggestion from Dan Jacobson.
-
-2003-04-10 Maciej W. Rozycki <macro@ds2.pg.gda.pl>
-
- * src/fs.h (S_MAGIC_DEVPTS): New magic for Linux's devpts.
- * src/stat.c (human_fstype): Handle Linux's devpts.
-
-2003-04-09 Paul Eggert <eggert@twinsun.com>
-
- * src/split.c (line_bytes_split): Arg is of type size_t, since
- that's all that is supported for now.
- (main): Check for overflow in obsolescent line count option.
-
-2003-04-09 Jim Meyering <jim@meyering.net>
-
- * tests/misc/split-fail: Add a new test for the above fix.
-
- * src/split.c (bytes_split): Use size_t temporary (rather than
- uintmax_t original) in remaining computations. From Paul Eggert.
-
- Handle command line option arguments larger than 2^31.
- This allows e.g., splitting into files of size 2GB and larger,
- and running split --lines=N with N=2^31 or more.
- But for --line-bytes=N, the restriction that N <= SIZE_MAX
- remains (for now), due to the way it is implemented.
-
- * src/split.c: Include "inttostr.h".
- (bytes_split, lines_split, line_bytes_split, main):
- Use uintmax_t, not size_t, for file sizes.
- (main): Give a better diagnostic for option arguments == 0.
- Use umaxtostr to print file sizes.
- Reported by Luke Hassell.
-
-2003-04-08 Jim Meyering <jim@meyering.net>
-
- * src/rm.c (usage): Mention that --directory (-d) works only
- on some systems. Suggestion from Samuel Tardieu.
-
- * tests/basename/basic: Run $PERL to see if it is available,
- rather than testing its value.
- * tests/sum/sysv, tests/tsort/basic-1, tests/unexpand/basic-1:
- * tests/basename/basic, tests/dd/skip-seek, tests/dircolors/simple:
- * tests/expr/basic, tests/factor/basic, tests/fmt/basic:
- * tests/ls-2/tests, tests/md5sum/basic-1, tests/md5sum/newline-1:
- * tests/misc/sort, tests/misc/tty-eof, tests/mv/i-1:
- * tests/rm/empty-name, tests/rm/fail-eperm, tests/rm/unreadable:
- * tests/seq/basic, tests/sha1sum/basic-1, tests/sha1sum/sample-vec:
- * tests/sum/basic-1, tests/seq/basic: Likewise.
-
- * tests/misc/Makefile.am (TESTS): Add split-fail.
- * tests/misc/split-fail: New file.
-
- * src/split.c: Rename local variables: nchars -> n_bytes.
- (lines_split): Rename local, nlines -> n_lines.
- (main): Rename local variable: s/accum/n_units/.
- (main): Use STDIN_FILENO, not literal `0'.
-
-2003-04-07 Jim Meyering <jim@meyering.net>
-
- * src/stat.c: Add #include directives for Ultrix 4.4.
- Based on a suggested change from Bert Deknuydt.
-
-2003-04-06 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (makefile-check): New rule.
- (local-check): Add it.
-
-2003-04-05 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (nearly all of them):
- Use $(VAR) rather than @VAR@, now that we can rely on automake to
- emit a definition for each substituted variable.
- * tests/Makefile.am.in: Likewise.
-
- * tests/rm/rm5: Add a comment explaining why this test fails when
- using Tru64's broken sed.
- * tests/rm/rm3: Likewise.
-
- Make `kill -t' output signal descriptions (not `?') on Tru64.
- * src/kill.c (sys_siglist): Also check for __sys_siglist.
- Patch by Tony Leneis.
- * configure.ac: Also check for declaration of __sys_siglist.
- Required for Tru64 4.0D, 4.0F, and 5.1.
- Reported by Tony Leneis.
-
-2003-04-04 Jim Meyering <jim@meyering.net>
-
- * src/Makefile.am (PERL): Remove unnecessary definition.
-
- Because of inappropriate (but POSIX-mandated) behavior of rename,
- `mv a b' would not remove `a' in some unusual cases. Work around
- this by unlinking `a' when necessary.
-
- * src/copy.c (same_file_ok): Add an output parameter.
- Set it in the offending case.
- (copy_internal): When necessary, unlink SRC_PATH and inform caller.
- Reported by Ed Avis.
- * tests/mv/hard-4: New test for the above.
- * tests/mv/Makefile.am (TESTS): Add hard-4.
-
- Clean up rules for automatically generated sources:
- * src/Makefile.am (dircolors.h, wheel-size.h, wheel.h, false.c):
- Make each generated file be read-only.
- Add each file name to BUILT_SOURCES separately.
- (MAINTAINERCLEANFILES): Set to $(BUILT_SOURCES).
-
- Put LOCALEDIR macro definition in new file: localedir.h.
- * src/Makefile.am (DEFS): Remove definition.
- (localedir.h): New rule.
- (BUILT_SOURCES, DISTCLEANFILES): Add localedir.h.
- * src/system.h: Include "localedir.h".
-
-2003-04-02 Jim Meyering <jim@meyering.net>
-
- * Version 5.0.
-
- * tests/misc/Makefile.am (TESTS): Add false.
-
- * Makefile.maint (TMPDIR): Make sure it's defined.
- (my-distcheck): Build in $(TMPDIR), not `.'.
-
- * src/Makefile.am (false.c): Change all occurrences of
- `(EXIT_SUCCESS)' to `(EXIT_FAILURE)' so that false exits
- unsuccessfully also with --help. Reported by Paul Jarc,
- * tests/misc/false: New test for the above.
-
-2003-03-30 Jim Meyering <jim@meyering.net>
-
- * NEWS: Note the location of older NEWS files.
-
- * src/remove.c (is_empty_dir): Don't let a failing closedir
- clobber errno. Spotted by Arnold Robbins.
-
- * src/env.c: Fix typo in comment. From Arnold Robbins.
-
-2003-03-29 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.12.
-
- * README: Note to expect build problems for stat.c on Ultrix 4.3.
- Note that there are some harmless test failures when running
- `make check' as root on some systems.
-
-2003-03-28 Jim Meyering <jim@meyering.net>
-
- * tests/stty/row-col-1: Skip this test if stty can't get window size.
- This happens when connecting to sparc-solaris5.7 via ssh from within
- emacs. Reported by Karl Berry.
-
- * tests/du/basic: Use seq, not `yes' to generate 4KB of data.
- Otherwise, on systems (DJGPP) that emulate pipes using files,
- this test would never complete, waiting for `yes' to terminate.
- * tests/du/slink: As above, use seq, not `yes' to generate link target.
- * tests/rm/hash: As above, use seq, not `yes' to generate dir name.
- Reported by Rich Dawe.
-
-2003-03-27 Jim Meyering <jim@meyering.net>
-
- * src/id.c: Remove Arnold Robbins' obsolete e-mail address
- from `written by...' comment, at his request.
-
-2003-03-24 Paul Eggert <eggert@twinsun.com>
-
- Fix buffer overrun problem reported by TAKAI Kousuke, along
- with some other POSIX incompatibilities.
-
- * src/printf.c (print_esc): Do not treat \x specially if
- POSIXLY_CORRECT. Avoid buffer overrun if the format ends
- in backslash. Treat incomplete escape sequences as strings
- of characters, as POSIX requires.
- (print_formatted): Allow multiple flags. Avoid buffer overrun
- if the format is incomplete.
-
-2003-03-24 Jim Meyering <jim@meyering.net>
-
- * tests/misc/printf: Add tests for the above fixes and changes.
-
-2003-03-26 Jim Meyering <jim@meyering.net>
-
- * src/copy.h (struct cp_options): Add a comment.
-
-2003-03-23 Jim Meyering <jim@meyering.net>
-
- * README: Describe problem with 64-bit mode on HPUX 11.x,
- with patch for /usr/include/inttypes.h.
- * TODO: Plan to add an autoconf test to work around the bug.
-
-2003-03-22 Jim Meyering <jim@meyering.net>
-
- * src/stat.c: Don't include <sys/sysmacros.h>.
- That is already done via system.h. Otherwise, the multiple
- inclusion would evoke redefinition warnings from Cray's /bin/cc,
- aka Cray Standard C Version 4.0.3 (057126) Mar 22 2003 22:02:28.
- (human_fstype): Factor some directives `up', out of this function.
- Cast away `const' to avoid error from Cray's /bin/cc.
-
-2003-03-20 Jim Meyering <jim@meyering.net>
-
- * announce-gen (print_changelog_deltas): Ensure that a newline
- precedes each row of `*'s.
-
-2003-03-20 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.11.
-
- * src/seq.c (valid_format): Also accept ` ' and `'' as valid
- format flag characters.
- Do not require that a field width be specified.
- Do not fail when given a field width of `0'.
- Reported by Dan Jacobson.
- * tests/seq/basic: Add new tests for the above-fixed bug.
-
- * src/Makefile.am (all-local): Append $(EXEEXT) to use of `su'
- (install-root): Likewise.
- (install-exec-local): Likewise.
- Based on a patch from Richard Dawe.
-
-2003-03-19 Jim Meyering <jim@meyering.net>
-
- * man/Makefile.am (.x.1): Use $(LN_S) instead of 'ln -s',
- because the DJGPP 2.03 port of 'ln -s' doesn't work.
- Include $(EXEEXT) in program names.
- Since $(LN_S) may degenerate to `cp -p', be careful
- to invoke it from the destination directory.
- Mostly from Richard Dawe.
- * configure.ac: Use AC_PROG_LN_S.
-
- * tests/mv/part-symlink: Unset CDPATH. Otherwise, having the
- CDPATH shell variable set could cause this test to fail.
- Reported by Karl Berry.
-
-2003-03-18 Jim Meyering <jim@meyering.net>
-
- * src/fmt.c [struct Word] (paren, period, punct, final): Change the
- type of each member from bool <MEMBER>:1 to unsigned int <MEMBER>:1.
- AIX 5.1's xlc could not compile the former.
- Patch by Petter Reinholdtsen. Also reported by Mike Jetzer.
-
-2003-03-17 Richard Dawe <rich@phekda.freeserve.co.uk>
-
- * configure.ac: Include $(EXEEXT) in OPTIONAL_BIN_PROGS'
- program names, since automake only adds $(EXEEXT) to programs
- in its *_PROGRAMS.
-
-2003-03-16 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (rm): Put two local variables in static storage,
- so they can't be clobbered by the potential longjmp.
-
-2003-03-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.cfg (gnu_rel_host): Fix code to match the comment
- so that a version number with a two-digit component can still count
- as an alpha release. Reported by Richard A Downing.
- (gnu_rel_host): Define in terms of $(RELEASE_TYPE) instead.
-
-2003-03-14 Jim Meyering <jim@meyering.net>
-
- * src/ansi2knr.c: Remove no-longer-used file.
- * src/ansi2knr.1: Likewise.
-
- * Makefile.maint (prev_version_file): Don't use ?= for this particular
- assignment, since it causes trouble with old versions of GNU make
- (e.g. 3.76.1). The other uses of `?=' are inoffensive. Details here.
- http://mail.gnu.org/archive/html/bug-coreutils/2003-03/msg00028.html
- Patch from Alexandre Duret-Lutz.
-
- * Use patched automake-1.7.3. Regenerate Makefile.in files in
- subdirectories so that each includes a definition of ACLOCAL_M4.
-
- * announce-gen (main): Label the compressed source URLs.
-
- * Version 4.5.10.
-
- * tests/du/slink: Relax the test for the `local'ness of a file system,
- so that now it works also for tmpfs.
-
- * tests/du/hard-link: Transform output from first du, so that this
- test doesn't fail on file systems like tmpfs that order directory
- entries differently.
-
-2003-03-13 Jim Meyering <jim@meyering.net>
-
- * tests/du/8gb: Work around what appears to be an NFS failure that
- would make this test fail on some systems.
-
-2003-03-11 Jim Meyering <jim@meyering.net>
-
- * tests/du/basic: Make the test file exactly 4k bytes long.
-
- * src/split.c (longopts): Don't hard-code `2' here.
- Instead, just specify `&verbose', and ...
- (main): ... remove the `case 2:' block for --verbose.
-
- * tests/du/basic: Make the test file larger than 64 bytes, so that
- we don't immediately disqualify file systems (e.g., NetApp) on which
- smaller files take up zero disk blocks. Reported by Vin Shelton.
-
-2003-03-10 Jim Meyering <jim@meyering.net>
-
- Don't segfault for a negative field width or precision in format string.
- Note that this is just a stopgap fix. The longer term solution may
- involve adapting bash's builtins/printf.def.
-
- * src/printf.c: (UNSPECIFIED): Define.
- (print_direc): Use the special value, UNSPECIFIED, to indicate
- that field_width or precision has not been specified.
- (print_formatted): Fail if field_width or precision is the
- special value, UNSPECIFIED.
- Reported by Oliver Kiddle <okiddle@yahoo.co.uk>
-
- * src/sys2.h (INT_MIN): Define, if necessary.
- * tests/misc/printf: Add a test for the above-fixed bug.
-
-2003-03-09 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (AD_stack_pop): Cast sizeof... to int before
- changing its sign. This avoids a warning from gcc on 64-bit systems.
- Reported by Bob Proulx.
- (pop_dir): Reverse order of sign change and cast, to be consistent
- with the above.
-
-2003-03-08 Jim Meyering <jim@meyering.net>
-
- * tests/Makefile.am (evar-check): Check for POSIXLY_CORRECT not as a
- shell variable, but only in the environment. With /bin/sh->bash, the
- shell variable is set to `y', and that would cause a spurious warning.
- Reported by Bob Proulx.
-
- * tests/Makefile.am (check-root): Remove touch/fifo.
- It doesn't appear to have to be run as root.
-
- * tests/rm/fail-2eperm: Rather than simply using the first non-root
- user name, make sure that the selected user name has a usable shell.
- Reported by Paul Jarc.
-
- Before, when using shred on a device, one had to specify --exact,
- or be careful to choose a size that would not be rounded up and
- exceed the maximum value; that could result in a failure of
- the final write.
- * src/shred.c (do_wipefd): --exact is now the default for non-regular
- files. Suggestion from Ben Elliston.
- (usage): Say it.
-
- * tests/misc/tty-eof: Require at least version 1.11 of Expect.pm.
- Old versions of Expect.pm (e.g., 1.07) lack the log_user function.
- Patch by Bob Proulx.
-
- * src/Makefile.am (check-misc): Check for use of `defined' in
- #define directives.
- Change to $(srcdir) before running grep.
-
- * src/sleep.c: Remove now-unused #include and #define directives.
-
- * src/du.c (process_file): If a file's size is not being counted
- e.g., because it's a hard link to a file we've already counted,
- then don't print a line for it.
-
- * tests/du/hard-link: New test for the above-fixed bug.
- * tests/du/Makefile.am (TESTS): Add hard-link.
-
- `du -S' didn't work
- * src/du.c: Revert most of the `reorganization' change of 2003-02-20,
- and make the two-array approach work.
-
- * tests/du/basic: Correct/add tests for the above fix.
- Set LC_ALL, etc., now that we use sort.
- Check the block/size of a small file, too.
- Correct expected results for simple dir1/dir2/file case.
- Add another test of du -S.
-
-2003-03-07 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
-
- Avoid build failure with gcc on hppa1.1-hp-hpux10.20 (see GCC PR
- middle-end/9986). As one of GCC's optimizations, it transforms a
- fputs_unlocked call to a fputc_unlocked call when the string is
- one character long. However, hpux doesn't have fputc_unlocked.
-
- * expr.c (usage): Use putchar, not fputs, to output a single character.
- * ls.c (dired_dump_obstack): Likewise.
- * ptx.c (output_one_tex_line, output_one_dumb_line): Likewise.
- * stat.c (print_it): Likewise.
-
-2003-03-07 Jim Meyering <jim@meyering.net>
-
- * src/cp.c: Remove everything associated with mmap-stack.c.
- This reverts the two changes of 2003-02-21.
- * src/du.c: Remove everything associated with mmap-stack.c.
- This reverts the change of 2003-02-19.
-
-2003-03-06 Jim Meyering <jim@meyering.net>
-
- * tests/cp/same-file: Unset CDPATH. Otherwise, having the
- CDPATH shell variable set could cause this test to fail.
- Reported by Karl Berry.
-
-2003-03-05 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.9.
-
- * src/printf.c (print_esc): Remove pointless comparison of unsigned
- integer with zero, to avoid a warning from Intel's ecc.
- Reported by Nelson Beebe.
-
- * src/du.c (process_file): Sizes must all be of type uintmax_t.
- Otherwise, for files or totals that are too big, numbers would
- be truncated. Patch mostly by Michael Stone.
- Reported by Ingo Saitz as Debian bug #183210.
-
- * tests/du/8gb: New test for the above-fixed bug.
- * tests/du/Makefile.am (TESTS): Add 8gb.
-
- * src/du.c (MAX_N_DESCRIPTORS): Use 3 * UTILS_OPEN_MAX / 4
- rather than UTILS_OPEN_MAX - 10.
-
-2003-03-04 Jim Meyering <jim@meyering.net>
-
- * README: Refer new feature discussion to bug-coreutils@gnu.org,
- rather than bug-gnu-utils, now that the former is better known.
- Suggestion from Göran Uddeborg.
-
- * src/stat.c (usage): Capitalize consistently.
- Reported by Göran Uddeborg.
-
- * Makefile.maint (rel-files): Include $(signatures), so that
- those files are also copied into $(release_archive_dir).
-
- * src/df.c (find_mount_point): Call error here, now that restore_cwd
- no longer does it.
- * src/remove.c (AD_pop_and_chdir): Likewise.
-
- * tests/Makefile.am (check-root): Add fail-2eperm.
-
-2003-03-03 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (remove_cwd_entries): Include the full filename of
- the offending file, not just the basename.
-
- * tests/misc/tty-eof: Set $ME properly.
-
- * Makefile.maint (THIS_VERSION_REGEXP, PREV_VERSION_REGEXP):
- Remove now-unused variables.
- (tag-prev-version, prev-cvs-tag): Likewise.
-
- * src/remove.c (remove_cwd_entries) [!ROOT_CAN_UNLINK_DIRS]: Give an
- accurate diagnostic when failing to remove a file owned by some other
- user. Reported by Ivo Timmermans via Michael Stone.
- This fixes Debian bug# 178471.
-
- * tests/rm/Makefile.am (TESTS): Add fail-2eperm.
- * tests/rm/fail-2eperm: New test, for the above-fixed bug.
- Based on a report from Ivo Timmermans.
-
-2003-03-02 Jim Meyering <jim@meyering.net>
-
- * src/copy.c (copy_internal) [un_backup]: When recovering from a
- failure to create a hard link, do not remove the entry associating
- the source dev/ino with the destination file name.
- * tests/mv/Makefile.am (TESTS): Add hard-3.
- * tests/mv/hard-3: New test, for the above-fixed bug.
- Inspired by a report from Iida Yosiaki.
-
-2003-03-01 Jim Meyering <jim@meyering.net>
-
- * src/df.c (print_header): Don't embed spaces in a separate `Type'
- header string. Instead, put `Filesystem' and `Type' headers in the
- same string, so translators can use horizontal space as needed.
- Reported by Jean Charles Delepine.
-
-2003-02-28 Jim Meyering <jim@meyering.net>
-
- * src/copy.c (copy_internal): When link fails because of an
- existing destination file, unlink that file and try again.
- Reported by Iida Yosiaki.
-
- * tests/mv/Makefile.am (TESTS): Add hard-2.
- * tests/mv/hard-2: New test for the above-fixed bug.
- Based on a test case from Iida Yosiaki.
-
-2003-02-26 Jim Meyering <jim@meyering.net>
-
- * tests/du/basic: Don't test du's -b option here. Directory byte
- counts are smaller (512 rather than 4096) on at least OSF/1 5.1
- and IBM AIX 4.2. Reported by Nelson Beebe.
-
-2003-02-25 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (announcement): Now that ChangeLog entries
- are output by announce-gen, don't do it here.
- * announce-gen (print_changelog_deltas): New function.
- (main): Use it.
-
-2003-02-22 Jim Meyering <jim@meyering.net>
-
- * announce-gen: New option: --release-type=TYPE
- * Makefile.maint (beta, major): New targets. Remove `release'.
- Put them all together on a line.
- Pass the release type (via RELEASE_TYPE envvar) to the MAKE
- invocation of `announcement'.
- (announcement): Invoke announce-gen with --release-type=$RELEASE_TYPE.
-
- * announce-gen: New option: --news=NEWS_FILE.
- Extract NEWS entries here, not via rules in Makefile.maint.
- * Makefile.maint (announcement): Now that NEWS entries are
- extracted by announce-gen, don't do it here.
- (news-r1, news-r2): Remove now-unused definitions.
-
-2003-02-21 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.8.
-
- Merge in changes from autoconf's version of this file.
- * Makefile.maint (www-gnu): Define.
- (standards.texi-url_prefix): Use $(www-gnu).
- (make-stds.texi-url_prefix): Likewise.
-
- * src/cp.c: Include "mmap-stack.h".
- (main): Invoke `run' through a macro that (when possible) runs it
- with a large, mmap'd stack.
-
- * src/cp.c (run): New function, preparing for the above.
- Exit from this function, not from main
- (main): Call run.
-
- * src/du.c: New option: --apparent-size.
- (enum) [APPARENT_SIZE_OPTION]: New member.
- (long_options): Add it.
- (usage): Describe it.
- (main): Handle it.
- ['b']: Set apparent_size.
- David Eisner reported that the behavior of --bytes had changed.
- Paul Eggert proposed the use of a new option, --apparent-size.
-
- * src/du.c (apparent_size): New global.
- (print_only_size): Reflect the fact that we're printing byte counts,
- not ST_NBLOCKSIZE-byte-block counts.
- (print_size): Call print_only_size rather than duplicating its code.
- (process_file): Accumulate byte counts, rather than block counts.
-
- * src/du.c (process_file): Always reset size_to_propagate_to_parent
- for --separate-dirs (-S).
-
-2003-02-20 Jim Meyering <jim@meyering.net>
-
- * Use automake-1.7.3. Regenerate dependent files.
-
- * src/stat.c (print_stat): New format: %B (to print ST_NBLOCKSIZE).
- This makes %b (number of ST_NBLOCKSIZE-byte blocks) more useful.
- (usage) [%B]: Describe it.
- [%b]: Refer to %B.
-
- * src/du.c (process_file): Reorganize the code to use only
- one `sum' array, and change how -S works back to the way it was
- before 2003-01-31. Patch by Bruno Haible.
-
- * tests/du/basic: New test.
- * tests/du/Makefile.am (TESTS): Add basic.
-
- * tests/envvar-check: Add checks for the following:
- BLOCK_SIZE, DU_BLOCK_SIZE, DF_BLOCK_SIZE, LS_BLOCK_SIZE.
-
- * tests/Makefile.am: Rename phony target envvar-check to evar-check
- so as not to conflict with the distributed file by the same name.
-
- * src/du.c (process_file): Set info->skip before any possible return.
-
- Report correct usage for directories, not 0.
- * src/du.c (process_file): Return for `file_type == FTW_DPRE'
- _before_ recording the dev/ino of a directory.
- Reported by Bruno Haible.
-
- Now, df always displays the device file name corresponding to the
- listed mount point under `Filesystem'. Before, for an unmounted
- block- or character-special file argument, it would display the
- command-line argument instead.
- * src/df.c (show_disk): Return a value indicating whether
- there was a match. Don't try to find a mount point here.
- (show_entry): If show_disk doesn't find a match, call show_point.
-
-2003-02-19 Jim Meyering <jim@meyering.net>
-
- * src/du.c: Include "mmap-stack.h".
- (du_files): Add prototype with ATTRIBUTE_NORETURN.
- Exit from this function, not from...
- (main): ...here.
- Instead, if possible, invoke du_files through a macro that
- runs it with a large, mmap'd stack.
-
- * src/join.c (usage): Change wording in --help output:
- use FILENUM instead of `SIDE' and say what FILENUM means.
- Reported by Bernhard Gabler.
-
- * src/df.c (print_header): Rather than using a hard-coded literal
- string of spaces matching the length of the English `...Type' header,
- output the right number of spaces to match the selected translation.
- Reported by Yann Dirson and Jean Charles Delepine as Debian bug 131113.
-
- * src/split.c (bytes_split): Remove unnecessary `else' after break.
- (lines_split): Likewise. and correct misleading indentation.
-
- * src/split.c: Include "full-read.h".
- (bytes_split, lines_split, line_bytes_split): Use full_read,
- not safe_read. The way split was using the latter, a short read
- could cause split to terminate before EOF.
-
- * tests/misc/tty-eof: Test all programs that can read stdin,
- requiring no arguments and that write to standard output.
-
- * tests/misc/tty-eof: New file. Renamed from ...
- * tests/misc/cat-tty-eof: Remove file. Rename to tty-eof.
- * tests/misc/Makefile.am (TESTS): Reflect renaming.
-
-2003-02-18 Jim Meyering <jim@meyering.net>
-
- cksum would perform an extra read after encountering EOF
- * src/cksum.c (cksum): Exit the loop upon EOF, too.
- Patch by Michael Bacarella.
-
- Test for the bug fixed today in cksum, md5sum, and sha1sum.
- * tests/misc/cat-tty-eof: Generalize, clean-up, and test for
- cat, cksum, md5sum, and sha1sum all in the same loop.
-
-2003-02-14 Jim Meyering <jim@meyering.net>
-
- * src/remove.c: Include "euidaccess.h".
- Remove declaration of euidaccess.
-
-2003-02-12 Jim Meyering <jim@meyering.net>
-
- * src/pathchk.c (portable_chars_only): Remove unnecessary `const'
- in cast to avoid warning from icc. Reported by Alexandre Duret-Lutz.
-
-2003-02-10 Jim Meyering <jim@meyering.net>
-
- * src/test.c: Don't include group-member.h.
- Include euidaccess.h.
- (eaccess): Rewrite function to set the real uid and gid temporarily
- to the effective uid and gid, then invoke 'access', and then set the
- real uid and gid back. On systems that lack setreuid or setregid,
- fall back on the kludges in euidaccess. Before, it would not work
- for e.g., files with ACLs, files that were marked immutable,
- or on file systems mounted read-only. Nelson Beebe raised the issue.
- Paul Eggert suggested the new implementation.
-
-2003-02-09 Jim Meyering <jim@meyering.net>
-
- * src/test.c (test_stat): Remove function. It's job is done (only
- when necessary) by the wrapper in lib/stat.c. Adjust all uses.
-
-2003-02-08 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.7.
-
- * tests/mv/part-symlink: Don't assume that the file owner username
- length is less than 9 in ls output: instead, omit that field
- altogether. Reported by, and suggested fix from, Ferdinand.
-
- * tests/du/restore-wd: New test for just-fixed bug in ftw.c.
- * tests/du/Makefile.am (TESTS): Add restore-wd.
-
- * src/rm.c: Correct now-invalid comment about cycle-detection.
-
-2003-02-06 Jim Meyering <jim@meyering.net>
-
- * NEWS: Add entries from old/*/NEWS
- from fileutils-4.1 through 4.1.11 and
- from sh-utils-2.0 through 2.0.15. Suggestion from Karl Berry.
-
- * Version 4.5.6.
-
- * src/du.c (process_file): Don't return early for excluded files
- or for files whose dev/inode we've already seen.
-
-2003-02-05 Jim Meyering <jim@meyering.net>
-
- * tests/du/exclude: New file.
- * tests/du/Makefile.am (TESTS): Add exclude.
-
-2003-02-04 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/who.c (print_boottime, print_deadprocs, print_runlevel):
- Fix memory allocation arithmetic.
-
-2003-02-04 Jim Meyering <jim@meyering.net>
-
- `df /dev/block-or-char-device-file--not-mounted' now reports
- the name of the file system on which the file resides, usually `/'.
- Before, it would leave the `Mounted on' field blank.
- * src/df.c (show_disk): Move function to precede find_mount_point.
- (show_disk): Add parameter: STATP.
- If we don't find a matching device name, then resort to calling
- find_mount_point. Reported by Bob Proulx.
-
-2003-02-03 Andreas Schwab <schwab@suse.de>
-
- * tests/rm/cycle: Require non-root.
- * tests/rm/isatty: Likewise.
-
-2003-02-02 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.5.
-
- * man/Makefile.am (check-x-vs-1): Use @PATH_SEPARATOR@, not `:'.
-
- Ensure that there are no offending uses of `:'.
- * Makefile.maint (makefile_path_separator_check): New rule.
- (local-check): Add it to the list.
-
-2003-02-01 Jim Meyering <jim@meyering.net>
-
- * src/du.c (MAX_N_DESCRIPTORS): Define.
-
- * src/stat.c (G_fail): New global.
- (human_time): Diagnose failed localtime, not failed nstrftime.
- (main): Fail if G_fail is set.
-
-2003-01-31 Richard Dawe <rich@phekda.freeserve.co.uk>
-
- * tests/basename/Makefile.am: Use @PATH_SEPARATOR@ instead of
- hard-coding the path-separator. Also double-quote the new PATH,
- to avoid problems when the path-separator is a semi-colon or when
- `pwd` contains e.g. a space.
- * tests/chgrp/Makefile.am: Likewise.
- * tests/chmod/Makefile.am: Likewise.
- * tests/chown/Makefile.am: Likewise.
- * tests/cp/Makefile.am: Likewise.
- * tests/dd/Makefile.am: Likewise.
- * tests/dircolors/Makefile.am: Likewise.
- * tests/du/Makefile.am: Likewise.
- * tests/expr/Makefile.am: Likewise.
- * tests/factor/Makefile.am: Likewise.
- * tests/fmt/Makefile.am: Likewise.
- * tests/install/Makefile.am: Likewise.
- * tests/ln/Makefile.am: Likewise.
- * tests/ls/Makefile.am: Likewise.
- * tests/ls-2/Makefile.am: Likewise.
- * tests/md5sum/Makefile.am: Likewise.
- * tests/misc/Makefile.am: Likewise.
- * tests/mkdir/Makefile.am: Likewise.
- * tests/mv/Makefile.am: Likewise.
- * tests/od/Makefile.am: Likewise.
- * tests/rm/Makefile.am: Likewise.
- * tests/rmdir/Makefile.am: Likewise.
- * tests/seq/Makefile.am: Likewise.
- * tests/sha1sum/Makefile.am: Likewise.
- * tests/shred/Makefile.am: Likewise.
- * tests/stty/Makefile.am: Likewise.
- * tests/sum/Makefile.am: Likewise.
- * tests/tail-2/Makefile.am: Likewise.
- * tests/touch/Makefile.am: Likewise.
- * tests/tsort/Makefile.am: Likewise.
- * tests/unexpand/Makefile.am: Likewise.
-
-2003-01-31 Jim Meyering <jim@meyering.net>
-
- * src/stat.c: Include "file-type.h"
- (print_human_type): Remove function.
- (human_access): Rename from print_human_access. Return a string.
- (human_time): Rename from print_human_time. Return a string.
- (print_stat): Arrange so that field width and an alignment specifier
- are honored for the %A, %F, %x, %y, and %z formats.
- [%F]: Use file_type; this gives slightly different file type strings,
- e.g., `directory' instead of `Directory' and `regular file' or
- `regular empty file' instead of `Regular file'.
- Prompted by a report from Richard Dawe that the uses of
- S_IFSOCK and S_IFIFO in print_human_time were not portable
- to systems using e.g., DJGPP.
-
-2003-01-31 Richard Dawe <rich@phekda.freeserve.co.uk>
-
- * src/stat.c (print_stat): Use S_ISLNK rather than an explicit
- test using S_IFMT and S_IFLNK. S_IFLNK may not be defined.
-
-2003-01-31 Jim Meyering <jim@meyering.net>
-
- * src/du.c (main): Upon processing an invalid option or an invalid
- --exclude-from or --max-depth option argument, don't exit right away,
- in case there are others. Rather record the failure and exit after
- processing other options.
-
- * GNUmakefile (TAR_OPTIONS): Set and export, in order to make
- tar archive easier to reproduce.
-
- Rewrite to perform directory traversal using nftw.
-
- * src/du.c: Include "dirname.h", "ftw.h", and "quotearg.h".
- (AUTHORS): Add self.
- (opt_one_file_system): Move global into `main'.
- (path, xstat, exit_status): Remove declarations.
- (arg_length, suffix_length): New globals.
- (G_fail): New global, sort of like the old `exit_status'.
- (IS_FTW_DIR_TYPE): Define.
- (print_only_size): New function.
- (process_file): New function.
- (str_init, ensure_space, str_copyc, str_concatc): Remove functions.
- (str_trunc, pop_dir, count_entry): Likewise.
- (du_files): Rewrite to use nftw.
-
-2003-01-30 Jim Meyering <jim@meyering.net>
-
- * tests/du/trailing-slash: Ensure that du/ftw follows a command-line
- symlink-to-directory with -L, even without the trailing slash.
-
-2003-01-27 Jim Meyering <jim@meyering.net>
-
- * src/Makefile.am (check-misc): Check for st_blocks, too.
-
- * src/stat.c (print_stat): Use ST_NBLOCKS rather than `->st_blocks'.
- Reported by Richard Dawe.
-
-2003-01-27 Andreas Schwab <schwab@suse.de>
-
- * src/ls.c (quote_name): Add fourth parameter, width, into which to
- store the screen columns, and return the number of bytes instead.
- (print_dir): Pass NULL as fourth parameter of quote_name.
- (print_name_with_quoting): Likewise.
- (length_of_file_name_and_frills): Get the width from the fourth
- parameter of quote_name instead of return value.
-
-2003-01-27 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (decode_switches): If `dired' is set without
- `format == long_format', then silently reset dired. This doesn't
- change the behavior of ls (all prior uses of dired were protected
- by `&& format == long_format'), and lets us...
- (DIRED_INDENT): ... remove the `format == long_format' conjunct.
- (PUSH_CURRENT_DIRED_POS): Likewise.
- (main): Likewise.
-
-2003-01-22 Jim Meyering <jim@meyering.net>
-
- * tests/du/no-x: New test, for functionality added to lib/ftw.c.
- * tests/du/Makefile.am (TESTS): Add no-x.
-
-2003-01-21 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (remove_entry) [ROOT_CAN_UNLINK_DIRS
- && HAVE_STRUCT_DIRENT_D_TYPE]: If a file has d_type == DT_UNKNOWN
- it may still be a directory -- or not (e.g., with FreeBSD on an
- NFS-mounted file system), so resort to calling lstat to find out.
- Based on a patch by Michael van Elst.
-
- * tests/cp/same-file: Don't assume that the file owner username
- length is less than 9 in ls output: instead, omit that field
- altogether. Reported by, and suggested fix from, Ferdinand.
-
-2003-01-20 Jim Meyering <jim@meyering.net>
-
- * tests/date/Test.pm (wide-fmt): New test to demonstrate that
- large format widths no longer cause strftime to infloop.
-
- * Makefile.maint (mail_gpg_sign_cookie): Remove now-unused definition.
-
-2003-01-19 Jim Meyering <jim@meyering.net>
-
- * src/readlink.c: Include "canonicalize.h".
-
-2003-01-18 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (Dereference_symlink) [DEREF_COMMAND_LINE_SYMLINK_TO_DIR]:
- New member.
- (enum) [DEREFERENCE_COMMAND_LINE_SYMLINK_TO_DIR_OPTION]: New member.
- (long_options): Add option --dereference-command-line-symlink-to-dir.
- (main): Make DEREF_COMMAND_LINE_SYMLINK_TO_DIR be the default,
- rather than DEREF_COMMAND_LINE_ARGUMENTS, when none of the
- -d, -F, -l options is specified.
- (decode_switches): Handle --dereference-command-line-symlink-to-dir.
- (gobble_file): Honor DEREF_COMMAND_LINE_SYMLINK_TO_DIR.
- Change --dereference-command-line (-H) to dereference *all*
- command line arguments, including broken symlinks.
-
-2003-01-15 Paul Eggert <eggert@twinsun.com>
-
- Change ls -H back to the way it was yesterday, since this is
- compatible with FreeBSD and the POSIX spec is confusing
- and somewhat contradictory.
-
- * src/ls.c (DEREF_COMMAND_LINE_ARGUMENTS): Change name back
- from DEREF_COMMAND_LINE_SYMLINK_TO_DIR, updating all uses.
- (long_options): Change the long option name back.
- (usage): Change the usage back.
- (gobble_file): When -H is specified, dereference a top-level
- arg even if it points to a non-directory.
-
-2003-01-15 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (gobble_file): Fall back on using lstat when required:
- when --dereference (-L) is not specified, and
- - when operating on a dangling symlink
- - when operating on command-line-symlink-to-directories
- This fixes numerous problems. Here are examples:
- - `ls dangling-symlink' would fail with `no such file...'
- Now it prints `dangling-symlink'.
- - `ls -i symlink' would mistakenly print the inode of the referent.
- Now it prints the inode of the symlink. Likewise for --size (-s).
- Based on a patch from Michael Stone.
- Reported by Deepak Goel as Debian bug #173793.
-
- Rename ls's --dereference-command-line (-H)
- option to --dereference-command-line-symlink-to-dir.
- * src/ls.c [enum Dereference_symlink]
- (DEREF_COMMAND_LINE_SYMLINK_TO_DIR): Rename from
- DEREF_COMMAND_LINE_ARGUMENTS. Update all uses.
- (long_options): Rename the long option.
- (usage): Say that --dereference-... changes how ls treats
- only symlinks to directories specified on the command line.
-
-2003-01-14 Jim Meyering <jim@meyering.net>
-
- * tests/ls/dangle: New file/test, for the above fix.
- * tests/ls/inode: Another new file/test, for the above fix.
- * tests/ls/Makefile.am (TESTS): Add dangle and inode.
-
- * src/ls.c (gobble_file): Fix a bug introduced in 4.5.4 that made it
- so that ls --color would no longer highlight the names of files with
- the execute bit set when not specified on the command line.
- Patch by Michael Stone. Reported by Stephen Depooter as
- Debian bug 175135.
-
- * tests/ls-2/tests (color-exe): New test, for the above fix.
-
-2003-01-13 Jim Meyering <jim@meyering.net>
-
- * tests/shred/exact: Also test for just fixed bug with --zero.
-
- * src/shred.c (long_opts): --zero does not require an argument.
- Patch by Michael Stone. Reported by Roland Turner as Debian bug 172019.
-
-2003-01-12 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (cvs-update): Skip any file with local modifications.
-
- * src/unexpand.c (usage): Document --first-only and mention that
- --tabs=N (-t) enables --all (-a). Reported by wiregauze@yahoo.com.
-
-2002-12-01 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/df.c: Include "canonicalize.h".
- Use canonicalize_file_name unconditionally.
-
-2003-01-09 Jim Meyering <jim@meyering.net>
-
- * README: Add readlink.
-
-2002-11-30 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/df.c: Include "xgetcwd.h".
- * src/pwd.c: Likewise.
-
-2002-11-30 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/shred.c: Remove declaration of xstrdup.
- We already get it via xalloc.h which is included via system.h.
-
-2002-08-27 Dmitry V. Levin <ldv@altlinux.org>
-
- New program: readlink.
-
- * src/Makefile.am (bin_PROGRAMS): Add readlink.
- * src/readlink.c: New file.
-
- * man/readlink.x: New file.
- * man/Makefile.am (dist_man_MANS): Add readlink.1.
- (readlink.1): New rule.
-
-2003-01-09 Jim Meyering <jim@meyering.net>
-
- When selecting ranges of byte offsets (as opposed to ranges of fields)
- and when --output-delimiter=STRING is specified, output STRING between
- ranges of selected bytes.
- * src/cut.c (RANGE_START_SENTINEL): Define.
- (output_delimiter_specified): New global.
- (print_kth): Add parameter. Adjust all callers.
- (set_fields): Mark each range-start index with RANGE_START_SENTINEL.
- (cut_bytes): When requested, output STRING between ranges of
- selected bytes.
- (main): Make a diagnostic a little clearer.
- Based on a patch from Jan Nieuwenhuizen.
-
- * tests/cut/Test.pm: New tests for the above.
-
- * src/cut.c (set_fields): Make code agree with comment:
- Don't merge abutting ranges like 4- and 2-3. This makes no
- difference currently, but is required to support an upcoming change.
-
-2003-01-07 Jim Meyering <jim@meyering.net>
-
- * src/cut.c (set_fields): Fix typo in comment.
-
- * tests/touch/not-owner: New test, mostly extracted from fail-diag.
- * tests/touch/Makefile.am (TESTS): Add not-owner.
- * tests/touch/fail-diag: Remove the test for non-owner diagnostic.
- Now, this tests only the nonexistent-directory diagnostic.
- Suggestion from Michael Stone.
-
- * tests/touch/fail-diag: Fix typo: s/ld/ls/.
-
-2003-01-04 Jim Meyering <jim@meyering.net>
-
- * src/copy.h: Remove use of PARAMS.
- * src/remove.h: Likewise.
- * src/chown-core.h: Likewise.
-
- rm could be tricked into mistakenly reporting a cycle.
- * src/remove.c: [cycle_check_state]: New global.
- (remove_cwd_entries): Adapt to new semantics of cycle_check.
- (rm): Call cycle_check_init and cycle_check_free for each file.
- * tests/rm/cycle (rm): New test, for the above fix.
- * tests/rm/Makefile.am (TESTS): Add cycle.
-
- When rm detects a cycle, don't abort the entire command,
- but rather just the affected command line argument.
- * src/remove.c: Include <setjmp.h>
- (struct dirstack_state) [current_arg_jumpbuf]: New member.
- (remove_cwd_entries): Call longjmp if we detect a cycle.
- (rm): Call setjmp here.
-
- * src/remove.c (cycle_check, is_power_of_two): Remove functions.
- Instead, include cycle-check.h and use it.
-
- * src/remove.h (struct dev_ino): Remove declaration.
-
- * src/remove.c (remove_cwd_entries): Fix typos in comment.
-
- Don't include trailing /. in diagnostics about directories.
- * src/remove.c (full_filename_): When FILENAME is just `.'
- and there is a nonempty directory-name part, don't append `/.'.
- * tests/rm/unread2: Remove trailing /. from diagnostic.
- * tests/rm/rm2: Likewise.
-
- * src/remove.c (struct dirstack_state): Define.
- To be used in place of these file-scoped globals ...
- (dir_stack, len_stack, Active_dir): Remove globals.
- (ds_init, ds_free): New functions.
- (full_filename): Define.
- (full_filename_): Rename from full_filename.
-
- Begin to make AD_* functions more generic.
- * src/remove.c (AD_push_initial): Don't set status to RM_OK here.
- (AD_push): Likewise.
- (AD_INIT_OTHER_MEMBERS): Define.
- (remove_dir): Define the `status' member manually after each
- call to AD_push or AD_push_initial.
-
- * src/Makefile.am (check-misc): New rule, to ensure that no more
- S_IS* macro definitions sneak into the code.
- (check): Depend on check-misc.
-
- * src/remove.c [S_ISLNK]: Don't define. It's already defined in sys2.h.
- * src/du.c (count_entry) [S_ISLNK]: Don't define.
- * src/shred.c [S_ISLNK, S_ISFIFO, S_ISSOCK]: Don't define.
-
-2003-01-03 Jim Meyering <jim@meyering.net>
-
- * src/true.c: Add copyright.
- (AUTHORS): I suppose I've written it.
-
- * src/Makefile.am (false.c): Make the generated file be read-only.
-
-2003-01-04 Jim Meyering <jim@meyering.net>
-
- * src/ls.c: Include "dev-ino.h".
- [struct dev_ino]: Remove declaration.
-
-2003-01-02 Jim Meyering <jim@meyering.net>
-
- * src/cp.c (do_copy): Tweak diagnostic to be consistent with the one
- from mv: s/missing file arguments/missing file argument/.
- With --target-directory=DIR, cp and mv work with a single file argument.
- Reported by Karl Berry.
-
- * tests/rm/isatty: Enable this test.
-
-2002-12-31 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (AD_push_initial): Don't set status to RM_OK here.
- (AD_push): Likewise.
- (AD_INIT_OTHER_MEMBERS): Define.
- (remove_dir): Define the `status' member manually after each
- call to AD_push or AD_push_initial.
-
- * src/ls.c [struct dev_ino]: Remove definition.
- Include "dev-ino.h" instead.
-
-2002-12-28 Jim Meyering <jim@meyering.net>
-
- * tests/du/Makefile.am (TESTS): Add no-deref.
- * tests/du/no-deref: New script.
-
-2002-12-23 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (remove_cwd_entries): Fix typo in comment.
-
-2002-12-21 Jim Meyering <jim@meyering.net>
-
- * announce-gen: Generate MML-formatted announcement.
- This makes it a *lot* harder to send stale MD5/SHA1 signatures.
-
-2002-12-20 Jim Meyering <jim@meyering.net>
-
- * src/touch.c (touch): Change the wording of a diagnostic so
- that it makes sense both when the file exists and when it doesn't.
- Suggestion from Michael Stone.
-
-2002-12-18 Jim Meyering <jim@meyering.net>
-
- * src/stty.c (valid_options): Declare to be static.
-
-2002-12-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.cfg: Remove rules related to generating m4/jm-glibc-io.m4.
-
- * src/chmod.c, src/copy.c, src/copy.h, src/cp-hash.h, src/csplit.c:
- * src/date.c, src/expr.c, src/fmt.c, src/id.c, src/install.c:
- * src/ls.c, src/od.c, src/pathchk.c, src/pr.c, src/remove.c:
- * src/shred.c, src/sort.c, src/stat.c, src/stty.c, src/sum.c:
- * src/tee.c, src/test.c: Remove all uses of `PARAMS'.
-
- * src/remove.c (PARAMS): Remove definition.
- * src/sys2.h: Likewise.
-
- * src/ls.c, src/stat.c, src/date.c: Remove declaration of nstrftime.
- Include strftime.h instead.
-
-2002-12-14 Jim Meyering <jim@meyering.net>
-
- * Makefile.cfg ($(url_dir_list)): Use .../coreutils, not .../fetish.
-
- * src/system.h [! HAVE_DECL_MEMRCHR]: Declare memrchr.
- This is necessary at least for Irix6.5 when using c89.
- Reported by Nelson Beebe.
-
- * tests/misc/Makefile.am (TESTS): Add cat-tty-eof.
-
- * tests/misc/cat-tty-eof: New test.
-
- * src/mknod.c (usage): Specify how major and minor mode numbers
- are interpreted. Report forwarded by Kristin E Thomas.
- * src/mknod.c: Remove now-redundant usage-specifying comment.
-
-2002-12-13 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.4.
-
- * tests/du/trailing-slash: Allow for a directory of size `0'.
- That happens at least on file systems of type tmpfs on linux-2.4.18.
-
- * announce-gen: New script to begin replacing the commands
- associated with the rule here...
- * Makefile.maint (announcement): Invoke announce-gen.
- * Makefile.am (EXTRA_DIST): Add announce-gen.
-
- * tests/cp/preserve-2: New file/test, for latest fix.
- * tests/cp/Makefile.am (TESTS): Add preserve-2.
-
-2002-12-11 TAKAI Kousuke <takai@vlsi.kuee.kyoto-u.ac.jp>
-
- Fix a bug whereby cp would fail to parse an option like
- --preserve=mode,ownership.
- * src/cp.c (decode_preserve_arg): Advance `comma' to
- point the character following the comma.
-
-2002-12-11 Jim Meyering <jim@meyering.net>
-
- * src/pathchk.c (NEED_PATHCONF_WRAPPER): Undefine before defining,
- in case it's already defined.
-
-2002-12-09 Jim Meyering <jim@meyering.net>
-
- * tests/touch/fail-diag: Don't get a test failure if /no exists.
- Instead, evoke a framework failure if /no-$$ exists.
- Reported by Michael Stone.
-
-2002-12-08 Jim Meyering <jim@meyering.net>
-
- * src/du.c (lstat) [! LSTAT_FOLLOWS_SLASHED_SYMLINK]:
- Define to rpl_lstat, so that even on systems like Solaris 5.8,
- du honors (per POSIX) the trailing slash on an argument referring
- to a symlink-to-directory.
-
-2002-12-06 Jim Meyering <jim@meyering.net>
-
- * Use autoconf-2.57. Regenerate dependent files.
- * Use automake-1.7.2. Regenerate dependent files.
-
- * src/ls.c (gobble_file): Also stat the file if it's a
- regular file and --indicator-style=classify (aka -F).
- Thanks to Ed Santiago for opening my eyes.
-
- * tests/ls/file-type: New file. Test for the above.
- A test to contrast ls -F and ls --indicator-style=file-type.
- * tests/ls/Makefile.am (TESTS): Add file-type.
-
-2002-12-04 Jim Meyering <jim@meyering.net>
-
- * tests/ls/follow-slink: Make sure the symlink was created.
- Richard Dawe reported that `ln -s link link' succeeds, but creates
- no file on systems running some version of the DJGPP libc.
-
-2002-12-03 Jim Meyering <jim@meyering.net>
-
- * src/Makefile.am (AUTOMAKE_OPTIONS): Remove definition (to ansi2knr)
- since this package no longer panders to K&R compilers.
-
-2002-12-02 Jim Meyering <jim@meyering.net>
-
- * tests/du/slink: Skip this test if `.' is on a non-local file system.
-
- * tests/Fetish.pm (_at_replace): Do the substitution only if there's
- something to replace.
-
-2002-12-01 Jim Meyering <jim@meyering.net>
-
- * src/stat.c: Don't include <string.h> or <ctype.h>.
- That's already done via system.h.
- * src/dircolors.c: Don't include <ctype.h>.
-
-2002-11-30 Jim Meyering <jim@meyering.net>
-
- * ls.c (gobble_file): Remove the block of code that caused
- `ls --color -F symlink-to-dir' to list the files in
- `symlink-to-dir/.'. Now, it prints `symlink-to-dir@', (just
- like `ls -F symlink-to-dir') but with the addition of highlighting.
- Similarly, `ls --color -dF symlink-to-dir' would print
- `symlink-to-dir/'; now it prints `symlink-to-dir@'.
- Reported by Jeff Sheinberg as Debian bug #168203.
- * tests/ls-2/tests (sl-F-color, sl-dF-color): New tests for the above.
-
- ls is now more efficient: with certain options, it no longer needs
- to stat each directory entry on systems with valid dirent.d_type.
- * src/ls.c (print_dir): Add DT_LNK and DT_REG.
- (main): Make --recursive set format_needs_type, not format_needs_stat.
- (gobble_file): Remove a FIXME comment, now that it's fixed.
-
-2002-11-24 Jim Meyering <jim@meyering.net>
-
- * src/du.c (du_files): Don't strip any trailing slash.
- Rewrite so that `/' is no longer represented internally as
- the empty string.
- (count_entry): When appending a file name component,
- account for the fact that the current path may end in `/'.
- François Pinard reported that `du symlink-to-dir/' was not
- equivalent to `du symlink-to-dir/.'. Now it is.
- * tests/du/trailing-slash: New file/test, for the above fix.
- * tests/du/Makefile.am (TESTS): Add trailing-slash.
-
-2002-11-23 Jim Meyering <jim@meyering.net>
-
- * src/tac.c (output): Declare some local variables to be of type size_t,
- rather than `int' to avoid warnings from gcc.
-
-2002-11-21 Paul Eggert <eggert@twinsun.com>
-
- * src/ls.c (decode_switches): Use case-sensitive matching to
- decode the QUOTING_STYLE environment variable. This is more
- consistent with the documentation, and with --quoting-style.
-
-2002-11-21 Martin Buck <martin.buck@ascom.ch
-
- * src/stty.c (struct speeds): Add support for all baud rates defined
- in linux-2.4.19.
-
-2002-11-19 Jim Meyering <jim@meyering.net>
-
- * tests/sum/sysv: Export LC_ALL=C, to avoid failure when
- run in a UTF locale. Report and suggested fix by Bruno Haible.
- * tests/fmt/basic: Likewise.
-
-2002-11-17 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Update via autoupdate.
- Add `AM_GNU_GETTEXT_VERSION(0.11.5)'.
-
- * src/mv.c (movefile): Don't remove trailing slashes from SOURCE.
- Reported by Hans Ginzel.
-
-2002-11-15 Jim Meyering <jim@meyering.net>
-
- * Makefile.cfg (gnu_rel_host): Define.
- (url_dir_list): Choose from (alpha|ftp).gnu.org depending
- on whether $(VERSION) looks like a major release number.
-
- * Makefile.maint (mail_gpg_sign_cookie): Backslash-escape `#'.
- (release): Rename from `alpha'.
- (alpha): Depend on release.
-
- * Makefile.maint (signatures): Define with ?=, so it's easy to override.
-
-2002-11-14 Jim Meyering <jim@meyering.net>
-
- * Makefile.maint (mail_gpg_sign_cookie): Make optional.
- (announcement): Use the new variable.
-
- * Makefile.maint: Sync with Bison, i.e.:
- (po-check): Scan .l and .y files instead of the
- .c and the .h files that they generate. This fixes the bug
- reported by Tim Van Holder in:
- <http://mail.gnu.org/pipermail/bison-patches/2002-November/001352.html>
- Look for N_ as well as for _. Try to avoid matching #define for
- N_ and _.
- From Paul Eggert.
-
-2002-11-12 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (HAVE_SYMLINKS): Remove unnecessary macro definition.
- Replace sole use with equivalent `#ifdef S_ISLNK'.
- Inconsistency reported by Dmitry V. Levin.
-
-2002-11-11 Jim Meyering <jim@meyering.net>
-
- * src/stat.c (usage): Transform --help items output via s/ - / /,
- so that help2man produces properly formatted man pages.
- Reported by Herbert Xu as Debian bug #168400.
-
-2002-11-10 Jim Meyering <jim@meyering.net>
-
- * src/ls.c (sighandler): Handle SIGTSTP specially.
- Based on suggestions from Solar Designer and Dmitry V. Levin.
- Add comments.
-
- * Makefile.cfg (cvs_files): Define. From autoconf.
- (local_updates): Likewise.
-
- * src/ls.c (restore_default_color_handler, sigtstp_handler):
- Remove functions.
- (sighandler): New function, based on the one in sort.c.
- (main): Use sigaction, if possible; otherwise signal.
- Handle these signals:
- SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, SIGTSTP.
- Don't register our handler if the signal is already being ignored.
-
- * src/dd.c (interrupt_handler): Use raise, rather than kill+getpid.
- * src/csplit.c (interrupt_handler): Likewise.
- * src/sort.c (sighandler): Likewise.
- (main): Declare `i' and `nsigs' to be unsigned, not int.
-
-2002-11-09 Jim Meyering <jim@meyering.net>
-
- ls --color: restore terminal text color upon signal.
- * src/ls.c: Include "full-write.h" and <signal.h>.
- (restore_default_color, restore_default_color_handler): New functions.
- (sigtstp_handler, put_indicator_direct): New functions.
- (main) [print_with_color]: Register signal handlers.
- Patch mostly by Solar Designer and Stanislav Ievlev.
-
- Update from autoconf.
- * Makefile.maint (AMTAR): Remove definition.
- (update, cvs-update, po-update, do-po-update): New rules.
- (wget-update): Update (thus renaming to cvs-update).
- (automake_repo): Use anoncvs@sources.redhat.com.
-
-2002-11-06 Jim Meyering <jim@meyering.net>
-
- * tests/misc/Makefile.am (TESTS): Add printf-hex.
-
- * tests/misc/printf: Be careful to test the code in this package,
- not the shell built-in function.
-
- * src/printf.c (print_esc): A hexadecimal escape sequence has
- at most two hex. digits, not three. Reported by Padraig Brady.
- (usage): Update description.
- * tests/misc/printf-hex: New file/test, for the above fix.
-
-2002-10-07 Paul Eggert <eggert@twinsun.com>
-
- Add support for locale-specific size indications (e.g.,
- thousands-separators) and for explicit size suffixes on output.
-
- * doc/coreutils.texi (Block size): Say that:
- This affects display format as well as block size.
- Fractional block counts are rounded up.
- ls file size blocksize defaults to 1.
- A block size spec preceded by ' generates thousands separators.
- A suffix without a preceding integer generates suffixes.
- (tail invocation): 32k -> 32 KiB.
- (What information is listed): ls -h is now equivalent to
- ls --block-size=human, and ls -H is now equivalent to
- ls --block-size=si. Displayed file size is now always affected by
- --block-size.
-
- * lib/inttostr.c, lib/inttostr.h, lib/imaxtostr.c, lib/offtostr.c,
- lib/umaxtostr.c: New files, taken from GNU tar.
-
- * lib/Makefile.am (libfetish_a_SOURCES): Add imaxtostr.c, offtostr.c,
- umaxtostr.c.
- (EXTRA_DIST): Add inttostr.c.
-
- * lib/human.c, lib/human.h: Rewrite to support locale-specific
- notations like thousands separators.
- Specify what includer of include.h must include beforehand.
- (human_group_digits, human_suppress_point_zero, human_autoscale,
- human_base_1024, human_SI, human_B): New enum values.
- (human_readable): Rename from human_readable_inexact; put the
- options before the sizes. All uses changed. The old human_readable
- function has been removed; use inttostr.h instead.
- (human_options): Renamed from human_block_size, with new signature
- that allows block sizes up to UINTMAX_MAX. All callers changed.
-
- * m4/prereq.m4 (jm_PREREQ_HUMAN): Check for locale.h, localeconv,
- AC_HEADER_STDBOOL. No need to check for limits.h since it's in
- freestanding C89. No need to check for stdlib.h or string.h since
- autoconf does this now.
-
- * src/cksum.c (cksum): Use primitives from inttostr.h, not
- human.h, to print large numbers simply.
- * src/csplit.c (handle_line_error, parse_patterns): Likewise.
- * src/dd.c (print_stats, main): Likewise.
- * src/df.c (print_header): Likewise.
- * src/factor.c (print_factors): Likewise.
- * src/ls.c (print_long_format, print_file_name_and_frills): Likewise.
- * src/shred.c (dopass): Likewise.
- * src/sort.c (checkfp): Likewise.
- * src/sum.c (bsd_sum_file, sysv_sym_file): Likewise.
- * src/tail.c (xlseek): Likewise.
- * src/wc.c (write_counts, wc): Likewise.
-
- * src/df.c (human_output_opts): New var.
- (output_block_size): Now uintmax_t, not int, to handle larger
- block sizes. All uses changed.
- * src/du.c: Likewise.
- * src/ls.c: Likewise.
-
- * src/df.c (print_header): In the header line, prefer SI to human
- representation if it's shorter; if neither is shorter, try to
- intuit what the user would prefer.
-
- * src/expr.c (inttostr): Remove; use new imaxtostr library
- function instead.
-
- * src/ls.c (file_output_block_size): New var, to distinguish
- file sizes from other sizes.
- (decode_switches): Set it.
-
- * src/shred.c (OUTPUT_BLOCK_SIZE): remove.
- (dopass): When printing progress, use floor for what has been done
- so far (since we should be conservative there), and ceiling for
- what needs to be done (since that's what other programs use).
-
-2002-10-19 Jim Meyering <jim@meyering.net>
-
- * src/pinky.c (print_heading): Align TTY and Name headings.
- Reported by Karl Eichwalder.
-
-2002-10-18 Jim Meyering <jim@meyering.net>
-
- * src/split.c (cwrite): Change type of `bytes' parameter to size_t
- Remove now-useless cast.
- (stdread): Remove function.
- (bytes_split): Use size_t instead of int.
- Use safe_read, not stdread.
- (lines_split): Likewise.
- Use memchr rather than a `while' loop.
- (line_bytes_split): Use size_t instead of int.
- Use safe_read, not stdread.
- (main): Add some FIXME comments to remind me to remove casts.
-
- * src/system.h (ST_BLKSIZE): Correct comment describing how to
- reproduce HPUX-11 cat failure. From Petter Reinholdtsen.
-
-2002-10-17 Jim Meyering <jim@meyering.net>
-
- Fix a problem that could make e.g., `cat' misbehave on systems which
- give invalid (unreasonably large) values for stat.st_blksize.
- * src/system.h (ST_BLKSIZE): Ensure that the result is in [1..4MB].
- Reported by Petter Reinholdtsen.
-
-2002-10-14 Jim Meyering <jim@meyering.net>
-
- Specifying a printf conversion specifer as nl's separator string
- could cause nl to segfault.
- * src/nl.c (build_print_fmt): Don't include separator string
- in the printf format; it might contain `%'.
- Use a better bound on the length of the print_fmt buffer.
- (print_lineno): Print the separator here instead.
- Reported by Doug Coleman.
-
- * tests/misc/nl: New file/tests, including a test for the above.
- * tests/misc/Makefile.am (TESTS): Add nl.
-
- * tests/misc/split-l: New test, to make sure `split --lines=N' works.
- * tests/misc/Makefile.am (TESTS): Add split-l.
-
-2002-10-13 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.3.
-
- * src/du.c (usage): Tweak description of --dereference-args/-D.
-
- * src/du.c (count_entry): Also save cwd when dereferencing (via
- --dereference-args, -D) a command-line argument.
- Reported by Michal Svec. Based on a patch by Andreas Schwab.
-
- * src/Makefile.am (../AUTHORS): New target/rule.
-
-2002-10-12 Jim Meyering <jim@meyering.net>
-
- * src/paste.c (paste_parallel): Declare local, `delims_saved', to be
- of type size_t, since that's the way it's used and avoids a warning.
-
- * src/csplit.c (struct cstring) [len]: Declare to be unsigned int,
- since that's how it's always used and avoids a new warning from gcc.
- (read_input): Adapt to new safe_read ABI.
-
- * src/cut.c (cut_fields): Add a temporary size_t variable, n_bytes,
- to avoid warnings.
-
- * src/pinky.c (print_long_entry): fread returns size_t.
- Declare local `bytes' accordingly, to avoid warning.
-
- tail -c +N would perform an extra read after encountering EOF
- [this change is analogous (bytes vs. lines) to the one of 2002-01-27]
- * src/tail.c (start_bytes): Detect EOF, inform caller.
- (tail_bytes): Upon EOF in start_bytes, return immediately.
- (file_lines): Reorganize to use memrchr rather than an explicit loop.
- Adapt to new safe_read ABI.
-
-2002-10-11 Jim Meyering <jim@meyering.net>
-
- * tests/du/deref: New file/test, for the above fix.
- * tests/du/Makefile.am (TESTS): Add deref.
-
-2002-10-10 Jim Meyering <jim@meyering.net>
-
- * tests/ln/Makefile.am (TESTS): Add target-1.
- * tests/ln/target-1: New file/test, for the fix on 2002-10-08.
-
-2002-10-09 Jim Meyering <jim@meyering.net>
-
- * tests/cp/backup-is-src: Ensure that certain environment variables
- are not set (e.g., SIMPLE_BACKUP_SUFFIX). Reported by Duncan Roe.
-
- * tests/tail-2/big-4gb: Mark this as an expensive test; it would
- consume 4GB of disk space on systems without support for sparse files.
- Fix a logic error that'd make it `cat err' even though dd didn't fail.
-
- * src/dircolors.hin (.jar): Fix typo: s/;3$/;31/.
- Patch by steven@magelico.net, forwarded by Michael Stone.
-
- * tests/ls/dired: Ensure that ls produces English messages.
- Patch by Alexey Vyskubov, forwarded by Michael Stone.
-
-2002-10-08 Dmitry V. Levin <ldv@altlinux.org>
-
- * src/ln.c (main): Fix target_directory parsing when n_files == 1.
-
-2002-10-08 Jim Meyering <jim@meyering.net>
-
- * tests/tail-2/big-4gb: Use double quotes around diagnostic.
- Fix syntax in test: use =, not ==.
- Reported by Bob Proulx.
- Change all the rest like this: grep -lR "testing framework'" .\
- |xargs perl -pi -e 's/'\''(\$0: failure in testing framework)'\''/"$1"/'
-
- * src/sum.c (sysv_sum_file): Adapt to new safe_read ABI.
- * src/tr.c (squeeze_filter, read_and_delete, read_and_xlate): Likewise.
- * src/tac.c (save_stdin, tac_stdin_to_mem): Likewise.
- * src/wc.c (wc): Likewise.
-
-2002-10-07 Paul Eggert <eggert@twinsun.com>
-
- * src/cat.c (cat):
- Don't advance the write pointer past the end of the write buffer.
- * src/sort.c (begfield, limfield): Likewise.
-
-2002-10-07 Jim Meyering <jim@meyering.net>
-
- * src/cat.c (simple_cat, cat): Adapt to new safe_read ABI.
- * src/head.c (head_bytes, head_lines): Likewise.
-
-2002-10-06 Jim Meyering <jim@meyering.net>
-
- * src/dd.c (scanargs): Ensure that specified block sizes (specified
- via ibs=N, obs=N, and bs=N) are no larger than SSIZE_MAX.
- (skip, dd_copy): Adapt to new safe_read ABI.
-
- * Makefile.maint (signatures): Define.
- (%.sig): New rule.
- (announcement): Depend on $(signatures).
-
- * Makefile.maint (announcement): Output all URLs for detached
- signatures, not just the last one from the previous loop.
-
-2002-10-05 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.2.
-
- * src/remove.c (remove_entry) [ROOT_CAN_UNLINK_DIRS]: With `rm -i DIR',
- don't recurse into directory, DIR. Prompted by a report from
- Leonardo Milano.
-
- * tests/rm/i-no-r: New file/test, for the above fix.
- * tests/rm/Makefile.am (TESTS): Add i-no-r.
-
- * tests/tail-2/big-4gb: New file/test, for the fix of 2002-09-27.
- * tests/tail-2/Makefile.am (TESTS): Add big-4gb.
-
-2002-10-03 Jim Meyering <jim@meyering.net>
-
- * src/rm.c (AUTHORS): Mark translatable string with `N_ (...)'.
- * src/df.c (AUTHORS): Likewise.
- * src/du.c (AUTHORS): Likewise.
- * src/tail.c (AUTHORS): Likewise.
- * src/touch.c (AUTHORS): Likewise.
-
-2002-10-02 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (SUBDIRS): Remove `old'.
- (EXTRA_DIST): List the files in old/.
- * configure.ac (AC_CONFIG_FILES): Remove old/* names.
- Suggestion from Akim Demaille.
-
-2002-10-01 Jim Meyering <jim@meyering.net>
-
- * src/sys2.h (SSIZE_MAX): Define.
-
-2002-09-30 Jim Meyering <jim@meyering.net>
-
- * src/csplit.c: Don't include stdlib.h here. It's already included
- via system.h.
-
-2002-09-29 Jim Meyering <jim@meyering.net>
-
- * src/tr.c (find_bracketed_repeat): Rearrange pointer/integer
- expression to avoid bogus warning from gcc.
-
- * src/cat.c (simple_cat): Use a temporary to avoid bogus warnings.
- (cat): Declare insize and outsize to be of type size_t, not int.
- Rearrange pointer/integer expressions to avoid bogus warnings.
- (main): Declare insize and outsize to be of type size_t, not int.
-
- * src/tail.c (parse_options): Give a sensible diagnostic for
- an invalid byte or line count. Reported by Mikko Tuumanen.
-
- * src/touch.c (main): Split a long line.
-
- * tests/du/Makefile.am (TESTS): Add slink.
- * tests/du/slink: New test for system.h change of 2002-08-31.
-
- In move mode, always first try to rename. Before, upon failure to
- rename a directory, this code would never attempt to rename any
- other file in that directory, but would thenceforth always copy.
- On some systems (e.g., NetApp's OnTap-6.4), renaming a directory
- may fail with EXDEV, yet renaming files within that directory to
- a newly-created destination directory succeeds.
- * src/copy.c (copy_internal): Remove local, move_mode;
- use x->move_mode instead. Based on a patch from Tom Haynes.
-
-2002-09-28 Jim Meyering <jim@meyering.net>
-
- * src/split.c (FAIL_ONLY_ONE_WAY): New macro.
- Factor out some duplication.
- (main): Use it.
- [case 'a']: Use strtoul rather than strtol to avoid compiler warnings.
-
- * src/sort.c (begfield, limfield): Rearrange comparisons to avoid
- compiler warnings.
- (fillbuf, keycompare): Cast literal `-1' to size_t in comparisons,
- to avoid compiler warnings.
-
- * src/shred.c (dopass): Use a uintmax_t temporary to avoid bogus
- compiler warnings.
-
- Fix things so `mkdir -p' can create very deep directories, e.g.,
- mkdir -p $(perl -e 'print "a/" x 40000') now works.
- * src/mkdir.c (main): For --parents (-p), call make_path with the
- entire directory name, so we don't ever require that file operations
- like stat or chmod be performed on the entire command line argument.
- * makepath.c (make_path): Restore umask *before* creating the final
- component.
-
-2002-09-27 Andreas Schwab <schwab@suse.de>
-
- * src/tail.c (tail_bytes): Change type of bytes_remaining to off_t
- to avoid overflow. Reported by Hans Lermen.
-
-2002-09-26 Jim Meyering <jim@meyering.net>
-
- * src/install.c (get_ids): Use strtoul, not strtol. Remove some casts.
-
-2002-09-25 Jim Meyering <jim@meyering.net>
-
- * src/test.c (eaccess): Change type of local `euid' from int to uid_t
- and add a cast, to avoid a warning about `signed and unsigned type in
- conditional expression'.
-
-2002-09-22 Jim Meyering <jim@meyering.net>
-
- * src/rmdir.c: Include "dirname.h", for declaration of
- strip_trailing_slashes.
-
- * src/stat.c (PRIdMAX, PRIuMAX): Remove definitions.
- Now they're defined through system.h.
-
- * src/cp-hash.c, src/dd.c, src/df.c, src/du.c, src/ls.c,
- * src/stat.c, src/wc.c: Remove all inclusions of inttypes.h,
- since it's already included from sys2.h via system.h.
-
- * Use automake-1.6f. Regenerate dependent files.
-
- * src/Makefile.am (PERL): Remove duplicate definition.
-
- fmt's -s, -t, -c options didn't work properly for long lines.
- Since get_line may end up calling put_paragraph (for long lines),
- be sure to set global, `other_indent', before it is used there.
-
- * src/fmt.c (set_other_indent): New function, factored out of...
- (get_paragraph): ... here. Call it.
- (get_line): Call set_other_indent before calling flush_paragraph,
- which calls fmt_paragraph, which in turn calls put_paragraph,
- which uses other_indent.
-
- * tests/fmt/Makefile.am (TESTS): Add long-line.
- * tests/fmt/long-line: New file/test, for the above fix.
-
-2002-09-21 Jim Meyering <jim@meyering.net>
-
- * src/od.c: No longer include deprecated <values.h>.
- It was required solely for now-removed reference to BITSPERBYTE.
- * src/install.c: Likewise.
- Suggestion from Bruno Haible.
-
-2002-09-06 Andreas Schwab <schwab@suse.de>
-
- `rmdir -p dir-specified-with-trailing-slash/' would fail.
- * src/rmdir.c (remove_parents): Strip trailing slashes.
-
-2002-09-20 Jim Meyering <jim@meyering.net>
-
- * tests/rmdir/t-slash: New file/test, for the above fix.
- * tests/rmdir/Makefile.am (TESTS): Add t-slash.
-
- * Makefile.maint (announcement): Arrange to gpg-sign the message.
- Add a URL for each detached signature file.
-
-2002-09-07 Bruno Haible <bruno@clisp.org>
-
- * configure.ac: Add need-ngettext to AM_GNU_GETTEXT invocation.
-
-2002-09-18 Jim Meyering <jim@meyering.net>
-
- `od -t x8' used the wrong (`l'-prefixed) printf format.
- Likewise for the o8 and u8 formats.
- * src/od.c (ISPEC_TO_FORMAT): Define macro.
- (decode_one_format): Use PRIdMAX, PRIoMAX, etc. for LONG_LONG.
- Reported by Arun Sharma.
-
-2002-09-17 Jim Meyering <jim@meyering.net>
-
- * src/sys2.h (PRIdMAX, PRIoMAX, PRIuMAX, PRIxMAX): Define if necessary.
- From gettext's intl/loadmsgcat.c.
-
- * tests/od/x8: New file/test, for the above fix.
- * tests/od/Makefile.am (TESTS): Add x8.
-
-2002-09-15 Jim Meyering <jim@meyering.net>
-
- * Use autoconf-2.54. Regenerate dependent files.
-
- * src/csplit.c (get_format_width): Add cast to avoid
- warning about `signed and unsigned type in conditional expression'.
-
-2002-09-14 Jim Meyering <jim@meyering.net>
-
- * src/who.c (print_user): Change type of local to size_t
- to avoid warnings about `comparison between signed and unsigned'.
- * src/ptx.c (generate_all_output): Likewise.
-
- * src/dd.c (main, skip): Add casts to avoid warnings about
- `comparison between signed and unsigned'.
-
- * src/id.c (print_full_info, print_group_list): Add casts to avoid
- warnings about `signed and unsigned type in conditional expression'.
-
- * src/md5sum.c: Change type of global, digest_hex_bytes, to size_t
- to avoid warnings about `comparison between signed and unsigned'.
- (split_3): Change parameter names to be readable and add comment.
- Clean up the test for whether a line may be ignored.
-
-2002-09-13 Jim Meyering <jim@meyering.net>
-
- * src/printf.c (main): Handle leading command line argument of `--'.
- Reported by Raul: DervishD <raul@pleyades.net>
- * tests/misc/printf: New file: test for the above.
- * tests/misc/Makefile.am (TESTS): Add printf.
-
- * src/date.c (usage): Explain that %S's range of [0..60] is required --
- rather than 0..59 -- to accommodate the occasional positive leap second.
- Reported by Richard Neill.
-
-2002-09-12 Jim Meyering <jim@meyering.net>
-
- * src/Makefile.am (nanosec_libs): Define.
- (sleep_LDADD, tail_LDADD): Use it here.
-
- Factor nanosleep-related code into ../lib/xnanosleep.c.
- * src/sleep.c: Include xnanosleep.h.
- Factor out fenv.h-related code.
- (timespec_subtract): Remove function.
- (main): Remove code that deals with computing start and stop times
- as well as the loop around nanosleep. Now that's in xnanosleep.c.
-
- Allow S (in --sleep-interval=S) to be a floating point value.
- * src/tail.c: Include xnanosleep.h and xstrtod.h.
- Move declaration of global variable, sleep_interval, to ...
- (main): ...here.
- (usage): Update description of --sleep-interval option.
- (tail_forever): New parameter, sleep_interval. Update caller.
- Use xnanosleep, rather than sleep.
- (parse_options): New parameter, sleep_interval. Update caller.
- Use xstrtod, now that we accept floating point values.
- Prompted by a patch from Augey Mikus.
-
-2002-09-06 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (prompt): Change comment to give a better note to
- translators. From Michael Piefel.
-
-2002-09-02 Jim Meyering <jim@meyering.net>
-
- * README: A good problem report/patch includes diffs against
- the most recent test release.
-
- * src/pathchk.c (NEED_PATHCONF_WRAPPER): Define.
- (pathconf_wrapper): Define only if NEED_PATHCONF_WRAPPER is set.
-
- * src/kill.c (print_table_row): Use an unsigned type for widths
- to avoid warning about comparison between signed and unsigned.
- (list_signals): Likewise.
-
- * src/od.c (skip): Add a cast to avoid warning about comparison
- between signed and unsigned.
- * src/install.c (get_ids): Likewise. Also rearrange range-checking
- comparisons to make them more readable.
-
-2002-09-01 Jim Meyering <jim@meyering.net>
-
- * Version 4.5.1.
-
-2002-08-31 Jim Meyering <jim@meyering.net>
-
- Symlinks were always reported as using 0 blocks.
- * src/system.h (ST_NBLOCKS): Don't depend on file type.
- This reverts the change of 2000-01-30.
- Based on a report and patch from Neil Brown via Michael Stone.
- This fixes Debian Bug#156358.
-
- * Most files: Change `exit (0)' to `exit (EXIT_SUCCESS)',
- `exit (1)' to `exit (EXIT_FAILURE)', and
- `usage (1)' to `usage (EXIT_FAILURE)'.
-
- * chgrp.c, chmod.c, chown.c, chroot.c, cp.c, date.c, dd.c, du.c,
- * hostname.c, id.c, install.c, ln.c, mkdir.c, mkfifo.c, mknod.c,
- * nice.c, pinky.c, printf.c, pwd.c, shred.c, sleep.c, stty.c,
- * su.c, tac-pipe.c, tail.c, tee.c, touch.c, uname.c, uptime.c,
- * users.c, who.c: Change `error (1, ...' to `error (EXIT_FAILURE, ...'.
- But don't change `error (0, ...' to `error (EXIT_SUCCESS, ...', since
- error never exits successfully.
-
-2002-08-29 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (remove_cwd_entries): Use closedir (not CLOSEDIR)
- when ignoring any return value.
-
- * src/remove.c (remove_cwd_entries): Detect and diagnose readdir
- failures. On some systems (at least EMC Celerra and Solaris5.8),
- this appears to be necessary.
- (is_empty_dir): Likewise. Also, always close directory handle.
- * src/ls.c (print_dir): Likewise.
- (print_dir): Rename local variable: reading -> dirp.
- Reported by Mike Coleman.
-
-2002-08-28 Jim Meyering <jim@meyering.net>
-
- * src/remove.c (remove_cwd_entries): Use CLOSEDIR, not closedir.
- Give a diagnostic and fail if closedir fails.
-
-2002-08-26 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (THANKS-to-translators): New rule.
- (EXTRA_DIST): Add both THANKS-to-translators and THANKStt.in.
- * THANKStt.in: New file.
-
- * src/cat.c (close_stdout_wrapper): New, kludgey, function and
- file-scoped global.
- (main): Register it with atexit.
- Close STDOUT_FILENO, to avoid a problem when writing to
- /dev/audio on at least Solaris 5.7 and 5.8 systems.
- Reported by Shing-Shong Shei.
-
-2002-08-25 Jim Meyering <jim@meyering.net>
-
- * src/cat.c (main): Close STDIN_FILENO rather than a literal `0'.
- * src/tac.c (main): Likewise.
- * src/tail.c (main): Likewise.
- * src/tee.c (main): Likewise.
- * src/tr.c (main): Likewise.
- * src/wc.c (main): Likewise.
-
-2002-08-20 Jim Meyering <jim@meyering.net>
-
- * tests/mv/setup: Rewrite not to use `: ${VAR=not_set}' paradigm.
-
-2002-08-10 Paul Eggert <eggert@twinsun.com>
-
- * src/nohup.sh: Don't use "exec --"; it's not portable and
- shouldn't be needed.
-
-2002-08-09 Jim Meyering <jim@meyering.net>
-
- * src/pr.c (main): Don't ignore -COLUMN if it's the last option.
- (usage): Clarify help text for the -COLUMN option.
- Patch by Padraig Brady.
- * tests/pr/Test.pm [col-last]: New test for the above.
-
- * configure.ac: Start with version 4.5.1, chosen so that it's larger
- than the latest version numbers of the component packages.
-
- * man/Makefile.am (check-x-vs-1): Set and export PATH so we use
- programs in ../src.
-
-2002-08-08 Jim Meyering <jim@meyering.net>
-
- * src/date.c: Guard inclusion of <langinfo.h> with
- `#if HAVE_LANGINFO_CODESET', not `#if HAVE_LANGINFO_H'.
- * src/sort.c: Likewise.
- Patch by GOTO Masanori.
-
-2002-08-05 Paul Eggert <eggert@twinsun.com>
-
- Fix some minor time-related bugs with POSIX time arguments.
- Some valid time stamps were being rejected (notably -1, and
- time stamps before 1900 on 64-bit hosts). And some invalid
- time stamps were being accepted, e.g. September 31.
-
- * src/date.c (main): Adjust to posixtime signature change.
- * src/touch.c (main): Likewise. Remove unnecessary initialization.
- Use localtime, not posixtm, to warn about obsolete "touch".
-
-2002-08-05 Jim Meyering <jim@meyering.net>
-
- * tests/misc/Makefile.am (TESTS): Add nice and pathchk1.
-
-2002-08-04 Jim Meyering <jim@meyering.net>
-
- * src/Makefile.am (check-README): New target/rule.
- (check): Depend on it.
-
- * configure.ac (AC_CONFIG_FILES): Add old/Makefile and old/*/Makefile.
-
-2002-08-03 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (SUBDIRS): Add old.
- * old/: New directory, containing legacy ChangeLog* and NEWS files
- from the fileutils, sh-utils, and textutils packages.
-
- * src/Makefile.am (AM_INSTALLCHECK_STD_OPTIONS_EXEMPT): Set to false.
-
-2002-08-02 Paul Eggert <eggert@twinsun.com>
-
- * NEWS, doc/coreutils.texi: uniq now obeys LC_COLLATE.
-
- * src/uniq.c: Include hard-locale.h, xmemcoll.h.
- (hard_LC_COLLATE): New var.
- (different): Args are now char *, not const char *.
- Use xmemcoll instead of memcmp to compare lines, so that
- LC_COLLATE has effect. However, use memcmp if it is an
- easy locale.
- (check_file): Do not include newline in comparison, so that
- xmemcoll has a byte to stomp on temporarily.
- (main): Set hard_LC_COLLATE.
-
-2002-07-29 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (SUBDIRS): Remove djgpp, for now.
-
-2002-07-20 Jim Meyering <jim@meyering.net>
-
- * Makefile.am (false.c): Convert only the final EXIT_SUCCESS
- into EXIT_FAILURE. Otherwise, false --help and false --version
- would fail.
-
-2002-07-08 Jim Meyering <jim@meyering.net>
-
- * src/Makefile.am (uninstall-local): Search for @GNU_PACKAGE@,
- rather than the hard-coded `sh-utils'.
-
-2002-07-01 Jim Meyering <jim@meyering.net>
-
- * configure.ac: Merge the three files from fileutils,
- textutils, and sh-utils.
- * Makefile.am: Likewise.
- * src/Makefile.am: Likewise.
diff --git a/contrib/gnu-sort/FREEBSD-upgrade b/contrib/gnu-sort/FREEBSD-upgrade
deleted file mode 100644
index 5cb5371..0000000
--- a/contrib/gnu-sort/FREEBSD-upgrade
+++ /dev/null
@@ -1,14 +0,0 @@
-$FreeBSD$
-
-GNU Sort
- originals can be found at: ftp://ftp.gnu.org/gnu/coreutils/
-
-Configure by:
- ./configure --disable-nls --without-libiconv-prefix \
- --without-libintl-prefix
-
-Imported by:
-
- cvs import \
- -m "Virgin import (trimmed) of GNU Sort, coreutils 5.2.1" \
- src/contrib/gnu-sort FSF SORT_v5_2_1
diff --git a/contrib/gnu-sort/INSTALL b/contrib/gnu-sort/INSTALL
deleted file mode 100644
index 54caf7c..0000000
--- a/contrib/gnu-sort/INSTALL
+++ /dev/null
@@ -1,229 +0,0 @@
-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
-Foundation, Inc.
-
- This file is free documentation; the Free Software Foundation gives
-unlimited permission to copy, distribute and modify it.
-
-Basic Installation
-==================
-
- These are generic installation instructions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. (Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.)
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You only need
-`configure.ac' if you want to change it or regenerate `configure' using
-a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system. If you're
- using `csh' on an old version of System V, you might need to type
- `sh ./configure' instead to prevent `csh' from trying to execute
- `configure' itself.
-
- Running `configure' takes awhile. While running, it prints some
- messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package.
-
- 4. Type `make install' to install the programs and any data files and
- documentation.
-
- 5. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
- If you have to use a `make' that does not support the `VPATH'
-variable, you have to compile the package for one architecture at a
-time in the source code directory. After you have installed the
-package for one architecture, use `make distclean' before reconfiguring
-for another architecture.
-
-Installation Names
-==================
-
- By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc. You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the `--target=TYPE' option to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-will cause the specified gcc to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of the options to `configure', and exit.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
-
diff --git a/contrib/gnu-sort/NEWS b/contrib/gnu-sort/NEWS
deleted file mode 100644
index 31f459b..0000000
--- a/contrib/gnu-sort/NEWS
+++ /dev/null
@@ -1,904 +0,0 @@
-GNU coreutils NEWS -*- outline -*-
-
-* Major changes in release 5.3.0 (2004-03-17) [unstable]
-
-** Bug fixes
-
- rm (without -f) no longer hangs when attempting to remove a symlink
- to a file on an off-line NFS-mounted partition.
-
- cut's --output-delimiter=D option works with abutting byte ranges.
-
- rm no longer gets a failed assertion under some unusual conditions.
-
- Several fixes to chgrp and chown for compatibility with POSIX and BSD:
-
- Do not affect symbolic links by default.
- Now, operate on whatever a symbolic points to, instead.
- To get the old behavior, use --no-dereference (-h).
-
- --dereference now works, even when the specified owner
- and/or group match those of an affected symlink.
-
- Check for incompatible options. When -R and --dereference are
- both used, then either -H or -L must also be used. When -R and -h
- are both used, then -P must be in effect.
-
- -H, -L, and -P have no effect unless -R is also specified.
- If -P and -R are both specified, -h is assumed.
-
- Do not optimize away the chown() system call when the file's owner
- and group already have the desired value. This optimization was
- incorrect, as it failed to update the last-changed time and reset
- special permission bits, as POSIX requires.
-
- Do not report an error if the owner or group of a
- recursively-encountered symbolic link cannot be updated because
- the file system does not support it.
-
- md5sum and sha1sum now report an error when given so many input
- lines that their line counter overflows, instead of silently
- reporting incorrect results.
-
- rm no longer requires read access to the current directory.
-
- "sort -o -" now writes to a file named "-" instead of to standard
- output; POSIX requires this.
-
- tail -f no longer mishandles pipes and fifos. With no operands,
- tail now ignores -f if standard input is a pipe, as POSIX requires.
-
- For some types of errors (e.g., read-only file system, I/O error)
- when first encountering a directory, `rm -r' would mistakenly fail
- to remove files under that directory.
-
- If d/x is a directory and x a file, "ln x d/" now reports an error
- instead of incorrectly creating a link to d/x/x.
-
- Fixes for "nice":
-
- If it fails to lower the nice value due to lack of permissions,
- it goes ahead and runs the command anyway, as POSIX requires.
-
- It no longer incorrectly reports an error if the current nice
- value happens to be -1.
-
- It no longer assumes that nice values range from -20 through 19.
-
- It now consistently adjusts out-of-range nice values to the
- closest values in range; formerly it sometimes reported an error.
-
- ptx now diagnoses invalid values for its --width=N (-w)
- and --gap-size=N (-g) options.
-
- tee now exits when it gets a SIGPIPE signal, as POSIX requires.
- To get tee's old behavior, use the shell command "(trap '' PIPE; tee)".
- Also, "tee -" now writes to standard output instead of to a file named "-".
-
- ls no longer segfaults on systems for which SIZE_MAX != (size_t) -1
-
- echo now conforms to POSIX better. It supports the \0ooo syntax for
- octal escapes, and \c now terminates printing immediately. If
- POSIXLY_CORRECT is set and the first argument is not "-n", echo now
- outputs all option-like arguments instead of treating them as options.
-
- printf has several changes:
-
- It now uses 'intmax_t' (not 'long int') to format integers, so it
- can now format 64-bit integers on most modern hosts.
-
- On modern hosts it now supports the C99-inspired %a, %A, %F conversion
- specs, the "'" and "0" flags, and the ll, j, t, and z length modifiers
- (this is compatible with recent Bash versions).
-
- The printf command now rejects invalid conversion specifications
- like %#d, instead of relying on undefined behavior in the underlying
- printf function.
-
- who now prints user names in full instead of truncating them after 8 bytes.
-
-** New features
-
- For efficiency, `sort -m' no longer copies input to a temporary file
- merely because the input happens to come from a pipe. As a result,
- some relatively-contrived examples like `cat F | sort -m -o F - G'
- are no longer safe, as `sort' might start writing F before `cat' is
- done reading it. This problem cannot occur unless `-m' is used.
-
- When outside the default POSIX locale, the 'who' and 'pinky'
- commands now output time stamps like "2004-06-21 13:09" instead of
- the traditional "Jun 21 13:09".
-
- pwd now works even when run from a working directory whose name
- is longer than PATH_MAX.
-
- cp, install, ln, and mv have a new --no-target-directory (-T) option,
- and -t is now a short name for their --target-directory option.
-
- cp -pu and mv -u (when copying) now don't bother to update the
- destination if the resulting time stamp would be no newer than the
- preexisting time stamp. This saves work in the common case when
- copying or moving multiple times to the same destination in a file
- system with a coarse time stamp resolution.
-
- dd has new conversions for the conv= option:
-
- nocreat do not create the output file
- excl fail if the output file already exists
- fdatasync physically write output file data before finishing
- fsync likewise, but also write metadata
-
- dd has new iflag= and oflag= options with the following flags:
-
- append append mode (makes sense for output file only)
- direct use direct I/O for data
- dsync use synchronized I/O for data
- sync likewise, but also for metadata
- nonblock use non-blocking I/O
- nofollow do not follow symlinks
-
- stty now provides support (iutf8) for setting UTF-8 input mode.
-
- With stat, a specified format is no longer automatically newline terminated.
- If you want a newline at the end of your output, append `\n' to the format
- string.
-
- 'df', 'du', and 'ls' now take the default block size from the
- BLOCKSIZE environment variable if the BLOCK_SIZE, DF_BLOCK_SIZE,
- DU_BLOCK_SIZE, and LS_BLOCK_SIZE environment variables are not set.
- Unlike the other variables, though, BLOCKSIZE does not affect
- values like 'ls -l' sizes that are normally displayed as bytes.
- This new behavior is for compatibility with BSD.
-
- du accepts a new option --files0-from=FILE, where FILE contains a
- list of NUL-terminated file names.
-
- `date -d' and `touch -d' now accept integer counts of seconds since
- 1970 when prefixed by `@'. For example, `@321' represents
- 1970-01-01 00:05:21 UTC.
-
- `date -d', `date -f' and `touch -d' now handle fractional time
- stamps like 2004-02-27 14:19:13.489392193.
-
- `date' has a new option --iso-8601=ns that outputs
- nanosecond-resolution time stamps.
-
- echo -e '\xHH' now outputs a byte whose hexadecimal value is HH,
- for compatibility with bash.
-
- In the following cases POSIX allows the default GNU behavior,
- so when POSIXLY_CORRECT is set:
-
- false, printf, true, unlink, and yes all support --help and --option.
- ls supports TABSIZE.
- pr no longer depends on LC_TIME for the date format in non-POSIX locales.
- printf supports \u, \U, \x.
- tail supports two or more files when using the obsolete option syntax.
-
- The usual `--' operand is now supported by chroot, hostid, hostname,
- pwd, sync, and yes.
-
- The stat option --filesystem has been renamed to --file-system, for
- consistency with POSIX "file system" and with cp and du --one-file-system.
-
-** Removed features
-
- tail's undocumented --max-consecutive-size-changes option has been removed.
-
-* Major changes in release 5.2.1 (2004-03-12) [stable]
-
-** Bug fixes
-
- mv could mistakenly fail to preserve hard links when moving two
- or more arguments between partitions.
-
- `cp --sparse=always F /dev/hdx' no longer tries to use lseek to create
- holes in the destination.
-
- nohup now sets the close-on-exec flag for its copy of the stderr file
- descriptor. This avoids some nohup-induced hangs. For example, before
- this change, if you ran `ssh localhost', then `nohup sleep 600 </dev/null &',
- and then exited that remote shell, the ssh session would hang until the
- 10-minute sleep terminated. With the fixed nohup, the ssh session
- terminates immediately.
-
- `expr' now conforms to POSIX better:
-
- Integers like -0 and 00 are now treated as zero.
-
- The `|' operator now returns 0, not its first argument, if both
- arguments are null or zero. E.g., `expr "" \| ""' now returns 0,
- not the empty string.
-
- The `|' and `&' operators now use short-circuit evaluation, e.g.,
- `expr 1 \| 1 / 0' no longer reports a division by zero.
-
-** New features
-
- `chown user.group file' now has its traditional meaning even when
- conforming to POSIX 1003.1-2001, so long as no user has a name
- containing `.' that happens to equal `user.group'.
-
-
-* Major changes in release 5.2.0 (2004-02-19) [stable]
-
-** Bug fixes
-
- none
-
-
-* Major changes in release 5.1.3 (2004-02-08): candidate to become stable 5.2.0
-
-** Bug fixes
-
- `cp -d' now works as required even on systems like OSF V5.1 that
- declare stat and lstat as `static inline' functions.
-
- time stamps output by stat now include actual fractional seconds,
- when available -- or .0000000 for files without that information.
-
- seq no longer infloops when printing 2^31 or more numbers.
- For reference, seq `echo 2^31|bc` > /dev/null takes about one hour
- on a 1.6 GHz Athlon 2000 XP. Now it can output 2^53-1 numbers before
- misbehaving.
-
-* Major changes in release 5.1.2 (2004-01-25):
-
-** Bug fixes
-
- rmdir -p exits with status 1 on error; formerly it sometimes exited
- with status 0 when given more than one argument.
-
- nohup now always exits with status 127 when it finds an error,
- as POSIX requires; formerly it sometimes exited with status 1.
-
- Several programs (including cut, date, dd, env, hostname, nl, pr,
- stty, and tr) now always exit with status 1 when they find an error;
- formerly they sometimes exited with status 2.
-
- factor no longer reports a usage error if stdin has the wrong format.
-
- paste no longer infloops on ppc systems (bug introduced in 5.1.1)
-
-
-* Major changes in release 5.1.1 (2004-01-17):
-
-** Configuration option
-
- You can select the default level of POSIX conformance at configure-time,
- e.g., by ./configure DEFAULT_POSIX2_VERSION=199209
-
-** Bug fixes
-
- fold -s works once again on systems with differing sizes for int
- and size_t (bug introduced in 5.1.0)
-
-** New features
-
- touch -r now specifies the origin for any relative times in the -d
- operand, if both options are given. For example, "touch -r FOO -d
- '-5 seconds' BAR" sets BAR's modification time to be five seconds
- before FOO's.
-
- join: The obsolete options "-j1 FIELD", "-j2 FIELD", and
- "-o LIST1 LIST2..." are no longer supported on POSIX 1003.1-2001 systems.
- Portable scripts should use "-1 FIELD", "-2 FIELD", and
- "-o LIST1,LIST2..." respectively. If join was compiled on a
- POSIX 1003.1-2001 system, you may enable the old behavior
- by setting _POSIX2_VERSION=199209 in your environment.
-
-
-* Major changes in release 5.1.0 (2003-12-21):
-
-** New features
-
- chgrp, chmod, and chown can now process (with -R) hierarchies of virtually
- unlimited depth. Before, they would fail to operate on any file they
- encountered with a relative name of length PATH_MAX (often 4096) or longer.
-
- chgrp, chmod, chown, and rm accept the new options:
- --preserve-root, --no-preserve-root (default)
-
- chgrp and chown now accept POSIX-mandated -L, -H, and -P options
-
- du can now process hierarchies of virtually unlimited depth.
- Before, du was limited by the user's stack size and it would get a
- stack overflow error (often a segmentation fault) when applied to
- a hierarchy of depth around 30,000 or larger.
-
- du works even when run from an inaccessible directory
-
- du -D now dereferences all symlinks specified on the command line,
- not just the ones that reference directories
-
- du now accepts -P (--no-dereference), for compatibility with du
- of NetBSD and for consistency with e.g., chown and chgrp
-
- du's -H option will soon have the meaning required by POSIX
- (--dereference-args, aka -D) rather then the current meaning of --si.
- Now, using -H elicits a warning to that effect.
-
- When given -l and similar options, ls now adjusts the output column
- widths to fit the data, so that output lines are shorter and have
- columns that line up better. This may adversely affect shell
- scripts that expect fixed-width columns, but such shell scripts were
- not portable anyway, even with old GNU ls where the columns became
- ragged when a datum was too wide.
-
- du accepts a new option, -0/--null, to make it produce NUL-terminated
- output lines
-
-** Bug fixes
-
- printf, seq, tail, and sleep now parse floating-point operands
- and options in the C locale. POSIX requires this for printf.
-
- od -c -w9999999 no longer segfaults
-
- csplit no longer reads from freed memory (dumping core on some systems)
-
- csplit would mistakenly exhaust virtual memory in some cases
-
- ls --width=N (for very large N) is no longer subject to an address
- arithmetic bug that could result in bounds violations.
-
- ls --width=N (with -x or -C) no longer allocates more space
- (potentially much more) than necessary for a given directory.
-
- dd `unblock' and `sync' may now be combined (e.g., dd conv=unblock,sync)
-
-* Major changes in release 5.0.91 (2003-09-08):
-
-** New features
-
- date accepts a new option --rfc-2822, an alias for --rfc-822.
-
- split accepts a new option -d or --numeric-suffixes.
-
- cp, install, mv, and touch now preserve microsecond resolution on
- file timestamps, on platforms that have the 'utimes' system call.
- Unfortunately there is no system call yet to preserve file
- timestamps to their full nanosecond resolution; microsecond
- resolution is the best we can do right now.
-
- sort now supports the zero byte (NUL) as a field separator; use -t '\0'.
- The -t '' option, which formerly had no effect, is now an error.
-
- sort option order no longer matters for the options -S, -d, -i, -o, and -t.
- Stronger options override weaker, and incompatible options are diagnosed.
-
- `sha1sum --check' now accepts the BSD format for SHA1 message digests
- in addition to the BSD format for MD5 ones.
-
- who -l now means `who --login', not `who --lookup', per POSIX.
- who's -l option has been eliciting an unconditional warning about
- this impending change since sh-utils-2.0.12 (April 2002).
-
-** Bug fixes
-
- Mistakenly renaming a file onto itself, e.g., via `mv B b' when `B' is
- the same directory entry as `b' no longer destroys the directory entry
- referenced by both `b' and `B'. Note that this would happen only on
- file systems like VFAT where two different names may refer to the same
- directory entry, usually due to lower->upper case mapping of file names.
- Now, the above can happen only on file systems that perform name mapping and
- that support hard links (stat.st_nlink > 1). This mitigates the problem
- in two ways: few file systems appear to be affected (hpfs and ntfs are),
- when the bug is triggered, mv no longer removes the last hard link to a file.
- *** ATTENTION ***: if you know how to distinguish the following two cases
- without writing to the file system in question, please let me know:
- 1) B and b refer to the same directory entry on a file system like NTFS
- (B may well have a link count larger than 1)
- 2) B and b are hard links to the same file
-
- stat no longer overruns a buffer for format strings ending in `%'
-
- fold -s -wN would infloop for N < 8 with TABs in the input.
- E.g., this would not terminate: printf 'a\t' | fold -w2 -s
-
- `split -a0', although of questionable utility, is accepted once again.
-
- `df DIR' used to hang under some conditions on OSF/1 5.1. Now it doesn't.
-
- seq's --width (-w) option now works properly even when the endpoint
- requiring the larger width is negative and smaller than the other endpoint.
-
- seq's default step is 1, even if LAST < FIRST.
-
- paste no longer mistakenly outputs 0xFF bytes for a nonempty input file
- without a trailing newline.
-
- `tail -n0 -f FILE' and `tail -c0 -f FILE' no longer perform what amounted
- to a busy wait, rather than sleeping between iterations.
-
- tail's long-undocumented --allow-missing option now elicits a warning
-
-
-* Major changes in release 5.0.90 (2003-07-29):
-
-** New features
-
- sort is now up to 30% more CPU-efficient in some cases
-
- `test' is now more compatible with Bash and POSIX:
-
- `test -t', `test --help', and `test --version' now silently exit
- with status 0. To test whether standard output is a terminal, use
- `test -t 1'. To get help and version info for `test', use
- `[ --help' and `[ --version'.
-
- `test' now exits with status 2 (not 1) if there is an error.
-
- wc count field widths now are heuristically adjusted depending on the input
- size, if known. If only one count is printed, it is guaranteed to
- be printed without leading spaces.
-
- Previously, wc did not align the count fields if POSIXLY_CORRECT was set,
- but POSIX did not actually require this undesirable behavior, so it
- has been removed.
-
-** Bug fixes
-
- kill no longer tries to operate on argv[0] (introduced in 5.0.1)
- Why wasn't this noticed? Although many tests use kill, none of
- them made an effort to avoid using the shell's built-in kill.
-
- `[' invoked with no arguments no longer evokes a segfault
-
- rm without --recursive (aka -r or -R) no longer prompts regarding
- unwritable directories, as required by POSIX.
-
- uniq -c now uses a SPACE, not a TAB between the count and the
- corresponding line, as required by POSIX.
-
- expr now exits with status 2 if the expression is syntactically valid,
- and with status 3 if an error occurred. POSIX requires this.
-
- expr now reports trouble if string comparison fails due to a collation error.
-
- split now generates suffixes properly on EBCDIC hosts.
-
- split -a0 now works, as POSIX requires.
-
- `sort --version' and `sort --help' fail, as they should
- when their output is redirected to /dev/full.
-
- `su --version > /dev/full' now fails, as it should.
-
-** Fewer arbitrary limitations
-
- cut requires 97% less memory when very large field numbers or
- byte offsets are specified.
-
-
-* Major changes in release 5.0.1 (2003-07-15):
-
-** New programs
-- new program: `[' (much like `test')
-
-** New features
-- head now accepts --lines=-N (--bytes=-N) to print all but the
- N lines (bytes) at the end of the file
-- md5sum --check now accepts the output of the BSD md5sum program, e.g.,
- MD5 (f) = d41d8cd98f00b204e9800998ecf8427e
-- date -d DATE can now parse a DATE string like May-23-2003
-- chown: `.' is no longer recognized as a separator in the OWNER:GROUP
- specifier on POSIX 1003.1-2001 systems. If chown *was not* compiled
- on such a system, then it still accepts `.', by default. If chown
- was compiled on a POSIX 1003.1-2001 system, then you may enable the
- old behavior by setting _POSIX2_VERSION=199209 in your environment.
-- chown no longer tries to preserve set-user-ID and set-group-ID bits;
- on some systems, the chown syscall resets those bits, and previous
- versions of the chown command would call chmod to restore the original,
- pre-chown(2) settings, but that behavior is problematic.
- 1) There was a window whereby a malicious user, M, could subvert a
- chown command run by some other user and operating on files in a
- directory where M has write access.
- 2) Before (and even now, on systems with chown(2) that doesn't reset
- those bits), an unwary admin. could use chown unwittingly to create e.g.,
- a set-user-ID root copy of /bin/sh.
-
-** Bug fixes
-- chown --dereference no longer leaks a file descriptor per symlink processed
-- `du /' once again prints the `/' on the last line
-- split's --verbose option works once again [broken in 4.5.10 and 5.0]
-- tail -f is no longer subject to a race condition that could make it
- delay displaying the last part of a file that had stopped growing. That
- bug could also make tail -f give an unwarranted `file truncated' warning.
-- du no longer runs out of file descriptors unnecessarily
-- df and `readlink --canonicalize' no longer corrupt the heap on
- non-glibc, non-solaris systems
-- `env -u UNSET_VARIABLE' no longer dumps core on non-glibc systems
-- readlink's --canonicalize option now works on systems like Solaris that
- lack the canonicalize_file_name function but do have resolvepath.
-- mv now removes `a' in this example on all systems: touch a; ln a b; mv a b
- This behavior is contrary to POSIX (which requires that the mv command do
- nothing and exit successfully), but I suspect POSIX will change.
-- date's %r format directive now honors locale settings
-- date's `-' (no-pad) format flag now affects the space-padded-by-default
- conversion specifiers, %e, %k, %l
-- fmt now diagnoses invalid obsolescent width specifications like `-72x'
-- fmt now exits nonzero when unable to open an input file
-- tsort now fails when given an odd number of input tokens,
- as required by POSIX. Before, it would act as if the final token
- appeared one additional time.
-
-** Fewer arbitrary limitations
-- tail's byte and line counts are no longer limited to OFF_T_MAX.
- Now the limit is UINTMAX_MAX (usually 2^64).
-- split can now handle --bytes=N and --lines=N with N=2^31 or more.
-
-** Portability
-- `kill -t' now prints signal descriptions (rather than `?') on systems
- like Tru64 with __sys_siglist but no strsignal function.
-- stat.c now compiles on Ultrix systems
-- sleep now works on AIX systems that lack support for clock_gettime
-- rm now works around Darwin6.5's broken readdir function
- Before `rm -rf DIR' would fail to remove all files in DIR
- if there were more than 338.
-
-* Major changes in release 5.0 (2003-04-02):
-- false --help now exits nonzero
-
-[4.5.12]
-* printf no longer treats \x specially when POSIXLY_CORRECT is set
-* printf avoids buffer overrun with format ending in a backslash and
-* printf avoids buffer overrun with incomplete conversion specifier
-* printf accepts multiple flags in a single conversion specifier
-
-[4.5.11]
-* seq no longer requires that a field width be specified
-* seq no longer fails when given a field width of `0'
-* seq now accepts ` ' and `'' as valid format flag characters
-* df now shows a HOSTNAME: prefix for each remote-mounted file system on AIX 5.1
-* portability tweaks for HP-UX, AIX 5.1, DJGPP
-
-[4.5.10]
-* printf no longer segfaults for a negative field width or precision
-* shred now always enables --exact for non-regular files
-* du no longer lists hard-linked files more than once
-* du no longer dumps core on some systems due to `infinite' recursion
- via nftw's use of the buggy replacement function in getcwd.c
-* portability patches for a few vendor compilers and 64-bit systems
-* du -S *really* now works like it did before the change in 4.5.5
-
-[4.5.9]
-* du no longer truncates file sizes or sums to fit in 32-bit size_t
-* work around Linux kernel bug in getcwd (fixed in 2.4.21-pre4), so that pwd
- now fails if the name of the working directory is so long that getcwd
- truncates it. Before it would print the truncated name and exit successfully.
-* `df /some/mount-point' no longer hangs on a GNU libc system when another
- hard-mounted NFS file system (preceding /some/mount-point in /proc/mounts)
- is inaccessible.
-* rm -rf now gives an accurate diagnostic when failing to remove a file
- under certain unusual conditions
-* mv and `cp --preserve=links' now preserve multiple hard links even under
- certain unusual conditions where they used to fail
-
-[4.5.8]
-* du -S once again works like it did before the change in 4.5.5
-* stat accepts a new file format, %B, for the size of each block reported by %b
-* du accepts new option: --apparent-size
-* du --bytes (-b) works the same way it did in fileutils-3.16 and before
-* du reports proper sizes for directories (not zero) (broken in 4.5.6 or 4.5.7)
-* df now always displays under `Filesystem', the device file name
- corresponding to the listed mount point. Before, for a block- or character-
- special file command line argument, df would display that argument. E.g.,
- `df /dev/hda' would list `/dev/hda' as the `Filesystem', rather than say
- /dev/hda3 (the device on which `/' is mounted), as it does now.
-* test now works properly when invoked from a set user ID or set group ID
- context and when testing access to files subject to alternate protection
- mechanisms. For example, without this change, a set-UID program that invoked
- `test -w F' (to see if F is writable) could mistakenly report that it *was*
- writable, even though F was on a read-only file system, or F had an ACL
- prohibiting write access, or F was marked as immutable.
-
-[4.5.7]
-* du would fail with more than one DIR argument when any but the last did not
- contain a slash (due to a bug in ftw.c)
-
-[4.5.6]
-* du no longer segfaults on Solaris systems (fixed heap-corrupting bug in ftw.c)
-* du --exclude=FILE works once again (this was broken by the rewrite for 4.5.5)
-* du no longer gets a failed assertion for certain hierarchy lay-outs
- involving hard-linked directories
-* `who -r' no longer segfaults when using non-C-locale messages
-* df now displays a mount point (usually `/') for non-mounted
- character-special and block files
-
-[4.5.5]
-* ls --dired produces correct byte offset for file names containing
- nonprintable characters in a multibyte locale
-* du has been rewritten to use a variant of GNU libc's ftw.c
-* du now counts the space associated with a directory's directory entry,
- even if it cannot list or chdir into that subdirectory.
-* du -S now includes the st_size of each entry corresponding to a subdirectory
-* rm on FreeBSD can once again remove directories from NFS-mounted file systems
-* ls has a new option --dereference-command-line-symlink-to-dir, which
- corresponds to the new default behavior when none of -d, -l -F, -H, -L
- has been specified.
-* ls dangling-symlink now prints `dangling-symlink'.
- Before, it would fail with `no such file or directory'.
-* ls -s symlink-to-non-dir and ls -i symlink-to-non-dir now print
- attributes of `symlink', rather than attributes of their referents.
-* Fix a bug introduced in 4.5.4 that made it so that ls --color would no
- longer highlight the names of files with the execute bit set when not
- specified on the command line.
-* shred's --zero (-z) option no longer gobbles up any following argument.
- Before, `shred --zero file' would produce `shred: missing file argument',
- and worse, `shred --zero f1 f2 ...' would appear to work, but would leave
- the first file untouched.
-* readlink: new program
-* cut: new feature: when used to select ranges of byte offsets (as opposed
- to ranges of fields) and when --output-delimiter=STRING is specified,
- output STRING between ranges of selected bytes.
-* rm -r can no longer be tricked into mistakenly reporting a cycle.
-* when rm detects a directory cycle, it no longer aborts the entire command,
- but rather merely stops processing the affected command line argument.
-
-[4.5.4]
-* cp no longer fails to parse options like this: --preserve=mode,ownership
-* `ls --color -F symlink-to-dir' works properly
-* ls is much more efficient on directories with valid dirent.d_type.
-* stty supports all baud rates defined in linux-2.4.19.
-* `du symlink-to-dir/' would improperly remove the trailing slash
-* `du ""' would evoke a bounds violation.
-* In the unlikely event that running `du /' resulted in `stat ("/", ...)'
- failing, du would give a diagnostic about `' (empty string) rather than `/'.
-* printf: a hexadecimal escape sequence has at most two hex. digits, not three.
-* The following features have been added to the --block-size option
- and similar environment variables of df, du, and ls.
- - A leading "'" generates numbers with thousands separators.
- For example:
- $ ls -l --block-size="'1" file
- -rw-rw-r-- 1 eggert src 47,483,707 Sep 24 23:40 file
- - A size suffix without a leading integer generates a suffix in the output.
- For example:
- $ ls -l --block-size="K"
- -rw-rw-r-- 1 eggert src 46371K Sep 24 23:40 file
-* ls's --block-size option now affects file sizes in all cases, not
- just for --block-size=human-readable and --block-size=si. Fractional
- sizes are now always rounded up, for consistency with df and du.
-* df now displays the block size using powers of 1000 if the requested
- block size seems to be a multiple of a power of 1000.
-* nl no longer gets a segfault when run like this `yes|nl -s%n'
-
-[4.5.3]
-* du --dereference-args (-D) no longer fails in certain cases
-* `ln --target-dir=DIR' no longer fails when given a single argument
-
-[4.5.2]
-* `rm -i dir' (without --recursive (-r)) no longer recurses into dir
-* `tail -c N FILE' now works with files of size >= 4GB
-* `mkdir -p' can now create very deep (e.g. 40,000-component) directories
-* rmdir -p dir-with-trailing-slash/ no longer fails
-* printf now honors the `--' command line delimiter
-* od's 8-byte formats x8, o8, and u8 now work
-* tail now accepts fractional seconds for its --sleep-interval=S (-s) option
-
-[4.5.1]
-* du and ls now report sizes of symbolic links (before they'd always report 0)
-* uniq now obeys the LC_COLLATE locale, as per POSIX 1003.1-2001 TC1.
-
-========================================================================
-Here are the NEWS entries made from fileutils-4.1 until the
-point at which the packages merged to form the coreutils:
-
-[4.1.11]
-* `rm symlink-to-unwritable' doesn't prompt [introduced in 4.1.10]
-[4.1.10]
-* rm once again gives a reasonable diagnostic when failing to remove a file
- owned by someone else in a sticky directory [introduced in 4.1.9]
-* df now rounds all quantities up, as per POSIX.
-* New ls time style: long-iso, which generates YYYY-MM-DD HH:MM.
-* Any time style can be preceded by "posix-"; this causes "ls" to
- use traditional timestamp format when in the POSIX locale.
-* The default time style is now posix-long-iso instead of posix-iso.
- Set TIME_STYLE="posix-iso" to revert to the behavior of 4.1.1 thru 4.1.9.
-* `rm dangling-symlink' doesn't prompt [introduced in 4.1.9]
-* stat: remove support for --secure/-s option and related %S and %C format specs
-* stat: rename --link/-l to --dereference/-L.
- The old options will continue to work for a while.
-[4.1.9]
-* rm can now remove very deep hierarchies, in spite of any limit on stack size
-* new programs: link, unlink, and stat
-* New ls option: --author (for the Hurd).
-* `touch -c no-such-file' no longer fails, per POSIX
-[4.1.8]
-* mv no longer mistakenly creates links to preexisting destination files
- that aren't moved
-[4.1.7]
-* rm: close a hole that would allow a running rm process to be subverted
-[4.1.6]
-* New cp option: --copy-contents.
-* cp -r is now equivalent to cp -R. Use cp -R -L --copy-contents to get the
- traditional (and rarely desirable) cp -r behavior.
-* ls now accepts --time-style=+FORMAT, where +FORMAT works like date's format
-* The obsolete usage `touch [-acm] MMDDhhmm[YY] FILE...' is no longer
- supported on systems conforming to POSIX 1003.1-2001. Use touch -t instead.
-* cp and inter-partition mv no longer give a misleading diagnostic in some
- unusual cases
-[4.1.5]
-* cp -r no longer preserves symlinks
-* The block size notation is now compatible with SI and with IEC 60027-2.
- For example, --block-size=1MB now means --block-size=1000000,
- whereas --block-size=1MiB now means --block-size=1048576.
- A missing `B' (e.g. `1M') has the same meaning as before.
- A trailing `B' now means decimal, not binary; this is a silent change.
- The nonstandard `D' suffix (e.g. `1MD') is now obsolescent.
-* -H or --si now outputs the trailing 'B', for consistency with the above.
-* Programs now output trailing 'K' (not 'k') to mean 1024, as per IEC 60027-2.
-* New df, du short option -B is short for --block-size.
-* You can omit an integer `1' before a block size suffix,
- e.g. `df -BG' is equivalent to `df -B 1G' and to `df --block-size=1G'.
-* The following options are now obsolescent, as their names are
- incompatible with IEC 60027-2:
- df, du: -m or --megabytes (use -BM or --block-size=1M)
- df, du, ls: --kilobytes (use --block-size=1K)
-[4.1.4]
-* df --local no longer lists smbfs file systems whose name starts with //
-* dd now detects the Linux/tape/lseek bug at run time and warns about it.
-[4.1.3]
-* ls -R once again outputs a blank line between per-directory groups of files.
- This was broken by the cycle-detection change in 4.1.1.
-* dd once again uses `lseek' on character devices like /dev/mem and /dev/kmem.
- On systems with the linux kernel (at least up to 2.4.16), dd must still
- resort to emulating `skip=N' behavior using reads on tape devices, because
- lseek has no effect, yet appears to succeed. This may be a kernel bug.
-[4.1.2]
-* cp no longer fails when two or more source files are the same;
- now it just gives a warning and doesn't copy the file the second time.
- E.g., cp a a d/ produces this:
- cp: warning: source file `a' specified more than once
-* chmod would set the wrong bit when given symbolic mode strings like
- these: g=o, o=g, o=u. E.g., `chmod a=,o=w,ug=o f' would give a mode
- of --w-r---w- rather than --w--w--w-.
-[4.1.1]
-* mv (likewise for cp), now fails rather than silently clobbering one of
- the source files in the following example:
- rm -rf a b c; mkdir a b c; touch a/f b/f; mv a/f b/f c
-* ls -R detects directory cycles, per POSIX. It warns and doesn't infloop.
-* cp's -P option now means the same as --no-dereference, per POSIX.
- Use --parents to get the old meaning.
-* When copying with the -H and -L options, cp can preserve logical
- links between source files with --preserve=links
-* cp accepts new options:
- --preserve[={mode,ownership,timestamps,links,all}]
- --no-preserve={mode,ownership,timestamps,links,all}
-* cp's -p and --preserve options remain unchanged and are equivalent
- to `--preserve=mode,ownership,timestamps'
-* mv and cp accept a new option: --reply={yes,no,query}; provides a consistent
- mechanism to control whether one is prompted about certain existing
- destination files. Note that cp's and mv's -f options don't have the
- same meaning: cp's -f option no longer merely turns off `-i'.
-* remove portability limitations (e.g., PATH_MAX on the Hurd, fixes for
- 64-bit systems)
-* mv now prompts before overwriting an existing, unwritable destination file
- when stdin is a tty, unless --force (-f) is specified, as per POSIX.
-* mv: fix the bug whereby `mv -uf source dest' would delete source,
- even though it's older than dest.
-* chown's --from=CURRENT_OWNER:CURRENT_GROUP option now works
-* cp now ensures that the set-user-ID and set-group-ID bits are cleared for
- the destination file when when copying and not preserving permissions.
-* `ln -f --backup k k' gives a clearer diagnostic
-* ls no longer truncates user names or group names that are longer
- than 8 characters.
-* ls's new --dereference-command-line option causes it to dereference
- symbolic links on the command-line only. It is the default unless
- one of the -d, -F, or -l options are given.
-* ls -H now means the same as ls --dereference-command-line, as per POSIX.
-* ls -g now acts like ls -l, except it does not display owner, as per POSIX.
-* ls -n now implies -l, as per POSIX.
-* ls can now display dates and times in one of four time styles:
-
- - The `full-iso' time style gives full ISO-style time stamps like
- `2001-05-14 23:45:56.477817180 -0700'.
- - The 'iso' time style gives ISO-style time stamps like '2001-05-14 '
- and '05-14 23:45'.
- - The 'locale' time style gives locale-dependent time stamps like
- 'touko 14 2001' and 'touko 14 23:45' (in a Finnish locale).
- - The 'posix-iso' time style gives traditional POSIX-locale
- time stamps like 'May 14 2001' and 'May 14 23:45' unless the user
- specifies a non-POSIX locale, in which case it uses ISO-style dates.
- This is the default.
-
- You can specify a time style with an option like --time-style='iso'
- or with an environment variable like TIME_STYLE='iso'. GNU Emacs 21
- and later can parse ISO dates, but older Emacs versions cannot, so
- if you are using an older version of Emacs outside the default POSIX
- locale, you may need to set TIME_STYLE="locale".
-
-* --full-time is now an alias for "-l --time-style=full-iso".
-
-
-========================================================================
-Here are the NEWS entries made from sh-utils-2.0 until the
-point at which the packages merged to form the coreutils:
-
- [2.0.15]
-* date no longer accepts e.g., September 31 in the MMDDhhmm syntax
-* fix a bug in this package's .m4 files and in configure.ac
- [2.0.14]
-* nohup's behavior is changed as follows, to conform to POSIX 1003.1-2001:
- - nohup no longer adjusts scheduling priority; use "nice" for that.
- - nohup now redirects stderr to stdout, if stderr is not a terminal.
- - nohup exit status is now 126 if command was found but not invoked,
- 127 if nohup failed or if command was not found.
- [2.0.13]
-* uname and uptime work better on *BSD systems
-* pathchk now exits nonzero for a path with a directory component
- that specifies a non-directory
- [2.0.12]
-* kill: new program
-* who accepts new options: --all (-a), --boot (-b), --dead (-d), --login,
- --process (-p), --runlevel (-r), --short (-s), --time (-t), --users (-u).
- The -u option now produces POSIX-specified results and is the same as
- the long option `--users'. --idle is no longer the same as -u.
-* The following changes apply on systems conforming to POSIX 1003.1-2001,
- and are required by the new POSIX standard:
- - `date -I' is no longer supported. Instead, use `date --iso-8601'.
- - `nice -NUM' is no longer supported. Instead, use `nice -n NUM'.
-* New 'uname' options -i or --hardware-platform, and -o or --operating-system.
- 'uname -a' now outputs -i and -o information at the end.
- New uname option --kernel-version is an alias for -v.
- Uname option --release has been renamed to --kernel-release,
- and --sysname has been renamed to --kernel-name;
- the old options will work for a while, but are no longer documented.
-* 'expr' now uses the LC_COLLATE locale for string comparison, as per POSIX.
-* 'expr' now requires '+' rather than 'quote' to quote tokens;
- this removes an incompatibility with POSIX.
-* date -d 'last friday' would print a date/time that was one hour off
- (e.g., 23:00 on *thursday* rather than 00:00 of the preceding friday)
- when run such that the current time and the target date/time fall on
- opposite sides of a daylight savings time transition.
- This problem arose only with relative date strings like `last monday'.
- It was not a problem with strings that include absolute dates.
-* factor is twice as fast, for large numbers
- [2.0.11]
-* setting the date now works properly, even when using -u
-* `date -f - < /dev/null' no longer dumps core
-* some DOS/Windows portability changes
- [2.0j]
-* `date -d DATE' now parses certain relative DATEs correctly
- [2.0i]
-* fixed a bug introduced in 2.0h that made many programs fail with a
- `write error' when invoked with the --version option
- [2.0h]
-* all programs fail when printing --help or --version output to a full device
-* printf exits nonzero upon write failure
-* yes now detects and terminates upon write failure
-* date --rfc-822 now always emits day and month names from the `C' locale
-* portability tweaks for Solaris8, Ultrix, and DOS
- [2.0g]
-* date now handles two-digit years with leading zeros correctly.
-* printf interprets unicode, \uNNNN \UNNNNNNNN, on systems with the
- required support; from Bruno Haible.
-* stty's rprnt attribute now works on HPUX 10.20
-* seq's --equal-width option works more portably
- [2.0f]
-* fix build problems with ut_name vs. ut_user
- [2.0e]
-* stty: fix long-standing bug that caused test failures on at least HPUX
- systems when COLUMNS was set to zero
-* still more portability fixes
-* unified lib/: now that directory and most of the configuration framework
- is common between fileutils, textutils, and sh-utils
- [2.0d]
-* fix portability problem with sleep vs lib/strtod.c's requirement for -lm
- [2.0c]
-* fix portability problems with nanosleep.c and with the new code in sleep.c
- [2.0b]
-* Regenerate lib/Makefile.in so that nanosleep.c is distributed.
- [2.0a]
-* sleep accepts floating point arguments on command line
-* sleep's clock continues counting down when sleep is suspended
-* when a suspended sleep process is resumed, it continues sleeping if
- there is any time remaining
-* who once again prints whatever host information it has, even without --lookup
-
-========================================================================
-For older NEWS entries for the fileutils, textutils, and sh-utils
-packages, see ./old/*/NEWS.
-
- This package began as the union of the following:
- textutils-2.1, fileutils-4.1.11, sh-utils-2.0.15.
diff --git a/contrib/gnu-sort/README b/contrib/gnu-sort/README
deleted file mode 100644
index df35be4..0000000
--- a/contrib/gnu-sort/README
+++ /dev/null
@@ -1,147 +0,0 @@
-These are the GNU core utilities. This package is the union of
-the GNU fileutils, sh-utils, and textutils packages.
-
-Most of these programs have significant advantages over their Unix
-counterparts, such as greater speed, additional options, and fewer
-arbitrary limits.
-
-The programs that can be built with this package are:
-
- [ basename cat chgrp chmod chown chroot cksum comm cp csplit cut date dd
- df dir dircolors dirname du echo env expand expr factor false fmt fold
- ginstall groups head hostid hostname id join kill link ln logname ls
- md5sum mkdir mkfifo mknod mv nice nl nohup od paste pathchk pinky pr
- printenv printf ptx pwd readlink rm rmdir seq sha1sum shred sleep sort
- split stat stty su sum sync tac tail tee test touch tr true tsort tty
- uname unexpand uniq unlink uptime users vdir wc who whoami yes
-
-See the file NEWS for a list of major changes in the current release.
-
-See the file INSTALL for compilation and installation instructions.
-
-These programs are intended to conform to POSIX (with BSD and other
-extensions), like the rest of the GNU system. By default they conform
-to older POSIX (1003.2-1992), and therefore support obsolete usages
-like "head -10" and "chown owner.group file". This default is
-overridden at build-time by the value of <unistd.h>'s _POSIX2_VERSION
-macro, and this in turn can be overridden at runtime as described in
-the documentation under "Standards conformance".
-
-The ls, dir, and vdir commands are all separate executables instead of
-one program that checks argv[0] because people often rename these
-programs to things like gls, gnuls, l, etc. Renaming a program
-file shouldn't affect how it operates, so that people can get the
-behavior they want with whatever name they want.
-
-Special thanks to Paul Eggert, Brian Matthews, Bruce Evans, Karl Berry,
-Kaveh Ghazi, and François Pinard for help with debugging and porting
-these programs. Many thanks to all of the people who have taken the
-time to submit problem reports and fixes. All contributed changes are
-attributed in the ChangeLog file.
-
-And thanks to the following people who have provided accounts for
-portability testing on many different types of systems: Bob Proulx,
-Christian Robert, François Pinard, Greg McGary, Harlan Stenn,
-Joel N. Weber, Mark D. Roth, Matt Schalit, Nelson H. F. Beebe,
-Réjean Payette, Sam Tardieu.
-
-Thanks to Michael Stone for inflicting test releases of the fileutils
-on Debian's unstable distribution, and to all the kind folks who used
-that distribution and found and reported bugs.
-
-Note that each man page is now automatically generated from a template
-and from the corresponding --help usage message. Patches to the template
-files (man/*.x) are welcome. However, the authoritative documentation
-is in texinfo form in the doc directory.
-
-If you run the tests on a SunOS4.1.4 system, expect the ctime-part of
-the ls `time-1' test to fail. I believe that is due to a bug in the
-way Sun implemented link(2) and chmod(2).
-
-***************************************
-Last-minute notes, before coreutils-5.0
----------------------------------------
-
-A known problem exists when compiling on HPUX on both hppa and ia64
-in 64-bit mode (i.e. +DD64) on all known HPUX 11.x versions. This
-is not due to a bug in the package but instead due to a bug in the
-system header file which breaks things in 64-bit mode. The default
-compilation mode is 32-bit and the software compiles fine using the
-default mode. To build this software in 64-bit mode you will need
-to fix the system /usr/include/inttypes.h header file. After
-correcting that file the software also compiles fine in 64-bit mode.
-Here is one possible patch to correct the problem.
-
---- /usr/include/inttypes.h.orig Thu May 30 01:00:00 1996
-+++ /usr/include/inttypes.h Sun Mar 23 00:20:36 2003
-@@ -489 +489 @@
--#ifndef __STDC_32_MODE__
-+#ifndef __LP64__
-
-If you run the tests as root, note that a few of them create files
-and/or run programs as a non-root user, `nobody' by default.
-If you want to use some other non-root username, specify it via
-the NON_ROOT_USERNAME environment variable. Depending on the
-permissions with which the working directories have been created,
-using `nobody' may fail, because that user won't have the required
-read and write access to the build and test directories.
-I find that it is best to unpack and build as a non-privileged
-user, and then to run the following command as that user in order
-to run the privilege-requiring tests:
-
- sudo env NON_ROOT_USERNAME=$USER make check
-
-If you can run the tests as root, please do so and report any
-problems. We get much less test coverage in that mode, and it's
-arguably more important that these tools work well when run by
-root than when run by less privileged users.
-
-***************************************
-
-There are pretty many tests, but nowhere near as many as we need.
-Additions and corrections are very welcome.
-
-If you see a problem that you've already reported, feel free to re-report
-it -- it won't bother me to get a reminder. Besides, the more messages I
-get regarding a particular problem the sooner it'll be fixed -- usually.
-If you sent a complete patch and, after a couple weeks you haven't
-received any acknowledgement, please ping us. A complete patch includes
-a well-written ChangeLog entry, unified (diff -u format) diffs relative
-to the most recent test release (or, better, relative to the latest
-sources in the CVS repository), an explanation for why the patch is
-necessary or useful, and if at all possible, enough information to
-reproduce whatever problem prompted it. Plus, you'll earn lots of
-karma if you include a test case to exercise any bug(s) you fix.
-Instructions for checking out the latest source via CVS are here:
-
- http://savannah.gnu.org/cvs/?group=coreutils
-
-
-If your patch adds a new feature, please try to get some sort of consensus
-that it is a worthwhile change. One way to do that is to send mail to
-bug-coreutils@gnu.org including as much description and justification
-as you can. Based on the feedback that generates, you may be able to
-convince us that it's worth adding.
-
-
-WARNING: If you modify files like configure.in, m4/*.m4, aclocal.m4,
-or any Makefile.am, then don't be surprised if what gets regenerated no
-longer works. To make things work, you'll have to be using appropriate
-versions of automake and autoconf. As for what versions are `appropriate',
-use the versions of
-
- * autoconf specified via AC_PREREQ in m4/jm-macros.m4
- * automake specified via AM_INIT_AUTOMAKE in configure.ac
-
-Usually it's fine to use versions that are newer than those specified.
-
-These programs all recognize the `--version' option. When reporting
-bugs, please include in the subject line both the package name/version
-and the name of the program for which you found a problem.
-
-For general documentation on the coding and usage standards
-this distribution follows, see the GNU Coding Standards,
-http://www.gnu.org/prep/standards_toc.html.
-
-Mail suggestions and bug reports for these programs to
-the address on the last line of --help output.
diff --git a/contrib/gnu-sort/THANKS b/contrib/gnu-sort/THANKS
deleted file mode 100644
index 44b7b02..0000000
--- a/contrib/gnu-sort/THANKS
+++ /dev/null
@@ -1,463 +0,0 @@
-These people have contributed to the GNU coreutils (formerly, the fileutils,
-textutils, and/or sh-utils packages). Some have reported problems, others
-have contributed improvements to the documentation, actual code, and even
-complete programs. Those contributions are described in the ChangeLog
-files. If your name has been left out, if you'd rather not be listed,
-or if you'd prefer a different address be used, please send a note to
-the bug-report mailing list (as seen on last line of e.g., cp --help).
-
-??? kytek@cybercomm.net
-A Costa agcosta@gis.net
-Achim Blumensath blume@corona.oche.de
-Adam Klein aklein@debian.org
-Akim Demaille demaille@inf.enst.fr
-Alain Magloire alain@qnx.com
-Alan Iwi iwi@atm.ox.ac.uk
-Albert Chin-A-Young china@thewrittenword.com
-Albert Hopkins ahopkins@dynacare.com
-Alberto Accomazzi alberto@cfa0.harvard.edu
-aldomel aldomel@ix.netcom.com
-Alen Muzinic zveki@fly.cc.fer.hr
-Alexandre Duret-Lutz duret_g@epita.fr
-Alexey Solovyov alekso@math.uu.se
-Alexey Vyskubov alexey@pippuri.mawhrin.net
-Alfred M. Szmidt ams@kemisten.nu
-Andi Kleen freitag@alancoxonachip.com
-Andre Novaes Cunha Andre.Cunha@br.global-one.net
-Andreas Gruenbacher ag@bestbits.at
-Andreas Jaeger jaeger@gnu.org
-Andreas Luik luik@isa.de
-Andreas Schwab schwab@suse.de
-Andreas Stolcke stolcke@ICSI.Berkeley.EDU
-Andrei Gaponenko andr@triumf.ca
-Andres Soolo andres@soolo.matti.ee
-Andrew Burgess aab@cichlid.com
-Andrew Dalke dalke@bioreason.com
-Andrew Fabbro andrew@fabbro.org
-Andrew Pham andpha@us.ibm.com
-Andrew Tridgell tridge@samba.org
-Andrey Borzenkov arvidjaar@mail.ru
-Andries Brouwer Andries.Brouwer@cwi.nl
-Andy Longton alongton@metamark.com
-Anthony Thyssen anthony@griffith.edu.au
-Antonio Rendas ajrendas@yahoo.com
-Ariel Faigon ariel@cthulhu.engr.sgi.com
-Arne H. Juul arnej@solan.unit.no
-Arne Henrik Juul arnej@imf.unit.no
-Arnold Robbins arnold@skeeve.com
-Arthur Pool pool@commerce.uq.edu.au
-Arun Sharma arun.sharma@intel.com
-Arvind Autar Autar022@planet.nl
-Augey Mikus mikus@dqc.org
-Austin Donnelly Austin.Donnelly@cl.cam.ac.uk
-Axel Kittenberger Anshil@gmx.net
-Bauke Jan Douma bjdouma@xs4all.nl
-Ben Elliston bje@air.net.au
-Ben Harris bjh21@netbsd.org
-Benjamin Cutler cutlerbc@simla.colostate.edu
-Bengt Martensson bengt@mathematik.uni-Bremen.de
-Bernard Giroud bernard.giroud@creditlyonnais.ch
-Bernd Leibing bernd.leibing@rz.uni-ulm.de
-Bernd Melchers melchers@cis.fu-berlin.de
-Bernhard Baehr bernhard.baehr@gmx.de
-Bernhard Gabler bernhard@uni-koblenz.de
-Bernhard Rosenkraenzer bero@redhat.de
-Bert Deknuydt Bert.Deknuydt@esat.kuleuven.ac.be
-Bill Peters peters@gaffel.as.arizona.edu
-Bjorn Helgaas helgaas@rsn.hp.com
-Bob McCracken kerouac@ravenet.com
-Bob Proulx rwp@fc.hp.com
-Branden Robinson branden@necrotic.deadbeast.net
-Brendan O'Dea bod@compusol.com.au
-Brian Kimball bfk@footbag.org
-Brian Youmans 3diff@gnu.org
-Bruce Korb bkorb@veritas.com
-Bruce Robertson brucer@theodolite.dyndns.org
-Bruno Haible haible@clisp.cons.org
-Carl Johnson carlj@cjlinux.home.org
-Carl Lowenstein cdl@mpl.UCSD.EDU
-Carlos Canau Carlos.Canau@relay.puug.pt
-Charles Karney karney@pppl.gov
-Charles Randall crandall@matchlogic.com
-Chip Salzenberg chip@valinux.com
-Chris Faylor cgf@cygnus.com
-Chris J. Bednar cjb@AdvancedDataSolutions.com
-Chris Lesniewski ctl@mit.edu
-Chris Sylvain csylvain@umm.edu
-Chris Yeo cyeo@biking.org
-Christi Alice Scarborough christi@chiark.greenend.org.uk
-Christian Harkort christian.harkort@web.de
-Christian Krackowizer ckrackowiz@std.schuler-ag.com
-Christian Rose menthos@menthos.com
-Christian von Roques roques@pond.sub.org
-Chuck Hedrick hedrick@klinzhai.rutgers.edu
-Clark Morgan cmorgan@aracnet.com
-Clement Wang clem.wang@overture.com
-Colin Plumb colin@nyx.net
-Colin Watson cjw44@riva.ucam.org
-Collin Rogowski collin@rogowski.de
-Cray-Cyber Project http://www.cray-cyber.org
-Dale Scheetz dwarf@polaris.net
-Dan Hagerty hag@gnu.ai.it.edu
-Dan Jacobson http://www.geocities.com/jidani
-Dan Pascu dan@services.iiruc.ro
-Daniel Bergstrom noa@melody.se
-Dániel Varga danielv@axelero.hu
-Danny Levinson danny.levinson@overture.com
-Darren Salt ds@youmustbejoking.demon.co.uk
-Dave Beckett dajobe@dajobe.org
-David Dyck dcd@tc.fluke.COM
-David Eisner cradle@umd.edu
-David Flynn dav@chess.plus.com
-David Godfrey dave@delta.demon.co.uk
-David Luyer david_luyer@pacific.net.au
-David Malone dwmalone@cnri.dit.ie
-Deepak Goel deego@gnufans.org
-Dennis Henriksen opus@flamingo.osrl.dk
-Dennis Smit ds@nerds-incorporated.org
-Derek Clegg dclegg@next.com
-Dick Streefland dick_streefland@tasking.com
-Dirk Lattermann dlatt@t-online.de
-Dirk-Jan Faber djfaber@snow.nl
-Dmitry Rutsky rutsky@school.ioffe.rssi.ru
-Dmitry V. Levin ldv@altlinux.org
-Don Parsons dparsons@synapse.kent.edu
-Donni Erpel donald@appc11.gsi.de
-Doug Coleman coleman@iarc1.ece.utexas.edu
-Doug McLaren dougmc@comco.com
-Dragos Harabor dharabor@us.oracle.com
-Duncan Roe duncanr@optimation.com.au
-Ed Avis ed@membled.com
-Edzer Pebesma Edzer.Pebesma@rivm.nl
-Eirik Fuller eirik@hackrat.com
-Eivind eivindt@multinet.no
-Eli Zaretskii eliz@is.elta.co.il
-Emile LeBlanc leblanc@math.toronto.edu
-Eric Backus ericb@lsid.hp.com
-Eric G. Miller egm2@jps.net
-Eric Pemente pemente@northpark.edu
-Eric S. Raymond esr@snark.thyrsus.com
-Erik Bennett bennett@cvo.oneworld.com
-Erik Corry erik@kroete2.freinet.de
-Felix Lee flee@teleport.com
-Ferdinand fw@scenic.mine.nu
-Fletcher Mattox fletcher@cs.utexas.edu
-Florin Iucha fiucha@hsys.mic.ro
-François Pinard pinard@iro.umontreal.ca
-Frank Adler fadler@allesklar.de
-Frank T Lofaro ftlofaro@snooks.Egr.UNLV.EDU
-Fred Fish fnf@ninemoons.com
-Frédéric L. W. Meunier 0@pervalidus.net
-Frederik Eaton frederik@caltech.edu
-Gabor Z. Papp gzp@gzp.org.hu
-Gaël Quéri gqueri@mail.dotcom.fr
-Galen Hazelwood galenh@micron.net
-Gary Anderson ganderson@clark.net
-Gary V. Vaughan gary@gnu.org
-Gaute Hvoslef Kvalnes gaute@verdsveven.com
-Geoff Collyer geoff at collyer.net
-Geoff Kuenning geoff@cs.hmc.edu
-Geoff Odhner geoff@franklin.com
-Geoff Whale geoffw@cse.unsw.EDU.AU
-Gerhard Poul gpoul@gnu.org
-Germano Leichsenring germano@jedi.cs.kobe-u.ac.jp
-Göran Uddeborg goeran@uddeborg.pp.se
-GOTO Masanori gotom@debian.or.jp
-Greg Louis glouis@dynamicro.on.ca
-Greg McGary gkm@gnu.org
-Greg Schafer gschafer@zip.com.au
-Greg Troxel gdt@bbn.com
-Greg Wooledge gawooledge@sherwin.com
-Gregory Leblanc gleblanc@cu-portland.edu
-Guido Leenders guido.leenders@invantive.com
-H. J. Lu hjl@valinux.com
-Hans Ginzel hans@matfyz.cz
-Hans Lermen lermen@fgan.de
-Hans Verkuil hans@wyst.hobby.nl
-Harry Liu rliu@lek.ugcs.caltech.edu
-Harti Brandt brandt@fokus.fraunhofer.de
-Herbert Xu herbert@gondor.apana.org.au
-Holger Berger hberger@ess.nec.de
-Hon-Yin Kok hkok@yoda.unl.edu
-Hugh Daniel hugh@xanadu.com
-Ian Bruce ian.bruce@myrealbox.com
-Ian Jackson ijackson@chiark.greenend.org.uk
-Ian Lance Taylor ian@cygnus.com
-Ian Turner vectro@pipeline.com
-Iida Yosiaki iida@gnu.org
-Ingo Saitz ingo@debian.org
-Ivo Timmermans ivo@debian.org
-James james@albion.glarp.com
-James Antill jmanti%essex.ac.uk@seralph21.essex.ac.uk
-James Sneeringer jvs@ocslink.com
-James Tanis jtt@soscorp.com
-James Youngman james+usenet@free-lunch.demon.co.uk
-Jamie Lokier jamie@imbolc.ucc.ie
-Jan Fedak J.Fedak@sh.cvut.cz
-Jan Nieuwenhuizen janneke@gnu.org
-Janos Farkas chexum@shadow.banki.hu
-Jarkko Hietaniemi jhi@epsilon.hut.fi
-Jean Charles Delepine delepine@u-picardie.fr
-Jeff Moore jbm@mordor.com
-Jeff Sheinberg jeff@bsrd.net
-Jens Elkner elkner@imsgroup.de
-Jens Schmidt jms@jsds.hamburg.com
-Jerome Abela abela@hsc.fr
-Jérôme Zago bug-coreutils-ml@agt-the-walker.net
-Jesse Kornblum kornblum@usna.edu
-Jesse Thilo jgt2@eecs.lehigh.edu
-Jie Xu xuj@iag.net
-Jim Blandy jimb@cyclic.com
-Jim Dennis jimd@starshine.org
-Joakim Rosqvist dvljrt@cs.umu.se
-Jochen Hein jochen@jochen.org
-Joe Orton joe@manyfish.co.uk
-Johan Danielsson joda@pdc.kth.se
-John Bley jbb6@acpub.duke.edu
-John David Anglin dave.anglin@nrc.ca
-John Gatewood Ham zappaman@alphabox.compsci.buu.ac.th
-John Gotts jgotts@umich.edu
-John Kendall kendall@capps.com
-John Kodis kodis@acm.org
-John Murphy jam@philabs.research.philips.com
-John Roll john@panic.harvard.edu
-John Salmon johns@mullet.anu.edu.au
-John Summerfield summer@OS2.ami.com.au
-Jon Peatfield J.S.Peatfield@damtp.cam.ac.uk
-Joost van Baal joostvb@xs4all.nl
-Jorge Stolfi stolfi@ic.unicamp.br
-Joseph S. Myers jsm28@cam.ac.uk
-Juan F. Codagnone juam@arnet.com.ar
-Jungshik Shin jshin@pantheon.yale.edu
-Jürgen Fluk louis@dachau.marco.de
-Jurriaan thunder7@xs4all.nl
-jvogel jvogel@linkny.com
-Kai Henningsen kai@debian.org
-Kai-Uwe Rommel rommel@informatik.tu-muenchen.de
-Kalle Olavi Niemitalo kon@iki.fi
-Kamal Paul Nigam Kamal_Paul_Nigam@gs35.sp.cs.cmu.edu
-Karl Eichwalder keichwa@gmx.net
-Karl Heuer kwzh@gnu.org
-Karl-Michael Schneider schneide@phil.uni-passau.de
-Karsten Thygesen karthy@kom.auc.dk
-Kaveh R. Ghazi ghazi@caip.rutgers.edu
-Keith M. Briggs keith.briggs@bt.com
-Keith Owens kaos@audio.apana.org.au
-Keith Thompson kst@cts.com
-Ken Pizzini kenp@halcyon.com
-Kristin E Thomas kristint@us.ibm.com
-Kjetil Torgrim Homme kjetilho@ifi.uio.no
-Kristoffer Rose kris@diku.dk
-Larry McVoy lm@sgi.com
-Lars Hecking lhecking@nmrc.ucc.ie
-Leah Q eequor@earthlink.net
-Lehti Rami rammer@cs.tut.fi
-Leonard N. Zubkoff lnz@dandelion.com
-Leonardo Milano lmilano@udel.edu
-Lorne Baker lbaker@nitro.avint.net
-Luke Hassell lukehassell@yahoo.com
-M. P. Suzuki mpsuzuki@hiroshima-u.ac.jp
-Maciej Kwapulinski pikpok@univ.gda.pl
-Manas Garg manas@cygsoft.com
-Manfred Hollstein manfred@s-direktnet.de
-Marc Boucher marc@mbsi.ca
-Marc Haber mh+debian-bugs@zugschlus.de
-Marc Olzheim marcolz@stack.nl
-Marco Franzen Marco.Franzen@Thyron.com
-Marcus Brinkmann http://www.marcus-brinkmann.de
-Marcus Daniels marcus@ee.pdx.edu
-Mark A. Thomas thommark@access.digex.net
-Mark Conty Mark_Conty@cargill.com
-Mark D. Roth roth@uiuc.edu
-Mark Funkenhauser mfunkenhauser@rogers.com
-Mark Harris mark@monitor.designacc.com
-Mark Hewitt mhewitt@armature.com
-Mark Hounschell markh@compro.net
-Mark Hubbart discord@mac.com
-Mark Kettenis kettenis@phys.uva.nl
-Mark Nudelman marknu@flash.net
-Mark W. Eichin eichin@cygnus.com
-Markus Demleitner msdemlei@auriga.ari.uni-heidelberg.de
-Martin martin@dresden.nacamar.de
-Martin Buck martin.buck@ascom.ch
-Martin Gallant martyg@goodbit.net
-Martin Hippe martin.hippe@schlund.de
-Martin Michlmayr tbm@cyrius.com
-Martin Mitchell martin@debian.org
-Martin P.J. Zinser zinser@decus.de
-Marty Leisner leisner@sdsp.mc.xerox.com
-Masami Takikawa takikawm@CS.ORST.EDU
-Mate Wierdl mw@moni.msci.memphis.edu
-Matej Vela mvela@public.srce.hr
-Matt Perry matt@primefactor.com
-Matt Schalit mschalit@pacbell.net
-Matt Swift swift@alum.mit.edu
-Matthew Arnison maffew@cat.org.au
-Matthew Braun matthew@ans.net
-Matthew Clarke Matthew_Clarke@mindlink.bc.ca
-Matthew S. Levine mslevine@theory.lcs.mit.edu
-Matthew Smith matts@bluesguitar.org
-Matthew Swift swift@alum.mit.edu
-Matthias Urlichs smurf@noris.de
-Matti Aarnio matti.aarnio@zmailer.org
-Mattias Wadenstein maswan@acc.umu.se
-Meelis Roos mroos@tartu.cyber.ee
-Michael michael@aplatform.com
-Michael ??? michael@roka.net
-Michael Bacarella mbac@netgraft.com>
-Michael Deutschmann michael@talamasca.ocis.net
-Michael Elizabeth Chastain mec.gnu@mindspring.com
-Michael Gaughen mgaughen@polyserve.com
-Michael Hasselberg mikelh@zonta.ping.de
-Michael Hohn hohn@math.utah.edu
-Michael J. Croghan mcroghan@usatoday.com
-Michael McFarland sidlon@yahoo.com
-Michael Piefel piefel@informatik.hu-berlin.de
-Michael Steffens michael.steffens@s.netic.de
-Michael Stone mstone@debian.org
-Michael Stutz stutz@dsl.org
-Michael van Elst mlelstv@dev.de.cw.net
-Michael Veksler mveksler@techunix.technion.ac.il
-Michail Litvak mci@owl.openwall.com
-Michal Politowski mpol@charybda.icm.edu.pl
-Michal Svec msvec@suse.cz
-Michel Robitaille robitail@IRO.UMontreal.CA
-Michiel Bacchiani bacchian@raven.bu.edu
-Mike Castle dalgoda@ix.netcom.com
-Mike Coleman mkc@mathdogs.com
-Mike Jetzer mjetzer@mke.catalystwms.com
-Mikko Tuumanen m@sorvankyla.yok.utu.fi
-Mikulas Patocka mikulas@artax.karlin.mff.cuni.cz
-Miles Bader miles@gnu.ai.mit.edu
-Minh Tran-Le tranle@intellicorp.com
-Morten Welinder terra@diku.dk
-Neal H Walfield neal@cs.uml.edu
-Neil Brown neilb@cse.unsw.edu.au
-Nelson H. F. Beebe beebe@math.utah.edu
-Nick Estes debian@nickstoys.com
-Nick Lawes nlawes@silverplatter.com
-Niklas Edmundsson nikke@acc.umu.se
-Nikola Milutinovic Nikola.Milutinovic@ev.co.yu
-Noah Friedman friedman@splode.com
-Noel Cragg noel@red-bean.com
-Olatunji Oluwabukunmi Ruwase tjruwase@stanford.edu
-Olav Morkrid olav@funcom.com
-Ole Laursen olau@hardworking.dk
-Oliver Kiddle okiddle@yahoo.co.uk
-Ørn E. Hansen oehansen@daimi.aau.dk
-Oskar Liljeblad osk@hem.passagen.se
-Patrick Mauritz oxygene@studentenbude.ath.cx
-Paul Eggert eggert@twinsun.com
-Paul Jarc prj@po.cwru.edu
-Paul Nevai nevai@ops.mps.ohio-state.edu
-Paul Sauer paul@alexa.com
-Paul Slootman paul@debian.org
-Paul Worrall paul@basilisk.uklinux.net
-Pawel Prokop pablo@wizard.ae.krakow.pl
-Per Cederqvist ceder@lysator.liu.se
-Per Kristian Hove perhov@math.ntnu.no
-Peter Eriksson peter@ifm.liu.se
-Peter Horst peter@ointment.org
-Peter Moulder reiter@netspace.net.au
-Peter Samuelson psamuels@sampo.creighton.edu
-Peter Seebach seebs@taniemarie.solon.com
-Petter Reinholdtsen pere@hungry.com
-Phelippe Neveu pneveu@pcigeomatics.com
-Phil Richards phil.richards@vf.vodafone.co.uk
-Philippe De Muyter phdm@macqel.be
-Philippe Schnoebelen Philippe.Schnoebelen@imag.fr
-Phillip Jones mouse@datastacks.com
-Piergiorgio Sartor sartor@sony.de
-Piotr Kwapulinski kwap@univ.gda.pl
-Prashant TR tr@eth.net
-Rainer Orth ro@TechFak.Uni-Bielefeld.DE
-Ralf W. Stephan stephan@tmt.de
-Ralph Loader loader@maths.ox.ac.uk
-Raul Miller moth@magenta.com
-Raúl Núñez de Arenas Coronado raul@pleyades.net
-Reuben Thomas rrt@sc3d.org
-Richard A Downing richard.downing@bcs.org.uk
-Richard Braakman dark@xs4all.nl
-Richard Dawe rich@phekda.freeserve.co.uk
-Richard J. Rauenzahn rrauenza@hairball.cup.hp.com
-Richard Neill rn214@hermes.cam.ac.uk
-Richard Sharman rsharman@magmacom.com
-Rick Sladkey jrs@world.std.com
-Rik Faith faith@cs.unc.edu
-Risto Kankkunen kankkune@lingsoft.fi
-Robert H. de Vries robert@and.nl
-Robert Millan zeratul2@wanadoo.es
-Rogier Wolff R.E.Wolff@BitWizard.nl
-Roland Huebner ro-huebner@gmx.de
-Roland Turner raz.tah.bet@raz.cx
-Ronald F. Guilmette rfg@netcom.com
-Ross Alexander r.alexander@auckland.ac.nz
-Ross Paterson rap@doc.ic.ac.uk
-Ross Ridge rridge@calum.csclub.uwaterloo.ca
-Sami Farin sfarin@ratol.fi
-Samuel Tardieu sam@rfc1149.net
-Samuli Karkkainen Samuli.Karkkainen@hut.fi
-Sander van Malssen svm@kozmix.ow.nl
-Santiago Vila Doncel sanvila@unex.es
-Savochkin Andrey Vladimirovich saw@msu.ru
-Scott Lurndal slurn@griffin.engr.sgi.com
-Shing-Shong Shei shei@cs.indiana.edu
-Soeren Sonnenburg sonnenburg@informatik.hu-berlin.de
-Solar Designer solar@owl.openwall.com
-Stanislav Ievlev inger@altlinux.ru
-Stéphane Chazelas Stephane_CHAZELAS@yahoo.fr
-Stephen Depooter sbdep@myrealbox.com
-Stephen Eglen eglen@pcg.wustl.edu
-Stephen Gildea gildea@stop.mail-abuse.org
-Stephen Smoogen smooge@mindspring.com
-Steve McConnel steve@acadcomp.sil.org
-Steven G. Johnson stevenj@alum.mit.edu
-Steven Mocking ufo@quicknet.nl
-Steven P Watson steven@magelico.net
-Stuart Kemp skemp@peter.bmc.com
-Szakacsits Szabolcs szaka@sienet.hu
-Tadayoshi Funaba tadf@kt.rim.or.jp
-TAKAI Kousuke takai@vlsi.kuee.kyoto-u.ac.jp
-Theodore Ts'o tytso@rsts-11.mit.edu
-Thomas Bushnell thomas@gnu.ai.mit.edu
-Thomas Goerlich thomas@schnappmatik.de
-Thomas Luzat thomas@luzat.com
-Thomas Quinot thomas@Cuivre.FR.EU.ORG
-Tim J. Robbins tjr@FreeBSD.org
-Tim Mooney mooney@dogbert.cc.ndsu.NoDak.edu
-Tim Smithers mouse@dmouse.com.au
-Tim Waugh twaugh@redhat
-Todd A. Jacobs tjacobs@codegnome.org
-Tom Haynes thomas@netapp.com
-Tom Quinn trq@dionysos.thphys.ox.ac.uk
-Tommi Kyntola tkyntola@cc.hut.fi
-Ton Hospel thospel@mail.dma.be
-Ton Nijkes ton@murphy.nl
-Tony Kocurko akocurko@mun.ca
-Tony Leneis tony@plaza.ds.adp.com
-Tony Robinson ajr@eng.cam.ac.uk
-Torbjorn Granlund tege@nada.kth.se
-Torbjorn Lindgren tl@funcom.no
-Torsten Landschoff torsten@pclab.ifg.uni-kiel.de
-Ulrich Drepper drepper@gnu.org
-Urs Thuermann urs@isnogud.escape.de
-Uwe H. Steinfeld usteinfeld@gmx.net
-Vesselin Atanasov vesselin@bgnet.bg
-Vin Shelton acs@alumni.princeton.edu
-Volker Borchert bt@teknon.de
-Volker Paul vpaul@dohle.com
-Wartan Hachaturow wart@tepkom.ru
-Wayne Stewart wstewa@atl.com
-Wenjun Zheng zwj@yahoo.com
-Werner Almesberger Werner.Almesberger@epfl.ch
-Wichert Akkerman wichert@cistron.nl
-Will Edgington wedgingt@acm.org
-William Bader william@nscs.fast.net
-William Dowling will@franklin.com
-William Lewis wiml@omnigroup.com
-wiregauze wiregauze@yahoo.com
-Wojciech Purczynski cliph@isec.pl
-Wolfram Kleff kleff@cs.uni-bonn.de
-Won-kyu Park wkpark@chem.skku.ac.kr
-Yann Dirson dirson@debian.org
-Zvi Har'El rl@math.technion.ac.il
diff --git a/contrib/gnu-sort/THANKS-to-translators b/contrib/gnu-sort/THANKS-to-translators
deleted file mode 100644
index c84ff64..0000000
--- a/contrib/gnu-sort/THANKS-to-translators
+++ /dev/null
@@ -1,36 +0,0 @@
-The following teams have translated the many diagnostics of this
-package into many different languages. Thank you!
-
----
-http://www.iro.umontreal.ca/contrib/po/HTML/team-af.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-be.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-ca.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-cs.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-da.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-de.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-el.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-es.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-et.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-fi.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-fr.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-ga.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-gl.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-hu.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-it.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-ja.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-ko.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-lg.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-ms.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-nb.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-nl.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-no.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-pl.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-pt.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-pt_BR.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-ru.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-sk.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-sl.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-sv.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-tr.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-zh_CN.html
-http://www.iro.umontreal.ca/contrib/po/HTML/team-zh_TW.html
diff --git a/contrib/gnu-sort/TODO b/contrib/gnu-sort/TODO
deleted file mode 100644
index 82a74bf..0000000
--- a/contrib/gnu-sort/TODO
+++ /dev/null
@@ -1,171 +0,0 @@
-restore djgpp, eventually
-merge TODO lists
-add unit tests for lib/*.c
-
-strip: add an option to specify the program used to strip binaries.
- suggestion from Karl Berry
-
-doc/coreutils.texi:
- Address this comment: FIXME: mv's behavior in this case is system-dependent
- Better still: fix the code so it's *not* system-dependent.
-
-implement --target-directory=DIR for install (per texinfo documentation)
-
-ls: add --format=FORMAT option that controls how each line is printed.
-
-cp --no-preserve=X should not attempt to preserve attribute X
- reported by Andreas Schwab
-
-copy.c: Address the FIXME-maybe comment in copy_internal.
-And once that's done, add an exclusion so that `cp --link'
-no longer incurs the overhead of saving src. dev/ino and dest. filename
-in the hash table.
-
-See if we can be consistent about where --verbose sends its output:
- These all send --verbose output to stdout:
- head, tail, rm, cp, mv, ln, chmod, chown, chgrp, install, ln
- These send it to stderr:
- shred mkdir split
- readlink is different
-
-Write an autoconf test to work around build failure in HPUX's 64-bit mode.
-See notes in README -- and remove them once there's a work-around.
-
-Integrate use of sendfile, suggested here:
- http://mail.gnu.org/archive/html/bug-fileutils/2003-03/msg00030.html
-I don't plan to do that, since a few tests demonstrate no significant benefit.
-
-Should printf '\0123' print "\n3"?
- per report from TAKAI Kousuke on Mar 27
- http://mail.gnu.org/archive/html/bug-coreutils/2003-03/index.html
-
-printf: consider adapting builtins/printf.def from bash
-
-df: add `--total' option, suggested here http://bugs.debian.org/186007
-
-seq: give better diagnostics for invalid formats:
- e.g. no or too many % directives
-seq: consider allowing format string to contain no %-directives
-
-m4: rename all macros that start with AC_ to start with another prefix
-
-resolve RH report on cp -a forwarded by Tim Waugh
-
-Martin Michlmayr's patch to provide ls with `--sort directory' option
-
-tail: don't use xlseek; it *exits*.
- Instead, maybe use a macro and return nonzero.
-
-add mktemp? Suggested by Nelson Beebe
-
-df: alignment problem of `Used' heading with e.g., -mP
- reported by Karl Berry
-
-tr: support nontrivial equivalence classes, e.g. [=e=] with LC_COLLATE=fr_FR
-
-fix tail -f to work with named pipes; reported by Ian D. Allen
- $ mkfifo j; tail -f j & sleep 1; echo x > j
- ./tail: j: file truncated
- ./tail: j: cannot seek to offset 0: Illegal seek
-
-lib/strftime.c: Since %N is the only format that we need but that
- glibc's strftime doesn't support, consider using a wrapper that
- would expand /%(-_)?\d*N/ to the desired string and then pass the
- resulting string to glibc's strftime.
-
-sort: Compress temporary files when doing large external sort/merges.
- This improves performance when you can compress/uncompress faster than
- you can read/write, which is common in these days of fast CPUs.
- suggestion from Charles Randall on 2001-08-10
-
-sort: Add an ordering option -R that causes 'sort' to sort according
- to a random permutation of the correct sort order. Also, add an
- option --random-seed=SEED that causes 'sort' to use an arbitrary
- string SEED to select which permutations to use, in a deterministic
- manner: that is, if you sort a permutation of the same input file
- with the same --random-seed=SEED option twice, you'll get the same
- output. The default SEED is chosen at random, and contains enough
- information to ensure that the output permutation is random.
- suggestion from Feth AREZKI, Stephan Kasal, and Paul Eggert on 2003-07-17
-
-unexpand: [http://www.opengroup.org/onlinepubs/007908799/xcu/unexpand.html]
- printf 'x\t \t y\n'|unexpand -t 8,9 should print its input, unmodified.
- printf 'x\t \t y\n'|unexpand -t 5,8 should print "x\ty\n"
-
-Let GNU su use the `wheel' group if appropriate.
- (there are a couple patches, already)
-
-sort: Investigate better sorting algorithms; see Knuth vol. 3.
-
- We tried list merge sort, but it was about 50% slower than the
- recursive algorithm currently used by sortlines, and it used more
- comparisons. We're not sure why this was, as the theory suggests it
- should do fewer comparisons, so perhaps this should be revisited.
- List merge sort was implemented in the style of Knuth algorithm
- 5.2.4L, with the optimization suggested by exercise 5.2.4-22. The
- test case was 140,213,394 bytes, 426,4424 lines, text taken from the
- GCC 3.3 distribution, sort.c compiled with GCC 2.95.4 and running on
- Debian 3.0r1 GNU/Linux, 2.4GHz Pentium 4, single pass with no
- temporary files and plenty of RAM.
-
- Since comparisons seem to be the bottleneck, perhaps the best
- algorithm to try next should be merge insertion. See Knuth section
- 5.3.1, who credits Lester Ford, Jr. and Selmer Johnson, American
- Mathematical Monthly 66 (1959), 387-389.
-
-cp --recursive: perform dir traversals in source and dest hierarchy rather
- than forming full file names. The latter (current) approach fails
- unnecessarily when the names become very long.
-
-tail --p is now ambiguous
-
-Remove suspicious uses of alloca (ones that may allocate more than
- about 4k)
-
-Adapt these contribution guidelines for coreutils:
- http://sources.redhat.com/automake/contribute.html
-
-
-Changes expected to go in, post-5.2.1:
-======================================
-
- wc: add an option, --files0-from [as for du] to make it read NUL-delimited
- file name arguments from a file.
-
- dd patch from Olivier Delhomme
-
- Apply Andreas Gruenbacher's ACL and xattr changes
-
- Apply Bruno Haible's hostname changes
-
- test/mv/*: clean up $other_partition_tmpdir in all cases
-
- ls: when both -l and --dereference-command-line-symlink-to-dir are
- specified, consider whether to let the latter select whether to
- dereference command line symlinks to directories. Since -l has
- an implicit --NO-dereference-command-line-symlink-to-dir meaning.
- Pointed out by Karl Berry.
-
- A more efficient version of factor, and possibly one that
- accepts inputs of size 2^64 and larger.
-
- Re-add a separate test for du's stack space usage (like the one removed
- from tests/rm/deep-1).
-
- dd: consider adding an option to suppress `bytes/block read/written'
- output to stderr. Suggested here:
- http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=165045
-
- Pending copyright papers:
- ------------------------
- ls --color: Ed Avis' patch to suppress escape sequences for
- non-highlighted files
-
- getpwnam from Bruce Korb
-
- pb (progress bar) from Miika Pekkarinen
-
- Look into improving the performance of md5sum.
- `openssl md5' is consistently about 30% faster than md5sum on an idle
- AMD 2000-XP system with plenty of RAM and a 261 MB input file.
- openssl's md5 implementation is in assembly, generated by a perl script.
diff --git a/contrib/gnu-sort/lib/__fpending.c b/contrib/gnu-sort/lib/__fpending.c
deleted file mode 100644
index a872102..0000000
--- a/contrib/gnu-sort/lib/__fpending.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* __fpending.c -- return the number of pending output bytes on a stream
- Copyright (C) 2000 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Jim Meyering. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "__fpending.h"
-
-size_t
-__fpending (FILE *fp)
-{
- return PENDING_OUTPUT_N_BYTES;
-}
diff --git a/contrib/gnu-sort/lib/__fpending.h b/contrib/gnu-sort/lib/__fpending.h
deleted file mode 100644
index 5a51582..0000000
--- a/contrib/gnu-sort/lib/__fpending.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stddef.h>
-#include <stdio.h>
-
-#if HAVE_STDIO_EXT_H
-# include <stdio_ext.h>
-#endif
-
-#ifndef HAVE_DECL___FPENDING
-"this configure-time declaration test was not run"
-#endif
-#if !HAVE_DECL___FPENDING
-size_t __fpending (FILE *);
-#endif
diff --git a/contrib/gnu-sort/lib/argmatch.c b/contrib/gnu-sort/lib/argmatch.c
deleted file mode 100644
index 1a8ec2f..0000000
--- a/contrib/gnu-sort/lib/argmatch.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/* argmatch.c -- find a match for a string in an array
-
- Copyright (C) 1990, 1998, 1999, 2001, 2002, 2003, 2004 Free
- Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by David MacKenzie <djm@ai.mit.edu>
- Modified by Akim Demaille <demaille@inf.enst.fr> */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/* Specification. */
-#include "argmatch.h"
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-#include "error.h"
-#include "exit.h"
-#include "quotearg.h"
-#include "quote.h"
-#include "unlocked-io.h"
-
-/* When reporting an invalid argument, show nonprinting characters
- by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use
- literal_quoting_style. */
-#ifndef ARGMATCH_QUOTING_STYLE
-# define ARGMATCH_QUOTING_STYLE locale_quoting_style
-#endif
-
-/* Non failing version of argmatch call this function after failing. */
-#ifndef ARGMATCH_DIE
-# include "exitfail.h"
-# define ARGMATCH_DIE exit (exit_failure)
-#endif
-
-#ifdef ARGMATCH_DIE_DECL
-ARGMATCH_DIE_DECL;
-#endif
-
-static void
-__argmatch_die (void)
-{
- ARGMATCH_DIE;
-}
-
-/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h.
- Default to __argmatch_die, but allow caller to change this at run-time. */
-argmatch_exit_fn argmatch_die = __argmatch_die;
-
-
-/* If ARG is an unambiguous match for an element of the
- null-terminated array ARGLIST, return the index in ARGLIST
- of the matched element, else -1 if it does not match any element
- or -2 if it is ambiguous (is a prefix of more than one element).
-
- If VALLIST is none null, use it to resolve ambiguities limited to
- synonyms, i.e., for
- "yes", "yop" -> 0
- "no", "nope" -> 1
- "y" is a valid argument, for `0', and "n" for `1'. */
-
-ptrdiff_t
-argmatch (const char *arg, const char *const *arglist,
- const char *vallist, size_t valsize)
-{
- size_t i; /* Temporary index in ARGLIST. */
- size_t arglen; /* Length of ARG. */
- ptrdiff_t matchind = -1; /* Index of first nonexact match. */
- bool ambiguous = false; /* If true, multiple nonexact match(es). */
-
- arglen = strlen (arg);
-
- /* Test all elements for either exact match or abbreviated matches. */
- for (i = 0; arglist[i]; i++)
- {
- if (!strncmp (arglist[i], arg, arglen))
- {
- if (strlen (arglist[i]) == arglen)
- /* Exact match found. */
- return i;
- else if (matchind == -1)
- /* First nonexact match found. */
- matchind = i;
- else
- {
- /* Second nonexact match found. */
- if (vallist == NULL
- || memcmp (vallist + valsize * matchind,
- vallist + valsize * i, valsize))
- {
- /* There is a real ambiguity, or we could not
- disambiguate. */
- ambiguous = true;
- }
- }
- }
- }
- if (ambiguous)
- return -2;
- else
- return matchind;
-}
-
-/* Error reporting for argmatch.
- CONTEXT is a description of the type of entity that was being matched.
- VALUE is the invalid value that was given.
- PROBLEM is the return value from argmatch. */
-
-void
-argmatch_invalid (const char *context, const char *value, ptrdiff_t problem)
-{
- char const *format = (problem == -1
- ? _("invalid argument %s for %s")
- : _("ambiguous argument %s for %s"));
-
- error (0, 0, format, quotearg_n_style (0, ARGMATCH_QUOTING_STYLE, value),
- quote_n (1, context));
-}
-
-/* List the valid arguments for argmatch.
- ARGLIST is the same as in argmatch.
- VALLIST is a pointer to an array of values.
- VALSIZE is the size of the elements of VALLIST */
-void
-argmatch_valid (const char *const *arglist,
- const char *vallist, size_t valsize)
-{
- size_t i;
- const char *last_val = NULL;
-
- /* We try to put synonyms on the same line. The assumption is that
- synonyms follow each other */
- fprintf (stderr, _("Valid arguments are:"));
- for (i = 0; arglist[i]; i++)
- if ((i == 0)
- || memcmp (last_val, vallist + valsize * i, valsize))
- {
- fprintf (stderr, "\n - `%s'", arglist[i]);
- last_val = vallist + valsize * i;
- }
- else
- {
- fprintf (stderr, ", `%s'", arglist[i]);
- }
- putc ('\n', stderr);
-}
-
-/* Never failing versions of the previous functions.
-
- CONTEXT is the context for which argmatch is called (e.g.,
- "--version-control", or "$VERSION_CONTROL" etc.). Upon failure,
- calls the (supposed never to return) function EXIT_FN. */
-
-ptrdiff_t
-__xargmatch_internal (const char *context,
- const char *arg, const char *const *arglist,
- const char *vallist, size_t valsize,
- argmatch_exit_fn exit_fn)
-{
- ptrdiff_t res = argmatch (arg, arglist, vallist, valsize);
- if (res >= 0)
- /* Success. */
- return res;
-
- /* We failed. Explain why. */
- argmatch_invalid (context, arg, res);
- argmatch_valid (arglist, vallist, valsize);
- (*exit_fn) ();
-
- return -1; /* To please the compilers. */
-}
-
-/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and
- return the first corresponding argument in ARGLIST */
-const char *
-argmatch_to_argument (const char *value,
- const char *const *arglist,
- const char *vallist, size_t valsize)
-{
- size_t i;
-
- for (i = 0; arglist[i]; i++)
- if (!memcmp (value, vallist + valsize * i, valsize))
- return arglist[i];
- return NULL;
-}
-
-#ifdef TEST
-/*
- * Based on "getversion.c" by David MacKenzie <djm@gnu.ai.mit.edu>
- */
-char *program_name;
-
-/* When to make backup files. */
-enum backup_type
-{
- /* Never make backups. */
- none,
-
- /* Make simple backups of every file. */
- simple,
-
- /* Make numbered backups of files that already have numbered backups,
- and simple backups of the others. */
- numbered_existing,
-
- /* Make numbered backups of every file. */
- numbered
-};
-
-/* Two tables describing arguments (keys) and their corresponding
- values */
-static const char *const backup_args[] =
-{
- "no", "none", "off",
- "simple", "never",
- "existing", "nil",
- "numbered", "t",
- 0
-};
-
-static const enum backup_type backup_vals[] =
-{
- none, none, none,
- simple, simple,
- numbered_existing, numbered_existing,
- numbered, numbered
-};
-
-int
-main (int argc, const char *const *argv)
-{
- const char *cp;
- enum backup_type backup_type = none;
-
- program_name = (char *) argv[0];
-
- if (argc > 2)
- {
- fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name);
- exit (1);
- }
-
- if ((cp = getenv ("VERSION_CONTROL")))
- backup_type = XARGMATCH ("$VERSION_CONTROL", cp,
- backup_args, backup_vals);
-
- if (argc == 2)
- backup_type = XARGMATCH (program_name, argv[1],
- backup_args, backup_vals);
-
- printf ("The version control is `%s'\n",
- ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals));
-
- return 0;
-}
-#endif
diff --git a/contrib/gnu-sort/lib/argmatch.h b/contrib/gnu-sort/lib/argmatch.h
deleted file mode 100644
index 8952394..0000000
--- a/contrib/gnu-sort/lib/argmatch.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* argmatch.h -- definitions and prototypes for argmatch.c
-
- Copyright (C) 1990, 1998, 1999, 2001, 2002, 2004 Free Software
- Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by David MacKenzie <djm@ai.mit.edu>
- Modified by Akim Demaille <demaille@inf.enst.fr> */
-
-#ifndef ARGMATCH_H_
-# define ARGMATCH_H_ 1
-
-# include <stddef.h>
-
-# define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array))
-
-# define ARGMATCH_CONSTRAINT(Arglist, Vallist) \
- (ARRAY_CARDINALITY (Arglist) == ARRAY_CARDINALITY (Vallist) + 1)
-
-/* Assert there are as many real arguments as there are values
- (argument list ends with a NULL guard). ARGMATCH_VERIFY is
- preferred, since it is guaranteed to be checked at compile-time.
- ARGMATCH_ASSERT is for backward compatibility only. */
-
-# define ARGMATCH_VERIFY(Arglist, Vallist) \
- struct argmatch_verify \
- { \
- char argmatch_verify[ARGMATCH_CONSTRAINT(Arglist, Vallist) ? 1 : -1]; \
- }
-
-# define ARGMATCH_ASSERT(Arglist, Vallist) \
- assert (ARGMATCH_CONSTRAINT (Arglist, Vallist))
-
-/* Return the index of the element of ARGLIST (NULL terminated) that
- matches with ARG. If VALLIST is not NULL, then use it to resolve
- false ambiguities (i.e., different matches of ARG but corresponding
- to the same values in VALLIST). */
-
-ptrdiff_t argmatch (char const *arg, char const *const *arglist,
- char const *vallist, size_t valsize);
-
-# define ARGMATCH(Arg, Arglist, Vallist) \
- argmatch (Arg, Arglist, (char const *) (Vallist), sizeof *(Vallist))
-
-/* xargmatch calls this function when it fails. This function should not
- return. By default, this is a function that calls ARGMATCH_DIE which
- in turn defaults to `exit (exit_failure)'. */
-typedef void (*argmatch_exit_fn) (void);
-extern argmatch_exit_fn argmatch_die;
-
-/* Report on stderr why argmatch failed. Report correct values. */
-
-void argmatch_invalid (char const *context, char const *value,
- ptrdiff_t problem);
-
-/* Left for compatibility with the old name invalid_arg */
-
-# define invalid_arg(Context, Value, Problem) \
- argmatch_invalid (Context, Value, Problem)
-
-
-
-/* Report on stderr the list of possible arguments. */
-
-void argmatch_valid (char const *const *arglist,
- char const *vallist, size_t valsize);
-
-# define ARGMATCH_VALID(Arglist, Vallist) \
- argmatch_valid (Arglist, (char const *) (Vallist), sizeof *(Vallist))
-
-
-
-/* Same as argmatch, but upon failure, reports a explanation on the
- failure, and exits using the function EXIT_FN. */
-
-ptrdiff_t __xargmatch_internal (char const *context,
- char const *arg, char const *const *arglist,
- char const *vallist, size_t valsize,
- argmatch_exit_fn exit_fn);
-
-/* Programmer friendly interface to __xargmatch_internal. */
-
-# define XARGMATCH(Context, Arg, Arglist, Vallist) \
- ((Vallist) [__xargmatch_internal (Context, Arg, Arglist, \
- (char const *) (Vallist), \
- sizeof *(Vallist), \
- argmatch_die)])
-
-/* Convert a value into a corresponding argument. */
-
-char const *argmatch_to_argument (char const *value,
- char const *const *arglist,
- char const *vallist, size_t valsize);
-
-# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \
- argmatch_to_argument (Value, Arglist, \
- (char const *) (Vallist), sizeof *(Vallist))
-
-#endif /* ARGMATCH_H_ */
diff --git a/contrib/gnu-sort/lib/closeout.c b/contrib/gnu-sort/lib/closeout.c
deleted file mode 100644
index 3c7bed9..0000000
--- a/contrib/gnu-sort/lib/closeout.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* closeout.c - close standard output
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
- Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "closeout.h"
-
-#include <stdio.h>
-#include <errno.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-#include "error.h"
-#include "exitfail.h"
-#include "quotearg.h"
-#include "unlocked-io.h"
-#include "__fpending.h"
-
-static const char *file_name;
-
-/* Set the file name to be reported in the event an error is detected
- by close_stdout. */
-void
-close_stdout_set_file_name (const char *file)
-{
- file_name = file;
-}
-
-/* Close standard output, exiting with status 'exit_failure' on failure.
- If a program writes *anything* to stdout, that program should `fflush'
- stdout and make sure that it succeeds before exiting. Otherwise,
- suppose that you go to the extreme of checking the return status
- of every function that does an explicit write to stdout. The last
- printf can succeed in writing to the internal stream buffer, and yet
- the fclose(stdout) could still fail (due e.g., to a disk full error)
- when it tries to write out that buffered data. Thus, you would be
- left with an incomplete output file and the offending program would
- exit successfully.
-
- FIXME: note the fflush suggested above is implicit in the fclose
- we actually do below. Consider doing only the fflush and/or using
- setvbuf to inhibit buffering.
-
- Besides, it's wasteful to check the return value from every call
- that writes to stdout -- just let the internal stream state record
- the failure. That's what the ferror test is checking below.
-
- It's important to detect such failures and exit nonzero because many
- tools (most notably `make' and other build-management systems) depend
- on being able to detect failure in other tools via their exit status. */
-
-void
-close_stdout (void)
-{
- int e = ferror (stdout) ? 0 : -1;
-
- /* If the stream's error bit is clear and there is nothing to flush,
- then return right away. */
- if (e && __fpending (stdout) == 0)
- return;
-
- if (fclose (stdout) != 0)
- e = errno;
-
- if (0 <= e)
- {
- char const *write_error = _("write error");
- if (file_name)
- error (exit_failure, e, "%s: %s", quotearg_colon (file_name),
- write_error);
- else
- error (exit_failure, e, "%s", write_error);
- }
-}
diff --git a/contrib/gnu-sort/lib/closeout.h b/contrib/gnu-sort/lib/closeout.h
deleted file mode 100644
index 1b715ee..0000000
--- a/contrib/gnu-sort/lib/closeout.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Close standard output.
-
- Copyright (C) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef CLOSEOUT_H
-# define CLOSEOUT_H 1
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-void close_stdout_set_file_name (const char *file);
-void close_stdout (void);
-
-# ifdef __cplusplus
-}
-# endif
-
-#endif
diff --git a/contrib/gnu-sort/lib/dup-safer.c b/contrib/gnu-sort/lib/dup-safer.c
deleted file mode 100644
index 408a1bd..0000000
--- a/contrib/gnu-sort/lib/dup-safer.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Invoke dup, but avoid some glitches.
- Copyright (C) 2001, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <errno.h>
-
-#if HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifndef STDERR_FILENO
-# define STDERR_FILENO 2
-#endif
-
-#include <unistd-safer.h>
-
-/* Like dup, but do not return STDIN_FILENO, STDOUT_FILENO, or
- STDERR_FILENO. */
-
-int
-dup_safer (int fd)
-{
-#ifdef F_DUPFD
- return fcntl (fd, F_DUPFD, STDERR_FILENO + 1);
-#else
- int f = dup (fd);
- if (0 <= f && f <= STDERR_FILENO)
- {
- int f1 = dup_safer (f);
- int e = errno;
- close (f);
- errno = e;
- f = f1;
- }
- return f;
-#endif
-}
diff --git a/contrib/gnu-sort/lib/error.c b/contrib/gnu-sort/lib/error.c
deleted file mode 100644
index 5a5e126..0000000
--- a/contrib/gnu-sort/lib/error.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/* Error handler for noninteractive utilities
- Copyright (C) 1990-1998, 2000-2002, 2003, 2004 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "error.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef _LIBC
-# include <libintl.h>
-#else
-# include "gettext.h"
-#endif
-
-#ifdef _LIBC
-# include <wchar.h>
-# define mbsrtowcs __mbsrtowcs
-#endif
-
-#if !_LIBC
-# include "unlocked-io.h"
-#endif
-
-#ifndef _
-# define _(String) String
-#endif
-
-/* If NULL, error will flush stdout, then print on stderr the program
- name, a colon and a space. Otherwise, error will call this
- function without parameters instead. */
-void (*error_print_progname) (void);
-
-/* This variable is incremented each time `error' is called. */
-unsigned int error_message_count;
-
-#ifdef _LIBC
-/* In the GNU C library, there is a predefined variable for this. */
-
-# define program_name program_invocation_name
-# include <errno.h>
-# include <libio/libioP.h>
-
-/* In GNU libc we want do not want to use the common name `error' directly.
- Instead make it a weak alias. */
-extern void __error (int status, int errnum, const char *message, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-extern void __error_at_line (int status, int errnum, const char *file_name,
- unsigned int line_number, const char *message,
- ...)
- __attribute__ ((__format__ (__printf__, 5, 6)));;
-# define error __error
-# define error_at_line __error_at_line
-
-# include <libio/iolibio.h>
-# define fflush(s) INTUSE(_IO_fflush) (s)
-# undef putc
-# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
-
-# include <bits/libc-lock.h>
-
-#else /* not _LIBC */
-
-# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
-# ifndef HAVE_DECL_STRERROR_R
-"this configure-time declaration test was not run"
-# endif
-char *strerror_r ();
-# endif
-
-# ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-# endif
-
-/* The calling program should define program_name and set it to the
- name of the executing program. */
-extern char *program_name;
-
-# if HAVE_STRERROR_R || defined strerror_r
-# define __strerror_r strerror_r
-# endif
-#endif /* not _LIBC */
-
-static void
-print_errno_message (int errnum)
-{
- char const *s = NULL;
-
-#if defined HAVE_STRERROR_R || _LIBC
- char errbuf[1024];
-# if STRERROR_R_CHAR_P || _LIBC
- s = __strerror_r (errnum, errbuf, sizeof errbuf);
-# else
- if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
- s = errbuf;
-# endif
-#endif
-
-#if !_LIBC
- if (! s && ! (s = strerror (errnum)))
- s = _("Unknown system error");
-#endif
-
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- {
- __fwprintf (stderr, L": %s", s);
- return;
- }
-#endif
-
- fprintf (stderr, ": %s", s);
-}
-
-static void
-error_tail (int status, int errnum, const char *message, va_list args)
-{
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- {
-# define ALLOCA_LIMIT 2000
- size_t len = strlen (message) + 1;
- const wchar_t *wmessage = L"out of memory";
- wchar_t *wbuf = (len < ALLOCA_LIMIT
- ? alloca (len * sizeof *wbuf)
- : len <= SIZE_MAX / sizeof *wbuf
- ? malloc (len * sizeof *wbuf)
- : NULL);
-
- if (wbuf)
- {
- size_t res;
- mbstate_t st;
- const char *tmp = message;
- memset (&st, '\0', sizeof (st));
- res = mbsrtowcs (wbuf, &tmp, len, &st);
- wmessage = res == (size_t) -1 ? L"???" : wbuf;
- }
-
- __vfwprintf (stderr, wmessage, args);
- if (! (len < ALLOCA_LIMIT))
- free (wbuf);
- }
- else
-#endif
- vfprintf (stderr, message, args);
- va_end (args);
-
- ++error_message_count;
- if (errnum)
- print_errno_message (errnum);
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- putwc (L'\n', stderr);
- else
-#endif
- putc ('\n', stderr);
- fflush (stderr);
- if (status)
- exit (status);
-}
-
-
-/* Print the program name and error message MESSAGE, which is a printf-style
- format string with optional args.
- If ERRNUM is nonzero, print its corresponding system error message.
- Exit with status STATUS if it is nonzero. */
-void
-error (int status, int errnum, const char *message, ...)
-{
- va_list args;
-
-#if defined _LIBC && defined __libc_ptf_call
- /* We do not want this call to be cut short by a thread
- cancellation. Therefore disable cancellation for now. */
- int state = PTHREAD_CANCEL_ENABLE;
- __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
- 0);
-#endif
-
- fflush (stdout);
-#ifdef _LIBC
- _IO_flockfile (stderr);
-#endif
- if (error_print_progname)
- (*error_print_progname) ();
- else
- {
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- __fwprintf (stderr, L"%s: ", program_name);
- else
-#endif
- fprintf (stderr, "%s: ", program_name);
- }
-
- va_start (args, message);
- error_tail (status, errnum, message, args);
-
-#ifdef _LIBC
- _IO_funlockfile (stderr);
-# ifdef __libc_ptf_call
- __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
-# endif
-#endif
-}
-
-/* Sometimes we want to have at most one error per line. This
- variable controls whether this mode is selected or not. */
-int error_one_per_line;
-
-void
-error_at_line (int status, int errnum, const char *file_name,
- unsigned int line_number, const char *message, ...)
-{
- va_list args;
-
- if (error_one_per_line)
- {
- static const char *old_file_name;
- static unsigned int old_line_number;
-
- if (old_line_number == line_number
- && (file_name == old_file_name
- || strcmp (old_file_name, file_name) == 0))
- /* Simply return and print nothing. */
- return;
-
- old_file_name = file_name;
- old_line_number = line_number;
- }
-
-#if defined _LIBC && defined __libc_ptf_call
- /* We do not want this call to be cut short by a thread
- cancellation. Therefore disable cancellation for now. */
- int state = PTHREAD_CANCEL_ENABLE;
- __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
- 0);
-#endif
-
- fflush (stdout);
-#ifdef _LIBC
- _IO_flockfile (stderr);
-#endif
- if (error_print_progname)
- (*error_print_progname) ();
- else
- {
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- __fwprintf (stderr, L"%s: ", program_name);
- else
-#endif
- fprintf (stderr, "%s:", program_name);
- }
-
- if (file_name != NULL)
- {
-#if _LIBC
- if (_IO_fwide (stderr, 0) > 0)
- __fwprintf (stderr, L"%s:%d: ", file_name, line_number);
- else
-#endif
- fprintf (stderr, "%s:%d: ", file_name, line_number);
- }
-
- va_start (args, message);
- error_tail (status, errnum, message, args);
-
-#ifdef _LIBC
- _IO_funlockfile (stderr);
-# ifdef __libc_ptf_call
- __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
-# endif
-#endif
-}
-
-#ifdef _LIBC
-/* Make the weak alias. */
-# undef error
-# undef error_at_line
-weak_alias (__error, error)
-weak_alias (__error_at_line, error_at_line)
-#endif
diff --git a/contrib/gnu-sort/lib/error.h b/contrib/gnu-sort/lib/error.h
deleted file mode 100644
index 8ed6359..0000000
--- a/contrib/gnu-sort/lib/error.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Declaration for error-reporting function
- Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _ERROR_H
-#define _ERROR_H 1
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
-# define __attribute__(Spec) /* empty */
-# endif
-/* The __-protected variants of `format' and `printf' attributes
- are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
-# define __format__ format
-# define __printf__ printf
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Print a message with `fprintf (stderr, FORMAT, ...)';
- if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
- If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
-
-extern void error (int __status, int __errnum, const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 3, 4)));
-
-extern void error_at_line (int __status, int __errnum, const char *__fname,
- unsigned int __lineno, const char *__format, ...)
- __attribute__ ((__format__ (__printf__, 5, 6)));
-
-/* If NULL, error will flush stdout, then print on stderr the program
- name, a colon and a space. Otherwise, error will call this
- function without parameters instead. */
-extern void (*error_print_progname) (void);
-
-/* This variable is incremented each time `error' is called. */
-extern unsigned int error_message_count;
-
-/* Sometimes we want to have at most one error per line. This
- variable controls whether this mode is selected or not. */
-extern int error_one_per_line;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* error.h */
diff --git a/contrib/gnu-sort/lib/exit.h b/contrib/gnu-sort/lib/exit.h
deleted file mode 100644
index 4e8d465..0000000
--- a/contrib/gnu-sort/lib/exit.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* exit() function.
- Copyright (C) 1995, 2001 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _EXIT_H
-#define _EXIT_H
-
-/* Get exit() declaration. */
-#include <stdlib.h>
-
-/* Some systems do not define EXIT_*, even with STDC_HEADERS. */
-#ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
-#endif
-#ifndef EXIT_FAILURE
-# define EXIT_FAILURE 1
-#endif
-
-#endif /* _EXIT_H */
diff --git a/contrib/gnu-sort/lib/exitfail.c b/contrib/gnu-sort/lib/exitfail.c
deleted file mode 100644
index 2ae5f69..0000000
--- a/contrib/gnu-sort/lib/exitfail.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Failure exit status
-
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING.
- If not, write to the Free Software Foundation,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "exitfail.h"
-#include "exit.h"
-
-int volatile exit_failure = EXIT_FAILURE;
diff --git a/contrib/gnu-sort/lib/exitfail.h b/contrib/gnu-sort/lib/exitfail.h
deleted file mode 100644
index cf5ab71..0000000
--- a/contrib/gnu-sort/lib/exitfail.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Failure exit status
-
- Copyright (C) 2002 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING.
- If not, write to the Free Software Foundation,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-extern int volatile exit_failure;
diff --git a/contrib/gnu-sort/lib/fopen-safer.c b/contrib/gnu-sort/lib/fopen-safer.c
deleted file mode 100644
index c5c97c8..0000000
--- a/contrib/gnu-sort/lib/fopen-safer.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Invoke fopen, but avoid some glitches.
- Copyright (C) 2001, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <unistd-safer.h>
-
-#ifndef STDERR_FILENO
-# define STDERR_FILENO 2
-#endif
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdio-safer.h>
-
-/* Like fopen, but do not return stdin, stdout, or stderr. */
-
-FILE *
-fopen_safer (char const *file, char const *mode)
-{
- FILE *fp = fopen (file, mode);
-
- if (fp)
- {
- int fd = fileno (fp);
-
- if (0 <= fd && fd <= STDERR_FILENO)
- {
- int f = dup_safer (fd);
-
- if (f < 0)
- {
- int e = errno;
- fclose (fp);
- errno = e;
- return NULL;
- }
-
- if (fclose (fp) != 0
- || ! (fp = fdopen (f, mode)))
- {
- int e = errno;
- close (f);
- errno = e;
- return NULL;
- }
- }
- }
-
- return fp;
-}
diff --git a/contrib/gnu-sort/lib/gettext.h b/contrib/gnu-sort/lib/gettext.h
deleted file mode 100644
index 835732e..0000000
--- a/contrib/gnu-sort/lib/gettext.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Convenience header for conditional use of GNU <libintl.h>.
- Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H 1
-
-/* NLS can be disabled through the configure --disable-nls option. */
-#if ENABLE_NLS
-
-/* Get declarations of GNU message catalog functions. */
-# include <libintl.h>
-
-#else
-
-/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
- chokes if dcgettext is defined as a macro. So include it now, to make
- later inclusions of <locale.h> a NOP. We don't include <libintl.h>
- as well because people using "gettext.h" will not include <libintl.h>,
- and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
- is OK. */
-#if defined(__sun)
-# include <locale.h>
-#endif
-
-/* Disabled NLS.
- The casts to 'const char *' serve the purpose of producing warnings
- for invalid uses of the value returned from these functions.
- On pre-ANSI systems without 'const', the config.h file is supposed to
- contain "#define const". */
-# define gettext(Msgid) ((const char *) (Msgid))
-# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
-# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
-# define ngettext(Msgid1, Msgid2, N) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dngettext(Domainname, Msgid1, Msgid2, N) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
- ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
-# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
-
-#endif
-
-/* A pseudo function call that serves as a marker for the automated
- extraction of messages, but does not call gettext(). The run-time
- translation is done at a different place in the code.
- The argument, String, should be a literal string. Concatenated strings
- and other string expressions won't work.
- The macro's expansion is not parenthesized, so that it is suitable as
- initializer for static 'char[]' or 'const char[]' variables. */
-#define gettext_noop(String) String
-
-#endif /* _LIBGETTEXT_H */
diff --git a/contrib/gnu-sort/lib/hard-locale.c b/contrib/gnu-sort/lib/hard-locale.c
deleted file mode 100644
index 45b7d05..0000000
--- a/contrib/gnu-sort/lib/hard-locale.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* hard-locale.c -- Determine whether a locale is hard.
-
- Copyright (C) 1997, 1998, 1999, 2002, 2003, 2004 Free Software
- Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-/* $FreeBSD$ */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "hard-locale.h"
-
-#if HAVE_LOCALE_H
-# include <locale.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-
-/* Return true if the current CATEGORY locale is hard, i.e. if you
- can't get away with assuming traditional C or POSIX behavior. */
-bool
-hard_locale (int category)
-{
-#if ! HAVE_SETLOCALE
- return false;
-#else
-
- bool hard = true;
- char const *p = setlocale (category, NULL);
-
- if (p)
- {
-# if defined(__FreeBSD__) || (defined __GLIBC__ && 2 <= __GLIBC__)
- if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
- hard = false;
-# else
- char *locale = malloc (strlen (p) + 1);
- if (locale)
- {
- strcpy (locale, p);
-
- /* Temporarily set the locale to the "C" and "POSIX" locales
- to find their names, so that we can determine whether one
- or the other is the caller's locale. */
- if (((p = setlocale (category, "C"))
- && strcmp (p, locale) == 0)
- || ((p = setlocale (category, "POSIX"))
- && strcmp (p, locale) == 0))
- hard = false;
-
- /* Restore the caller's locale. */
- setlocale (category, locale);
- free (locale);
- }
-# endif
- }
-
- return hard;
-
-#endif
-}
diff --git a/contrib/gnu-sort/lib/hard-locale.h b/contrib/gnu-sort/lib/hard-locale.h
deleted file mode 100644
index 010cb27..0000000
--- a/contrib/gnu-sort/lib/hard-locale.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Determine whether a locale is hard.
-
- Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef HARD_LOCALE_H_
-# define HARD_LOCALE_H_ 1
-
-# include <stdbool.h>
-
-bool hard_locale (int);
-
-#endif /* HARD_LOCALE_H_ */
diff --git a/contrib/gnu-sort/lib/human.c b/contrib/gnu-sort/lib/human.c
deleted file mode 100644
index f024c73..0000000
--- a/contrib/gnu-sort/lib/human.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/* human.c -- print human readable file size
-
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert and Larry McVoy. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "human.h"
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-#ifndef UINTMAX_MAX
-# define UINTMAX_MAX ((uintmax_t) -1)
-#endif
-
-#if HAVE_LOCALE_H && HAVE_LOCALECONV
-# include <locale.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-#include <argmatch.h>
-#include <error.h>
-#include <xstrtol.h>
-
-/* The maximum length of a suffix like "KiB". */
-#define HUMAN_READABLE_SUFFIX_LENGTH_MAX 3
-
-static const char power_letter[] =
-{
- 0, /* not used */
- 'K', /* kibi ('k' for kilo is a special case) */
- 'M', /* mega or mebi */
- 'G', /* giga or gibi */
- 'T', /* tera or tebi */
- 'P', /* peta or pebi */
- 'E', /* exa or exbi */
- 'Z', /* zetta or 2**70 */
- 'Y' /* yotta or 2**80 */
-};
-
-
-/* If INEXACT_STYLE is not human_round_to_nearest, and if easily
- possible, adjust VALUE according to the style. */
-
-static long double
-adjust_value (int inexact_style, long double value)
-{
- /* Do not use the floorl or ceill functions, as that would mean
- checking for their presence and possibly linking with the
- standard math library, which is a porting pain. So leave the
- value alone if it is too large to easily round. */
- if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
- {
- uintmax_t u = value;
- value = u + (inexact_style == human_ceiling && u != value);
- }
-
- return value;
-}
-
-/* Group the digits of NUMBER according to the grouping rules of the
- current locale. NUMBER contains NUMBERLEN digits. Modify the
- bytes pointed to by NUMBER in place, subtracting 1 from NUMBER for
- each byte inserted. Return the starting address of the modified
- number.
-
- To group the digits, use GROUPING and THOUSANDS_SEP as in `struct
- lconv' from <locale.h>. */
-
-static char *
-group_number (char *number, size_t numberlen,
- char const *grouping, char const *thousands_sep)
-{
- register char *d;
- size_t grouplen = SIZE_MAX;
- size_t thousands_seplen = strlen (thousands_sep);
- size_t i = numberlen;
-
- /* The maximum possible value for NUMBERLEN is the number of digits
- in the square of the largest uintmax_t, so double the size of
- uintmax_t before converting to a bound. 302 / 1000 is ceil
- (log10 (2.0)). Add 1 for integer division truncation. */
- char buf[2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1];
-
- memcpy (buf, number, numberlen);
- d = number + numberlen;
-
- for (;;)
- {
- unsigned char g = *grouping;
-
- if (g)
- {
- grouplen = g < CHAR_MAX ? g : i;
- grouping++;
- }
-
- if (i < grouplen)
- grouplen = i;
-
- d -= grouplen;
- i -= grouplen;
- memcpy (d, buf + i, grouplen);
- if (i == 0)
- return d;
-
- d -= thousands_seplen;
- memcpy (d, thousands_sep, thousands_seplen);
- }
-}
-
-/* Convert N to a human readable format in BUF, using the options OPTS.
-
- N is expressed in units of FROM_BLOCK_SIZE. FROM_BLOCK_SIZE must
- be nonnegative.
-
- Use units of TO_BLOCK_SIZE in the output number. TO_BLOCK_SIZE
- must be positive.
-
- Use (OPTS & (human_round_to_nearest | human_floor | human_ceiling))
- to determine whether to take the ceiling or floor of any result
- that cannot be expressed exactly.
-
- If (OPTS & human_group_digits), group the thousands digits
- according to the locale, e.g., `1,000,000' in an American English
- locale.
-
- If (OPTS & human_autoscale), deduce the output block size
- automatically; TO_BLOCK_SIZE must be 1 but it has no effect on the
- output. Use powers of 1024 if (OPTS & human_base_1024), and powers
- of 1000 otherwise. For example, assuming powers of 1024, 8500
- would be converted to 8.3, 133456345 to 127, 56990456345 to 53, and
- so on. Numbers smaller than the power aren't modified.
- human_autoscale is normally used together with human_SI.
-
- If (OPTS & human_SI), append an SI prefix indicating which power is
- being used. If in addition (OPTS & human_B), append "B" (if base
- 1000) or "iB" (if base 1024) to the SI prefix. When ((OPTS &
- human_SI) && ! (OPTS & human_autoscale)), TO_BLOCK_SIZE must be a
- power of 1024 or of 1000, depending on (OPTS &
- human_base_1024). */
-
-char *
-human_readable (uintmax_t n, char *buf, int opts,
- uintmax_t from_block_size, uintmax_t to_block_size)
-{
- int inexact_style =
- opts & (human_round_to_nearest | human_floor | human_ceiling);
- unsigned int base = opts & human_base_1024 ? 1024 : 1000;
- uintmax_t amt;
- int tenths;
- int exponent = -1;
- int exponent_max = sizeof power_letter - 1;
- char *p;
- char *psuffix;
- char const *integerlim;
-
- /* 0 means adjusted N == AMT.TENTHS;
- 1 means AMT.TENTHS < adjusted N < AMT.TENTHS + 0.05;
- 2 means adjusted N == AMT.TENTHS + 0.05;
- 3 means AMT.TENTHS + 0.05 < adjusted N < AMT.TENTHS + 0.1. */
- int rounding;
-
- char const *decimal_point = ".";
- size_t decimal_pointlen = 1;
- char const *grouping = "";
- char const *thousands_sep = "";
-#if HAVE_LOCALE_H && HAVE_LOCALECONV
- struct lconv const *l = localeconv ();
- size_t pointlen = strlen (l->decimal_point);
- if (0 < pointlen && pointlen <= MB_LEN_MAX)
- {
- decimal_point = l->decimal_point;
- decimal_pointlen = pointlen;
- }
- grouping = l->grouping;
- if (strlen (l->thousands_sep) <= MB_LEN_MAX)
- thousands_sep = l->thousands_sep;
-#endif
-
- psuffix = buf + LONGEST_HUMAN_READABLE - HUMAN_READABLE_SUFFIX_LENGTH_MAX;
- p = psuffix;
-
- /* Adjust AMT out of FROM_BLOCK_SIZE units and into TO_BLOCK_SIZE
- units. If this can be done exactly with integer arithmetic, do
- not use floating point operations. */
- if (to_block_size <= from_block_size)
- {
- if (from_block_size % to_block_size == 0)
- {
- uintmax_t multiplier = from_block_size / to_block_size;
- amt = n * multiplier;
- if (amt / multiplier == n)
- {
- tenths = 0;
- rounding = 0;
- goto use_integer_arithmetic;
- }
- }
- }
- else if (from_block_size != 0 && to_block_size % from_block_size == 0)
- {
- uintmax_t divisor = to_block_size / from_block_size;
- uintmax_t r10 = (n % divisor) * 10;
- uintmax_t r2 = (r10 % divisor) * 2;
- amt = n / divisor;
- tenths = r10 / divisor;
- rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
- goto use_integer_arithmetic;
- }
-
- {
- /* Either the result cannot be computed easily using uintmax_t,
- or from_block_size is zero. Fall back on floating point.
- FIXME: This can yield answers that are slightly off. */
-
- long double dto_block_size = to_block_size;
- long double damt = n * (from_block_size / dto_block_size);
- size_t buflen;
- size_t nonintegerlen;
-
- if (! (opts & human_autoscale))
- {
- sprintf (buf, "%.0Lf", adjust_value (inexact_style, damt));
- buflen = strlen (buf);
- nonintegerlen = 0;
- }
- else
- {
- long double e = 1;
- exponent = 0;
-
- do
- {
- e *= base;
- exponent++;
- }
- while (e * base <= damt && exponent < exponent_max);
-
- damt /= e;
-
- sprintf (buf, "%.1Lf", adjust_value (inexact_style, damt));
- buflen = strlen (buf);
- nonintegerlen = decimal_pointlen + 1;
-
- if (1 + nonintegerlen + ! (opts & human_base_1024) < buflen
- || ((opts & human_suppress_point_zero)
- && buf[buflen - 1] == '0'))
- {
- sprintf (buf, "%.0Lf",
- adjust_value (inexact_style, damt * 10) / 10);
- buflen = strlen (buf);
- nonintegerlen = 0;
- }
- }
-
- p = psuffix - buflen;
- memmove (p, buf, buflen);
- integerlim = p + buflen - nonintegerlen;
- }
- goto do_grouping;
-
- use_integer_arithmetic:
- {
- /* The computation can be done exactly, with integer arithmetic.
-
- Use power of BASE notation if requested and if adjusted AMT is
- large enough. */
-
- if (opts & human_autoscale)
- {
- exponent = 0;
-
- if (base <= amt)
- {
- do
- {
- unsigned int r10 = (amt % base) * 10 + tenths;
- unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
- amt /= base;
- tenths = r10 / base;
- rounding = (r2 < base
- ? (r2 + rounding) != 0
- : 2 + (base < r2 + rounding));
- exponent++;
- }
- while (base <= amt && exponent < exponent_max);
-
- if (amt < 10)
- {
- if (inexact_style == human_round_to_nearest
- ? 2 < rounding + (tenths & 1)
- : inexact_style == human_ceiling && 0 < rounding)
- {
- tenths++;
- rounding = 0;
-
- if (tenths == 10)
- {
- amt++;
- tenths = 0;
- }
- }
-
- if (amt < 10
- && (tenths || ! (opts & human_suppress_point_zero)))
- {
- *--p = '0' + tenths;
- p -= decimal_pointlen;
- memcpy (p, decimal_point, decimal_pointlen);
- tenths = rounding = 0;
- }
- }
- }
- }
-
- if (inexact_style == human_round_to_nearest
- ? 5 < tenths + (0 < rounding + (amt & 1))
- : inexact_style == human_ceiling && 0 < tenths + rounding)
- {
- amt++;
-
- if ((opts & human_autoscale)
- && amt == base && exponent < exponent_max)
- {
- exponent++;
- if (! (opts & human_suppress_point_zero))
- {
- *--p = '0';
- p -= decimal_pointlen;
- memcpy (p, decimal_point, decimal_pointlen);
- }
- amt = 1;
- }
- }
-
- integerlim = p;
-
- do
- {
- int digit = amt % 10;
- *--p = digit + '0';
- }
- while ((amt /= 10) != 0);
- }
-
- do_grouping:
- if (opts & human_group_digits)
- p = group_number (p, integerlim - p, grouping, thousands_sep);
-
- if (opts & human_SI)
- {
- if (exponent < 0)
- {
- uintmax_t power;
- exponent = 0;
- for (power = 1; power < to_block_size; power *= base)
- if (++exponent == exponent_max)
- break;
- }
-
- if (exponent)
- *psuffix++ = (! (opts & human_base_1024) && exponent == 1
- ? 'k'
- : power_letter[exponent]);
-
- if (opts & human_B)
- {
- if ((opts & human_base_1024) && exponent)
- *psuffix++ = 'i';
- *psuffix++ = 'B';
- }
- }
-
- *psuffix = '\0';
-
- return p;
-}
-
-
-/* The default block size used for output. This number may change in
- the future as disks get larger. */
-#ifndef DEFAULT_BLOCK_SIZE
-# define DEFAULT_BLOCK_SIZE 1024
-#endif
-
-static char const *const block_size_args[] = { "human-readable", "si", 0 };
-static int const block_size_opts[] =
- {
- human_autoscale + human_SI + human_base_1024,
- human_autoscale + human_SI
- };
-
-static uintmax_t
-default_block_size (void)
-{
- return getenv ("POSIXLY_CORRECT") ? 512 : DEFAULT_BLOCK_SIZE;
-}
-
-static strtol_error
-humblock (char const *spec, uintmax_t *block_size, int *options)
-{
- int i;
- int opts = 0;
-
- if (! spec
- && ! (spec = getenv ("BLOCK_SIZE"))
- && ! (spec = getenv ("BLOCKSIZE")))
- *block_size = default_block_size ();
- else
- {
- if (*spec == '\'')
- {
- opts |= human_group_digits;
- spec++;
- }
-
- if (0 <= (i = ARGMATCH (spec, block_size_args, block_size_opts)))
- {
- opts |= block_size_opts[i];
- *block_size = 1;
- }
- else
- {
- char *ptr;
- strtol_error e = xstrtoumax (spec, &ptr, 0, block_size,
- "eEgGkKmMpPtTyYzZ0");
- if (e != LONGINT_OK)
- return e;
- for (; ! ('0' <= *spec && *spec <= '9'); spec++)
- if (spec == ptr)
- {
- opts |= human_SI;
- if (ptr[-1] == 'B')
- opts |= human_B;
- if (ptr[-1] != 'B' || ptr[-2] == 'i')
- opts |= human_base_1024;
- break;
- }
- }
- }
-
- *options = opts;
- return LONGINT_OK;
-}
-
-int
-human_options (char const *spec, bool report_errors, uintmax_t *block_size)
-{
- int opts;
- strtol_error e = humblock (spec, block_size, &opts);
- if (*block_size == 0)
- {
- *block_size = default_block_size ();
- e = LONGINT_INVALID;
- }
- if (e != LONGINT_OK && report_errors)
- STRTOL_FATAL_ERROR (spec, _("block size"), e);
- return opts;
-}
diff --git a/contrib/gnu-sort/lib/human.h b/contrib/gnu-sort/lib/human.h
deleted file mode 100644
index b67ba4e..0000000
--- a/contrib/gnu-sort/lib/human.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* human.h -- print human readable file size
-
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert and Larry McVoy. */
-
-#ifndef HUMAN_H_
-# define HUMAN_H_ 1
-
-# if HAVE_CONFIG_H
-# include <config.h>
-# endif
-
-# include <limits.h>
-# include <stdbool.h>
-
-# if HAVE_STDINT_H
-# include <stdint.h>
-# endif
-# if HAVE_UNISTD_H
-# include <unistd.h>
-# endif
-
-/* A conservative bound on the maximum length of a human-readable string.
- The output can be the square of the largest uintmax_t, so double
- its size before converting to a bound.
- 302 / 1000 is ceil (log10 (2.0)). Add 1 for integer division truncation.
- Also, the output can have a thousands separator between every digit,
- so multiply by MB_LEN_MAX + 1 and then subtract MB_LEN_MAX.
- Finally, append 3, the maximum length of a suffix. */
-# define LONGEST_HUMAN_READABLE \
- ((2 * sizeof (uintmax_t) * CHAR_BIT * 302 / 1000 + 1) * (MB_LEN_MAX + 1) \
- - MB_LEN_MAX + 3)
-
-/* Options for human_readable. */
-enum
-{
- /* Unless otherwise specified these options may be ORed together. */
-
- /* The following three options are mutually exclusive. */
- /* Round to plus infinity (default). */
- human_ceiling = 0,
- /* Round to nearest, ties to even. */
- human_round_to_nearest = 1,
- /* Round to minus infinity. */
- human_floor = 2,
-
- /* Group digits together, e.g. `1,000,000'. This uses the
- locale-defined grouping; the traditional C locale does not group,
- so this has effect only if some other locale is in use. */
- human_group_digits = 4,
-
- /* When autoscaling, suppress ".0" at end. */
- human_suppress_point_zero = 8,
-
- /* Scale output and use SI-style units, ignoring the output block size. */
- human_autoscale = 16,
-
- /* Prefer base 1024 to base 1000. */
- human_base_1024 = 32,
-
- /* Append SI prefix, e.g. "k" or "M". */
- human_SI = 64,
-
- /* Append "B" (if base 1000) or "iB" (if base 1024) to SI prefix. */
- human_B = 128
-};
-
-char *human_readable (uintmax_t, char *, int, uintmax_t, uintmax_t);
-
-int human_options (char const *, bool, uintmax_t *);
-
-#endif /* HUMAN_H_ */
diff --git a/contrib/gnu-sort/lib/inttostr.c b/contrib/gnu-sort/lib/inttostr.c
deleted file mode 100644
index 78a48af..0000000
--- a/contrib/gnu-sort/lib/inttostr.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* inttostr.c -- convert integers to printable strings
-
- Copyright (C) 2001 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert */
-
-#include "inttostr.h"
-
-/* Convert I to a printable string in BUF, which must be at least
- INT_BUFSIZE_BOUND (INTTYPE) bytes long. Return the address of the
- printable string, which need not start at BUF. */
-
-char *
-inttostr (inttype i, char *buf)
-{
- char *p = buf + INT_STRLEN_BOUND (inttype);
- *p = 0;
-
- if (i < 0)
- {
- do
- *--p = '0' - i % 10;
- while ((i /= 10) != 0);
-
- *--p = '-';
- }
- else
- {
- do
- *--p = '0' + i % 10;
- while ((i /= 10) != 0);
- }
-
- return p;
-}
diff --git a/contrib/gnu-sort/lib/inttostr.h b/contrib/gnu-sort/lib/inttostr.h
deleted file mode 100644
index 6f2416b..0000000
--- a/contrib/gnu-sort/lib/inttostr.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* inttostr.h -- convert integers to printable strings
-
- Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-
-#include <limits.h>
-
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-/* Upper bound on the string length of an integer converted to string.
- 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
- add 1 for integer division truncation; add 1 more for a minus sign. */
-#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2)
-
-#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
-
-char *offtostr (off_t, char *);
-char *imaxtostr (intmax_t, char *);
-char *umaxtostr (uintmax_t, char *);
diff --git a/contrib/gnu-sort/lib/long-options.c b/contrib/gnu-sort/lib/long-options.c
deleted file mode 100644
index 1c4e74a..0000000
--- a/contrib/gnu-sort/lib/long-options.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Utility to accept --help and --version options as unobtrusively as possible.
-
- Copyright (C) 1993, 1994, 1998, 1999, 2000, 2002, 2003, 2004 Free
- Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Jim Meyering. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/* Specification. */
-#include "long-options.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <getopt.h>
-
-#include "version-etc.h"
-
-static struct option const long_options[] =
-{
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'v'},
- {0, 0, 0, 0}
-};
-
-/* Process long options --help and --version, but only if argc == 2.
- Be careful not to gobble up `--'. */
-
-void
-parse_long_options (int argc,
- char **argv,
- const char *command_name,
- const char *package,
- const char *version,
- void (*usage_func) (int),
- /* const char *author1, ...*/ ...)
-{
- int c;
- int saved_opterr;
-
- saved_opterr = opterr;
-
- /* Don't print an error message for unrecognized options. */
- opterr = 0;
-
- if (argc == 2
- && (c = getopt_long (argc, argv, "+", long_options, NULL)) != -1)
- {
- switch (c)
- {
- case 'h':
- (*usage_func) (EXIT_SUCCESS);
-
- case 'v':
- {
- va_list authors;
- va_start (authors, usage_func);
- version_etc_va (stdout, command_name, package, version, authors);
- exit (0);
- }
-
- default:
- /* Don't process any other long-named options. */
- break;
- }
- }
-
- /* Restore previous value. */
- opterr = saved_opterr;
-
- /* Reset this to zero so that getopt internals get initialized from
- the probably-new parameters when/if getopt is called later. */
- optind = 0;
-}
diff --git a/contrib/gnu-sort/lib/long-options.h b/contrib/gnu-sort/lib/long-options.h
deleted file mode 100644
index 50f0c34..0000000
--- a/contrib/gnu-sort/lib/long-options.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* long-options.h -- declaration for --help- and --version-handling function.
- Copyright (C) 1993, 1994, 1998, 1999, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Jim Meyering. */
-
-void parse_long_options (int _argc,
- char **_argv,
- const char *_command_name,
- const char *_package,
- const char *_version,
- void (*_usage) (int),
- /* const char *author1, ...*/ ...);
diff --git a/contrib/gnu-sort/lib/memcoll.c b/contrib/gnu-sort/lib/memcoll.c
deleted file mode 100644
index e777e6a..0000000
--- a/contrib/gnu-sort/lib/memcoll.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Locale-specific memory comparison.
- Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Contributed by Paul Eggert <eggert@twinsun.com>. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "memcoll.h"
-
-#include <errno.h>
-#include <string.h>
-
-/* Compare S1 (with length S1LEN) and S2 (with length S2LEN) according
- to the LC_COLLATE locale. S1 and S2 do not overlap, and are not
- adjacent. Perhaps temporarily modify the bytes after S1 and S2,
- but restore their original contents before returning. Set errno to an
- error number if there is an error, and to zero otherwise. */
-int
-memcoll (char *s1, size_t s1len, char *s2, size_t s2len)
-{
- int diff;
-
-#if HAVE_STRCOLL
-
- char n1 = s1[s1len];
- char n2 = s2[s2len];
-
- s1[s1len++] = '\0';
- s2[s2len++] = '\0';
-
- while (! (errno = 0, (diff = strcoll (s1, s2)) || errno))
- {
- /* strcoll found no difference, but perhaps it was fooled by NUL
- characters in the data. Work around this problem by advancing
- past the NUL chars. */
- size_t size1 = strlen (s1) + 1;
- size_t size2 = strlen (s2) + 1;
- s1 += size1;
- s2 += size2;
- s1len -= size1;
- s2len -= size2;
-
- if (s1len == 0)
- {
- if (s2len != 0)
- diff = -1;
- break;
- }
- else if (s2len == 0)
- {
- diff = 1;
- break;
- }
- }
-
- s1[s1len - 1] = n1;
- s2[s2len - 1] = n2;
-
-#else
-
- diff = memcmp (s1, s2, s1len < s2len ? s1len : s2len);
- if (! diff)
- diff = s1len < s2len ? -1 : s1len != s2len;
- errno = 0;
-
-#endif
-
- return diff;
-}
diff --git a/contrib/gnu-sort/lib/memcoll.h b/contrib/gnu-sort/lib/memcoll.h
deleted file mode 100644
index 66b2ecb..0000000
--- a/contrib/gnu-sort/lib/memcoll.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Locale-specific memory comparison.
-
- Copyright (C) 1999, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Contributed by Paul Eggert <eggert@twinsun.com>. */
-
-#ifndef MEMCOLL_H_
-# define MEMCOLL_H_ 1
-
-# include <stddef.h>
-
-int memcoll (char *, size_t, char *, size_t);
-
-#endif /* MEMCOLL_H_ */
diff --git a/contrib/gnu-sort/lib/pathmax.h b/contrib/gnu-sort/lib/pathmax.h
deleted file mode 100644
index bdd756e..0000000
--- a/contrib/gnu-sort/lib/pathmax.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Define PATH_MAX somehow. Requires sys/types.h.
- Copyright (C) 1992, 1999, 2001, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _PATHMAX_H
-# define _PATHMAX_H
-
-# if HAVE_UNISTD_H
-# include <unistd.h>
-# endif
-
-/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
- PATH_MAX but might cause redefinition warnings when sys/param.h is
- later included (as on MORE/BSD 4.3). */
-# if defined _POSIX_VERSION || !defined __GNUC__
-# include <limits.h>
-# endif
-
-# ifndef _POSIX_PATH_MAX
-# define _POSIX_PATH_MAX 255
-# endif
-
-# if !defined PATH_MAX && defined _PC_PATH_MAX
-# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 \
- : pathconf ("/", _PC_PATH_MAX))
-# endif
-
-/* Don't include sys/param.h if it already has been. */
-# if defined HAVE_SYS_PARAM_H && !defined PATH_MAX && !defined MAXPATHLEN
-# include <sys/param.h>
-# endif
-
-# if !defined PATH_MAX && defined MAXPATHLEN
-# define PATH_MAX MAXPATHLEN
-# endif
-
-# ifndef PATH_MAX
-# define PATH_MAX _POSIX_PATH_MAX
-# endif
-
-#endif /* _PATHMAX_H */
diff --git a/contrib/gnu-sort/lib/physmem.c b/contrib/gnu-sort/lib/physmem.c
deleted file mode 100644
index dc67b57..0000000
--- a/contrib/gnu-sort/lib/physmem.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/* Calculate the size of physical memory.
- Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "physmem.h"
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#if HAVE_SYS_PSTAT_H
-# include <sys/pstat.h>
-#endif
-
-#if HAVE_SYS_SYSMP_H
-# include <sys/sysmp.h>
-#endif
-
-#if HAVE_SYS_SYSINFO_H && HAVE_MACHINE_HAL_SYSINFO_H
-# include <sys/sysinfo.h>
-# include <machine/hal_sysinfo.h>
-#endif
-
-#if HAVE_SYS_TABLE_H
-# include <sys/table.h>
-#endif
-
-#include <sys/types.h>
-
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-
-#if HAVE_SYS_SYSCTL_H
-# include <sys/sysctl.h>
-#endif
-
-#if HAVE_SYS_SYSTEMCFG_H
-# include <sys/systemcfg.h>
-#endif
-
-#ifdef _WIN32
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-/* MEMORYSTATUSEX is missing from older windows headers, so define
- a local replacement. */
-typedef struct
-{
- DWORD dwLength;
- DWORD dwMemoryLoad;
- DWORDLONG ullTotalPhys;
- DWORDLONG ullAvailPhys;
- DWORDLONG ullTotalPageFile;
- DWORDLONG ullAvailPageFile;
- DWORDLONG ullTotalVirtual;
- DWORDLONG ullAvailVirtual;
- DWORDLONG ullAvailExtendedVirtual;
-} lMEMORYSTATUSEX;
-typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
-#endif
-
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
-/* Return the total amount of physical memory. */
-double
-physmem_total (void)
-{
-#if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE
- { /* This works on linux-gnu, solaris2 and cygwin. */
- double pages = sysconf (_SC_PHYS_PAGES);
- double pagesize = sysconf (_SC_PAGESIZE);
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
-#endif
-
-#if HAVE_PSTAT_GETSTATIC
- { /* This works on hpux11. */
- struct pst_static pss;
- if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0))
- {
- double pages = pss.physical_memory;
- double pagesize = pss.page_size;
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
- }
-#endif
-
-#if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE
- { /* This works on irix6. */
- struct rminfo realmem;
- if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0)
- {
- double pagesize = sysconf (_SC_PAGESIZE);
- double pages = realmem.physmem;
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
- }
-#endif
-
-#if HAVE_GETSYSINFO && defined GSI_PHYSMEM
- { /* This works on Tru64 UNIX V4/5. */
- int physmem;
-
- if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem),
- NULL, NULL, NULL) == 1)
- {
- double kbytes = physmem;
-
- if (0 <= kbytes)
- return kbytes * 1024.0;
- }
- }
-#endif
-
-#if HAVE_SYSCTL && defined HW_PHYSMEM
- { /* This works on *bsd and darwin. */
- unsigned int physmem;
- size_t len = sizeof physmem;
- static int mib[2] = { CTL_HW, HW_PHYSMEM };
-
- if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0
- && len == sizeof (physmem))
- return (double) physmem;
- }
-#endif
-
-#if HAVE__SYSTEM_CONFIGURATION
- /* This works on AIX. */
- return _system_configuration.physmem;
-#endif
-
-#if defined _WIN32
- { /* this works on windows */
- PFN_MS_EX pfnex;
- HMODULE h = GetModuleHandle ("kernel32.dll");
-
- if (!h)
- return 0.0;
-
- /* Use GlobalMemoryStatusEx if available. */
- if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
- {
- lMEMORYSTATUSEX lms_ex;
- lms_ex.dwLength = sizeof lms_ex;
- if (!pfnex (&lms_ex))
- return 0.0;
- return (double) lms_ex.ullTotalPhys;
- }
-
- /* Fall back to GlobalMemoryStatus which is always available.
- but returns wrong results for physical memory > 4GB. */
- else
- {
- MEMORYSTATUS ms;
- GlobalMemoryStatus (&ms);
- return (double) ms.dwTotalPhys;
- }
- }
-#endif
-
- /* Guess 64 MB. It's probably an older host, so guess small. */
- return 64 * 1024 * 1024;
-}
-
-/* Return the amount of physical memory available. */
-double
-physmem_available (void)
-{
-#if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE
- { /* This works on linux-gnu, solaris2 and cygwin. */
- double pages = sysconf (_SC_AVPHYS_PAGES);
- double pagesize = sysconf (_SC_PAGESIZE);
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
-#endif
-
-#if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC
- { /* This works on hpux11. */
- struct pst_static pss;
- struct pst_dynamic psd;
- if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)
- && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0))
- {
- double pages = psd.psd_free;
- double pagesize = pss.page_size;
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
- }
-#endif
-
-#if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE
- { /* This works on irix6. */
- struct rminfo realmem;
- if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0)
- {
- double pagesize = sysconf (_SC_PAGESIZE);
- double pages = realmem.availrmem;
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
- }
-#endif
-
-#if HAVE_TABLE && defined TBL_VMSTATS
- { /* This works on Tru64 UNIX V4/5. */
- struct tbl_vmstats vmstats;
-
- if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1)
- {
- double pages = vmstats.free_count;
- double pagesize = vmstats.pagesize;
-
- if (0 <= pages && 0 <= pagesize)
- return pages * pagesize;
- }
- }
-#endif
-
-#if HAVE_SYSCTL && defined HW_USERMEM
- { /* This works on *bsd and darwin. */
- unsigned int usermem;
- size_t len = sizeof usermem;
- static int mib[2] = { CTL_HW, HW_USERMEM };
-
- if (sysctl (mib, ARRAY_SIZE (mib), &usermem, &len, NULL, 0) == 0
- && len == sizeof (usermem))
- return (double) usermem;
- }
-#endif
-
-#if defined _WIN32
- { /* this works on windows */
- PFN_MS_EX pfnex;
- HMODULE h = GetModuleHandle ("kernel32.dll");
-
- if (!h)
- return 0.0;
-
- /* Use GlobalMemoryStatusEx if available. */
- if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx")))
- {
- lMEMORYSTATUSEX lms_ex;
- lms_ex.dwLength = sizeof lms_ex;
- if (!pfnex (&lms_ex))
- return 0.0;
- return (double) lms_ex.ullAvailPhys;
- }
-
- /* Fall back to GlobalMemoryStatus which is always available.
- but returns wrong results for physical memory > 4GB */
- else
- {
- MEMORYSTATUS ms;
- GlobalMemoryStatus (&ms);
- return (double) ms.dwAvailPhys;
- }
- }
-#endif
-
- /* Guess 25% of physical memory. */
- return physmem_total () / 4;
-}
-
-
-#if DEBUG
-
-# include <stdio.h>
-# include <stdlib.h>
-
-int
-main (void)
-{
- printf ("%12.f %12.f\n", physmem_total (), physmem_available ());
- exit (0);
-}
-
-#endif /* DEBUG */
-
-/*
-Local Variables:
-compile-command: "gcc -DDEBUG -DHAVE_CONFIG_H -I.. -g -O -Wall -W physmem.c"
-End:
-*/
diff --git a/contrib/gnu-sort/lib/physmem.h b/contrib/gnu-sort/lib/physmem.h
deleted file mode 100644
index 67f880c..0000000
--- a/contrib/gnu-sort/lib/physmem.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* Calculate the size of physical memory.
-
- Copyright (C) 2000, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#ifndef PHYSMEM_H_
-# define PHYSMEM_H_ 1
-
-double physmem_total (void);
-double physmem_available (void);
-
-#endif /* PHYSMEM_H_ */
diff --git a/contrib/gnu-sort/lib/posixver.c b/contrib/gnu-sort/lib/posixver.c
deleted file mode 100644
index 754d7ac..0000000
--- a/contrib/gnu-sort/lib/posixver.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Which POSIX version to conform to, for utilities.
-
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "posixver.h"
-
-#include <limits.h>
-#include <stdlib.h>
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifndef _POSIX2_VERSION
-# define _POSIX2_VERSION 0
-#endif
-
-#ifndef DEFAULT_POSIX2_VERSION
-# define DEFAULT_POSIX2_VERSION _POSIX2_VERSION
-#endif
-
-/* The POSIX version that utilities should conform to. The default is
- specified by the system. */
-
-int
-posix2_version (void)
-{
- long int v = DEFAULT_POSIX2_VERSION;
- char const *s = getenv ("_POSIX2_VERSION");
-
- if (s && *s)
- {
- char *e;
- long int i = strtol (s, &e, 10);
- if (! *e)
- v = i;
- }
-
- return v < INT_MIN ? INT_MIN : v < INT_MAX ? v : INT_MAX;
-}
diff --git a/contrib/gnu-sort/lib/posixver.h b/contrib/gnu-sort/lib/posixver.h
deleted file mode 100644
index b64f6a2..0000000
--- a/contrib/gnu-sort/lib/posixver.h
+++ /dev/null
@@ -1 +0,0 @@
-int posix2_version (void);
diff --git a/contrib/gnu-sort/lib/quote.c b/contrib/gnu-sort/lib/quote.c
deleted file mode 100644
index 5f11d83..0000000
--- a/contrib/gnu-sort/lib/quote.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* quote.c - quote arguments for output
- Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert <eggert@twinsun.com> */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "quotearg.h"
-#include "quote.h"
-
-/* Return an unambiguous printable representation of NAME,
- allocated in slot N, suitable for diagnostics. */
-char const *
-quote_n (int n, char const *name)
-{
- return quotearg_n_style (n, locale_quoting_style, name);
-}
-
-/* Return an unambiguous printable representation of NAME,
- suitable for diagnostics. */
-char const *
-quote (char const *name)
-{
- return quote_n (0, name);
-}
diff --git a/contrib/gnu-sort/lib/quote.h b/contrib/gnu-sort/lib/quote.h
deleted file mode 100644
index 682f9d1..0000000
--- a/contrib/gnu-sort/lib/quote.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* quote.h - prototypes for quote.c
-
- Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software
- Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-
-char const *quote_n (int n, char const *name);
-char const *quote (char const *name);
diff --git a/contrib/gnu-sort/lib/quotearg.c b/contrib/gnu-sort/lib/quotearg.c
deleted file mode 100644
index 64fa676..0000000
--- a/contrib/gnu-sort/lib/quotearg.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/* quotearg.c - quote arguments for output
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
- Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert <eggert@twinsun.com> */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "quotearg.h"
-
-#include "xalloc.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-#if HAVE_WCHAR_H
-
-/* BSD/OS 4.1 wchar.h requires FILE and struct tm to be declared. */
-# include <stdio.h>
-# include <time.h>
-
-# include <wchar.h>
-#endif
-
-#if !HAVE_MBRTOWC
-/* Disable multibyte processing entirely. Since MB_CUR_MAX is 1, the
- other macros are defined only for documentation and to satisfy C
- syntax. */
-# undef MB_CUR_MAX
-# define MB_CUR_MAX 1
-# define mbrtowc(pwc, s, n, ps) ((*(pwc) = *(s)) != 0)
-# define iswprint(wc) isprint ((unsigned char) (wc))
-# undef HAVE_MBSINIT
-#endif
-
-#if !defined mbsinit && !HAVE_MBSINIT
-# define mbsinit(ps) 1
-#endif
-
-#ifndef iswprint
-# if HAVE_WCTYPE_H
-# include <wctype.h>
-# endif
-# if !defined iswprint && !HAVE_ISWPRINT
-# define iswprint(wc) 1
-# endif
-#endif
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-#define INT_BITS (sizeof (int) * CHAR_BIT)
-
-struct quoting_options
-{
- /* Basic quoting style. */
- enum quoting_style style;
-
- /* Quote the characters indicated by this bit vector even if the
- quoting style would not normally require them to be quoted. */
- int quote_these_too[(UCHAR_MAX / INT_BITS) + 1];
-};
-
-/* Names of quoting styles. */
-char const *const quoting_style_args[] =
-{
- "literal",
- "shell",
- "shell-always",
- "c",
- "escape",
- "locale",
- "clocale",
- 0
-};
-
-/* Correspondences to quoting style names. */
-enum quoting_style const quoting_style_vals[] =
-{
- literal_quoting_style,
- shell_quoting_style,
- shell_always_quoting_style,
- c_quoting_style,
- escape_quoting_style,
- locale_quoting_style,
- clocale_quoting_style
-};
-
-/* The default quoting options. */
-static struct quoting_options default_quoting_options;
-
-/* Allocate a new set of quoting options, with contents initially identical
- to O if O is not null, or to the default if O is null.
- It is the caller's responsibility to free the result. */
-struct quoting_options *
-clone_quoting_options (struct quoting_options *o)
-{
- int e = errno;
- struct quoting_options *p = xmalloc (sizeof *p);
- *p = *(o ? o : &default_quoting_options);
- errno = e;
- return p;
-}
-
-/* Get the value of O's quoting style. If O is null, use the default. */
-enum quoting_style
-get_quoting_style (struct quoting_options *o)
-{
- return (o ? o : &default_quoting_options)->style;
-}
-
-/* In O (or in the default if O is null),
- set the value of the quoting style to S. */
-void
-set_quoting_style (struct quoting_options *o, enum quoting_style s)
-{
- (o ? o : &default_quoting_options)->style = s;
-}
-
-/* In O (or in the default if O is null),
- set the value of the quoting options for character C to I.
- Return the old value. Currently, the only values defined for I are
- 0 (the default) and 1 (which means to quote the character even if
- it would not otherwise be quoted). */
-int
-set_char_quoting (struct quoting_options *o, char c, int i)
-{
- unsigned char uc = c;
- int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS;
- int shift = uc % INT_BITS;
- int r = (*p >> shift) & 1;
- *p ^= ((i & 1) ^ r) << shift;
- return r;
-}
-
-/* MSGID approximates a quotation mark. Return its translation if it
- has one; otherwise, return either it or "\"", depending on S. */
-static char const *
-gettext_quote (char const *msgid, enum quoting_style s)
-{
- char const *translation = _(msgid);
- if (translation == msgid && s == clocale_quoting_style)
- translation = "\"";
- return translation;
-}
-
-/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
- argument ARG (of size ARGSIZE), using QUOTING_STYLE and the
- non-quoting-style part of O to control quoting.
- Terminate the output with a null character, and return the written
- size of the output, not counting the terminating null.
- If BUFFERSIZE is too small to store the output string, return the
- value that would have been returned had BUFFERSIZE been large enough.
- If ARGSIZE is SIZE_MAX, use the string length of the argument for ARGSIZE.
-
- This function acts like quotearg_buffer (BUFFER, BUFFERSIZE, ARG,
- ARGSIZE, O), except it uses QUOTING_STYLE instead of the quoting
- style specified by O, and O may not be null. */
-
-static size_t
-quotearg_buffer_restyled (char *buffer, size_t buffersize,
- char const *arg, size_t argsize,
- enum quoting_style quoting_style,
- struct quoting_options const *o)
-{
- size_t i;
- size_t len = 0;
- char const *quote_string = 0;
- size_t quote_string_len = 0;
- bool backslash_escapes = false;
- bool unibyte_locale = MB_CUR_MAX == 1;
-
-#define STORE(c) \
- do \
- { \
- if (len < buffersize) \
- buffer[len] = (c); \
- len++; \
- } \
- while (0)
-
- switch (quoting_style)
- {
- case c_quoting_style:
- STORE ('"');
- backslash_escapes = true;
- quote_string = "\"";
- quote_string_len = 1;
- break;
-
- case escape_quoting_style:
- backslash_escapes = true;
- break;
-
- case locale_quoting_style:
- case clocale_quoting_style:
- {
- /* Get translations for open and closing quotation marks.
-
- The message catalog should translate "`" to a left
- quotation mark suitable for the locale, and similarly for
- "'". If the catalog has no translation,
- locale_quoting_style quotes `like this', and
- clocale_quoting_style quotes "like this".
-
- For example, an American English Unicode locale should
- translate "`" to U+201C (LEFT DOUBLE QUOTATION MARK), and
- should translate "'" to U+201D (RIGHT DOUBLE QUOTATION
- MARK). A British English Unicode locale should instead
- translate these to U+2018 (LEFT SINGLE QUOTATION MARK) and
- U+2019 (RIGHT SINGLE QUOTATION MARK), respectively. */
-
- char const *left = gettext_quote (N_("`"), quoting_style);
- char const *right = gettext_quote (N_("'"), quoting_style);
- for (quote_string = left; *quote_string; quote_string++)
- STORE (*quote_string);
- backslash_escapes = true;
- quote_string = right;
- quote_string_len = strlen (quote_string);
- }
- break;
-
- case shell_always_quoting_style:
- STORE ('\'');
- quote_string = "'";
- quote_string_len = 1;
- break;
-
- default:
- break;
- }
-
- for (i = 0; ! (argsize == SIZE_MAX ? arg[i] == '\0' : i == argsize); i++)
- {
- unsigned char c;
- unsigned char esc;
-
- if (backslash_escapes
- && quote_string_len
- && i + quote_string_len <= argsize
- && memcmp (arg + i, quote_string, quote_string_len) == 0)
- STORE ('\\');
-
- c = arg[i];
- switch (c)
- {
- case '\0':
- if (backslash_escapes)
- {
- STORE ('\\');
- STORE ('0');
- STORE ('0');
- c = '0';
- }
- break;
-
- case '?':
- switch (quoting_style)
- {
- case shell_quoting_style:
- goto use_shell_always_quoting_style;
-
- case c_quoting_style:
- if (i + 2 < argsize && arg[i + 1] == '?')
- switch (arg[i + 2])
- {
- case '!': case '\'':
- case '(': case ')': case '-': case '/':
- case '<': case '=': case '>':
- /* Escape the second '?' in what would otherwise be
- a trigraph. */
- c = arg[i + 2];
- i += 2;
- STORE ('?');
- STORE ('\\');
- STORE ('?');
- break;
- }
- break;
-
- default:
- break;
- }
- break;
-
- case '\a': esc = 'a'; goto c_escape;
- case '\b': esc = 'b'; goto c_escape;
- case '\f': esc = 'f'; goto c_escape;
- case '\n': esc = 'n'; goto c_and_shell_escape;
- case '\r': esc = 'r'; goto c_and_shell_escape;
- case '\t': esc = 't'; goto c_and_shell_escape;
- case '\v': esc = 'v'; goto c_escape;
- case '\\': esc = c; goto c_and_shell_escape;
-
- c_and_shell_escape:
- if (quoting_style == shell_quoting_style)
- goto use_shell_always_quoting_style;
- c_escape:
- if (backslash_escapes)
- {
- c = esc;
- goto store_escape;
- }
- break;
-
- case '{': case '}': /* sometimes special if isolated */
- if (! (argsize == SIZE_MAX ? arg[1] == '\0' : argsize == 1))
- break;
- /* Fall through. */
- case '#': case '~':
- if (i != 0)
- break;
- /* Fall through. */
- case ' ':
- case '!': /* special in bash */
- case '"': case '$': case '&':
- case '(': case ')': case '*': case ';':
- case '<':
- case '=': /* sometimes special in 0th or (with "set -k") later args */
- case '>': case '[':
- case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */
- case '`': case '|':
- /* A shell special character. In theory, '$' and '`' could
- be the first bytes of multibyte characters, which means
- we should check them with mbrtowc, but in practice this
- doesn't happen so it's not worth worrying about. */
- if (quoting_style == shell_quoting_style)
- goto use_shell_always_quoting_style;
- break;
-
- case '\'':
- switch (quoting_style)
- {
- case shell_quoting_style:
- goto use_shell_always_quoting_style;
-
- case shell_always_quoting_style:
- STORE ('\'');
- STORE ('\\');
- STORE ('\'');
- break;
-
- default:
- break;
- }
- break;
-
- case '%': case '+': case ',': case '-': case '.': case '/':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9': case ':':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z': case ']': case '_': case 'a': case 'b':
- case 'c': case 'd': case 'e': case 'f': case 'g': case 'h':
- case 'i': case 'j': case 'k': case 'l': case 'm': case 'n':
- case 'o': case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
- /* These characters don't cause problems, no matter what the
- quoting style is. They cannot start multibyte sequences. */
- break;
-
- default:
- /* If we have a multibyte sequence, copy it until we reach
- its end, find an error, or come back to the initial shift
- state. For C-like styles, if the sequence has
- unprintable characters, escape the whole sequence, since
- we can't easily escape single characters within it. */
- {
- /* Length of multibyte sequence found so far. */
- size_t m;
-
- bool printable;
-
- if (unibyte_locale)
- {
- m = 1;
- printable = isprint (c) != 0;
- }
- else
- {
- mbstate_t mbstate;
- memset (&mbstate, 0, sizeof mbstate);
-
- m = 0;
- printable = true;
- if (argsize == SIZE_MAX)
- argsize = strlen (arg);
-
- do
- {
- wchar_t w;
- size_t bytes = mbrtowc (&w, &arg[i + m],
- argsize - (i + m), &mbstate);
- if (bytes == 0)
- break;
- else if (bytes == (size_t) -1)
- {
- printable = false;
- break;
- }
- else if (bytes == (size_t) -2)
- {
- printable = false;
- while (i + m < argsize && arg[i + m])
- m++;
- break;
- }
- else
- {
- /* Work around a bug with older shells that "see" a '\'
- that is really the 2nd byte of a multibyte character.
- In practice the problem is limited to ASCII
- chars >= '@' that are shell special chars. */
- if ('[' == 0x5b && quoting_style == shell_quoting_style)
- {
- size_t j;
- for (j = 1; j < bytes; j++)
- switch (arg[i + m + j])
- {
- case '[': case '\\': case '^':
- case '`': case '|':
- goto use_shell_always_quoting_style;
- }
- }
-
- if (! iswprint (w))
- printable = false;
- m += bytes;
- }
- }
- while (! mbsinit (&mbstate));
- }
-
- if (1 < m || (backslash_escapes && ! printable))
- {
- /* Output a multibyte sequence, or an escaped
- unprintable unibyte character. */
- size_t ilim = i + m;
-
- for (;;)
- {
- if (backslash_escapes && ! printable)
- {
- STORE ('\\');
- STORE ('0' + (c >> 6));
- STORE ('0' + ((c >> 3) & 7));
- c = '0' + (c & 7);
- }
- if (ilim <= i + 1)
- break;
- STORE (c);
- c = arg[++i];
- }
-
- goto store_c;
- }
- }
- }
-
- if (! (backslash_escapes
- && o->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))))
- goto store_c;
-
- store_escape:
- STORE ('\\');
-
- store_c:
- STORE (c);
- }
-
- if (i == 0 && quoting_style == shell_quoting_style)
- goto use_shell_always_quoting_style;
-
- if (quote_string)
- for (; *quote_string; quote_string++)
- STORE (*quote_string);
-
- if (len < buffersize)
- buffer[len] = '\0';
- return len;
-
- use_shell_always_quoting_style:
- return quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
- shell_always_quoting_style, o);
-}
-
-/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
- argument ARG (of size ARGSIZE), using O to control quoting.
- If O is null, use the default.
- Terminate the output with a null character, and return the written
- size of the output, not counting the terminating null.
- If BUFFERSIZE is too small to store the output string, return the
- value that would have been returned had BUFFERSIZE been large enough.
- If ARGSIZE is SIZE_MAX, use the string length of the argument for
- ARGSIZE. */
-size_t
-quotearg_buffer (char *buffer, size_t buffersize,
- char const *arg, size_t argsize,
- struct quoting_options const *o)
-{
- struct quoting_options const *p = o ? o : &default_quoting_options;
- int e = errno;
- size_t r = quotearg_buffer_restyled (buffer, buffersize, arg, argsize,
- p->style, p);
- errno = e;
- return r;
-}
-
-/* Like quotearg_buffer (..., ARG, ARGSIZE, O), except return newly
- allocated storage containing the quoted string. */
-char *
-quotearg_alloc (char const *arg, size_t argsize,
- struct quoting_options const *o)
-{
- int e = errno;
- size_t bufsize = quotearg_buffer (0, 0, arg, argsize, o) + 1;
- char *buf = xmalloc (bufsize);
- quotearg_buffer (buf, bufsize, arg, argsize, o);
- errno = e;
- return buf;
-}
-
-/* Use storage slot N to return a quoted version of argument ARG.
- ARG is of size ARGSIZE, but if that is SIZE_MAX, ARG is a
- null-terminated string.
- OPTIONS specifies the quoting options.
- The returned value points to static storage that can be
- reused by the next call to this function with the same value of N.
- N must be nonnegative. N is deliberately declared with type "int"
- to allow for future extensions (using negative values). */
-static char *
-quotearg_n_options (int n, char const *arg, size_t argsize,
- struct quoting_options const *options)
-{
- int e = errno;
-
- /* Preallocate a slot 0 buffer, so that the caller can always quote
- one small component of a "memory exhausted" message in slot 0. */
- static char slot0[256];
- static unsigned int nslots = 1;
- unsigned int n0 = n;
- struct slotvec
- {
- size_t size;
- char *val;
- };
- static struct slotvec slotvec0 = {sizeof slot0, slot0};
- static struct slotvec *slotvec = &slotvec0;
-
- if (n < 0)
- abort ();
-
- if (nslots <= n0)
- {
- unsigned int n1 = n0 + 1;
-
- if (xalloc_oversized (n1, sizeof *slotvec))
- xalloc_die ();
-
- if (slotvec == &slotvec0)
- {
- slotvec = xmalloc (sizeof *slotvec);
- *slotvec = slotvec0;
- }
- slotvec = xrealloc (slotvec, n1 * sizeof *slotvec);
- memset (slotvec + nslots, 0, (n1 - nslots) * sizeof *slotvec);
- nslots = n1;
- }
-
- {
- size_t size = slotvec[n].size;
- char *val = slotvec[n].val;
- size_t qsize = quotearg_buffer (val, size, arg, argsize, options);
-
- if (size <= qsize)
- {
- slotvec[n].size = size = qsize + 1;
- if (val != slot0)
- free (val);
- slotvec[n].val = val = xmalloc (size);
- quotearg_buffer (val, size, arg, argsize, options);
- }
-
- errno = e;
- return val;
- }
-}
-
-char *
-quotearg_n (int n, char const *arg)
-{
- return quotearg_n_options (n, arg, SIZE_MAX, &default_quoting_options);
-}
-
-char *
-quotearg (char const *arg)
-{
- return quotearg_n (0, arg);
-}
-
-/* Return quoting options for STYLE, with no extra quoting. */
-static struct quoting_options
-quoting_options_from_style (enum quoting_style style)
-{
- struct quoting_options o;
- o.style = style;
- memset (o.quote_these_too, 0, sizeof o.quote_these_too);
- return o;
-}
-
-char *
-quotearg_n_style (int n, enum quoting_style s, char const *arg)
-{
- struct quoting_options const o = quoting_options_from_style (s);
- return quotearg_n_options (n, arg, SIZE_MAX, &o);
-}
-
-char *
-quotearg_n_style_mem (int n, enum quoting_style s,
- char const *arg, size_t argsize)
-{
- struct quoting_options const o = quoting_options_from_style (s);
- return quotearg_n_options (n, arg, argsize, &o);
-}
-
-char *
-quotearg_style (enum quoting_style s, char const *arg)
-{
- return quotearg_n_style (0, s, arg);
-}
-
-char *
-quotearg_char (char const *arg, char ch)
-{
- struct quoting_options options;
- options = default_quoting_options;
- set_char_quoting (&options, ch, 1);
- return quotearg_n_options (0, arg, SIZE_MAX, &options);
-}
-
-char *
-quotearg_colon (char const *arg)
-{
- return quotearg_char (arg, ':');
-}
diff --git a/contrib/gnu-sort/lib/quotearg.h b/contrib/gnu-sort/lib/quotearg.h
deleted file mode 100644
index 14dc316..0000000
--- a/contrib/gnu-sort/lib/quotearg.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* quotearg.h - quote arguments for output
-
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004 Free Software
- Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert <eggert@twinsun.com> */
-
-#ifndef QUOTEARG_H_
-# define QUOTEARG_H_ 1
-
-# include <stddef.h>
-
-/* Basic quoting styles. */
-enum quoting_style
- {
- /* Output names as-is (ls --quoting-style=literal). */
- literal_quoting_style,
-
- /* Quote names for the shell if they contain shell metacharacters
- or would cause ambiguous output (ls --quoting-style=shell). */
- shell_quoting_style,
-
- /* Quote names for the shell, even if they would normally not
- require quoting (ls --quoting-style=shell-always). */
- shell_always_quoting_style,
-
- /* Quote names as for a C language string (ls --quoting-style=c). */
- c_quoting_style,
-
- /* Like c_quoting_style except omit the surrounding double-quote
- characters (ls --quoting-style=escape). */
- escape_quoting_style,
-
- /* Like clocale_quoting_style, but quote `like this' instead of
- "like this" in the default C locale (ls --quoting-style=locale). */
- locale_quoting_style,
-
- /* Like c_quoting_style except use quotation marks appropriate for
- the locale (ls --quoting-style=clocale). */
- clocale_quoting_style
- };
-
-/* For now, --quoting-style=literal is the default, but this may change. */
-# ifndef DEFAULT_QUOTING_STYLE
-# define DEFAULT_QUOTING_STYLE literal_quoting_style
-# endif
-
-/* Names of quoting styles and their corresponding values. */
-extern char const *const quoting_style_args[];
-extern enum quoting_style const quoting_style_vals[];
-
-struct quoting_options;
-
-/* The functions listed below set and use a hidden variable
- that contains the default quoting style options. */
-
-/* Allocate a new set of quoting options, with contents initially identical
- to O if O is not null, or to the default if O is null.
- It is the caller's responsibility to free the result. */
-struct quoting_options *clone_quoting_options (struct quoting_options *o);
-
-/* Get the value of O's quoting style. If O is null, use the default. */
-enum quoting_style get_quoting_style (struct quoting_options *o);
-
-/* In O (or in the default if O is null),
- set the value of the quoting style to S. */
-void set_quoting_style (struct quoting_options *o, enum quoting_style s);
-
-/* In O (or in the default if O is null),
- set the value of the quoting options for character C to I.
- Return the old value. Currently, the only values defined for I are
- 0 (the default) and 1 (which means to quote the character even if
- it would not otherwise be quoted). */
-int set_char_quoting (struct quoting_options *o, char c, int i);
-
-/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of
- argument ARG (of size ARGSIZE), using O to control quoting.
- If O is null, use the default.
- Terminate the output with a null character, and return the written
- size of the output, not counting the terminating null.
- If BUFFERSIZE is too small to store the output string, return the
- value that would have been returned had BUFFERSIZE been large enough.
- If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */
-size_t quotearg_buffer (char *buffer, size_t buffersize,
- char const *arg, size_t argsize,
- struct quoting_options const *o);
-
-/* Like quotearg_buffer, except return the result in a newly allocated
- buffer. It is the caller's responsibility to free the result. */
-char *quotearg_alloc (char const *arg, size_t argsize,
- struct quoting_options const *o);
-
-/* Use storage slot N to return a quoted version of the string ARG.
- Use the default quoting options.
- The returned value points to static storage that can be
- reused by the next call to this function with the same value of N.
- N must be nonnegative. */
-char *quotearg_n (int n, char const *arg);
-
-/* Equivalent to quotearg_n (0, ARG). */
-char *quotearg (char const *arg);
-
-/* Use style S and storage slot N to return a quoted version of the string ARG.
- This is like quotearg_n (N, ARG), except that it uses S with no other
- options to specify the quoting method. */
-char *quotearg_n_style (int n, enum quoting_style s, char const *arg);
-
-/* Use style S and storage slot N to return a quoted version of the
- argument ARG of size ARGSIZE. This is like quotearg_n_style
- (N, S, ARG), except it can quote null bytes. */
-char *quotearg_n_style_mem (int n, enum quoting_style s,
- char const *arg, size_t argsize);
-
-/* Equivalent to quotearg_n_style (0, S, ARG). */
-char *quotearg_style (enum quoting_style s, char const *arg);
-
-/* Like quotearg (ARG), except also quote any instances of CH. */
-char *quotearg_char (char const *arg, char ch);
-
-/* Equivalent to quotearg_char (ARG, ':'). */
-char *quotearg_colon (char const *arg);
-
-#endif /* !QUOTEARG_H_ */
diff --git a/contrib/gnu-sort/lib/stat-macros.h b/contrib/gnu-sort/lib/stat-macros.h
deleted file mode 100644
index facbabb..0000000
--- a/contrib/gnu-sort/lib/stat-macros.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/* stat-related macros
-
- Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert and Jim Meyering. */
-
-#ifndef STAT_MACROS_H
-# define STAT_MACROS_H 1
-
-# if ! defined S_ISREG && ! defined S_IFREG
-# error "you must include <sys/stat.h> before including this file"
-# endif
-
-# ifndef S_IFMT
-# define S_IFMT 0170000
-# endif
-
-# if STAT_MACROS_BROKEN
-# undef S_ISBLK
-# undef S_ISCHR
-# undef S_ISDIR
-# undef S_ISDOOR
-# undef S_ISFIFO
-# undef S_ISLNK
-# undef S_ISNAM
-# undef S_ISMPB
-# undef S_ISMPC
-# undef S_ISNWK
-# undef S_ISREG
-# undef S_ISSOCK
-# endif
-
-
-# ifndef S_ISBLK
-# ifdef S_IFBLK
-# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
-# else
-# define S_ISBLK(m) 0
-# endif
-# endif
-
-# ifndef S_ISCHR
-# ifdef S_IFCHR
-# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
-# else
-# define S_ISCHR(m) 0
-# endif
-# endif
-
-# ifndef S_ISDIR
-# ifdef S_IFDIR
-# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
-# else
-# define S_ISDIR(m) 0
-# endif
-# endif
-
-# ifndef S_ISDOOR /* Solaris 2.5 and up */
-# ifdef S_IFDOOR
-# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
-# else
-# define S_ISDOOR(m) 0
-# endif
-# endif
-
-# ifndef S_ISFIFO
-# ifdef S_IFIFO
-# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
-# else
-# define S_ISFIFO(m) 0
-# endif
-# endif
-
-# ifndef S_ISLNK
-# ifdef S_IFLNK
-# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
-# else
-# define S_ISLNK(m) 0
-# endif
-# endif
-
-# ifndef S_ISMPB /* V7 */
-# ifdef S_IFMPB
-# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
-# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
-# else
-# define S_ISMPB(m) 0
-# define S_ISMPC(m) 0
-# endif
-# endif
-
-# ifndef S_ISNAM /* Xenix */
-# ifdef S_IFNAM
-# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
-# else
-# define S_ISNAM(m) 0
-# endif
-# endif
-
-# ifndef S_ISNWK /* HP/UX */
-# ifdef S_IFNWK
-# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
-# else
-# define S_ISNWK(m) 0
-# endif
-# endif
-
-# ifndef S_ISREG
-# ifdef S_IFREG
-# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-# else
-# define S_ISREG(m) 0
-# endif
-# endif
-
-# ifndef S_ISSOCK
-# ifdef S_IFSOCK
-# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
-# else
-# define S_ISSOCK(m) 0
-# endif
-# endif
-
-
-# ifndef S_TYPEISMQ
-# define S_TYPEISMQ(p) 0
-# endif
-
-# ifndef S_TYPEISTMO
-# define S_TYPEISTMO(p) 0
-# endif
-
-
-# ifndef S_TYPEISSEM
-# ifdef S_INSEM
-# define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM)
-# else
-# define S_TYPEISSEM(p) 0
-# endif
-# endif
-
-# ifndef S_TYPEISSHM
-# ifdef S_INSHD
-# define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD)
-# else
-# define S_TYPEISSHM(p) 0
-# endif
-# endif
-
-/* contiguous */
-# ifndef S_ISCTG
-# define S_ISCTG(p) 0
-# endif
-
-/* Cray DMF (data migration facility): off line, with data */
-# ifndef S_ISOFD
-# define S_ISOFD(p) 0
-# endif
-
-/* Cray DMF (data migration facility): off line, with no data */
-# ifndef S_ISOFL
-# define S_ISOFL(p) 0
-# endif
-
-/* If any of the following are undefined,
- define them to their de facto standard values. */
-# if !S_ISUID
-# define S_ISUID 04000
-# endif
-# if !S_ISGID
-# define S_ISGID 02000
-# endif
-
-/* S_ISVTX is a common extension to POSIX. */
-# ifndef S_ISVTX
-# define S_ISVTX 01000
-# endif
-
-# if !S_IRUSR && S_IREAD
-# define S_IRUSR S_IREAD
-# endif
-# if !S_IRUSR
-# define S_IRUSR 00400
-# endif
-# if !S_IRGRP
-# define S_IRGRP (S_IRUSR >> 3)
-# endif
-# if !S_IROTH
-# define S_IROTH (S_IRUSR >> 6)
-# endif
-
-# if !S_IWUSR && S_IWRITE
-# define S_IWUSR S_IWRITE
-# endif
-# if !S_IWUSR
-# define S_IWUSR 00200
-# endif
-# if !S_IWGRP
-# define S_IWGRP (S_IWUSR >> 3)
-# endif
-# if !S_IWOTH
-# define S_IWOTH (S_IWUSR >> 6)
-# endif
-
-# if !S_IXUSR && S_IEXEC
-# define S_IXUSR S_IEXEC
-# endif
-# if !S_IXUSR
-# define S_IXUSR 00100
-# endif
-# if !S_IXGRP
-# define S_IXGRP (S_IXUSR >> 3)
-# endif
-# if !S_IXOTH
-# define S_IXOTH (S_IXUSR >> 6)
-# endif
-
-# if !S_IRWXU
-# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
-# endif
-# if !S_IRWXG
-# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
-# endif
-# if !S_IRWXO
-# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
-# endif
-
-/* S_IXUGO is a common extension to POSIX. */
-# if !S_IXUGO
-# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
-# endif
-
-# ifndef S_IRWXUGO
-# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
-# endif
-
-/* All the mode bits that can be affected by chmod. */
-# define CHMOD_MODE_BITS \
- (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
-
-#endif /* STAT_MACROS_H */
diff --git a/contrib/gnu-sort/lib/stdio-safer.h b/contrib/gnu-sort/lib/stdio-safer.h
deleted file mode 100644
index 8a22f12..0000000
--- a/contrib/gnu-sort/lib/stdio-safer.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Invoke stdio functions, but avoid some glitches.
-
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#include <stdio.h>
-
-FILE *fopen_safer (char const *, char const *);
diff --git a/contrib/gnu-sort/lib/strnlen.c b/contrib/gnu-sort/lib/strnlen.c
deleted file mode 100644
index c9f3898..0000000
--- a/contrib/gnu-sort/lib/strnlen.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Find the length of STRING, but scan at most MAXLEN characters.
- Copyright (C) 1996, 1997, 1998, 2000-2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-#undef strnlen
-
-#include <string.h>
-
-#undef __strnlen
-#undef strnlen
-
-#ifndef _LIBC
-# define strnlen rpl_strnlen
-#endif
-
-#ifndef weak_alias
-# define __strnlen strnlen
-#endif
-
-/* Find the length of STRING, but scan at most MAXLEN characters.
- If no '\0' terminator is found in that many characters, return MAXLEN. */
-
-size_t
-__strnlen (const char *string, size_t maxlen)
-{
- const char *end = memchr (string, '\0', maxlen);
- return end ? (size_t) (end - string) : maxlen;
-}
-#ifdef weak_alias
-weak_alias (__strnlen, strnlen)
-#endif
diff --git a/contrib/gnu-sort/lib/timespec.h b/contrib/gnu-sort/lib/timespec.h
deleted file mode 100644
index 2c32a23..0000000
--- a/contrib/gnu-sort/lib/timespec.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* timespec -- System time interface
-
- Copyright (C) 2000, 2002, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if ! defined TIMESPEC_H
-# define TIMESPEC_H
-
-/* You must include config.h before including this file. */
-
-# include <sys/types.h>
-# if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-# else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-# endif
-
-# if ! HAVE_STRUCT_TIMESPEC
-/* Some systems don't define this struct, e.g., AIX 4.1, Ultrix 4.3. */
-struct timespec
-{
- time_t tv_sec;
- long tv_nsec;
-};
-# endif
-
-# ifdef ST_MTIM_NSEC
-# define ST_TIME_CMP_NS(a, b, ns) ((a).ns < (b).ns ? -1 : (a).ns > (b).ns)
-# else
-# define ST_TIME_CMP_NS(a, b, ns) 0
-# endif
-# define ST_TIME_CMP(a, b, s, ns) \
- ((a).s < (b).s ? -1 : (a).s > (b).s ? 1 : ST_TIME_CMP_NS(a, b, ns))
-# define ATIME_CMP(a, b) ST_TIME_CMP (a, b, st_atime, st_atim.ST_MTIM_NSEC)
-# define CTIME_CMP(a, b) ST_TIME_CMP (a, b, st_ctime, st_ctim.ST_MTIM_NSEC)
-# define MTIME_CMP(a, b) ST_TIME_CMP (a, b, st_mtime, st_mtim.ST_MTIM_NSEC)
-
-# ifdef ST_MTIM_NSEC
-# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
-# else
-# define TIMESPEC_NS(timespec) 0
-# endif
-
-# if ! HAVE_DECL_NANOSLEEP
-/* Don't specify a prototype here. Some systems (e.g., OSF) declare
- nanosleep with a conflicting one (const-less first parameter). */
-int nanosleep ();
-# endif
-
-int gettime (struct timespec *);
-int settime (struct timespec const *);
-
-#endif
diff --git a/contrib/gnu-sort/lib/umaxtostr.c b/contrib/gnu-sort/lib/umaxtostr.c
deleted file mode 100644
index 4f49a7f..0000000
--- a/contrib/gnu-sort/lib/umaxtostr.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#define inttostr umaxtostr
-#define inttype uintmax_t
-#include "inttostr.c"
diff --git a/contrib/gnu-sort/lib/unistd-safer.h b/contrib/gnu-sort/lib/unistd-safer.h
deleted file mode 100644
index 2976e9d..0000000
--- a/contrib/gnu-sort/lib/unistd-safer.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Invoke unistd functions, but avoid some glitches.
-
- Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-int dup_safer (int);
diff --git a/contrib/gnu-sort/lib/version-etc.c b/contrib/gnu-sort/lib/version-etc.c
deleted file mode 100644
index ccc135b..0000000
--- a/contrib/gnu-sort/lib/version-etc.c
+++ /dev/null
@@ -1,181 +0,0 @@
-/* Utility to help print --version output in a consistent format.
- Copyright (C) 1999-2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* $FreeBSD$ */
-
-/* Written by Jim Meyering. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-/* Specification. */
-#include "version-etc.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "unlocked-io.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-/* Default copyright goes to the FSF. */
-
-const char* version_etc_copyright =
- /* Do *not* mark this string for translation. */
- "Copyright (C) 2004 Free Software Foundation, Inc.";
-
-
-/* Like version_etc, below, but with the NULL-terminated author list
- provided via a variable of type va_list. */
-void
-version_etc_va (FILE *stream,
- const char *command_name, const char *package,
- const char *version, va_list authors)
-{
- size_t n_authors;
-
- /* Count the number of authors. */
- {
- va_list tmp_authors;
-
-#ifdef va_copy
- va_copy (tmp_authors, authors);
-#else
- tmp_authors = authors;
-#endif
-
- n_authors = 0;
- while (va_arg (tmp_authors, const char *) != NULL)
- ++n_authors;
-#ifdef va_copy
- va_end (tmp_authors);
-#endif
- }
-
- if (command_name)
- fprintf (stream, "%s (%s) %s\n", command_name, package, version);
- else
- fprintf (stream, "%s %s\n", package, version);
-
- switch (n_authors)
- {
- case 0:
- /* The caller must provide at least one author name. */
- abort ();
- case 1:
- /* TRANSLATORS: %s denotes an author name. */
- vfprintf (stream, _("Written by %s.\n"), authors);
- break;
- case 2:
- /* TRANSLATORS: Each %s denotes an author name. */
- vfprintf (stream, _("Written by %s and %s.\n"), authors);
- break;
- case 3:
- /* TRANSLATORS: Each %s denotes an author name. */
- vfprintf (stream, _("Written by %s, %s, and %s.\n"), authors);
- break;
- case 4:
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("Written by %s, %s, %s,\nand %s.\n"), authors);
- break;
- case 5:
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("Written by %s, %s, %s,\n%s, and %s.\n"), authors);
- break;
- case 6:
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, and %s.\n"),
- authors);
- break;
- case 7:
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, %s, and %s.\n"),
- authors);
- break;
- case 8:
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("\
-Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n"),
- authors);
- break;
- case 9:
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("\
-Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, and %s.\n"),
- authors);
- break;
- default:
- /* 10 or more authors. Use an abbreviation, since the human reader
- will probably not want to read the entire list anyway. */
- /* TRANSLATORS: Each %s denotes an author name.
- You can use line breaks, estimating that each author name occupies
- ca. 16 screen columns and that a screen line has ca. 80 columns. */
- vfprintf (stream, _("\
-Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, %s, and others.\n"),
- authors);
- break;
- }
- va_end (authors);
- putc ('\n', stream);
-
- fputs (version_etc_copyright, stream);
- putc ('\n', stream);
-
- fputs (_("\
-This is free software; see the source for copying conditions. There is NO\n\
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
- stream);
-}
-
-
-/* Display the --version information the standard way.
-
- If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of
- the program. The formats are therefore:
-
- PACKAGE VERSION
-
- or
-
- COMMAND_NAME (PACKAGE) VERSION.
-
- The author names are passed as separate arguments, with an additional
- NULL argument at the end. */
-void
-version_etc (FILE *stream,
- const char *command_name, const char *package,
- const char *version, /* const char *author1, ...*/ ...)
-{
- va_list authors;
-
- va_start (authors, version);
- version_etc_va (stream, command_name, package, version, authors);
-}
diff --git a/contrib/gnu-sort/lib/version-etc.h b/contrib/gnu-sort/lib/version-etc.h
deleted file mode 100644
index d505e75..0000000
--- a/contrib/gnu-sort/lib/version-etc.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Utility to help print --version output in a consistent format.
- Copyright (C) 1999, 2003 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Jim Meyering. */
-
-#ifndef VERSION_ETC_H
-# define VERSION_ETC_H 1
-
-# include <stdarg.h>
-# include <stdio.h>
-
-extern const char *version_etc_copyright;
-
-extern void version_etc_va (FILE *stream,
- const char *command_name, const char *package,
- const char *version, va_list authors);
-
-extern void version_etc (FILE *stream,
- const char *command_name, const char *package,
- const char *version,
- /* const char *author1, ...*/ ...);
-
-#endif /* VERSION_ETC_H */
diff --git a/contrib/gnu-sort/lib/xalloc-die.c b/contrib/gnu-sort/lib/xalloc-die.c
deleted file mode 100644
index ca3a689..0000000
--- a/contrib/gnu-sort/lib/xalloc-die.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Report a memory allocation failure and exit.
-
- Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004 Free
- Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "xalloc.h"
-
-#include <stdlib.h>
-
-#include "error.h"
-#include "exitfail.h"
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-void
-xalloc_die (void)
-{
- error (exit_failure, 0, "%s", _("memory exhausted"));
-
- /* The `noreturn' cannot be given to error, since it may return if
- its first argument is 0. To help compilers understand the
- xalloc_die does not return, call abort. Also, the abort is a
- safety feature if exit_failure is 0 (which shouldn't happen). */
- abort ();
-}
diff --git a/contrib/gnu-sort/lib/xalloc.h b/contrib/gnu-sort/lib/xalloc.h
deleted file mode 100644
index d81f2a6..0000000
--- a/contrib/gnu-sort/lib/xalloc.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* xalloc.h -- malloc with out-of-memory checking
-
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef XALLOC_H_
-# define XALLOC_H_
-
-# include <stddef.h>
-
-
-# ifdef __cplusplus
-extern "C" {
-# endif
-
-
-# ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-# endif
-# endif
-
-# ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
-# endif
-
-/* This function is always triggered when memory is exhausted.
- It must be defined by the application, either explicitly
- or by using gnulib's xalloc-die module. This is the
- function to call when one wants the program to die because of a
- memory allocation failure. */
-extern void xalloc_die (void) ATTRIBUTE_NORETURN;
-
-void *xmalloc (size_t s);
-void *xnmalloc (size_t n, size_t s);
-void *xzalloc (size_t s);
-void *xcalloc (size_t n, size_t s);
-void *xrealloc (void *p, size_t s);
-void *xnrealloc (void *p, size_t n, size_t s);
-void *x2realloc (void *p, size_t *pn);
-void *x2nrealloc (void *p, size_t *pn, size_t s);
-void *xclone (void const *p, size_t s);
-char *xstrdup (const char *str);
-
-/* Return 1 if an array of N objects, each of size S, cannot exist due
- to size arithmetic overflow. S must be positive and N must be
- nonnegative. This is a macro, not an inline function, so that it
- works correctly even when SIZE_MAX < N.
-
- By gnulib convention, SIZE_MAX represents overflow in size
- calculations, so the conservative dividend to use here is
- SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
- However, malloc (SIZE_MAX) fails on all known hosts where
- sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
- exactly-SIZE_MAX allocations on such hosts; this avoids a test and
- branch when S is known to be 1. */
-# define xalloc_oversized(n, s) \
- ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
-
-/* These macros are deprecated; they will go away soon, and are retained
- temporarily only to ease conversion to the functions described above. */
-# define CCLONE(p, n) xclone (p, (n) * sizeof *(p))
-# define CLONE(p) xclone (p, sizeof *(p))
-# define NEW(type, var) type *var = xmalloc (sizeof (type))
-# define XCALLOC(type, n) xcalloc (n, sizeof (type))
-# define XMALLOC(type, n) xnmalloc (n, sizeof (type))
-# define XREALLOC(p, type, n) xnrealloc (p, n, sizeof (type))
-# define XFREE(p) free (p)
-
-
-# ifdef __cplusplus
-}
-# endif
-
-
-#endif /* !XALLOC_H_ */
diff --git a/contrib/gnu-sort/lib/xmalloc.c b/contrib/gnu-sort/lib/xmalloc.c
deleted file mode 100644
index 9b7a948..0000000
--- a/contrib/gnu-sort/lib/xmalloc.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/* xmalloc.c -- malloc with out of memory checking
-
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "xalloc.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef SIZE_MAX
-# define SIZE_MAX ((size_t) -1)
-#endif
-
-/* Allocate an array of N objects, each with S bytes of memory,
- dynamically, with error checking. S must be nonzero. */
-
-static inline void *
-xnmalloc_inline (size_t n, size_t s)
-{
- void *p;
- if (xalloc_oversized (n, s) || (! (p = malloc (n * s)) && n != 0))
- xalloc_die ();
- return p;
-}
-
-void *
-xnmalloc (size_t n, size_t s)
-{
- return xnmalloc_inline (n, s);
-}
-
-/* Allocate N bytes of memory dynamically, with error checking. */
-
-void *
-xmalloc (size_t n)
-{
- return xnmalloc_inline (n, 1);
-}
-
-/* Change the size of an allocated block of memory P to an array of N
- objects each of S bytes, with error checking. S must be nonzero. */
-
-static inline void *
-xnrealloc_inline (void *p, size_t n, size_t s)
-{
- if (xalloc_oversized (n, s) || (! (p = realloc (p, n * s)) && n != 0))
- xalloc_die ();
- return p;
-}
-
-void *
-xnrealloc (void *p, size_t n, size_t s)
-{
- return xnrealloc_inline (p, n, s);
-}
-
-/* Change the size of an allocated block of memory P to N bytes,
- with error checking. */
-
-void *
-xrealloc (void *p, size_t n)
-{
- return xnrealloc_inline (p, n, 1);
-}
-
-
-/* If P is null, allocate a block of at least *PN such objects;
- otherwise, reallocate P so that it contains more than *PN objects
- each of S bytes. *PN must be nonzero unless P is null, and S must
- be nonzero. Set *PN to the new number of objects, and return the
- pointer to the new block. *PN is never set to zero, and the
- returned pointer is never null.
-
- Repeated reallocations are guaranteed to make progress, either by
- allocating an initial block with a nonzero size, or by allocating a
- larger block.
-
- In the following implementation, nonzero sizes are doubled so that
- repeated reallocations have O(N log N) overall cost rather than
- O(N**2) cost, but the specification for this function does not
- guarantee that sizes are doubled.
-
- Here is an example of use:
-
- int *p = NULL;
- size_t used = 0;
- size_t allocated = 0;
-
- void
- append_int (int value)
- {
- if (used == allocated)
- p = x2nrealloc (p, &allocated, sizeof *p);
- p[used++] = value;
- }
-
- This causes x2nrealloc to allocate a block of some nonzero size the
- first time it is called.
-
- To have finer-grained control over the initial size, set *PN to a
- nonzero value before calling this function with P == NULL. For
- example:
-
- int *p = NULL;
- size_t used = 0;
- size_t allocated = 0;
- size_t allocated1 = 1000;
-
- void
- append_int (int value)
- {
- if (used == allocated)
- {
- p = x2nrealloc (p, &allocated1, sizeof *p);
- allocated = allocated1;
- }
- p[used++] = value;
- }
-
- */
-
-static inline void *
-x2nrealloc_inline (void *p, size_t *pn, size_t s)
-{
- size_t n = *pn;
-
- if (! p)
- {
- if (! n)
- {
- /* The approximate size to use for initial small allocation
- requests, when the invoking code specifies an old size of
- zero. 64 bytes is the largest "small" request for the
- GNU C library malloc. */
- enum { DEFAULT_MXFAST = 64 };
-
- n = DEFAULT_MXFAST / s;
- n += !n;
- }
- }
- else
- {
- if (SIZE_MAX / 2 / s < n)
- xalloc_die ();
- n *= 2;
- }
-
- *pn = n;
- return xrealloc (p, n * s);
-}
-
-void *
-x2nrealloc (void *p, size_t *pn, size_t s)
-{
- return x2nrealloc_inline (p, pn, s);
-}
-
-/* If P is null, allocate a block of at least *PN bytes; otherwise,
- reallocate P so that it contains more than *PN bytes. *PN must be
- nonzero unless P is null. Set *PN to the new block's size, and
- return the pointer to the new block. *PN is never set to zero, and
- the returned pointer is never null. */
-
-void *
-x2realloc (void *p, size_t *pn)
-{
- return x2nrealloc_inline (p, pn, 1);
-}
-
-/* Allocate S bytes of zeroed memory dynamically, with error checking.
- There's no need for xnzalloc (N, S), since it would be equivalent
- to xcalloc (N, S). */
-
-void *
-xzalloc (size_t s)
-{
- return memset (xmalloc (s), 0, s);
-}
-
-/* Allocate zeroed memory for N elements of S bytes, with error
- checking. S must be nonzero. */
-
-void *
-xcalloc (size_t n, size_t s)
-{
- void *p;
- /* Test for overflow, since some calloc implementations don't have
- proper overflow checks. */
- if (xalloc_oversized (n, s) || (! (p = calloc (n, s)) && n != 0))
- xalloc_die ();
- return p;
-}
-
-/* Clone an object P of size S, with error checking. There's no need
- for xnclone (P, N, S), since xclone (P, N * S) works without any
- need for an arithmetic overflow check. */
-
-void *
-xclone (void const *p, size_t s)
-{
- return memcpy (xmalloc (s), p, s);
-}
diff --git a/contrib/gnu-sort/lib/xmemcoll.c b/contrib/gnu-sort/lib/xmemcoll.c
deleted file mode 100644
index 433d67f..0000000
--- a/contrib/gnu-sort/lib/xmemcoll.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Locale-specific memory comparison.
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Contributed by Paul Eggert <eggert@twinsun.com>. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <errno.h>
-#include <stdlib.h>
-
-#include "gettext.h"
-#define _(msgid) gettext (msgid)
-
-#include "error.h"
-#include "exitfail.h"
-#include "memcoll.h"
-#include "quotearg.h"
-#include "xmemcoll.h"
-
-/* Compare S1 (with length S1LEN) and S2 (with length S2LEN) according
- to the LC_COLLATE locale. S1 and S2 do not overlap, and are not
- adjacent. Temporarily modify the bytes after S1 and S2, but
- restore their original contents before returning. Report an error
- and exit if there is an error. */
-
-int
-xmemcoll (char *s1, size_t s1len, char *s2, size_t s2len)
-{
- int diff = memcoll (s1, s1len, s2, s2len);
- int collation_errno = errno;
-
- if (collation_errno)
- {
- error (0, collation_errno, _("string comparison failed"));
- error (0, 0, _("Set LC_ALL='C' to work around the problem."));
- error (exit_failure, 0,
- _("The strings compared were %s and %s."),
- quotearg_n_style_mem (0, locale_quoting_style, s1, s1len),
- quotearg_n_style_mem (1, locale_quoting_style, s2, s2len));
- }
-
- return diff;
-}
diff --git a/contrib/gnu-sort/lib/xmemcoll.h b/contrib/gnu-sort/lib/xmemcoll.h
deleted file mode 100644
index 2f422e8..0000000
--- a/contrib/gnu-sort/lib/xmemcoll.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include <stddef.h>
-int xmemcoll (char *, size_t, char *, size_t);
diff --git a/contrib/gnu-sort/lib/xstrtol.c b/contrib/gnu-sort/lib/xstrtol.c
deleted file mode 100644
index 906e4a1..0000000
--- a/contrib/gnu-sort/lib/xstrtol.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/* A more useful interface to strtol.
-
- Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2003, 2004 Free
- Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Jim Meyering. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifndef __strtol
-# define __strtol strtol
-# define __strtol_t long int
-# define __xstrtol xstrtol
-# define STRTOL_T_MINIMUM LONG_MIN
-# define STRTOL_T_MAXIMUM LONG_MAX
-#endif
-
-/* Some pre-ANSI implementations (e.g. SunOS 4)
- need stderr defined if assertion checking is enabled. */
-#include <stdio.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* The extra casts work around common compiler bugs. */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
- ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
- : (t) 0))
-#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
-
-#ifndef STRTOL_T_MINIMUM
-# define STRTOL_T_MINIMUM TYPE_MINIMUM (__strtol_t)
-# define STRTOL_T_MAXIMUM TYPE_MAXIMUM (__strtol_t)
-#endif
-
-#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii(c)
-#endif
-
-#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
-
-#include "xstrtol.h"
-
-#if !HAVE_DECL_STRTOIMAX && !defined strtoimax
-intmax_t strtoimax ();
-#endif
-
-#if !HAVE_DECL_STRTOUMAX && !defined strtoumax
-uintmax_t strtoumax ();
-#endif
-
-static strtol_error
-bkm_scale (__strtol_t *x, int scale_factor)
-{
- if (TYPE_SIGNED (__strtol_t) && *x < STRTOL_T_MINIMUM / scale_factor)
- {
- *x = STRTOL_T_MINIMUM;
- return LONGINT_OVERFLOW;
- }
- if (STRTOL_T_MAXIMUM / scale_factor < *x)
- {
- *x = STRTOL_T_MAXIMUM;
- return LONGINT_OVERFLOW;
- }
- *x *= scale_factor;
- return LONGINT_OK;
-}
-
-static strtol_error
-bkm_scale_by_power (__strtol_t *x, int base, int power)
-{
- strtol_error err = LONGINT_OK;
- while (power--)
- err |= bkm_scale (x, base);
- return err;
-}
-
-/* FIXME: comment. */
-
-strtol_error
-__xstrtol (const char *s, char **ptr, int strtol_base,
- __strtol_t *val, const char *valid_suffixes)
-{
- char *t_ptr;
- char **p;
- __strtol_t tmp;
- strtol_error err = LONGINT_OK;
-
- assert (0 <= strtol_base && strtol_base <= 36);
-
- p = (ptr ? ptr : &t_ptr);
-
- if (! TYPE_SIGNED (__strtol_t))
- {
- const char *q = s;
- unsigned char ch = *q;
- while (ISSPACE (ch))
- ch = *++q;
- if (ch == '-')
- return LONGINT_INVALID;
- }
-
- errno = 0;
- tmp = __strtol (s, p, strtol_base);
-
- if (*p == s)
- {
- /* If there is no number but there is a valid suffix, assume the
- number is 1. The string is invalid otherwise. */
- if (valid_suffixes && **p && strchr (valid_suffixes, **p))
- tmp = 1;
- else
- return LONGINT_INVALID;
- }
- else if (errno != 0)
- {
- if (errno != ERANGE)
- return LONGINT_INVALID;
- err = LONGINT_OVERFLOW;
- }
-
- /* Let valid_suffixes == NULL mean `allow any suffix'. */
- /* FIXME: update all callers except the ones that allow suffixes
- after the number, changing last parameter NULL to `""'. */
- if (!valid_suffixes)
- {
- *val = tmp;
- return err;
- }
-
- if (**p != '\0')
- {
- int base = 1024;
- int suffixes = 1;
- strtol_error overflow;
-
- if (!strchr (valid_suffixes, **p))
- {
- *val = tmp;
- return err | LONGINT_INVALID_SUFFIX_CHAR;
- }
-
- if (strchr (valid_suffixes, '0'))
- {
- /* The ``valid suffix'' '0' is a special flag meaning that
- an optional second suffix is allowed, which can change
- the base. A suffix "B" (e.g. "100MB") stands for a power
- of 1000, whereas a suffix "iB" (e.g. "100MiB") stands for
- a power of 1024. If no suffix (e.g. "100M"), assume
- power-of-1024. */
-
- switch (p[0][1])
- {
- case 'i':
- if (p[0][2] == 'B')
- suffixes += 2;
- break;
-
- case 'B':
- case 'D': /* 'D' is obsolescent */
- base = 1000;
- suffixes++;
- break;
- }
- }
-
- switch (**p)
- {
- case 'b':
- overflow = bkm_scale (&tmp, 512);
- break;
-
- case 'B':
- overflow = bkm_scale (&tmp, 1024);
- break;
-
- case 'c':
- overflow = 0;
- break;
-
- case 'E': /* exa or exbi */
- overflow = bkm_scale_by_power (&tmp, base, 6);
- break;
-
- case 'G': /* giga or gibi */
- case 'g': /* 'g' is undocumented; for compatibility only */
- overflow = bkm_scale_by_power (&tmp, base, 3);
- break;
-
- case 'k': /* kilo */
- case 'K': /* kibi */
- overflow = bkm_scale_by_power (&tmp, base, 1);
- break;
-
- case 'M': /* mega or mebi */
- case 'm': /* 'm' is undocumented; for compatibility only */
- overflow = bkm_scale_by_power (&tmp, base, 2);
- break;
-
- case 'P': /* peta or pebi */
- overflow = bkm_scale_by_power (&tmp, base, 5);
- break;
-
- case 'T': /* tera or tebi */
- case 't': /* 't' is undocumented; for compatibility only */
- overflow = bkm_scale_by_power (&tmp, base, 4);
- break;
-
- case 'w':
- overflow = bkm_scale (&tmp, 2);
- break;
-
- case 'Y': /* yotta or 2**80 */
- overflow = bkm_scale_by_power (&tmp, base, 8);
- break;
-
- case 'Z': /* zetta or 2**70 */
- overflow = bkm_scale_by_power (&tmp, base, 7);
- break;
-
- default:
- *val = tmp;
- return err | LONGINT_INVALID_SUFFIX_CHAR;
- }
-
- err |= overflow;
- *p += suffixes;
- if (**p)
- err |= LONGINT_INVALID_SUFFIX_CHAR;
- }
-
- *val = tmp;
- return err;
-}
-
-#ifdef TESTING_XSTRTO
-
-# include <stdio.h>
-# include "error.h"
-
-char *program_name;
-
-int
-main (int argc, char **argv)
-{
- strtol_error s_err;
- int i;
-
- program_name = argv[0];
- for (i=1; i<argc; i++)
- {
- char *p;
- __strtol_t val;
-
- s_err = __xstrtol (argv[i], &p, 0, &val, "bckmw");
- if (s_err == LONGINT_OK)
- {
- printf ("%s->%lu (%s)\n", argv[i], val, p);
- }
- else
- {
- STRTOL_FATAL_ERROR (argv[i], "arg", s_err);
- }
- }
- exit (0);
-}
-
-#endif /* TESTING_XSTRTO */
diff --git a/contrib/gnu-sort/lib/xstrtol.h b/contrib/gnu-sort/lib/xstrtol.h
deleted file mode 100644
index 0d6b984..0000000
--- a/contrib/gnu-sort/lib/xstrtol.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* A more useful interface to strtol.
-
- Copyright (C) 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004 Free
- Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef XSTRTOL_H_
-# define XSTRTOL_H_ 1
-
-# include "exitfail.h"
-
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# endif
-# if HAVE_STDINT_H
-# include <stdint.h>
-# endif
-
-# ifndef _STRTOL_ERROR
-enum strtol_error
- {
- LONGINT_OK = 0,
-
- /* These two values can be ORed together, to indicate that both
- errors occurred. */
- LONGINT_OVERFLOW = 1,
- LONGINT_INVALID_SUFFIX_CHAR = 2,
-
- LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR
- | LONGINT_OVERFLOW),
- LONGINT_INVALID = 4
- };
-typedef enum strtol_error strtol_error;
-# endif
-
-# define _DECLARE_XSTRTOL(name, type) \
- strtol_error name (const char *, char **, int, type *, const char *);
-_DECLARE_XSTRTOL (xstrtol, long int)
-_DECLARE_XSTRTOL (xstrtoul, unsigned long int)
-_DECLARE_XSTRTOL (xstrtoimax, intmax_t)
-_DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
-
-# define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \
- do \
- { \
- switch ((Err)) \
- { \
- default: \
- abort (); \
- \
- case LONGINT_INVALID: \
- error ((Exit_code), 0, "invalid %s `%s'", \
- (Argument_type_string), (Str)); \
- break; \
- \
- case LONGINT_INVALID_SUFFIX_CHAR: \
- case LONGINT_INVALID_SUFFIX_CHAR | LONGINT_OVERFLOW: \
- error ((Exit_code), 0, "invalid character following %s in `%s'", \
- (Argument_type_string), (Str)); \
- break; \
- \
- case LONGINT_OVERFLOW: \
- error ((Exit_code), 0, "%s `%s' too large", \
- (Argument_type_string), (Str)); \
- break; \
- } \
- } \
- while (0)
-
-# define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \
- _STRTOL_ERROR (exit_failure, Str, Argument_type_string, Err)
-
-# define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \
- _STRTOL_ERROR (0, Str, Argument_type_string, Err)
-
-#endif /* not XSTRTOL_H_ */
diff --git a/contrib/gnu-sort/lib/xstrtoul.c b/contrib/gnu-sort/lib/xstrtoul.c
deleted file mode 100644
index 285f7b9..0000000
--- a/contrib/gnu-sort/lib/xstrtoul.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#define __strtol strtoul
-#define __strtol_t unsigned long int
-#define __xstrtol xstrtoul
-#define STRTOL_T_MINIMUM 0
-#define STRTOL_T_MAXIMUM ULONG_MAX
-#include "xstrtol.c"
diff --git a/contrib/gnu-sort/lib/xstrtoumax.c b/contrib/gnu-sort/lib/xstrtoumax.c
deleted file mode 100644
index 8518ef0..0000000
--- a/contrib/gnu-sort/lib/xstrtoumax.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* xstrtoumax.c -- A more useful interface to strtoumax.
- Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/* Written by Paul Eggert. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include "xstrtol.h"
-
-#define __strtol strtoumax
-#define __strtol_t uintmax_t
-#define __xstrtol xstrtoumax
-#ifdef UINTMAX_MAX
-# define STRTOL_T_MINIMUM 0
-# define STRTOL_T_MAXIMUM UINTMAX_MAX
-#endif
-#include "xstrtol.c"
diff --git a/contrib/gnu-sort/man/sort.1 b/contrib/gnu-sort/man/sort.1
deleted file mode 100644
index 2bb445d..0000000
--- a/contrib/gnu-sort/man/sort.1
+++ /dev/null
@@ -1,113 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33.
-.TH SORT "1" "March 2004" "sort (coreutils) 5.2.1" "User Commands"
-.SH NAME
-sort \- sort lines of text files
-.SH SYNOPSIS
-.B sort
-[\fIOPTION\fR]... [\fIFILE\fR]...
-.SH DESCRIPTION
-.\" Add any additional description here
-.PP
-Write sorted concatenation of all FILE(s) to standard output.
-.PP
-Ordering options:
-.PP
-Mandatory arguments to long options are mandatory for short options too.
-.HP
-\fB\-b\fR, \fB\-\-ignore\-leading\-blanks\fR ignore leading blanks
-.TP
-\fB\-d\fR, \fB\-\-dictionary\-order\fR
-consider only blanks and alphanumeric characters
-.TP
-\fB\-f\fR, \fB\-\-ignore\-case\fR
-fold lower case to upper case characters
-.TP
-\fB\-g\fR, \fB\-\-general\-numeric\-sort\fR
-compare according to general numerical value
-.TP
-\fB\-i\fR, \fB\-\-ignore\-nonprinting\fR
-consider only printable characters
-.TP
-\fB\-M\fR, \fB\-\-month\-sort\fR
-compare (unknown) < `JAN' < ... < `DEC'
-.TP
-\fB\-n\fR, \fB\-\-numeric\-sort\fR
-compare according to string numerical value
-.TP
-\fB\-r\fR, \fB\-\-reverse\fR
-reverse the result of comparisons
-.PP
-Other options:
-.TP
-\fB\-c\fR, \fB\-\-check\fR
-check whether input is sorted; do not sort
-.TP
-\fB\-k\fR, \fB\-\-key\fR=\fIPOS1[\fR,POS2]
-start a key at POS1, end it at POS 2 (origin 1)
-.TP
-\fB\-m\fR, \fB\-\-merge\fR
-merge already sorted files; do not sort
-.TP
-\fB\-o\fR, \fB\-\-output\fR=\fIFILE\fR
-write result to FILE instead of standard output
-.TP
-\fB\-s\fR, \fB\-\-stable\fR
-stabilize sort by disabling last-resort comparison
-.TP
-\fB\-S\fR, \fB\-\-buffer\-size\fR=\fISIZE\fR
-use SIZE for main memory buffer
-.HP
-\fB\-t\fR, \fB\-\-field\-separator\fR=\fISEP\fR use SEP instead of non-blank to blank transition
-.TP
-\fB\-T\fR, \fB\-\-temporary\-directory\fR=\fIDIR\fR
-use DIR for temporaries, not $TMPDIR or /tmp;
-multiple options specify multiple directories
-.TP
-\fB\-u\fR, \fB\-\-unique\fR
-with \fB\-c\fR, check for strict ordering;
-without \fB\-c\fR, output only the first of an equal run
-.TP
-\fB\-z\fR, \fB\-\-zero\-terminated\fR
-end lines with 0 byte, not newline
-.TP
-\fB\-\-help\fR
-display this help and exit
-.TP
-\fB\-\-version\fR
-output version information and exit
-.PP
-POS is F[.C][OPTS], where F is the field number and C the character position
-in the field. OPTS is one or more single-letter ordering options, which
-override global ordering options for that key. If no key is given, use the
-entire line as the key.
-.PP
-SIZE may be followed by the following multiplicative suffixes:
-% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.
-.PP
-With no FILE, or when FILE is -, read standard input.
-.PP
-*** WARNING ***
-The locale specified by the environment affects sort order.
-Set LC_ALL=C to get the traditional sort order that uses
-native byte values.
-.SH AUTHOR
-Written by Mike Haertel and Paul Eggert.
-.SH "REPORTING BUGS"
-Report bugs to <bug-coreutils@gnu.org>.
-.SH COPYRIGHT
-Copyright \(co 2004 Free Software Foundation, Inc.
-.br
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-.SH "SEE ALSO"
-The full documentation for
-.B sort
-is maintained as a Texinfo manual. If the
-.B info
-and
-.B sort
-programs are properly installed at your site, the command
-.IP
-.B info coreutils sort
-.PP
-should give you access to the complete manual.
diff --git a/contrib/gnu-sort/src/sort.c b/contrib/gnu-sort/src/sort.c
deleted file mode 100644
index 0b9d33f..0000000
--- a/contrib/gnu-sort/src/sort.c
+++ /dev/null
@@ -1,3237 +0,0 @@
-/* $FreeBSD$ */
-/* sort - sort lines of text (with all kinds of options).
- Copyright (C) 88, 1991-2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- Written December 1988 by Mike Haertel.
- The author may be reached (Email) at the address mike@gnu.ai.mit.edu,
- or (US mail) as Mike Haertel c/o Free Software Foundation.
-
- Ørn E. Hansen added NLS support in 1997. */
-
-#include <config.h>
-
-#include <assert.h>
-#include <getopt.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <stdio.h>
-
-/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
-/* Get mbstate_t, mbrtowc(), wcwidth(). */
-#if HAVE_WCHAR_H
-# include <wchar.h>
-#endif
-
-/* Get isw* functions. */
-#if HAVE_WCTYPE_H
-# include <wctype.h>
-#endif
-
-/* Get nl_langinfo(). */
-#if HAVE_LANGINFO_CODESET
-# include <langinfo.h>
-#endif
-
-/* Include this after wctype.h so that we `#undef' ISPRINT
- (from Solaris's euc.h, from widec.h, from wctype.h) before
- redefining and using it. */
-#include "system.h"
-#include "error.h"
-#include "hard-locale.h"
-#include "inttostr.h"
-#include "long-options.h"
-#include "physmem.h"
-#include "posixver.h"
-#include "quote.h"
-#include "stdio-safer.h"
-#include "xmemcoll.h"
-#include "xstrtol.h"
-
-#if HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
-#ifndef RLIMIT_DATA
-struct rlimit { size_t rlim_cur; };
-# define getrlimit(Resource, Rlp) (-1)
-#endif
-
-/* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC
- installation; work around this configuration error. */
-#if !defined MB_LEN_MAX || MB_LEN_MAX == 1
-# define MB_LEN_MAX 16
-#endif
-
-/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
-#if HAVE_MBRTOWC && defined mbstate_t
-# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
-#endif
-
-/* The official name of this program (e.g., no `g' prefix). */
-#define PROGRAM_NAME "sort"
-
-#define AUTHORS "Mike Haertel", "Paul Eggert"
-
-#if HAVE_LANGINFO_CODESET
-# include <langinfo.h>
-#endif
-
-#ifndef SA_NOCLDSTOP
-# define sigprocmask(How, Set, Oset) /* empty */
-# define sigset_t int
-#endif
-
-#ifndef STDC_HEADERS
-double strtod ();
-#endif
-
-#define UCHAR_LIM (UCHAR_MAX + 1)
-
-#ifndef DEFAULT_TMPDIR
-# define DEFAULT_TMPDIR "/tmp"
-#endif
-
-/* Exit statuses. */
-enum
- {
- /* POSIX says to exit with status 1 if invoked with -c and the
- input is not properly sorted. */
- SORT_OUT_OF_ORDER = 1,
-
- /* POSIX says any other irregular exit must exit with a status
- code greater than 1. */
- SORT_FAILURE = 2
- };
-
-#define C_DECIMAL_POINT '.'
-#define NEGATION_SIGN '-'
-#define NUMERIC_ZERO '0'
-
-#if HAVE_SETLOCALE
-
-static char decimal_point;
-static int th_sep; /* if CHAR_MAX + 1, then there is no thousands separator */
-static int force_general_numcompare = 0;
-
-/* Nonzero if the corresponding locales are hard. */
-static bool hard_LC_COLLATE;
-# if HAVE_NL_LANGINFO
-static bool hard_LC_TIME;
-# endif
-
-# define IS_THOUSANDS_SEP(x) ((x) == th_sep)
-
-#else
-
-# define decimal_point C_DECIMAL_POINT
-# define IS_THOUSANDS_SEP(x) false
-
-#endif
-
-#define NONZERO(x) (x != 0)
-
-/* get a multibyte character's byte length. */
-#define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \
- do \
- { \
- wchar_t wc; \
- mbstate_t state_bak; \
- \
- state_bak = STATE; \
- mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \
- \
- switch (MBLENGTH) \
- { \
- case (size_t)-1: \
- case (size_t)-2: \
- STATE = state_bak; \
- /* Fall through. */ \
- case 0: \
- MBLENGTH = 1; \
- } \
- } \
- while (0)
-
-/* The kind of blanks for '-b' to skip in various options. */
-enum blanktype { bl_start, bl_end, bl_both };
-
-/* The character marking end of line. Default to \n. */
-static char eolchar = '\n';
-
-/* Lines are held in core as counted strings. */
-struct line
-{
- char *text; /* Text of the line. */
- size_t length; /* Length including final newline. */
- char *keybeg; /* Start of first key. */
- char *keylim; /* Limit of first key. */
-};
-
-/* Input buffers. */
-struct buffer
-{
- char *buf; /* Dynamically allocated buffer,
- partitioned into 3 regions:
- - input data;
- - unused area;
- - an array of lines, in reverse order. */
- size_t used; /* Number of bytes used for input data. */
- size_t nlines; /* Number of lines in the line array. */
- size_t alloc; /* Number of bytes allocated. */
- size_t left; /* Number of bytes left from previous reads. */
- size_t line_bytes; /* Number of bytes to reserve for each line. */
- bool eof; /* An EOF has been read. */
-};
-
-struct keyfield
-{
- size_t sword; /* Zero-origin 'word' to start at. */
- size_t schar; /* Additional characters to skip. */
- size_t eword; /* Zero-origin first word after field. */
- size_t echar; /* Additional characters in field. */
- bool const *ignore; /* Boolean array of characters to ignore. */
- char const *translate; /* Translation applied to characters. */
- bool skipsblanks; /* Skip leading blanks when finding start. */
- bool skipeblanks; /* Skip leading blanks when finding end. */
- bool numeric; /* Flag for numeric comparison. Handle
- strings of digits with optional decimal
- point, but no exponential notation. */
- bool general_numeric; /* Flag for general, numeric comparison.
- Handle numbers in exponential notation. */
- bool month; /* Flag for comparison by month name. */
- bool reverse; /* Reverse the sense of comparison. */
- struct keyfield *next; /* Next keyfield to try. */
-};
-
-struct month
-{
- char const *name;
- int val;
-};
-
-/* The name this program was run with. */
-char *program_name;
-
-/* FIXME: None of these tables work with multibyte character sets.
- Also, there are many other bugs when handling multibyte characters.
- One way to fix this is to rewrite `sort' to use wide characters
- internally, but doing this with good performance is a bit
- tricky. */
-
-/* Table of blanks. */
-static bool blanks[UCHAR_LIM];
-
-/* Table of non-printing characters. */
-static bool nonprinting[UCHAR_LIM];
-
-/* Table of non-dictionary characters (not letters, digits, or blanks). */
-static bool nondictionary[UCHAR_LIM];
-
-/* Translation table folding lower case to upper. */
-static char fold_toupper[UCHAR_LIM];
-
-#define MONTHS_PER_YEAR 12
-
-/* Table mapping month names to integers.
- Alphabetic order allows binary search. */
-static struct month monthtab[] =
-{
- {"APR", 4},
- {"AUG", 8},
- {"DEC", 12},
- {"FEB", 2},
- {"JAN", 1},
- {"JUL", 7},
- {"JUN", 6},
- {"MAR", 3},
- {"MAY", 5},
- {"NOV", 11},
- {"OCT", 10},
- {"SEP", 9}
-};
-
-/* During the merge phase, the number of files to merge at once. */
-#define NMERGE 16
-
-/* Minimum size for a merge or check buffer. */
-#define MIN_MERGE_BUFFER_SIZE (2 + sizeof (struct line))
-
-/* Minimum sort size; the code might not work with smaller sizes. */
-#define MIN_SORT_SIZE (NMERGE * MIN_MERGE_BUFFER_SIZE)
-
-/* The number of bytes needed for a merge or check buffer, which can
- function relatively efficiently even if it holds only one line. If
- a longer line is seen, this value is increased. */
-static size_t merge_buffer_size = MAX (MIN_MERGE_BUFFER_SIZE, 256 * 1024);
-
-/* The approximate maximum number of bytes of main memory to use, as
- specified by the user. Zero if the user has not specified a size. */
-static size_t sort_size;
-
-/* The guessed size for non-regular files. */
-#define INPUT_FILE_SIZE_GUESS (1024 * 1024)
-
-/* Array of directory names in which any temporary files are to be created. */
-static char const **temp_dirs;
-
-/* Number of temporary directory names used. */
-static size_t temp_dir_count;
-
-/* Number of allocated slots in temp_dirs. */
-static size_t temp_dir_alloc;
-
-/* Flag to reverse the order of all comparisons. */
-static bool reverse;
-
-/* Flag for stable sort. This turns off the last ditch bytewise
- comparison of lines, and instead leaves lines in the same order
- they were read if all keys compare equal. */
-static bool stable;
-
-/* Tab character separating fields. If tab_default, then fields are
- separated by the empty string between a non-blank character and a blank
- character. */
-static bool tab_default = true;
-static unsigned char tab[MB_LEN_MAX + 1];
-static size_t tab_length = 1;
-
-/* Flag to remove consecutive duplicate lines from the output.
- Only the last of a sequence of equal lines will be output. */
-static bool unique;
-
-/* Nonzero if any of the input files are the standard input. */
-static bool have_read_stdin;
-
-/* List of key field comparisons to be tried. */
-static struct keyfield *keylist;
-
-static void sortlines_temp (struct line *, size_t, struct line *);
-
-void
-usage (int status)
-{
- if (status != EXIT_SUCCESS)
- fprintf (stderr, _("Try `%s --help' for more information.\n"),
- program_name);
- else
- {
- printf (_("\
-Usage: %s [OPTION]... [FILE]...\n\
-"),
- program_name);
- fputs (_("\
-Write sorted concatenation of all FILE(s) to standard output.\n\
-\n\
-Ordering options:\n\
-\n\
-"), stdout);
- fputs (_("\
-Mandatory arguments to long options are mandatory for short options too.\n\
-"), stdout);
- fputs (_("\
- -b, --ignore-leading-blanks ignore leading blanks\n\
- -d, --dictionary-order consider only blanks and alphanumeric characters\n\
- -f, --ignore-case fold lower case to upper case characters\n\
-"), stdout);
- fputs (_("\
- -g, --general-numeric-sort compare according to general numerical value\n\
- -i, --ignore-nonprinting consider only printable characters\n\
- -M, --month-sort compare (unknown) < `JAN' < ... < `DEC'\n\
- -n, --numeric-sort compare according to string numerical value\n\
- -r, --reverse reverse the result of comparisons\n\
-\n\
-"), stdout);
- fputs (_("\
-Other options:\n\
-\n\
- -c, --check check whether input is sorted; do not sort\n\
- -k, --key=POS1[,POS2] start a key at POS1, end it at POS 2 (origin 1)\n\
- -m, --merge merge already sorted files; do not sort\n\
- -o, --output=FILE write result to FILE instead of standard output\n\
- -s, --stable stabilize sort by disabling last-resort comparison\n\
- -S, --buffer-size=SIZE use SIZE for main memory buffer\n\
-"), stdout);
- printf (_("\
- -t, --field-separator=SEP use SEP instead of non-blank to blank transition\n\
- -T, --temporary-directory=DIR use DIR for temporaries, not $TMPDIR or %s;\n\
- multiple options specify multiple directories\n\
- -u, --unique with -c, check for strict ordering;\n\
- without -c, output only the first of an equal run\n\
-"), DEFAULT_TMPDIR);
- fputs (_("\
- -z, --zero-terminated end lines with 0 byte, not newline\n\
-"), stdout);
- fputs (HELP_OPTION_DESCRIPTION, stdout);
- fputs (VERSION_OPTION_DESCRIPTION, stdout);
- fputs (_("\
-\n\
-POS is F[.C][OPTS], where F is the field number and C the character position\n\
-in the field. OPTS is one or more single-letter ordering options, which\n\
-override global ordering options for that key. If no key is given, use the\n\
-entire line as the key.\n\
-\n\
-SIZE may be followed by the following multiplicative suffixes:\n\
-"), stdout);
- fputs (_("\
-% 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y.\n\
-\n\
-With no FILE, or when FILE is -, read standard input.\n\
-\n\
-*** WARNING ***\n\
-The locale specified by the environment affects sort order.\n\
-Set LC_ALL=C to get the traditional sort order that uses\n\
-native byte values.\n\
-"), stdout );
- printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
- }
-
- exit (status);
-}
-
-#define COMMON_SHORT_OPTIONS "-bcdfgik:mMno:rsS:t:T:uz"
-
-static struct option const long_options[] =
-{
- {"ignore-leading-blanks", no_argument, NULL, 'b'},
- {"check", no_argument, NULL, 'c'},
- {"dictionary-order", no_argument, NULL, 'd'},
- {"ignore-case", no_argument, NULL, 'f'},
- {"general-numeric-sort", no_argument, NULL, 'g'},
- {"ignore-nonprinting", no_argument, NULL, 'i'},
- {"key", required_argument, NULL, 'k'},
- {"merge", no_argument, NULL, 'm'},
- {"month-sort", no_argument, NULL, 'M'},
- {"numeric-sort", no_argument, NULL, 'n'},
- {"output", required_argument, NULL, 'o'},
- {"reverse", no_argument, NULL, 'r'},
- {"stable", no_argument, NULL, 's'},
- {"buffer-size", required_argument, NULL, 'S'},
- {"field-separator", required_argument, NULL, 't'},
- {"temporary-directory", required_argument, NULL, 'T'},
- {"unique", no_argument, NULL, 'u'},
- {"zero-terminated", no_argument, NULL, 'z'},
- {GETOPT_HELP_OPTION_DECL},
- {GETOPT_VERSION_OPTION_DECL},
- {0, 0, 0, 0},
-};
-
-/* The set of signals that are caught. */
-static sigset_t caught_signals;
-
-/* The list of temporary files. */
-struct tempnode
-{
- struct tempnode *volatile next;
- char name[1]; /* Actual size is 1 + file name length. */
-};
-static struct tempnode *volatile temphead;
-
-/* Fucntion pointers. */
-static void
-(*inittables) (void);
-
-static char *
-(* begfield) (const struct line *line, const struct keyfield *key);
-
-static char *
-(* limfield) (const struct line *line, const struct keyfield *key);
-
-static int
-(*getmonth) (const char *s, size_t len);
-
-static int
-(* keycompare) (const struct line *a, const struct line *b);
-
-/* Test for white space multibyte character.
- Set LENGTH the byte length of investigated multibyte character. */
-#if HAVE_MBRTOWC
-static int
-ismbblank (const char *str, size_t len, size_t *length)
-{
- size_t mblength;
- wchar_t wc;
- mbstate_t state;
-
- memset (&state, '\0', sizeof(mbstate_t));
- mblength = mbrtowc (&wc, str, len, &state);
-
- if (mblength == (size_t)-1 || mblength == (size_t)-2)
- {
- *length = 1;
- return 0;
- }
-
- *length = (mblength < 1) ? 1 : mblength;
- return iswblank (wc);
-}
-#endif
-
-/* Clean up any remaining temporary files. */
-
-static void
-cleanup (void)
-{
- struct tempnode const *node;
-
- for (node = temphead; node; node = node->next)
- unlink (node->name);
-}
-
-/* Report MESSAGE for FILE, then clean up and exit.
- If FILE is null, it represents standard output. */
-
-static void die (char const *, char const *) ATTRIBUTE_NORETURN;
-static void
-die (char const *message, char const *file)
-{
- error (0, errno, "%s: %s", message, file ? file : _("standard output"));
- exit (SORT_FAILURE);
-}
-
-/* Create a new temporary file, returning its newly allocated name.
- Store into *PFP a stream open for writing. */
-
-static char *
-create_temp_file (FILE **pfp)
-{
- static char const slashbase[] = "/sortXXXXXX";
- static size_t temp_dir_index;
- sigset_t oldset;
- int fd;
- int saved_errno;
- char const *temp_dir = temp_dirs[temp_dir_index];
- size_t len = strlen (temp_dir);
- struct tempnode *node =
- xmalloc (sizeof node->next + len + sizeof slashbase);
- char *file = node->name;
-
- memcpy (file, temp_dir, len);
- memcpy (file + len, slashbase, sizeof slashbase);
- node->next = temphead;
- if (++temp_dir_index == temp_dir_count)
- temp_dir_index = 0;
-
- /* Create the temporary file in a critical section, to avoid races. */
- sigprocmask (SIG_BLOCK, &caught_signals, &oldset);
- fd = mkstemp (file);
- if (0 <= fd)
- temphead = node;
- saved_errno = errno;
- sigprocmask (SIG_SETMASK, &oldset, NULL);
- errno = saved_errno;
-
- if (fd < 0 || (*pfp = fdopen (fd, "w")) == NULL)
- die (_("cannot create temporary file"), file);
-
- return file;
-}
-
-/* Return a stream for FILE, opened with mode HOW. A null FILE means
- standard output; HOW should be "w". When opening for input, "-"
- means standard input. To avoid confusion, do not return file
- descriptors 0, 1, or 2. */
-
-static FILE *
-xfopen (const char *file, const char *how)
-{
- FILE *fp;
-
- if (!file)
- fp = stdout;
- else if (STREQ (file, "-") && *how == 'r')
- {
- have_read_stdin = true;
- fp = stdin;
- }
- else
- {
- if ((fp = fopen_safer (file, how)) == NULL)
- die (_("open failed"), file);
- }
-
- return fp;
-}
-
-/* Close FP, whose name is FILE, and report any errors. */
-
-static void
-xfclose (FILE *fp, char const *file)
-{
- if (fp == stdin)
- {
- /* Allow reading stdin from tty more than once. */
- if (feof (fp))
- clearerr (fp);
- }
- else
- {
- if (fclose (fp) != 0)
- die (_("close failed"), file);
- }
-}
-
-static void
-write_bytes (const char *buf, size_t n_bytes, FILE *fp, const char *output_file)
-{
- if (fwrite (buf, 1, n_bytes, fp) != n_bytes)
- die (_("write failed"), output_file);
-}
-
-/* Append DIR to the array of temporary directory names. */
-static void
-add_temp_dir (char const *dir)
-{
- if (temp_dir_count == temp_dir_alloc)
- temp_dirs = x2nrealloc (temp_dirs, &temp_dir_alloc, sizeof *temp_dirs);
-
- temp_dirs[temp_dir_count++] = dir;
-}
-
-/* Search through the list of temporary files for NAME;
- remove it if it is found on the list. */
-
-static void
-zaptemp (const char *name)
-{
- struct tempnode *volatile *pnode;
- struct tempnode *node;
-
- for (pnode = &temphead; (node = *pnode); pnode = &node->next)
- if (node->name == name)
- {
- unlink (name);
- *pnode = node->next;
- free (node);
- break;
- }
-}
-
-#if HAVE_LANGINFO_CODESET
-
-static int
-struct_month_cmp (const void *m1, const void *m2)
-{
- struct month const *month1 = m1;
- struct month const *month2 = m2;
- return strcmp (month1->name, month2->name);
-}
-
-#endif
-
-/* Initialize the character class tables. */
-
-static void
-inittables_uni (void)
-{
- int i;
-
- for (i = 0; i < UCHAR_LIM; ++i)
- {
- blanks[i] = !!ISBLANK (i);
- nonprinting[i] = !ISPRINT (i);
- nondictionary[i] = !ISALNUM (i) && !ISBLANK (i);
- fold_toupper[i] = (ISLOWER (i) ? toupper (i) : i);
- }
-
-#if HAVE_NL_LANGINFO
- /* If we're not in the "C" locale, read different names for months. */
- if (hard_LC_TIME)
- {
- for (i = 0; i < MONTHS_PER_YEAR; i++)
- {
- char const *s;
- size_t s_len;
- size_t j;
- char *name;
-
- s = (char *) nl_langinfo (ABMON_1 + i);
- s_len = strlen (s);
- monthtab[i].name = name = xmalloc (s_len + 1);
- monthtab[i].val = i + 1;
-
- for (j = 0; j < s_len; j++)
- name[j] = fold_toupper[to_uchar (s[j])];
- name[j] = '\0';
- }
- qsort ((void *) monthtab, MONTHS_PER_YEAR,
- sizeof *monthtab, struct_month_cmp);
- }
-#endif
-}
-
-#if HAVE_MBRTOWC
-static void
-inittables_mb (void)
-{
- int i, j, k, l;
- char *name, *s;
- size_t s_len, mblength;
- char mbc[MB_LEN_MAX];
- wchar_t wc, pwc;
- mbstate_t state_mb, state_wc;
-
- for (i = 0; i < MONTHS_PER_YEAR; i++)
- {
- s = (char *) nl_langinfo (ABMON_1 + i);
- s_len = strlen (s);
- monthtab[i].name = name = (char *) xmalloc (s_len + 1);
- monthtab[i].val = i + 1;
-
- memset (&state_mb, '\0', sizeof (mbstate_t));
- memset (&state_wc, '\0', sizeof (mbstate_t));
-
- for (j = 0; j < s_len;)
- {
- if (!ismbblank (s + j, s_len - j, &mblength))
- break;
- j += mblength;
- }
-
- for (k = 0; j < s_len;)
- {
- mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb);
- assert (mblength != (size_t)-1 && mblength != (size_t)-2);
- if (mblength == 0)
- break;
-
- pwc = towupper (wc);
- if (pwc == wc)
- {
- memcpy (mbc, s + j, mblength);
- j += mblength;
- }
- else
- {
- j += mblength;
- mblength = wcrtomb (mbc, pwc, &state_wc);
- assert (mblength != (size_t)0 && mblength != (size_t)-1);
- }
-
- for (l = 0; l < mblength; l++)
- name[k++] = mbc[l];
- }
- name[k] = '\0';
- }
- qsort ((void *) monthtab, MONTHS_PER_YEAR,
- sizeof (struct month), struct_month_cmp);
-}
-#endif
-
-/* Specify the amount of main memory to use when sorting. */
-static void
-specify_sort_size (char const *s)
-{
- uintmax_t n;
- char *suffix;
- enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPtTYZ");
-
- /* The default unit is KiB. */
- if (e == LONGINT_OK && ISDIGIT (suffix[-1]))
- {
- if (n <= UINTMAX_MAX / 1024)
- n *= 1024;
- else
- e = LONGINT_OVERFLOW;
- }
-
- /* A 'b' suffix means bytes; a '%' suffix means percent of memory. */
- if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1])
- switch (suffix[0])
- {
- case 'b':
- e = LONGINT_OK;
- break;
-
- case '%':
- {
- double mem = physmem_total () * n / 100;
-
- /* Use "<", not "<=", to avoid problems with rounding. */
- if (mem < UINTMAX_MAX)
- {
- n = mem;
- e = LONGINT_OK;
- }
- else
- e = LONGINT_OVERFLOW;
- }
- break;
- }
-
- if (e == LONGINT_OK)
- {
- /* If multiple sort sizes are specified, take the maximum, so
- that option order does not matter. */
- if (n < sort_size)
- return;
-
- sort_size = n;
- if (sort_size == n)
- {
- sort_size = MAX (sort_size, MIN_SORT_SIZE);
- return;
- }
-
- e = LONGINT_OVERFLOW;
- }
-
- STRTOL_FATAL_ERROR (s, _("sort size"), e);
-}
-
-/* Return the default sort size. */
-static size_t
-default_sort_size (void)
-{
- /* Let MEM be available memory or 1/8 of total memory, whichever
- is greater. */
- double avail = physmem_available ();
- double total = physmem_total ();
- double mem = MAX (avail, total / 8);
- struct rlimit rlimit;
-
- /* Let SIZE be MEM, but no more than the maximum object size or
- system resource limits. Avoid the MIN macro here, as it is not
- quite right when only one argument is floating point. Don't
- bother to check for values like RLIM_INFINITY since in practice
- they are not much less than SIZE_MAX. */
- size_t size = SIZE_MAX;
- if (mem < size)
- size = mem;
- if (getrlimit (RLIMIT_DATA, &rlimit) == 0 && rlimit.rlim_cur < size)
- size = rlimit.rlim_cur;
-#ifdef RLIMIT_AS
- if (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur < size)
- size = rlimit.rlim_cur;
-#endif
-
- /* Leave a large safety margin for the above limits, as failure can
- occur when they are exceeded. */
- size /= 2;
-
-#ifdef RLIMIT_RSS
- /* Leave a 1/16 margin for RSS to leave room for code, stack, etc.
- Exceeding RSS is not fatal, but can be quite slow. */
- if (getrlimit (RLIMIT_RSS, &rlimit) == 0 && rlimit.rlim_cur / 16 * 15 < size)
- size = rlimit.rlim_cur / 16 * 15;
-#endif
-
- /* Use no less than the minimum. */
- return MAX (size, MIN_SORT_SIZE);
-}
-
-/* Return the sort buffer size to use with the input files identified
- by FPS and FILES, which are alternate paths to the same files.
- NFILES gives the number of input files; NFPS may be less. Assume
- that each input line requires LINE_BYTES extra bytes' worth of line
- information. Do not exceed a bound on the size: if the bound is
- not specified by the user, use a default. */
-
-static size_t
-sort_buffer_size (FILE *const *fps, int nfps,
- char *const *files, int nfiles,
- size_t line_bytes)
-{
- /* A bound on the input size. If zero, the bound hasn't been
- determined yet. */
- static size_t size_bound;
-
- /* In the worst case, each input byte is a newline. */
- size_t worst_case_per_input_byte = line_bytes + 1;
-
- /* Keep enough room for one extra input line and an extra byte.
- This extra room might be needed when preparing to read EOF. */
- size_t size = worst_case_per_input_byte + 1;
-
- int i;
-
- for (i = 0; i < nfiles; i++)
- {
- struct stat st;
- off_t file_size;
- size_t worst_case;
-
- if ((i < nfps ? fstat (fileno (fps[i]), &st)
- : STREQ (files[i], "-") ? fstat (STDIN_FILENO, &st)
- : stat (files[i], &st))
- != 0)
- die (_("stat failed"), files[i]);
-
- if (S_ISREG (st.st_mode))
- file_size = st.st_size;
- else
- {
- /* The file has unknown size. If the user specified a sort
- buffer size, use that; otherwise, guess the size. */
- if (sort_size)
- return sort_size;
- file_size = INPUT_FILE_SIZE_GUESS;
- }
-
- if (! size_bound)
- {
- size_bound = sort_size;
- if (! size_bound)
- size_bound = default_sort_size ();
- }
-
- /* Add the amount of memory needed to represent the worst case
- where the input consists entirely of newlines followed by a
- single non-newline. Check for overflow. */
- worst_case = file_size * worst_case_per_input_byte + 1;
- if (file_size != worst_case / worst_case_per_input_byte
- || size_bound - size <= worst_case)
- return size_bound;
- size += worst_case;
- }
-
- return size;
-}
-
-/* Initialize BUF. Reserve LINE_BYTES bytes for each line; LINE_BYTES
- must be at least sizeof (struct line). Allocate ALLOC bytes
- initially. */
-
-static void
-initbuf (struct buffer *buf, size_t line_bytes, size_t alloc)
-{
- /* Ensure that the line array is properly aligned. If the desired
- size cannot be allocated, repeatedly halve it until allocation
- succeeds. The smaller allocation may hurt overall performance,
- but that's better than failing. */
- for (;;)
- {
- alloc += sizeof (struct line) - alloc % sizeof (struct line);
- buf->buf = malloc (alloc);
- if (buf->buf)
- break;
- alloc /= 2;
- if (alloc <= line_bytes + 1)
- xalloc_die ();
- }
-
- buf->line_bytes = line_bytes;
- buf->alloc = alloc;
- buf->used = buf->left = buf->nlines = 0;
- buf->eof = false;
-}
-
-/* Return one past the limit of the line array. */
-
-static inline struct line *
-buffer_linelim (struct buffer const *buf)
-{
- return (struct line *) (buf->buf + buf->alloc);
-}
-
-/* Return a pointer to the first character of the field specified
- by KEY in LINE. */
-
-static char *
-begfield_uni (const struct line *line, const struct keyfield *key)
-{
- register char *ptr = line->text, *lim = ptr + line->length - 1;
- register size_t sword = key->sword;
- register size_t schar = key->schar;
- register size_t remaining_bytes;
-
- /* The leading field separator itself is included in a field when -t
- is absent. */
-
- if (!tab_default)
- while (ptr < lim && sword--)
- {
- while (ptr < lim && *ptr != tab[0])
- ++ptr;
- if (ptr < lim)
- ++ptr;
- }
- else
- while (ptr < lim && sword--)
- {
- while (ptr < lim && blanks[to_uchar (*ptr)])
- ++ptr;
- while (ptr < lim && !blanks[to_uchar (*ptr)])
- ++ptr;
- }
-
- if (key->skipsblanks)
- while (ptr < lim && blanks[to_uchar (*ptr)])
- ++ptr;
-
- /* Advance PTR by SCHAR (if possible), but no further than LIM. */
- remaining_bytes = lim - ptr;
- if (schar < remaining_bytes)
- ptr += schar;
- else
- ptr = lim;
-
- return ptr;
-}
-
-#if HAVE_MBRTOWC
-static char *
-begfield_mb (const struct line *line, const struct keyfield *key)
-{
- int i;
- char *ptr = line->text, *lim = ptr + line->length - 1;
- size_t sword = key->sword;
- size_t schar = key->schar;
- size_t mblength;
- mbstate_t state;
-
- memset (&state, '\0', sizeof(mbstate_t));
-
- if (!tab_default)
- while (ptr < lim && sword--)
- {
- while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- if (ptr < lim)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- }
- else
- while (ptr < lim && sword--)
- {
- while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
- ptr += mblength;
- if (ptr < lim)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
- ptr += mblength;
- }
-
- if (key->skipsblanks)
- while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
- ptr += mblength;
-
- for (i = 0; i < schar; i++)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
-
- if (ptr + mblength > lim)
- break;
- else
- ptr += mblength;
- }
-
- return ptr;
-}
-#endif
-
-/* Return the limit of (a pointer to the first character after) the field
- in LINE specified by KEY. */
-
-static char *
-limfield_uni (const struct line *line, const struct keyfield *key)
-{
- register char *ptr = line->text, *lim = ptr + line->length - 1;
- register size_t eword = key->eword, echar = key->echar;
- register size_t remaining_bytes;
-
- /* Move PTR past EWORD fields or to one past the last byte on LINE,
- whichever comes first. If there are more than EWORD fields, leave
- PTR pointing at the beginning of the field having zero-based index,
- EWORD. If a delimiter character was specified (via -t), then that
- `beginning' is the first character following the delimiting TAB.
- Otherwise, leave PTR pointing at the first `blank' character after
- the preceding field. */
- if (!tab_default)
- while (ptr < lim && eword--)
- {
- while (ptr < lim && *ptr != tab[0])
- ++ptr;
- if (ptr < lim && (eword | echar))
- ++ptr;
- }
- else
- while (ptr < lim && eword--)
- {
- while (ptr < lim && blanks[to_uchar (*ptr)])
- ++ptr;
- while (ptr < lim && !blanks[to_uchar (*ptr)])
- ++ptr;
- }
-
-#ifdef POSIX_UNSPECIFIED
- /* The following block of code makes GNU sort incompatible with
- standard Unix sort, so it's ifdef'd out for now.
- The POSIX spec isn't clear on how to interpret this.
- FIXME: request clarification.
-
- From: kwzh@gnu.ai.mit.edu (Karl Heuer)
- Date: Thu, 30 May 96 12:20:41 -0400
- [Translated to POSIX 1003.1-2001 terminology by Paul Eggert.]
-
- [...]I believe I've found another bug in `sort'.
-
- $ cat /tmp/sort.in
- a b c 2 d
- pq rs 1 t
- $ textutils-1.15/src/sort -k1.7,1.7 </tmp/sort.in
- a b c 2 d
- pq rs 1 t
- $ /bin/sort -k1.7,1.7 </tmp/sort.in
- pq rs 1 t
- a b c 2 d
-
- Unix sort produced the answer I expected: sort on the single character
- in column 7. GNU sort produced different results, because it disagrees
- on the interpretation of the key-end spec "M.N". Unix sort reads this
- as "skip M-1 fields, then N-1 characters"; but GNU sort wants it to mean
- "skip M-1 fields, then either N-1 characters or the rest of the current
- field, whichever comes first". This extra clause applies only to
- key-ends, not key-starts.
- */
-
- /* Make LIM point to the end of (one byte past) the current field. */
- if (!tab_default)
- {
- char *newlim;
- newlim = memchr (ptr, tab[0], lim - ptr);
- if (newlim)
- lim = newlim;
- }
- else
- {
- char *newlim;
- newlim = ptr;
- while (newlim < lim && blanks[to_uchar (*newlim)])
- ++newlim;
- while (newlim < lim && !blanks[to_uchar (*newlim)])
- ++newlim;
- lim = newlim;
- }
-#endif
-
- /* If we're ignoring leading blanks when computing the End
- of the field, don't start counting bytes until after skipping
- past any leading blanks. */
- if (key->skipeblanks)
- while (ptr < lim && blanks[to_uchar (*ptr)])
- ++ptr;
-
- /* Advance PTR by ECHAR (if possible), but no further than LIM. */
- remaining_bytes = lim - ptr;
- if (echar < remaining_bytes)
- ptr += echar;
- else
- ptr = lim;
-
- return ptr;
-}
-
-#if HAVE_MBRTOWC
-static char *
-limfield_mb (const struct line *line, const struct keyfield *key)
-{
- char *ptr = line->text, *lim = ptr + line->length - 1;
- size_t eword = key->eword, echar = key->echar;
- int i;
- size_t mblength;
- mbstate_t state;
-
- memset (&state, '\0', sizeof(mbstate_t));
-
- if (!tab_default)
- while (ptr < lim && eword--)
- {
- while (ptr < lim && memcmp (ptr, tab, tab_length) != 0)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- if (ptr < lim && (eword | echar))
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- }
- else
- while (ptr < lim && eword--)
- {
- while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
- ptr += mblength;
- if (ptr < lim)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength))
- ptr += mblength;
- }
-
-
-# ifdef POSIX_UNSPECIFIED
- /* Make LIM point to the end of (one byte past) the current field. */
- if (!tab_default)
- {
- char *newlim, *p;
-
- newlim = NULL;
- for (p = ptr; p < lim;)
- {
- if (memcmp (p, tab, tab_length) == 0)
- {
- newlim = p;
- break;
- }
-
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- p += mblength;
- }
- }
- else
- {
- char *newlim;
- newlim = ptr;
-
- while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength))
- newlim += mblength;
- if (ptr < lim)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
- ptr += mblength;
- }
- while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength))
- newlim += mblength;
- lim = newlim;
- }
-# endif
-
- /* If we're skipping leading blanks, don't start counting characters
- * until after skipping past any leading blanks. */
- if (key->skipeblanks)
- while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength))
- ptr += mblength;
-
- memset (&state, '\0', sizeof(mbstate_t));
-
- /* Advance PTR by ECHAR (if possible), but no further than LIM. */
- for (i = 0; i < echar; i++)
- {
- GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state);
-
- if (ptr + mblength > lim)
- break;
- else
- ptr += mblength;
- }
-
- return ptr;
-}
-#endif
-
-/* Fill BUF reading from FP, moving buf->left bytes from the end
- of buf->buf to the beginning first. If EOF is reached and the
- file wasn't terminated by a newline, supply one. Set up BUF's line
- table too. FILE is the name of the file corresponding to FP.
- Return true if some input was read. */
-
-static bool
-fillbuf (struct buffer *buf, register FILE *fp, char const *file)
-{
- struct keyfield const *key = keylist;
- char eol = eolchar;
- size_t line_bytes = buf->line_bytes;
- size_t mergesize = merge_buffer_size - MIN_MERGE_BUFFER_SIZE;
-
- if (buf->eof)
- return false;
-
- if (buf->used != buf->left)
- {
- memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left);
- buf->used = buf->left;
- buf->nlines = 0;
- }
-
- for (;;)
- {
- char *ptr = buf->buf + buf->used;
- struct line *linelim = buffer_linelim (buf);
- struct line *line = linelim - buf->nlines;
- size_t avail = (char *) linelim - buf->nlines * line_bytes - ptr;
- char *line_start = buf->nlines ? line->text + line->length : buf->buf;
-
- while (line_bytes + 1 < avail)
- {
- /* Read as many bytes as possible, but do not read so many
- bytes that there might not be enough room for the
- corresponding line array. The worst case is when the
- rest of the input file consists entirely of newlines,
- except that the last byte is not a newline. */
- size_t readsize = (avail - 1) / (line_bytes + 1);
- size_t bytes_read = fread (ptr, 1, readsize, fp);
- char *ptrlim = ptr + bytes_read;
- char *p;
- avail -= bytes_read;
-
- if (bytes_read != readsize)
- {
- if (ferror (fp))
- die (_("read failed"), file);
- if (feof (fp))
- {
- buf->eof = true;
- if (buf->buf == ptrlim)
- return false;
- if (ptrlim[-1] != eol)
- *ptrlim++ = eol;
- }
- }
-
- /* Find and record each line in the just-read input. */
- while ((p = memchr (ptr, eol, ptrlim - ptr)))
- {
- ptr = p + 1;
- line--;
- line->text = line_start;
- line->length = ptr - line_start;
- mergesize = MAX (mergesize, line->length);
- avail -= line_bytes;
-
- if (key)
- {
- /* Precompute the position of the first key for
- efficiency. */
- line->keylim = (key->eword == SIZE_MAX
- ? p
- : limfield (line, key));
-
- if (key->sword != SIZE_MAX)
- line->keybeg = begfield (line, key);
- else
- {
- if (key->skipsblanks)
-#if HAVE_MBRTOWC
- {
- if (MB_CUR_MAX > 1)
- {
- size_t mblength;
-
- while (ismbblank (line_start, ptr - line_start, &mblength))
- line_start += mblength;
- }
- else
-#endif
- {
- while (blanks[to_uchar (*line_start)])
- line_start++;
- }
- }
- line->keybeg = line_start;
- }
- }
-
- line_start = ptr;
- }
-
- ptr = ptrlim;
- if (buf->eof)
- break;
- }
-
- buf->used = ptr - buf->buf;
- buf->nlines = buffer_linelim (buf) - line;
- if (buf->nlines != 0)
- {
- buf->left = ptr - line_start;
- merge_buffer_size = mergesize + MIN_MERGE_BUFFER_SIZE;
- return true;
- }
-
- /* The current input line is too long to fit in the buffer.
- Double the buffer size and try again. */
- buf->buf = x2nrealloc (buf->buf, &buf->alloc, sizeof *(buf->buf));
- }
-}
-
-/* Compare strings A and B containing decimal fractions < 1. Each string
- should begin with a decimal point followed immediately by the digits
- of the fraction. Strings not of this form are considered to be zero. */
-
-/* The goal here, is to take two numbers a and b... compare these
- in parallel. Instead of converting each, and then comparing the
- outcome. Most likely stopping the comparison before the conversion
- is complete. The algorithm used, in the old sort:
-
- Algorithm: fraccompare
- Action : compare two decimal fractions
- accepts : char *a, char *b
- returns : -1 if a<b, 0 if a=b, 1 if a>b.
- implement:
-
- if *a == decimal_point AND *b == decimal_point
- find first character different in a and b.
- if both are digits, return the difference *a - *b.
- if *a is a digit
- skip past zeros
- if digit return 1, else 0
- if *b is a digit
- skip past zeros
- if digit return -1, else 0
- if *a is a decimal_point
- skip past decimal_point and zeros
- if digit return 1, else 0
- if *b is a decimal_point
- skip past decimal_point and zeros
- if digit return -1, else 0
- return 0 */
-
-static int
-fraccompare (register const char *a, register const char *b)
-{
- if (*a == decimal_point && *b == decimal_point)
- {
- while (*++a == *++b)
- if (! ISDIGIT (*a))
- return 0;
- if (ISDIGIT (*a) && ISDIGIT (*b))
- return *a - *b;
- if (ISDIGIT (*a))
- goto a_trailing_nonzero;
- if (ISDIGIT (*b))
- goto b_trailing_nonzero;
- return 0;
- }
- else if (*a++ == decimal_point)
- {
- a_trailing_nonzero:
- while (*a == NUMERIC_ZERO)
- a++;
- return ISDIGIT (*a);
- }
- else if (*b++ == decimal_point)
- {
- b_trailing_nonzero:
- while (*b == NUMERIC_ZERO)
- b++;
- return - ISDIGIT (*b);
- }
- return 0;
-}
-
-/* Compare strings A and B as numbers without explicitly converting them to
- machine numbers. Comparatively slow for short strings, but asymptotically
- hideously fast. */
-
-static int
-numcompare (register const char *a, register const char *b)
-{
- char tmpa;
- char tmpb;
- int tmp;
- size_t log_a;
- size_t log_b;
-
-#if HAVE_MBRTOWC
- if (MB_CUR_MAX > 1)
- {
- size_t mblength;
- size_t alen = strnlen (a, MB_LEN_MAX);
- size_t blen = strnlen (b, MB_LEN_MAX);
-
- while (ismbblank (a, alen, &mblength))
- a += mblength, alen -= mblength;
- while (ismbblank (b, blen, &mblength))
- b += mblength, blen -= mblength;
-
- tmpa = *a;
- tmpb = *b;
- }
- else
-#endif
- {
- tmpa = *a;
- tmpb = *b;
-
- while (blanks[to_uchar (tmpa)])
- tmpa = *++a;
- while (blanks[to_uchar (tmpb)])
- tmpb = *++b;
- }
-
- if (tmpa == NEGATION_SIGN)
- {
- do
- tmpa = *++a;
- while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa));
- if (tmpb != NEGATION_SIGN)
- {
- if (tmpa == decimal_point)
- do
- tmpa = *++a;
- while (tmpa == NUMERIC_ZERO);
- if (ISDIGIT (tmpa))
- return -1;
- while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb))
- tmpb = *++b;
- if (tmpb == decimal_point)
- do
- tmpb = *++b;
- while (tmpb == NUMERIC_ZERO);
- if (ISDIGIT (tmpb))
- return -1;
- return 0;
- }
- do
- tmpb = *++b;
- while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb));
-
- while (tmpa == tmpb && ISDIGIT (tmpa))
- {
- do
- tmpa = *++a;
- while (IS_THOUSANDS_SEP (tmpa));
- do
- tmpb = *++b;
- while (IS_THOUSANDS_SEP (tmpb));
- }
-
- if ((tmpa == decimal_point && !ISDIGIT (tmpb))
- || (tmpb == decimal_point && !ISDIGIT (tmpa)))
- return -fraccompare (a, b);
-
- tmp = tmpb - tmpa;
-
- for (log_a = 0; ISDIGIT (tmpa); ++log_a)
- do
- tmpa = *++a;
- while (IS_THOUSANDS_SEP (tmpa));
-
- for (log_b = 0; ISDIGIT (tmpb); ++log_b)
- do
- tmpb = *++b;
- while (IS_THOUSANDS_SEP (tmpb));
-
- if (log_a != log_b)
- return log_a < log_b ? 1 : -1;
-
- if (!log_a)
- return 0;
-
- return tmp;
- }
- else if (tmpb == NEGATION_SIGN)
- {
- do
- tmpb = *++b;
- while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb));
- if (tmpb == decimal_point)
- do
- tmpb = *++b;
- while (tmpb == NUMERIC_ZERO);
- if (ISDIGIT (tmpb))
- return 1;
- while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa))
- tmpa = *++a;
- if (tmpa == decimal_point)
- do
- tmpa = *++a;
- while (tmpa == NUMERIC_ZERO);
- if (ISDIGIT (tmpa))
- return 1;
- return 0;
- }
- else
- {
- while (tmpa == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpa))
- tmpa = *++a;
- while (tmpb == NUMERIC_ZERO || IS_THOUSANDS_SEP (tmpb))
- tmpb = *++b;
-
- while (tmpa == tmpb && ISDIGIT (tmpa))
- {
- do
- tmpa = *++a;
- while (IS_THOUSANDS_SEP (tmpa));
- do
- tmpb = *++b;
- while (IS_THOUSANDS_SEP (tmpb));
- }
-
- if ((tmpa == decimal_point && !ISDIGIT (tmpb))
- || (tmpb == decimal_point && !ISDIGIT (tmpa)))
- return fraccompare (a, b);
-
- tmp = tmpa - tmpb;
-
- for (log_a = 0; ISDIGIT (tmpa); ++log_a)
- do
- tmpa = *++a;
- while (IS_THOUSANDS_SEP (tmpa));
-
- for (log_b = 0; ISDIGIT (tmpb); ++log_b)
- do
- tmpb = *++b;
- while (IS_THOUSANDS_SEP (tmpb));
-
- if (log_a != log_b)
- return log_a < log_b ? -1 : 1;
-
- if (!log_a)
- return 0;
-
- return tmp;
- }
-}
-
-static int
-general_numcompare (const char *sa, const char *sb)
-{
- /* FIXME: add option to warn about failed conversions. */
- /* FIXME: maybe add option to try expensive FP conversion
- only if A and B can't be compared more cheaply/accurately. */
-
- char *bufa, *ea;
- char *bufb, *eb;
- double a;
- double b;
-
- char *p;
- struct lconv *lconvp = localeconv ();
- size_t thousands_sep_len = strlen (lconvp->thousands_sep);
-
- bufa = (char *) xmalloc (strlen (sa) + 1);
- bufb = (char *) xmalloc (strlen (sb) + 1);
- strcpy (bufa, sa);
- strcpy (bufb, sb);
-
- if (force_general_numcompare)
- {
- while (1)
- {
- a = strtod (bufa, &ea);
- if (memcmp (ea, lconvp->thousands_sep, thousands_sep_len) == 0)
- {
- for (p = ea; *(p + thousands_sep_len) != '\0'; p++)
- *p = *(p + thousands_sep_len);
- *p = '\0';
- continue;
- }
- break;
- }
-
- while (1)
- {
- b = strtod (bufb, &eb);
- if (memcmp (eb, lconvp->thousands_sep, thousands_sep_len) == 0)
- {
- for (p = eb; *(p + thousands_sep_len) != '\0'; p++)
- *p = *(p + thousands_sep_len);
- *p = '\0';
- continue;
- }
- break;
- }
- }
- else
- {
- a = strtod (bufa, &ea);
- b = strtod (bufb, &eb);
- }
-
- /* Put conversion errors at the start of the collating sequence. */
- free (bufa);
- free (bufb);
- if (bufa == ea)
- return bufb == eb ? 0 : -1;
- if (bufb == eb)
- return 1;
-
- /* Sort numbers in the usual way, where -0 == +0. Put NaNs after
- conversion errors but before numbers; sort them by internal
- bit-pattern, for lack of a more portable alternative. */
- return (a < b ? -1
- : a > b ? 1
- : a == b ? 0
- : b == b ? -1
- : a == a ? 1
- : memcmp ((char *) &a, (char *) &b, sizeof a));
-}
-
-/* Return an integer in 1..12 of the month name S with length LEN.
- Return 0 if the name in S is not recognized. */
-
-static int
-getmonth_uni (const char *s, size_t len)
-{
- char *month;
- register size_t i;
- register int lo = 0, hi = MONTHS_PER_YEAR, result;
-
- while (len > 0 && blanks[to_uchar (*s)])
- {
- ++s;
- --len;
- }
-
- if (len == 0)
- return 0;
-
- month = alloca (len + 1);
- for (i = 0; i < len; ++i)
- month[i] = fold_toupper[to_uchar (s[i])];
- month[len] = '\0';
-
- do
- {
- int ix = (lo + hi) / 2;
-
- if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
- hi = ix;
- else
- lo = ix;
- }
- while (hi - lo > 1);
-
- result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
- ? monthtab[lo].val : 0);
-
- return result;
-}
-
-#if HAVE_MBRTOWC
-static int
-getmonth_mb (const char *s, size_t len)
-{
- char *month;
- register size_t i;
- register int lo = 0, hi = MONTHS_PER_YEAR, result;
- char *tmp;
- size_t wclength, mblength;
- const char **pp;
- const wchar_t **wpp;
- wchar_t *month_wcs;
- mbstate_t state;
-
- while (len > 0 && ismbblank (s, len, &mblength))
- {
- s += mblength;
- len -= mblength;
- }
-
- if (len == 0)
- return 0;
-
- month = (char *) alloca (len + 1);
-
- tmp = (char *) alloca (len + 1);
- memcpy (tmp, s, len);
- tmp[len] = '\0';
- pp = (const char **)&tmp;
- month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t));
- memset (&state, '\0', sizeof(mbstate_t));
-
- wclength = mbsrtowcs (month_wcs, pp, len + 1, &state);
- assert (wclength != (size_t)-1 && *pp == NULL);
-
- for (i = 0; i < wclength; i++)
- month_wcs[i] = towupper(month_wcs[i]);
- month_wcs[i] = L'\0';
-
- wpp = (const wchar_t **)&month_wcs;
-
- mblength = wcsrtombs (month, wpp, len + 1, &state);
- assert (mblength != (-1) && *wpp == NULL);
-
- do
- {
- int ix = (lo + hi) / 2;
-
- if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0)
- hi = ix;
- else
- lo = ix;
- }
- while (hi - lo > 1);
-
- result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name))
- ? monthtab[lo].val : 0);
-
- return result;
-}
-#endif
-
-/* Compare two lines A and B trying every key in sequence until there
- are no more keys or a difference is found. */
-
-static int
-keycompare_uni (const struct line *a, const struct line *b)
-{
- struct keyfield const *key = keylist;
-
- /* For the first iteration only, the key positions have been
- precomputed for us. */
- register char *texta = a->keybeg;
- register char *textb = b->keybeg;
- register char *lima = a->keylim;
- register char *limb = b->keylim;
-
- int diff;
-
- for (;;)
- {
- register char const *translate = key->translate;
- register bool const *ignore = key->ignore;
-
- /* Find the lengths. */
- size_t lena = lima <= texta ? 0 : lima - texta;
- size_t lenb = limb <= textb ? 0 : limb - textb;
-
- /* Actually compare the fields. */
- if (key->numeric | key->general_numeric)
- {
- char savea = *lima, saveb = *limb;
-
- *lima = *limb = '\0';
- diff = ((key->numeric ? numcompare : general_numcompare)
- (texta, textb));
- *lima = savea, *limb = saveb;
- }
- else if (key->month)
- diff = getmonth (texta, lena) - getmonth (textb, lenb);
- /* Sorting like this may become slow, so in a simple locale the user
- can select a faster sort that is similar to ascii sort */
- else if (HAVE_SETLOCALE && hard_LC_COLLATE)
- {
- if (ignore || translate)
- {
- char *copy_a = alloca (lena + 1 + lenb + 1);
- char *copy_b = copy_a + lena + 1;
- size_t new_len_a, new_len_b, i;
-
- /* Ignore and/or translate chars before comparing. */
- for (new_len_a = new_len_b = i = 0; i < MAX (lena, lenb); i++)
- {
- if (i < lena)
- {
- copy_a[new_len_a] = (translate
- ? translate[to_uchar (texta[i])]
- : texta[i]);
- if (!ignore || !ignore[to_uchar (texta[i])])
- ++new_len_a;
- }
- if (i < lenb)
- {
- copy_b[new_len_b] = (translate
- ? translate[to_uchar (textb[i])]
- : textb [i]);
- if (!ignore || !ignore[to_uchar (textb[i])])
- ++new_len_b;
- }
- }
-
- diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
- }
- else if (lena == 0)
- diff = - NONZERO (lenb);
- else if (lenb == 0)
- goto greater;
- else
- diff = xmemcoll (texta, lena, textb, lenb);
- }
- else if (ignore)
- {
-#define CMP_WITH_IGNORE(A, B) \
- do \
- { \
- for (;;) \
- { \
- while (texta < lima && ignore[to_uchar (*texta)]) \
- ++texta; \
- while (textb < limb && ignore[to_uchar (*textb)]) \
- ++textb; \
- if (! (texta < lima && textb < limb)) \
- break; \
- diff = to_uchar (A) - to_uchar (B); \
- if (diff) \
- goto not_equal; \
- ++texta; \
- ++textb; \
- } \
- \
- diff = (texta < lima) - (textb < limb); \
- } \
- while (0)
-
- if (translate)
- CMP_WITH_IGNORE (translate[to_uchar (*texta)],
- translate[to_uchar (*textb)]);
- else
- CMP_WITH_IGNORE (*texta, *textb);
- }
- else if (lena == 0)
- diff = - NONZERO (lenb);
- else if (lenb == 0)
- goto greater;
- else
- {
- if (translate)
- {
- while (texta < lima && textb < limb)
- {
- diff = (to_uchar (translate[to_uchar (*texta++)])
- - to_uchar (translate[to_uchar (*textb++)]));
- if (diff)
- goto not_equal;
- }
- }
- else
- {
- diff = memcmp (texta, textb, MIN (lena, lenb));
- if (diff)
- goto not_equal;
- }
- diff = lena < lenb ? -1 : lena != lenb;
- }
-
- if (diff)
- goto not_equal;
-
- key = key->next;
- if (! key)
- break;
-
- /* Find the beginning and limit of the next field. */
- if (key->eword != SIZE_MAX)
- lima = limfield (a, key), limb = limfield (b, key);
- else
- lima = a->text + a->length - 1, limb = b->text + b->length - 1;
-
- if (key->sword != SIZE_MAX)
- texta = begfield (a, key), textb = begfield (b, key);
- else
- {
- texta = a->text, textb = b->text;
- if (key->skipsblanks)
- {
- while (texta < lima && blanks[to_uchar (*texta)])
- ++texta;
- while (textb < limb && blanks[to_uchar (*textb)])
- ++textb;
- }
- }
- }
-
- return 0;
-
- greater:
- diff = 1;
- not_equal:
- return key->reverse ? -diff : diff;
-}
-
-#if HAVE_MBRTOWC
-static int
-keycompare_mb (const struct line *a, const struct line *b)
-{
- struct keyfield *key = keylist;
-
- /* For the first iteration only, the key positions have been
- precomputed for us. */
- char *texta = a->keybeg;
- char *textb = b->keybeg;
- char *lima = a->keylim;
- char *limb = b->keylim;
-
- size_t mblength_a, mblength_b;
- wchar_t wc_a, wc_b;
- mbstate_t state_a, state_b;
-
- int diff;
-
- memset (&state_a, '\0', sizeof(mbstate_t));
- memset (&state_b, '\0', sizeof(mbstate_t));
-
- for (;;)
- {
- unsigned char *translate = (unsigned char *) key->translate;
- bool const *ignore = key->ignore;
-
- /* Find the lengths. */
- size_t lena = lima <= texta ? 0 : lima - texta;
- size_t lenb = limb <= textb ? 0 : limb - textb;
-
- /* Actually compare the fields. */
- if (key->numeric | key->general_numeric)
- {
- char savea = *lima, saveb = *limb;
-
- *lima = *limb = '\0';
- if (force_general_numcompare)
- diff = general_numcompare (texta, textb);
- else
- diff = ((key->numeric ? numcompare : general_numcompare)
- (texta, textb));
- *lima = savea, *limb = saveb;
- }
- else if (key->month)
- diff = getmonth (texta, lena) - getmonth (textb, lenb);
- else
- {
- if (ignore || translate)
- {
- char *copy_a = (char *) alloca (lena + 1 + lenb + 1);
- char *copy_b = copy_a + lena + 1;
- size_t new_len_a, new_len_b;
- size_t i, j;
-
- /* Ignore and/or translate chars before comparing. */
-# define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \
- do \
- { \
- wchar_t uwc; \
- char mbc[MB_LEN_MAX]; \
- mbstate_t state_wc; \
- \
- for (NEW_LEN = i = 0; i < LEN;) \
- { \
- mbstate_t state_bak; \
- \
- state_bak = STATE; \
- MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \
- \
- if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \
- || MBLENGTH == 0) \
- { \
- if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \
- STATE = state_bak; \
- if (!ignore) \
- COPY[NEW_LEN++] = TEXT[i++]; \
- continue; \
- } \
- \
- if (ignore) \
- { \
- if ((ignore == nonprinting && !iswprint (WC)) \
- || (ignore == nondictionary \
- && !iswalnum (WC) && !iswblank (WC))) \
- { \
- i += MBLENGTH; \
- continue; \
- } \
- } \
- \
- if (translate) \
- { \
- \
- uwc = toupper(WC); \
- if (WC == uwc) \
- { \
- memcpy (mbc, TEXT + i, MBLENGTH); \
- i += MBLENGTH; \
- } \
- else \
- { \
- i += MBLENGTH; \
- WC = uwc; \
- memset (&state_wc, '\0', sizeof (mbstate_t)); \
- \
- MBLENGTH = wcrtomb (mbc, WC, &state_wc); \
- assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \
- } \
- \
- for (j = 0; j < MBLENGTH; j++) \
- COPY[NEW_LEN++] = mbc[j]; \
- } \
- else \
- for (j = 0; j < MBLENGTH; j++) \
- COPY[NEW_LEN++] = TEXT[i++]; \
- } \
- COPY[NEW_LEN] = '\0'; \
- } \
- while (0)
- IGNORE_CHARS (new_len_a, lena, texta, copy_a,
- wc_a, mblength_a, state_a);
- IGNORE_CHARS (new_len_b, lenb, textb, copy_b,
- wc_b, mblength_b, state_b);
- diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b);
- }
- else if (lena == 0)
- diff = - NONZERO (lenb);
- else if (lenb == 0)
- goto greater;
- else
- diff = xmemcoll (texta, lena, textb, lenb);
- }
-
- if (diff)
- goto not_equal;
-
- key = key->next;
- if (! key)
- break;
-
- /* Find the beginning and limit of the next field. */
- if (key->eword != -1)
- lima = limfield (a, key), limb = limfield (b, key);
- else
- lima = a->text + a->length - 1, limb = b->text + b->length - 1;
-
- if (key->sword != -1)
- texta = begfield (a, key), textb = begfield (b, key);
- else
- {
- texta = a->text, textb = b->text;
- if (key->skipsblanks)
- {
- while (texta < lima && ismbblank (texta, lima - texta, &mblength_a))
- texta += mblength_a;
- while (textb < limb && ismbblank (textb, limb - textb, &mblength_b))
- textb += mblength_b;
- }
- }
- }
-
- return 0;
-
-greater:
- diff = 1;
-not_equal:
- return key->reverse ? -diff : diff;
-}
-#endif
-
-/* Compare two lines A and B, returning negative, zero, or positive
- depending on whether A compares less than, equal to, or greater than B. */
-
-static int
-compare (register const struct line *a, register const struct line *b)
-{
- int diff;
- size_t alen, blen;
-
- /* First try to compare on the specified keys (if any).
- The only two cases with no key at all are unadorned sort,
- and unadorned sort -r. */
- if (keylist)
- {
- diff = keycompare (a, b);
- alloca (0);
- if (diff | unique | stable)
- return diff;
- }
-
- /* If the keys all compare equal (or no keys were specified)
- fall through to the default comparison. */
- alen = a->length - 1, blen = b->length - 1;
-
- if (alen == 0)
- diff = - NONZERO (blen);
- else if (blen == 0)
- diff = 1;
- else if (HAVE_SETLOCALE && hard_LC_COLLATE)
- diff = xmemcoll (a->text, alen, b->text, blen);
- else if (! (diff = memcmp (a->text, b->text, MIN (alen, blen))))
- diff = alen < blen ? -1 : alen != blen;
-
- return reverse ? -diff : diff;
-}
-
-/* Check that the lines read from FILE_NAME come in order. Print a
- diagnostic (FILE_NAME, line number, contents of line) to stderr and return
- false if they are not in order. Otherwise, print no diagnostic
- and return true. */
-
-static bool
-check (char const *file_name)
-{
- FILE *fp = xfopen (file_name, "r");
- struct buffer buf; /* Input buffer. */
- struct line temp; /* Copy of previous line. */
- size_t alloc = 0;
- uintmax_t line_number = 0;
- struct keyfield const *key = keylist;
- bool nonunique = ! unique;
- bool ordered = true;
-
- initbuf (&buf, sizeof (struct line),
- MAX (merge_buffer_size, sort_size));
- temp.text = NULL;
-
- while (fillbuf (&buf, fp, file_name))
- {
- struct line const *line = buffer_linelim (&buf);
- struct line const *linebase = line - buf.nlines;
-
- /* Make sure the line saved from the old buffer contents is
- less than or equal to the first line of the new buffer. */
- if (alloc && nonunique <= compare (&temp, line - 1))
- {
- found_disorder:
- {
- struct line const *disorder_line = line - 1;
- uintmax_t disorder_line_number =
- buffer_linelim (&buf) - disorder_line + line_number;
- char hr_buf[INT_BUFSIZE_BOUND (uintmax_t)];
- fprintf (stderr, _("%s: %s:%s: disorder: "),
- program_name, file_name,
- umaxtostr (disorder_line_number, hr_buf));
- write_bytes (disorder_line->text, disorder_line->length, stderr,
- _("standard error"));
- ordered = false;
- break;
- }
- }
-
- /* Compare each line in the buffer with its successor. */
- while (linebase < --line)
- if (nonunique <= compare (line, line - 1))
- goto found_disorder;
-
- line_number += buf.nlines;
-
- /* Save the last line of the buffer. */
- if (alloc < line->length)
- {
- do
- {
- alloc *= 2;
- if (! alloc)
- {
- alloc = line->length;
- break;
- }
- }
- while (alloc < line->length);
-
- temp.text = xrealloc (temp.text, alloc);
- }
- memcpy (temp.text, line->text, line->length);
- temp.length = line->length;
- if (key)
- {
- temp.keybeg = temp.text + (line->keybeg - line->text);
- temp.keylim = temp.text + (line->keylim - line->text);
- }
- }
-
- xfclose (fp, file_name);
- free (buf.buf);
- if (temp.text)
- free (temp.text);
- return ordered;
-}
-
-/* Merge lines from FILES onto OFP. NFILES cannot be greater than
- NMERGE. Close input and output files before returning.
- OUTPUT_FILE gives the name of the output file. If it is NULL,
- the output file is standard output. If OFP is NULL, the output
- file has not been opened yet (or written to, if standard output). */
-
-static void
-mergefps (char **files, register int nfiles,
- FILE *ofp, const char *output_file)
-{
- FILE *fps[NMERGE]; /* Input streams for each file. */
- struct buffer buffer[NMERGE]; /* Input buffers for each file. */
- struct line saved; /* Saved line storage for unique check. */
- struct line const *savedline = NULL;
- /* &saved if there is a saved line. */
- size_t savealloc = 0; /* Size allocated for the saved line. */
- struct line const *cur[NMERGE]; /* Current line in each line table. */
- struct line const *base[NMERGE]; /* Base of each line table. */
- int ord[NMERGE]; /* Table representing a permutation of fps,
- such that cur[ord[0]] is the smallest line
- and will be next output. */
- register int i, j, t;
- struct keyfield const *key = keylist;
- saved.text = NULL;
-
- /* Read initial lines from each input file. */
- for (i = 0; i < nfiles; )
- {
- fps[i] = xfopen (files[i], "r");
- initbuf (&buffer[i], sizeof (struct line),
- MAX (merge_buffer_size, sort_size / nfiles));
- if (fillbuf (&buffer[i], fps[i], files[i]))
- {
- struct line const *linelim = buffer_linelim (&buffer[i]);
- cur[i] = linelim - 1;
- base[i] = linelim - buffer[i].nlines;
- i++;
- }
- else
- {
- /* fps[i] is empty; eliminate it from future consideration. */
- xfclose (fps[i], files[i]);
- zaptemp (files[i]);
- free (buffer[i].buf);
- --nfiles;
- for (j = i; j < nfiles; ++j)
- files[j] = files[j + 1];
- }
- }
-
- if (! ofp)
- ofp = xfopen (output_file, "w");
-
- /* Set up the ord table according to comparisons among input lines.
- Since this only reorders two items if one is strictly greater than
- the other, it is stable. */
- for (i = 0; i < nfiles; ++i)
- ord[i] = i;
- for (i = 1; i < nfiles; ++i)
- if (0 < compare (cur[ord[i - 1]], cur[ord[i]]))
- t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0;
-
- /* Repeatedly output the smallest line until no input remains. */
- while (nfiles)
- {
- struct line const *smallest = cur[ord[0]];
-
- /* If uniquified output is turned on, output only the first of
- an identical series of lines. */
- if (unique)
- {
- if (savedline && compare (savedline, smallest))
- {
- savedline = 0;
- write_bytes (saved.text, saved.length, ofp, output_file);
- }
- if (!savedline)
- {
- savedline = &saved;
- if (savealloc < smallest->length)
- {
- do
- if (! savealloc)
- {
- savealloc = smallest->length;
- break;
- }
- while ((savealloc *= 2) < smallest->length);
-
- saved.text = xrealloc (saved.text, savealloc);
- }
- saved.length = smallest->length;
- memcpy (saved.text, smallest->text, saved.length);
- if (key)
- {
- saved.keybeg =
- saved.text + (smallest->keybeg - smallest->text);
- saved.keylim =
- saved.text + (smallest->keylim - smallest->text);
- }
- }
- }
- else
- write_bytes (smallest->text, smallest->length, ofp, output_file);
-
- /* Check if we need to read more lines into core. */
- if (base[ord[0]] < smallest)
- cur[ord[0]] = smallest - 1;
- else
- {
- if (fillbuf (&buffer[ord[0]], fps[ord[0]], files[ord[0]]))
- {
- struct line const *linelim = buffer_linelim (&buffer[ord[0]]);
- cur[ord[0]] = linelim - 1;
- base[ord[0]] = linelim - buffer[ord[0]].nlines;
- }
- else
- {
- /* We reached EOF on fps[ord[0]]. */
- for (i = 1; i < nfiles; ++i)
- if (ord[i] > ord[0])
- --ord[i];
- --nfiles;
- xfclose (fps[ord[0]], files[ord[0]]);
- zaptemp (files[ord[0]]);
- free (buffer[ord[0]].buf);
- for (i = ord[0]; i < nfiles; ++i)
- {
- fps[i] = fps[i + 1];
- files[i] = files[i + 1];
- buffer[i] = buffer[i + 1];
- cur[i] = cur[i + 1];
- base[i] = base[i + 1];
- }
- for (i = 0; i < nfiles; ++i)
- ord[i] = ord[i + 1];
- continue;
- }
- }
-
- /* The new line just read in may be larger than other lines
- already in core; push it back in the queue until we encounter
- a line larger than it. */
- for (i = 1; i < nfiles; ++i)
- {
- t = compare (cur[ord[0]], cur[ord[i]]);
- if (!t)
- t = ord[0] - ord[i];
- if (t < 0)
- break;
- }
- t = ord[0];
- for (j = 1; j < i; ++j)
- ord[j - 1] = ord[j];
- ord[i - 1] = t;
- }
-
- if (unique && savedline)
- {
- write_bytes (saved.text, saved.length, ofp, output_file);
- free (saved.text);
- }
-
- xfclose (ofp, output_file);
-}
-
-/* Merge into T the two sorted arrays of lines LO (with NLO members)
- and HI (with NHI members). T, LO, and HI point just past their
- respective arrays, and the arrays are in reverse order. NLO and
- NHI must be positive, and HI - NHI must equal T - (NLO + NHI). */
-
-static inline void
-mergelines (struct line *t,
- struct line const *lo, size_t nlo,
- struct line const *hi, size_t nhi)
-{
- for (;;)
- if (compare (lo - 1, hi - 1) <= 0)
- {
- *--t = *--lo;
- if (! --nlo)
- {
- /* HI - NHI equalled T - (NLO + NHI) when this function
- began. Therefore HI must equal T now, and there is no
- need to copy from HI to T. */
- return;
- }
- }
- else
- {
- *--t = *--hi;
- if (! --nhi)
- {
- do
- *--t = *--lo;
- while (--nlo);
-
- return;
- }
- }
-}
-
-/* Sort the array LINES with NLINES members, using TEMP for temporary space.
- NLINES must be at least 2.
- The input and output arrays are in reverse order, and LINES and
- TEMP point just past the end of their respective arrays.
-
- Use a recursive divide-and-conquer algorithm, in the style
- suggested by Knuth volume 3 (2nd edition), exercise 5.2.4-23. Use
- the optimization suggested by exercise 5.2.4-10; this requires room
- for only 1.5*N lines, rather than the usual 2*N lines. Knuth
- writes that this memory optimization was originally published by
- D. A. Bell, Comp J. 1 (1958), 75. */
-
-static void
-sortlines (struct line *lines, size_t nlines, struct line *temp)
-{
- if (nlines == 2)
- {
- if (0 < compare (&lines[-1], &lines[-2]))
- {
- struct line tmp = lines[-1];
- lines[-1] = lines[-2];
- lines[-2] = tmp;
- }
- }
- else
- {
- size_t nlo = nlines / 2;
- size_t nhi = nlines - nlo;
- struct line *lo = lines;
- struct line *hi = lines - nlo;
- struct line *sorted_lo = temp;
-
- sortlines (hi, nhi, temp);
- if (1 < nlo)
- sortlines_temp (lo, nlo, sorted_lo);
- else
- sorted_lo[-1] = lo[-1];
-
- mergelines (lines, sorted_lo, nlo, hi, nhi);
- }
-}
-
-/* Like sortlines (LINES, NLINES, TEMP), except output into TEMP
- rather than sorting in place. */
-
-static void
-sortlines_temp (struct line *lines, size_t nlines, struct line *temp)
-{
- if (nlines == 2)
- {
- bool swap = (0 < compare (&lines[-1], &lines[-2]));
- temp[-1] = lines[-1 - swap];
- temp[-2] = lines[-2 + swap];
- }
- else
- {
- size_t nlo = nlines / 2;
- size_t nhi = nlines - nlo;
- struct line *lo = lines;
- struct line *hi = lines - nlo;
- struct line *sorted_hi = temp - nlo;
-
- sortlines_temp (hi, nhi, sorted_hi);
- if (1 < nlo)
- sortlines (lo, nlo, temp);
-
- mergelines (temp, lo, nlo, sorted_hi, nhi);
- }
-}
-
-/* Return the index of the first of NFILES FILES that is the same file
- as OUTFILE. If none can be the same, return NFILES.
-
- This test ensures that an otherwise-erroneous use like
- "sort -m -o FILE ... FILE ..." copies FILE before writing to it.
- It's not clear that POSIX requires this nicety.
- Detect common error cases, but don't try to catch obscure cases like
- "cat ... FILE ... | sort -m -o FILE"
- where traditional "sort" doesn't copy the input and where
- people should know that they're getting into trouble anyway.
- Catching these obscure cases would slow down performance in
- common cases. */
-
-static int
-first_same_file (char * const *files, int nfiles, char const *outfile)
-{
- int i;
- bool got_outstat = false;
- struct stat instat, outstat;
-
- for (i = 0; i < nfiles; i++)
- {
- bool standard_input = STREQ (files[i], "-");
-
- if (outfile && STREQ (outfile, files[i]) && ! standard_input)
- return i;
-
- if (! got_outstat)
- {
- got_outstat = true;
- if ((outfile
- ? stat (outfile, &outstat)
- : fstat (STDOUT_FILENO, &outstat))
- != 0)
- return nfiles;
- }
-
- if (((standard_input
- ? fstat (STDIN_FILENO, &instat)
- : stat (files[i], &instat))
- == 0)
- && SAME_INODE (instat, outstat))
- return i;
- }
-
- return nfiles;
-}
-
-/* Merge NFILES FILES onto OUTPUT_FILE. However, merge at most
- MAX_MERGE input files directly onto OUTPUT_FILE. MAX_MERGE cannot
- exceed NMERGE. A null OUTPUT_FILE stands for standard output. */
-
-static void
-merge (char **files, int nfiles, int max_merge, char const *output_file)
-{
- while (max_merge < nfiles)
- {
- FILE *tfp;
- int i, t = 0;
- char *temp;
- for (i = 0; i < nfiles / NMERGE; ++i)
- {
- temp = create_temp_file (&tfp);
- mergefps (&files[i * NMERGE], NMERGE, tfp, temp);
- files[t++] = temp;
- }
- temp = create_temp_file (&tfp);
- mergefps (&files[i * NMERGE], nfiles % NMERGE, tfp, temp);
- files[t++] = temp;
- nfiles = t;
- if (nfiles == 1)
- break;
- }
-
- mergefps (files, nfiles, NULL, output_file);
-}
-
-/* Sort NFILES FILES onto OUTPUT_FILE. */
-
-static void
-sort (char * const *files, int nfiles, char const *output_file)
-{
- struct buffer buf;
- int n_temp_files = 0;
- bool output_file_created = false;
-
- buf.alloc = 0;
-
- while (nfiles)
- {
- char const *temp_output;
- char const *file = *files;
- FILE *fp = xfopen (file, "r");
- FILE *tfp;
- size_t bytes_per_line = (2 * sizeof (struct line)
- - sizeof (struct line) / 2);
-
- if (! buf.alloc)
- initbuf (&buf, bytes_per_line,
- sort_buffer_size (&fp, 1, files, nfiles, bytes_per_line));
- buf.eof = false;
- files++;
- nfiles--;
-
- while (fillbuf (&buf, fp, file))
- {
- struct line *line;
- struct line *linebase;
-
- if (buf.eof && nfiles
- && (bytes_per_line + 1
- < (buf.alloc - buf.used - bytes_per_line * buf.nlines)))
- {
- /* End of file, but there is more input and buffer room.
- Concatenate the next input file; this is faster in
- the usual case. */
- buf.left = buf.used;
- break;
- }
-
- line = buffer_linelim (&buf);
- linebase = line - buf.nlines;
- if (1 < buf.nlines)
- sortlines (line, buf.nlines, linebase);
- if (buf.eof && !nfiles && !n_temp_files && !buf.left)
- {
- xfclose (fp, file);
- tfp = xfopen (output_file, "w");
- temp_output = output_file;
- output_file_created = true;
- }
- else
- {
- ++n_temp_files;
- temp_output = create_temp_file (&tfp);
- }
-
- do
- {
- line--;
- write_bytes (line->text, line->length, tfp, temp_output);
- if (unique)
- while (linebase < line && compare (line, line - 1) == 0)
- line--;
- }
- while (linebase < line);
-
- xfclose (tfp, temp_output);
-
- if (output_file_created)
- goto finish;
- }
- xfclose (fp, file);
- }
-
- finish:
- free (buf.buf);
-
- if (! output_file_created)
- {
- int i = n_temp_files;
- struct tempnode *node;
- char **tempfiles = xnmalloc (n_temp_files, sizeof *tempfiles);
- for (node = temphead; i > 0; node = node->next)
- tempfiles[--i] = node->name;
- merge (tempfiles, n_temp_files, NMERGE, output_file);
- free (tempfiles);
- }
-}
-
-/* Insert key KEY at the end of the key list. */
-
-static void
-insertkey (struct keyfield *key)
-{
- struct keyfield **p;
-
- for (p = &keylist; *p; p = &(*p)->next)
- continue;
- *p = key;
- key->next = NULL;
-}
-
-/* Report a bad field specification SPEC, with extra info MSGID. */
-
-static void badfieldspec (char const *, char const *)
- ATTRIBUTE_NORETURN;
-static void
-badfieldspec (char const *spec, char const *msgid)
-{
- error (SORT_FAILURE, 0, _("%s: invalid field specification `%s'"),
- _(msgid), spec);
- abort ();
-}
-
-/* Parse the leading integer in STRING and store the resulting value
- (which must fit into size_t) into *VAL. Return the address of the
- suffix after the integer. If MSGID is NULL, return NULL after
- failure; otherwise, report MSGID and exit on failure. */
-
-static char const *
-parse_field_count (char const *string, size_t *val, char const *msgid)
-{
- char *suffix;
- uintmax_t n;
-
- switch (xstrtoumax (string, &suffix, 10, &n, ""))
- {
- case LONGINT_OK:
- case LONGINT_INVALID_SUFFIX_CHAR:
- *val = n;
- if (*val == n)
- break;
- /* Fall through. */
- case LONGINT_OVERFLOW:
- case LONGINT_OVERFLOW | LONGINT_INVALID_SUFFIX_CHAR:
- if (msgid)
- error (SORT_FAILURE, 0, _("%s: count `%.*s' too large"),
- _(msgid), (int) (suffix - string), string);
- return NULL;
-
- case LONGINT_INVALID:
- if (msgid)
- error (SORT_FAILURE, 0, _("%s: invalid count at start of `%s'"),
- _(msgid), string);
- return NULL;
- }
-
- return suffix;
-}
-
-/* Handle interrupts and hangups. */
-
-static void
-sighandler (int sig)
-{
-#ifndef SA_NOCLDSTOP
- signal (sig, SIG_IGN);
-#endif
-
- cleanup ();
-
- signal (sig, SIG_DFL);
- raise (sig);
-}
-
-/* Set the ordering options for KEY specified in S.
- Return the address of the first character in S that
- is not a valid ordering option.
- BLANKTYPE is the kind of blanks that 'b' should skip. */
-
-static char *
-set_ordering (register const char *s, struct keyfield *key,
- enum blanktype blanktype)
-{
- while (*s)
- {
- switch (*s)
- {
- case 'b':
- if (blanktype == bl_start || blanktype == bl_both)
- key->skipsblanks = true;
- if (blanktype == bl_end || blanktype == bl_both)
- key->skipeblanks = true;
- break;
- case 'd':
- key->ignore = nondictionary;
- break;
- case 'f':
- key->translate = fold_toupper;
- break;
- case 'g':
- key->general_numeric = true;
- break;
- case 'i':
- /* Option order should not matter, so don't let -i override
- -d. -d implies -i, but -i does not imply -d. */
- if (! key->ignore)
- key->ignore = nonprinting;
- break;
- case 'M':
- key->month = true;
- break;
- case 'n':
- key->numeric = true;
- break;
- case 'r':
- key->reverse = true;
- break;
- default:
- return (char *) s;
- }
- ++s;
- }
- return (char *) s;
-}
-
-static struct keyfield *
-new_key (void)
-{
- struct keyfield *key = xzalloc (sizeof *key);
- key->eword = SIZE_MAX;
- return key;
-}
-
-int
-main (int argc, char **argv)
-{
- struct keyfield *key;
- struct keyfield gkey;
- char const *s;
- int c = 0;
- bool checkonly = false;
- bool mergeonly = false;
- int nfiles = 0;
- bool posixly_correct = (getenv ("POSIXLY_CORRECT") != NULL);
- bool obsolete_usage = (posix2_version () < 200112);
- char const *short_options = (obsolete_usage
- ? COMMON_SHORT_OPTIONS "y::"
- : COMMON_SHORT_OPTIONS "y:");
- char *minus = "-", **files;
- char const *outfile = NULL;
-
- initialize_main (&argc, &argv);
- program_name = argv[0];
- setlocale (LC_ALL, "");
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-
- atexit (cleanup);
-
- initialize_exit_failure (SORT_FAILURE);
- atexit (close_stdout);
-
- hard_LC_COLLATE = hard_locale (LC_COLLATE);
-#if HAVE_NL_LANGINFO
- hard_LC_TIME = hard_locale (LC_TIME);
-#endif
-
-#if HAVE_SETLOCALE
- /* Let's get locale's representation of the decimal point */
- {
- struct lconv const *lconvp = localeconv ();
-
- decimal_point = *lconvp->decimal_point;
- if (! decimal_point || lconvp->decimal_point[1])
- {
- decimal_point = C_DECIMAL_POINT;
- if (lconvp->decimal_point[0] && lconvp->decimal_point[1])
- force_general_numcompare = 1;
- }
-
- /* We don't support multibyte thousands separators yet. */
- th_sep = *lconvp->thousands_sep;
- if (! th_sep || lconvp->thousands_sep[1])
- {
- th_sep = CHAR_MAX + 1;
- if (lconvp->thousands_sep[0] && lconvp->thousands_sep[1])
- force_general_numcompare = 1;
- }
- }
-#endif
-
-#if HAVE_MBRTOWC
- if (MB_CUR_MAX > 1)
- {
- inittables = inittables_mb;
- begfield = begfield_mb;
- limfield = limfield_mb;
- getmonth = getmonth_mb;
- keycompare = keycompare_mb;
- }
- else
-#endif
- {
- inittables = inittables_uni;
- begfield = begfield_uni;
- limfield = limfield_uni;
- keycompare = keycompare_uni;
- getmonth = getmonth_uni;
- }
-
- have_read_stdin = false;
- inittables ();
-
- {
- int i;
- static int const sig[] = { SIGHUP, SIGINT, SIGPIPE, SIGTERM };
- enum { nsigs = sizeof sig / sizeof sig[0] };
-
-#ifdef SA_NOCLDSTOP
- struct sigaction act;
-
- sigemptyset (&caught_signals);
- for (i = 0; i < nsigs; i++)
- {
- sigaction (sig[i], NULL, &act);
- if (act.sa_handler != SIG_IGN)
- sigaddset (&caught_signals, sig[i]);
- }
-
- act.sa_handler = sighandler;
- act.sa_mask = caught_signals;
- act.sa_flags = 0;
-
- for (i = 0; i < nsigs; i++)
- if (sigismember (&caught_signals, sig[i]))
- sigaction (sig[i], &act, NULL);
-#else
- for (i = 0; i < nsigs; i++)
- if (signal (sig[i], SIG_IGN) != SIG_IGN)
- signal (sig[i], sighandler);
-#endif
- }
-
- gkey.sword = gkey.eword = SIZE_MAX;
- gkey.ignore = NULL;
- gkey.translate = NULL;
- gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = false;
- gkey.skipsblanks = gkey.skipeblanks = false;
-
- files = xnmalloc (argc, sizeof *files);
-
- for (;;)
- {
- /* Parse an operand as a file after "--" was seen; or if
- pedantic and a file was seen, unless the POSIX version
- predates 1003.1-2001 and -c was not seen and the operand is
- "-o FILE" or "-oFILE". */
-
- if (c == -1
- || (posixly_correct && nfiles != 0
- && ! (obsolete_usage
- && ! checkonly
- && optind != argc
- && argv[optind][0] == '-' && argv[optind][1] == 'o'
- && (argv[optind][2] || optind + 1 != argc)))
- || ((c = getopt_long (argc, argv, short_options,
- long_options, NULL))
- == -1))
- {
- if (argc <= optind)
- break;
- files[nfiles++] = argv[optind++];
- }
- else switch (c)
- {
- case 1:
- key = NULL;
- if (obsolete_usage && optarg[0] == '+')
- {
- /* Treat +POS1 [-POS2] as a key if possible; but silently
- treat an operand as a file if it is not a valid +POS1. */
- key = new_key ();
- s = parse_field_count (optarg + 1, &key->sword, NULL);
- if (s && *s == '.')
- s = parse_field_count (s + 1, &key->schar, NULL);
- if (! (key->sword | key->schar))
- key->sword = SIZE_MAX;
- if (! s || *set_ordering (s, key, bl_start))
- {
- free (key);
- key = NULL;
- }
- else
- {
- if (optind != argc && argv[optind][0] == '-'
- && ISDIGIT (argv[optind][1]))
- {
- char const *optarg1 = argv[optind++];
- s = parse_field_count (optarg1 + 1, &key->eword,
- N_("invalid number after `-'"));
- if (*s == '.')
- s = parse_field_count (s + 1, &key->echar,
- N_("invalid number after `.'"));
- if (*set_ordering (s, key, bl_end))
- badfieldspec (optarg1,
- N_("stray character in field spec"));
- }
- insertkey (key);
- }
- }
- if (! key)
- files[nfiles++] = optarg;
- break;
-
- case 'b':
- case 'd':
- case 'f':
- case 'g':
- case 'i':
- case 'M':
- case 'n':
- case 'r':
- {
- char str[2];
- str[0] = c;
- str[1] = '\0';
- set_ordering (str, &gkey, bl_both);
- }
- break;
-
- case 'c':
- checkonly = true;
- break;
-
- case 'k':
- key = new_key ();
-
- /* Get POS1. */
- s = parse_field_count (optarg, &key->sword,
- N_("invalid number at field start"));
- if (! key->sword--)
- {
- /* Provoke with `sort -k0' */
- badfieldspec (optarg, N_("field number is zero"));
- }
- if (*s == '.')
- {
- s = parse_field_count (s + 1, &key->schar,
- N_("invalid number after `.'"));
- if (! key->schar--)
- {
- /* Provoke with `sort -k1.0' */
- badfieldspec (optarg, N_("character offset is zero"));
- }
- }
- if (! (key->sword | key->schar))
- key->sword = SIZE_MAX;
- s = set_ordering (s, key, bl_start);
- if (*s != ',')
- {
- key->eword = SIZE_MAX;
- key->echar = 0;
- }
- else
- {
- /* Get POS2. */
- s = parse_field_count (s + 1, &key->eword,
- N_("invalid number after `,'"));
- if (! key->eword--)
- {
- /* Provoke with `sort -k1,0' */
- badfieldspec (optarg, N_("field number is zero"));
- }
- if (*s == '.')
- s = parse_field_count (s + 1, &key->echar,
- N_("invalid number after `.'"));
- else
- {
- /* `-k 2,3' is equivalent to `+1 -3'. */
- key->eword++;
- }
- s = set_ordering (s, key, bl_end);
- }
- if (*s)
- badfieldspec (optarg, N_("stray character in field spec"));
- insertkey (key);
- break;
-
- case 'm':
- mergeonly = true;
- break;
-
- case 'o':
- if (outfile && !STREQ (outfile, optarg))
- error (SORT_FAILURE, 0, _("multiple output files specified"));
- outfile = optarg;
- break;
-
- case 's':
- stable = true;
- break;
-
- case 'S':
- specify_sort_size (optarg);
- break;
-
- case 't':
- {
- char newtab[MB_LEN_MAX + 1];
- size_t newtab_length = 1;
- strncpy (newtab, optarg, MB_LEN_MAX);
- if (! newtab[0])
- error (SORT_FAILURE, 0, _("empty tab"));
-#if HAVE_MBRTOWC
- if (MB_CUR_MAX > 1)
- {
- wchar_t wc;
- mbstate_t state;
- size_t i;
-
- memset (&state, '\0', sizeof (mbstate_t));
- newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, MB_LEN_MAX), &state);
- switch (newtab_length)
- {
- case (size_t) -1:
- case (size_t) -2:
- case 0:
- newtab_length = 1;
- }
-
- if (optarg[newtab_length])
- {
- /* Provoke with `sort -txx'. Complain about
- "multi-character tab" instead of "multibyte tab", so
- that the diagnostic's wording does not need to be
- changed once multibyte characters are supported. */
- error (SORT_FAILURE, 0, _("multi-character tab `%s'"),
- optarg);
- }
- }
- else
-#endif
-
- if (optarg[1])
- {
- if (STREQ (optarg, "\\0"))
- newtab[0] = '\0';
- else
- {
- /* Provoke with `sort -txx'. Complain about
- "multi-character tab" instead of "multibyte tab", so
- that the diagnostic's wording does not need to be
- changed once multibyte characters are supported. */
- error (SORT_FAILURE, 0, _("multi-character tab `%s'"),
- optarg);
- }
- }
- if (!tab_default && (tab_length != newtab_length
- || memcmp(tab, newtab, tab_length) != 0))
- error (SORT_FAILURE, 0, _("incompatible tabs"));
- memcpy(tab, newtab, newtab_length);
- tab_length = newtab_length;
- tab_default = false;
- }
- break;
-
- case 'T':
- add_temp_dir (optarg);
- break;
-
- case 'u':
- unique = true;
- break;
-
- case 'y':
- /* Accept and ignore e.g. -y0 for compatibility with Solaris
- 2.x through Solaris 7. -y is marked as obsolete starting
- with Solaris 8. */
- break;
-
- case 'z':
- eolchar = 0;
- break;
-
- case_GETOPT_HELP_CHAR;
-
- case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
-
- default:
- usage (SORT_FAILURE);
- }
- }
-
- /* Inheritance of global options to individual keys. */
- for (key = keylist; key; key = key->next)
- if (! (key->ignore || key->translate
- || (key->skipsblanks | key->reverse
- | key->skipeblanks | key->month | key->numeric
- | key->general_numeric)))
- {
- key->ignore = gkey.ignore;
- key->translate = gkey.translate;
- key->skipsblanks = gkey.skipsblanks;
- key->skipeblanks = gkey.skipeblanks;
- key->month = gkey.month;
- key->numeric = gkey.numeric;
- key->general_numeric = gkey.general_numeric;
- key->reverse = gkey.reverse;
- }
-
- if (!keylist && (gkey.ignore || gkey.translate
- || (gkey.skipsblanks | gkey.skipeblanks | gkey.month
- | gkey.numeric | gkey.general_numeric)))
- insertkey (&gkey);
- reverse = gkey.reverse;
-
- if (temp_dir_count == 0)
- {
- char const *tmp_dir = getenv ("TMPDIR");
- add_temp_dir (tmp_dir ? tmp_dir : DEFAULT_TMPDIR);
- }
-
- if (nfiles == 0)
- {
- nfiles = 1;
- files = &minus;
- }
-
- if (checkonly)
- {
- if (nfiles > 1)
- {
- error (0, 0, _("extra operand %s not allowed with -c"),
- quote (files[1]));
- usage (SORT_FAILURE);
- }
-
- /* POSIX requires that sort return 1 IFF invoked with -c and the
- input is not properly sorted. */
- exit (check (files[0]) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER);
- }
-
- if (mergeonly)
- {
- int max_merge = first_same_file (files, MIN (nfiles, NMERGE), outfile);
- merge (files, nfiles, max_merge, outfile);
- }
- else
- sort (files, nfiles, outfile);
-
- if (have_read_stdin && fclose (stdin) == EOF)
- die (_("close failed"), "-");
-
- exit (EXIT_SUCCESS);
-}
diff --git a/contrib/gnu-sort/src/system.h b/contrib/gnu-sort/src/system.h
deleted file mode 100644
index 3497969..0000000
--- a/contrib/gnu-sort/src/system.h
+++ /dev/null
@@ -1,831 +0,0 @@
-/* system-dependent definitions for fileutils, textutils, and sh-utils packages.
- Copyright (C) 1989, 1991-2004 Free Software Foundation, Inc.
-
- 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, or (at your option)
- any later version.
-
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include <alloca.h>
-
-/* Include sys/types.h before this file. */
-
-#if 2 <= __GLIBC__ && 2 <= __GLIBC_MINOR__
-# if ! defined _SYS_TYPES_H
-you must include <sys/types.h> before including this file
-# endif
-#endif
-
-#include <sys/stat.h>
-
-#if !defined HAVE_MKFIFO
-# define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
-#endif
-
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-
-/* <unistd.h> should be included before any preprocessor test
- of _POSIX_VERSION. */
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifndef STDIN_FILENO
-# define STDIN_FILENO 0
-#endif
-
-#ifndef STDOUT_FILENO
-# define STDOUT_FILENO 1
-#endif
-
-#ifndef STDERR_FILENO
-# define STDERR_FILENO 2
-#endif
-
-
-/* limits.h must come before pathmax.h because limits.h on some systems
- undefs PATH_MAX, whereas pathmax.h sets PATH_MAX. */
-#include <limits.h>
-
-#include "pathmax.h"
-#include "localedir.h"
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-/* Since major is a function on SVR4, we can't use `ifndef major'. */
-#if MAJOR_IN_MKDEV
-# include <sys/mkdev.h>
-# define HAVE_MAJOR
-#endif
-#if MAJOR_IN_SYSMACROS
-# include <sys/sysmacros.h>
-# define HAVE_MAJOR
-#endif
-#ifdef major /* Might be defined in sys/types.h. */
-# define HAVE_MAJOR
-#endif
-
-#ifndef HAVE_MAJOR
-# define major(dev) (((dev) >> 8) & 0xff)
-# define minor(dev) ((dev) & 0xff)
-# define makedev(maj, min) (((maj) << 8) | (min))
-#endif
-#undef HAVE_MAJOR
-
-#if ! defined makedev && defined mkdev
-# define makedev(maj, min) mkdev (maj, min)
-#endif
-
-#if HAVE_UTIME_H
-# include <utime.h>
-#endif
-
-/* Some systems (even some that do have <utime.h>) don't declare this
- structure anywhere. */
-#ifndef HAVE_STRUCT_UTIMBUF
-struct utimbuf
-{
- long actime;
- long modtime;
-};
-#endif
-
-/* Don't use bcopy! Use memmove if source and destination may overlap,
- memcpy otherwise. */
-
-#include <string.h>
-#if ! HAVE_DECL_MEMRCHR
-void *memrchr (const void *, int, size_t);
-#endif
-
-#include <errno.h>
-
-/* Some systems don't define the following symbols. */
-#ifndef ENOSYS
-# define ENOSYS (-1)
-#endif
-#ifndef EISDIR
-# define EISDIR (-1)
-#endif
-
-#include <stdbool.h>
-
-#define getopt system_getopt
-#include <stdlib.h>
-#undef getopt
-
-/* The following test is to work around the gross typo in
- systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE
- is defined to 0, not 1. */
-#if !EXIT_FAILURE
-# undef EXIT_FAILURE
-# define EXIT_FAILURE 1
-#endif
-
-#ifndef EXIT_SUCCESS
-# define EXIT_SUCCESS 0
-#endif
-
-/* Exit statuses for programs like 'env' that exec other programs.
- EXIT_FAILURE might not be 1, so use EXIT_FAIL in such programs. */
-enum
-{
- EXIT_FAIL = 1,
- EXIT_CANNOT_INVOKE = 126,
- EXIT_ENOENT = 127
-};
-
-#include "exitfail.h"
-
-/* Set exit_failure to STATUS if that's not the default already. */
-static inline void
-initialize_exit_failure (int status)
-{
- if (status != EXIT_FAILURE)
- exit_failure = status;
-}
-
-#if HAVE_FCNTL_H
-# include <fcntl.h>
-#else
-# include <sys/file.h>
-#endif
-
-#if !defined SEEK_SET
-# define SEEK_SET 0
-# define SEEK_CUR 1
-# define SEEK_END 2
-#endif
-#ifndef F_OK
-# define F_OK 0
-# define X_OK 1
-# define W_OK 2
-# define R_OK 4
-#endif
-
-/* For systems that distinguish between text and binary I/O.
- O_BINARY is usually declared in fcntl.h */
-#if !defined O_BINARY && defined _O_BINARY
- /* For MSC-compatible compilers. */
-# define O_BINARY _O_BINARY
-# define O_TEXT _O_TEXT
-#endif
-
-#if !defined O_DIRECT
-# define O_DIRECT 0
-#endif
-
-#if !defined O_DSYNC
-# define O_DSYNC 0
-#endif
-
-#if !defined O_NDELAY
-# define O_NDELAY 0
-#endif
-
-#if !defined O_NONBLOCK
-# define O_NONBLOCK O_NDELAY
-#endif
-
-#if !defined O_NOCTTY
-# define O_NOCTTY 0
-#endif
-
-#if !defined O_NOFOLLOW
-# define O_NOFOLLOW 0
-#endif
-
-#if !defined O_RSYNC
-# define O_RSYNC 0
-#endif
-
-#if !defined O_SYNC
-# define O_SYNC 0
-#endif
-
-#ifdef __BEOS__
- /* BeOS 5 has O_BINARY and O_TEXT, but they have no effect. */
-# undef O_BINARY
-# undef O_TEXT
-#endif
-
-#if O_BINARY
-# ifndef __DJGPP__
-# define setmode _setmode
-# define fileno(_fp) _fileno (_fp)
-# endif /* not DJGPP */
-# define SET_MODE(_f, _m) setmode (_f, _m)
-# define SET_BINARY(_f) do {if (!isatty(_f)) setmode (_f, O_BINARY);} while (0)
-# define SET_BINARY2(_f1, _f2) \
- do { \
- if (!isatty (_f1)) \
- { \
- setmode (_f1, O_BINARY); \
- if (!isatty (_f2)) \
- setmode (_f2, O_BINARY); \
- } \
- } while(0)
-#else
-# define SET_MODE(_f, _m) (void)0
-# define SET_BINARY(f) (void)0
-# define SET_BINARY2(f1,f2) (void)0
-# ifndef O_BINARY
-# define O_BINARY 0
-# endif
-# define O_TEXT 0
-#endif /* O_BINARY */
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NLENGTH(direct) (strlen((direct)->d_name))
-#else /* not HAVE_DIRENT_H */
-# define dirent direct
-# define NLENGTH(direct) ((direct)->d_namlen)
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif /* HAVE_SYS_NDIR_H */
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif /* HAVE_SYS_DIR_H */
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif /* HAVE_NDIR_H */
-#endif /* HAVE_DIRENT_H */
-
-#if CLOSEDIR_VOID
-/* Fake a return value. */
-# define CLOSEDIR(d) (closedir (d), 0)
-#else
-# define CLOSEDIR(d) closedir (d)
-#endif
-
-/* Get or fake the disk device blocksize.
- Usually defined by sys/param.h (if at all). */
-#if !defined DEV_BSIZE && defined BSIZE
-# define DEV_BSIZE BSIZE
-#endif
-#if !defined DEV_BSIZE && defined BBSIZE /* SGI */
-# define DEV_BSIZE BBSIZE
-#endif
-#ifndef DEV_BSIZE
-# define DEV_BSIZE 4096
-#endif
-
-/* Extract or fake data from a `struct stat'.
- ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
- ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
- ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
-#ifndef HAVE_STRUCT_STAT_ST_BLOCKS
-# define ST_BLKSIZE(statbuf) DEV_BSIZE
-# if defined _POSIX_SOURCE || !defined BSIZE /* fileblocks.c uses BSIZE. */
-# define ST_NBLOCKS(statbuf) \
- ((statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0))
-# else /* !_POSIX_SOURCE && BSIZE */
-# define ST_NBLOCKS(statbuf) \
- (S_ISREG ((statbuf).st_mode) \
- || S_ISDIR ((statbuf).st_mode) \
- ? st_blocks ((statbuf).st_size) : 0)
-# endif /* !_POSIX_SOURCE && BSIZE */
-#else /* HAVE_STRUCT_STAT_ST_BLOCKS */
-/* Some systems, like Sequents, return st_blksize of 0 on pipes.
- Also, when running `rsh hpux11-system cat any-file', cat would
- determine that the output stream had an st_blksize of 2147421096.
- So here we arbitrarily limit the `optimal' block size to 4MB.
- If anyone knows of a system for which the legitimate value for
- st_blksize can exceed 4MB, please report it as a bug in this code. */
-# define ST_BLKSIZE(statbuf) ((0 < (statbuf).st_blksize \
- && (statbuf).st_blksize <= (1 << 22)) /* 4MB */ \
- ? (statbuf).st_blksize : DEV_BSIZE)
-# if defined hpux || defined __hpux__ || defined __hpux
-/* HP-UX counts st_blocks in 1024-byte units.
- This loses when mixing HP-UX and BSD file systems with NFS. */
-# define ST_NBLOCKSIZE 1024
-# else /* !hpux */
-# if defined _AIX && defined _I386
-/* AIX PS/2 counts st_blocks in 4K units. */
-# define ST_NBLOCKSIZE (4 * 1024)
-# else /* not AIX PS/2 */
-# if defined _CRAY
-# define ST_NBLOCKS(statbuf) \
- (S_ISREG ((statbuf).st_mode) \
- || S_ISDIR ((statbuf).st_mode) \
- ? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
-# endif /* _CRAY */
-# endif /* not AIX PS/2 */
-# endif /* !hpux */
-#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
-
-#ifndef ST_NBLOCKS
-# define ST_NBLOCKS(statbuf) ((statbuf).st_blocks)
-#endif
-
-#ifndef ST_NBLOCKSIZE
-# define ST_NBLOCKSIZE 512
-#endif
-
-/* Redirection and wildcarding when done by the utility itself.
- Generally a noop, but used in particular for native VMS. */
-#ifndef initialize_main
-# define initialize_main(ac, av)
-#endif
-
-#include "stat-macros.h"
-
-#include "timespec.h"
-
-#ifndef RETSIGTYPE
-# define RETSIGTYPE void
-#endif
-
-#ifdef __DJGPP__
- /* We need the declaration of setmode. */
-# include <io.h>
- /* We need the declaration of __djgpp_set_ctrl_c. */
-# include <sys/exceptn.h>
-#endif
-
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#if HAVE_STDINT_H
-# include <stdint.h>
-#endif
-
-#if ULONG_MAX < ULLONG_MAX
-# define LONGEST_MODIFIER "ll"
-#else
-# define LONGEST_MODIFIER "l"
-#endif
-#if PRI_MACROS_BROKEN
-# undef PRIdMAX
-# undef PRIoMAX
-# undef PRIuMAX
-# undef PRIxMAX
-#endif
-#ifndef PRIdMAX
-# define PRIdMAX LONGEST_MODIFIER "d"
-#endif
-#ifndef PRIoMAX
-# define PRIoMAX LONGEST_MODIFIER "o"
-#endif
-#ifndef PRIuMAX
-# define PRIuMAX LONGEST_MODIFIER "u"
-#endif
-#ifndef PRIxMAX
-# define PRIxMAX LONGEST_MODIFIER "x"
-#endif
-
-#include <ctype.h>
-
-/* Jim Meyering writes:
-
- "... Some ctype macros are valid only for character codes that
- isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
- using /bin/cc or gcc but without giving an ansi option). So, all
- ctype uses should be through macros like ISPRINT... If
- STDC_HEADERS is defined, then autoconf has verified that the ctype
- macros don't need to be guarded with references to isascii. ...
- Defining isascii to 1 should let any compiler worth its salt
- eliminate the && through constant folding."
-
- Bruno Haible adds:
-
- "... Furthermore, isupper(c) etc. have an undefined result if c is
- outside the range -1 <= c <= 255. One is tempted to write isupper(c)
- with c being of type `char', but this is wrong if c is an 8-bit
- character >= 128 which gets sign-extended to a negative value.
- The macro ISUPPER protects against this as well." */
-
-#if STDC_HEADERS || (!defined (isascii) && !HAVE_ISASCII)
-# define IN_CTYPE_DOMAIN(c) 1
-#else
-# define IN_CTYPE_DOMAIN(c) isascii(c)
-#endif
-
-#ifdef isblank
-# define ISBLANK(c) (IN_CTYPE_DOMAIN (c) && isblank (c))
-#else
-# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
-#endif
-#ifdef isgraph
-# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isgraph (c))
-#else
-# define ISGRAPH(c) (IN_CTYPE_DOMAIN (c) && isprint (c) && !isspace (c))
-#endif
-
-/* This is defined in <sys/euc.h> on at least Solaris2.6 systems. */
-#undef ISPRINT
-
-#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
-#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
-#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
-#define ISCNTRL(c) (IN_CTYPE_DOMAIN (c) && iscntrl (c))
-#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
-#define ISPUNCT(c) (IN_CTYPE_DOMAIN (c) && ispunct (c))
-#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
-#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
-#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
-#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
-
-#if STDC_HEADERS
-# define TOLOWER(Ch) tolower (Ch)
-# define TOUPPER(Ch) toupper (Ch)
-#else
-# define TOLOWER(Ch) (ISUPPER (Ch) ? tolower (Ch) : (Ch))
-# define TOUPPER(Ch) (ISLOWER (Ch) ? toupper (Ch) : (Ch))
-#endif
-
-/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
- - Its arg may be any int or unsigned int; it need not be an unsigned char.
- - It's guaranteed to evaluate its argument exactly once.
- - It's typically faster.
- POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
- ISDIGIT_LOCALE unless it's important to use the locale's definition
- of `digit' even when the host does not conform to POSIX. */
-#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
-
-/* Convert a possibly-signed character to an unsigned character. This is
- a bit safer than casting to unsigned char, since it catches some type
- errors that the cast doesn't. */
-static inline unsigned char to_uchar (char ch) { return ch; }
-
-/* Take care of NLS matters. */
-
-#if HAVE_LOCALE_H
-# include <locale.h>
-#else
-# define setlocale(Category, Locale) /* empty */
-#endif
-
-#include "gettext.h"
-#if ! ENABLE_NLS
-# undef textdomain
-# define textdomain(Domainname) /* empty */
-# undef bindtextdomain
-# define bindtextdomain(Domainname, Dirname) /* empty */
-#endif
-
-#define _(msgid) gettext (msgid)
-#define N_(msgid) msgid
-
-#ifndef HAVE_SETLOCALE
-# define HAVE_SETLOCALE 0
-#endif
-
-#define STREQ(a, b) (strcmp ((a), (b)) == 0)
-
-#if !HAVE_DECL_FREE
-void free ();
-#endif
-
-#if !HAVE_DECL_MALLOC
-char *malloc ();
-#endif
-
-#if !HAVE_DECL_MEMCHR
-char *memchr ();
-#endif
-
-#if !HAVE_DECL_REALLOC
-char *realloc ();
-#endif
-
-#if !HAVE_DECL_STPCPY
-# ifndef stpcpy
-char *stpcpy ();
-# endif
-#endif
-
-#if !HAVE_DECL_STRNDUP
-char *strndup ();
-#endif
-
-#if !HAVE_DECL_STRSTR
-char *strstr ();
-#endif
-
-#if !HAVE_DECL_GETENV
-char *getenv ();
-#endif
-
-#if !HAVE_DECL_LSEEK
-off_t lseek ();
-#endif
-
-/* This is needed on some AIX systems. */
-#if !HAVE_DECL_STRTOUL
-unsigned long strtoul ();
-#endif
-
-#if !HAVE_DECL_GETLOGIN
-char *getlogin ();
-#endif
-
-#if !HAVE_DECL_TTYNAME
-char *ttyname ();
-#endif
-
-#if !HAVE_DECL_GETEUID
-uid_t geteuid ();
-#endif
-
-#if !HAVE_DECL_GETPWUID
-struct passwd *getpwuid ();
-#endif
-
-#if !HAVE_DECL_GETGRGID
-struct group *getgrgid ();
-#endif
-
-#if !HAVE_DECL_GETUID
-uid_t getuid ();
-#endif
-
-#include "xalloc.h"
-
-#if ! defined HAVE_MEMPCPY && ! defined mempcpy
-/* Be CAREFUL that there are no side effects in N. */
-# define mempcpy(D, S, N) ((void *) ((char *) memcpy (D, S, N) + (N)))
-#endif
-
-/* Include automatically-generated macros for unlocked I/O. */
-#include "unlocked-io.h"
-
-#define SAME_INODE(Stat_buf_1, Stat_buf_2) \
- ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino \
- && (Stat_buf_1).st_dev == (Stat_buf_2).st_dev)
-
-#define DOT_OR_DOTDOT(Basename) \
- (Basename[0] == '.' && (Basename[1] == '\0' \
- || (Basename[1] == '.' && Basename[2] == '\0')))
-
-/* A wrapper for readdir so that callers don't see entries for `.' or `..'. */
-static inline struct dirent const *
-readdir_ignoring_dot_and_dotdot (DIR *dirp)
-{
- while (1)
- {
- struct dirent const *dp = readdir (dirp);
- if (dp == NULL || ! DOT_OR_DOTDOT (dp->d_name))
- return dp;
- }
-}
-
-#if SETVBUF_REVERSED
-# define SETVBUF(Stream, Buffer, Type, Size) \
- setvbuf (Stream, Type, Buffer, Size)
-#else
-# define SETVBUF(Stream, Buffer, Type, Size) \
- setvbuf (Stream, Buffer, Type, Size)
-#endif
-
-/* Factor out some of the common --help and --version processing code. */
-
-/* These enum values cannot possibly conflict with the option values
- ordinarily used by commands, including CHAR_MAX + 1, etc. Avoid
- CHAR_MIN - 1, as it may equal -1, the getopt end-of-options value. */
-enum
-{
- GETOPT_HELP_CHAR = (CHAR_MIN - 2),
- GETOPT_VERSION_CHAR = (CHAR_MIN - 3)
-};
-
-#define GETOPT_HELP_OPTION_DECL \
- "help", no_argument, 0, GETOPT_HELP_CHAR
-#define GETOPT_VERSION_OPTION_DECL \
- "version", no_argument, 0, GETOPT_VERSION_CHAR
-
-#define case_GETOPT_HELP_CHAR \
- case GETOPT_HELP_CHAR: \
- usage (EXIT_SUCCESS); \
- break;
-
-#define HELP_OPTION_DESCRIPTION \
- _(" --help display this help and exit\n")
-#define VERSION_OPTION_DESCRIPTION \
- _(" --version output version information and exit\n")
-
-#include "closeout.h"
-#include "version-etc.h"
-
-#define case_GETOPT_VERSION_CHAR(Program_name, Authors) \
- case GETOPT_VERSION_CHAR: \
- version_etc (stdout, Program_name, GNU_PACKAGE, VERSION, Authors, \
- (char *) NULL); \
- exit (EXIT_SUCCESS); \
- break;
-
-#ifndef MAX
-# define MAX(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-#ifndef MIN
-# define MIN(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-
-/* The extra casts work around common compiler bugs. */
-#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-/* The outer cast is needed to work around a bug in Cray C 5.0.3.0.
- It is necessary at least when t == time_t. */
-#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
- ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) : (t) 0))
-#define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
-
-/* Upper bound on the string length of an integer converted to string.
- 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
- add 1 for integer division truncation; add 1 more for a minus sign. */
-#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2)
-
-#ifndef CHAR_MIN
-# define CHAR_MIN TYPE_MINIMUM (char)
-#endif
-
-#ifndef CHAR_MAX
-# define CHAR_MAX TYPE_MAXIMUM (char)
-#endif
-
-#ifndef SCHAR_MIN
-# define SCHAR_MIN (-1 - SCHAR_MAX)
-#endif
-
-#ifndef SCHAR_MAX
-# define SCHAR_MAX (CHAR_MAX == UCHAR_MAX ? CHAR_MAX / 2 : CHAR_MAX)
-#endif
-
-#ifndef UCHAR_MAX
-# define UCHAR_MAX TYPE_MAXIMUM (unsigned char)
-#endif
-
-#ifndef SHRT_MIN
-# define SHRT_MIN TYPE_MINIMUM (short int)
-#endif
-
-#ifndef SHRT_MAX
-# define SHRT_MAX TYPE_MAXIMUM (short int)
-#endif
-
-#ifndef INT_MAX
-# define INT_MAX TYPE_MAXIMUM (int)
-#endif
-
-#ifndef INT_MIN
-# define INT_MIN TYPE_MINIMUM (int)
-#endif
-
-#ifndef INTMAX_MAX
-# define INTMAX_MAX TYPE_MAXIMUM (intmax_t)
-#endif
-
-#ifndef INTMAX_MIN
-# define INTMAX_MIN TYPE_MINIMUM (intmax_t)
-#endif
-
-#ifndef UINT_MAX
-# define UINT_MAX TYPE_MAXIMUM (unsigned int)
-#endif
-
-#ifndef LONG_MAX
-# define LONG_MAX TYPE_MAXIMUM (long int)
-#endif
-
-#ifndef ULONG_MAX
-# define ULONG_MAX TYPE_MAXIMUM (unsigned long int)
-#endif
-
-#ifndef SIZE_MAX
-# define SIZE_MAX TYPE_MAXIMUM (size_t)
-#endif
-
-#ifndef SSIZE_MAX
-# define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
-#endif
-
-#ifndef UINTMAX_MAX
-# define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t)
-#endif
-
-#ifndef OFF_T_MIN
-# define OFF_T_MIN TYPE_MINIMUM (off_t)
-#endif
-
-#ifndef OFF_T_MAX
-# define OFF_T_MAX TYPE_MAXIMUM (off_t)
-#endif
-
-#ifndef UID_T_MAX
-# define UID_T_MAX TYPE_MAXIMUM (uid_t)
-#endif
-
-#ifndef GID_T_MAX
-# define GID_T_MAX TYPE_MAXIMUM (gid_t)
-#endif
-
-#ifndef PID_T_MAX
-# define PID_T_MAX TYPE_MAXIMUM (pid_t)
-#endif
-
-/* Use this to suppress gcc's `...may be used before initialized' warnings. */
-#ifdef lint
-# define IF_LINT(Code) Code
-#else
-# define IF_LINT(Code) /* empty */
-#endif
-
-#ifndef __attribute__
-# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
-# define __attribute__(x)
-# endif
-#endif
-
-#ifndef ATTRIBUTE_NORETURN
-# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
-#endif
-
-#ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
-#endif
-
-#if defined strdupa
-# define ASSIGN_STRDUPA(DEST, S) \
- do { DEST = strdupa (S); } while (0)
-#else
-# define ASSIGN_STRDUPA(DEST, S) \
- do \
- { \
- const char *s_ = (S); \
- size_t len_ = strlen (s_) + 1; \
- char *tmp_dest_ = alloca (len_); \
- DEST = memcpy (tmp_dest_, (s_), len_); \
- } \
- while (0)
-#endif
-
-#ifndef EOVERFLOW
-# define EOVERFLOW EINVAL
-#endif
-
-#if ! HAVE_FSEEKO && ! defined fseeko
-# define fseeko(s, o, w) ((o) == (long int) (o) \
- ? fseek (s, o, w) \
- : (errno = EOVERFLOW, -1))
-#endif
-
-/* Compute the greatest common divisor of U and V using Euclid's
- algorithm. U and V must be nonzero. */
-
-static inline size_t
-gcd (size_t u, size_t v)
-{
- do
- {
- size_t t = u % v;
- u = v;
- v = t;
- }
- while (v);
-
- return u;
-}
-
-/* Compute the least common multiple of U and V. U and V must be
- nonzero. There is no overflow checking, so callers should not
- specify outlandish sizes. */
-
-static inline size_t
-lcm (size_t u, size_t v)
-{
- return u * (v / gcd (u, v));
-}
-
-/* Return PTR, aligned upward to the next multiple of ALIGNMENT.
- ALIGNMENT must be nonzero. The caller must arrange for ((char *)
- PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
- locations. */
-
-static inline void *
-ptr_align (void *ptr, size_t alignment)
-{
- char *p0 = ptr;
- char *p1 = p0 + alignment - 1;
- return p1 - (size_t) p1 % alignment;
-}
diff --git a/crypto/openssl/fips/Makefile b/crypto/openssl/fips/Makefile
deleted file mode 100644
index 546b54b..0000000
--- a/crypto/openssl/fips/Makefile
+++ /dev/null
@@ -1,230 +0,0 @@
-#
-# OpenSSL/crypto/Makefile
-#
-
-DIR= fips
-TOP= ..
-CC= cc
-INCLUDE= -I. -I$(TOP) -I../include
-# INCLUDES targets sudbirs!
-INCLUDES= -I.. -I../.. -I../../include
-CFLAG= -g
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-RM= rm -f
-AR= ar r
-ARD= ar d
-TEST= fips_test_suite.c
-FIPS_TVDIR= testvectors
-FIPS_TVOK= $$HOME/fips/tv.ok
-
-FIPSCANLOC= $(FIPSLIBDIR)fipscanister.o
-
-RECURSIVE_MAKE= [ -n "$(FDIRS)" ] && for i in $(FDIRS) ; do \
- (cd $$i && echo "making $$target in $(DIR)/$$i..." && \
- $(MAKE) -e TOP=../.. DIR=$$i INCLUDES='${INCLUDES}' $$target ) || exit 1; \
- done;
-
-PEX_LIBS=
-EX_LIBS=
-
-CFLAGS= $(INCLUDE) $(CFLAG) -DHMAC_EXT=\"$${HMAC_EXT:-sha1}\"
-ASFLAGS= $(INCLUDE) $(ASFLAG)
-AFLAGS=$(ASFLAGS)
-
-LIBS=
-
-FDIRS=sha rand des aes dsa rsa dh hmac
-
-GENERAL=Makefile README fips-lib.com install.com
-
-LIB= $(TOP)/libcrypto.a
-SHARED_LIB= $(FIPSCANLIB)$(SHLIB_EXT)
-LIBSRC=fips.c
-LIBOBJ=fips.o
-
-FIPS_OBJ_LISTS=sha/lib hmac/lib rand/lib des/lib aes/lib dsa/lib rsa/lib dh/lib
-
-SRC= $(LIBSRC)
-
-EXHEADER=fips.h
-HEADER=$(EXHEADER) fips_utl.h fips_locl.h
-EXE=fipsld
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- @(cd ..; $(MAKE) DIRS=$(DIR) all)
-
-testapps:
- @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
-
-all:
- @if [ -z "$(FIPSLIBDIR)" ]; then \
- $(MAKE) -e subdirs lib fips_premain_dso$(EXE_EXT); \
- else \
- $(MAKE) -e lib fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT); \
- fi
-
-# Idea behind fipscanister.o is to "seize" the sequestered code between
-# known symbols for fingerprinting purposes, which would be commonly
-# done with ld -r start.o ... end.o. The latter however presents a minor
-# challenge on multi-ABI platforms. As just implied, we'd rather use ld,
-# but the trouble is that we don't generally know how ABI-selection
-# compiler flag is translated to corresponding linker flag. All compiler
-# drivers seem to recognize -r flag and pass it down to linker, but some
-# of them, including gcc, erroneously add -lc, as well as run-time
-# components, such as crt1.o and alike. Fortunately among those vendor
-# compilers which were observed to misinterpret -r flag multi-ABI ones
-# are equipped with smart linkers, which don't require any ABI-selection
-# flag and simply assume that all objects are of the same type as first
-# one in command line. So the idea is to identify gcc and deficient
-# vendor compiler drivers...
-
-fipscanister.o: fips_start.o $(LIBOBJ) $(FIPS_OBJ_LISTS) fips_end.o
- FIPS_ASM=""; \
- list="$(BN_ASM)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/bn/$$i" ; done; \
- list="$(AES_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/aes/$$i" ; done; \
- list="$(DES_ENC)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/des/$$i" ; done; \
- list="$(SHA1_ASM_OBJ)"; for i in $$list; do FIPS_ASM="$$FIPS_ASM ../crypto/sha/$$i" ; done; \
- if [ -n "$(CPUID_OBJ)" ]; then \
- CPUID=../crypto/$(CPUID_OBJ) ; \
- else \
- CPUID="" ; \
- fi ; \
- objs="fips_start.o $(LIBOBJ) $(FIPS_EX_OBJ) $$CPUID $$FIPS_ASM"; \
- for i in $(FIPS_OBJ_LISTS); do \
- dir=`dirname $$i`; script="s|^|$$dir/|;s| | $$dir/|g"; \
- objs="$$objs `sed "$$script" $$i`"; \
- done; \
- objs="$$objs fips_end.o" ; \
- os="`(uname -s) 2>/dev/null`"; cflags="$(CFLAGS)"; \
- [ "$$os" = "AIX" ] && cflags="$$cflags -Wl,-bnoobjreorder"; \
- if [ -n "${FIPS_SITE_LD}" ]; then \
- set -x; ${FIPS_SITE_LD} -r -o $@ $$objs; \
- elif $(CC) -dumpversion >/dev/null 2>&1; then \
- set -x; $(CC) $$cflags -r -nostdlib -o $@ $$objs ; \
- else case "$$os" in \
- HP-UX|OSF1|SunOS) set -x; /usr/ccs/bin/ld -r -o $@ $$objs ;; \
- *) set -x; $(CC) $$cflags -r -o $@ $$objs ;; \
- esac fi
- ./fips_standalone_sha1$(EXE_EXT) fipscanister.o > fipscanister.o.sha1
-
-# If another exception is immediately required, assign approprite
-# site-specific ld command to FIPS_SITE_LD environment variable.
-
-fips_start.o: fips_canister.c
- $(CC) $(CFLAGS) -DFIPS_START -c -o $@ fips_canister.c
-fips_end.o: fips_canister.c
- $(CC) $(CFLAGS) -DFIPS_END -c -o $@ fips_canister.c
-fips_premain_dso$(EXE_EXT): fips_premain.c
- $(CC) $(CFLAGS) -DFINGERPRINT_PREMAIN_DSO_LOAD -o $@ fips_premain.c \
- $(FIPSLIBDIR)fipscanister.o ../libcrypto.a $(EX_LIBS)
-# this is executed only when linking with external fipscanister.o
-fips_standalone_sha1$(EXE_EXT): sha/fips_standalone_sha1.c
- if [ -z "$(HOSTCC)" ] ; then \
- $(CC) $(CFLAGS) -DFIPSCANISTER_O -o $@ sha/fips_standalone_sha1.c $(FIPSLIBDIR)fipscanister.o $(EX_LIBS) ; \
- else \
- $(HOSTCC) $(HOSTCFLAGS) -o $ $@ -I../include -I../crypto sha/fips_standalone_sha1.c ../crypto/sha/sha1dgst.c ; \
- fi
-
-subdirs:
- @target=all; $(RECURSIVE_MAKE)
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
- @target=files; $(RECURSIVE_MAKE)
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl ../include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl ../test $(TEST)
- @target=links; $(RECURSIVE_MAKE)
-
-# lib: and $(LIB): are splitted to avoid end-less loop
-lib: $(LIB)
- if [ "$(FIPSCANISTERINTERNAL)" = "n" -a -n "$(FIPSCANLOC)" ]; then $(AR) ../$(FIPSCANLIB).a $(FIPSCANLOC); fi
- @touch lib
-
-$(LIB): $(FIPSLIBDIR)fipscanister.o
- $(AR) $(LIB) $(FIPSLIBDIR)fipscanister.o
- $(RANLIB) $(LIB) || echo Never mind.
-
-$(FIPSCANLIB): $(FIPSCANLOC)
- $(AR) ../$(FIPSCANLIB).a $(FIPSCANLOC)
- if [ "$(FIPSCANLIB)" = "libfips" ]; then \
- $(AR) $(LIB) $(FIPSCANLOC) ; \
- $(RANLIB) $(LIB) || echo Never Mind. ; \
- fi
- $(RANLIB) ../$(FIPSCANLIB).a || echo Never mind.
- @touch lib
-
-shared: lib subdirs fips_premain_dso$(EXE_EXT)
-
-libs:
- @target=lib; $(RECURSIVE_MAKE)
-
-fips_test: top
- @target=fips_test; $(RECURSIVE_MAKE)
-
-fips_test_diff:
- @if diff -b -B -I '^\#' -cr -X fips-nodiff.txt $(FIPS_TVDIR) $(FIPS_TVOK) ; then \
- echo "FIPS diff OK" ; \
- else \
- echo "***FIPS DIFF ERROR***" ; exit 1 ; \
- fi
-
-
-install:
- @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
- @headerlist="$(EXHEADER)"; for i in $$headerlist ;\
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done;
- @target=install; $(RECURSIVE_MAKE)
- for i in $(EXE) ; \
- do \
- echo "installing $$i"; \
- cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
- chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
- mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i; \
- done
- cp -p -f $(FIPSLIBDIR)fipscanister.o $(FIPSLIBDIR)fipscanister.o.sha1 \
- $(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fips_premain.c.sha1 \
- $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/; \
- chmod 0444 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/fips*
-
-lint:
- @target=lint; $(RECURSIVE_MAKE)
-
-depend:
- @[ -z "$(THIS)" ] || $(MAKEDEPEND) -- $(CFLAG) $(INCLUDE) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
- @[ -z "$(THIS)" ] || (set -e; target=depend; $(RECURSIVE_MAKE) )
- @if [ -z "$(THIS)" ]; then $(MAKE) -f $(TOP)/Makefile reflect THIS=$@; fi
-
-clean:
- rm -f fipscanister.o.sha1 fips_premain_dso$(EXE_EXT) fips_standalone_sha1$(EXE_EXT) \
- *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
- @target=clean; $(RECURSIVE_MAKE)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
- @target=dclean; $(RECURSIVE_MAKE)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips.o: ../include/openssl/asn1.h ../include/openssl/bio.h
-fips.o: ../include/openssl/crypto.h ../include/openssl/des.h
-fips.o: ../include/openssl/des_old.h ../include/openssl/e_os2.h
-fips.o: ../include/openssl/err.h ../include/openssl/evp.h
-fips.o: ../include/openssl/fips.h ../include/openssl/fips_rand.h
-fips.o: ../include/openssl/hmac.h ../include/openssl/lhash.h
-fips.o: ../include/openssl/obj_mac.h ../include/openssl/objects.h
-fips.o: ../include/openssl/opensslconf.h ../include/openssl/opensslv.h
-fips.o: ../include/openssl/ossl_typ.h ../include/openssl/rand.h
-fips.o: ../include/openssl/rsa.h ../include/openssl/safestack.h
-fips.o: ../include/openssl/stack.h ../include/openssl/symhacks.h
-fips.o: ../include/openssl/ui.h ../include/openssl/ui_compat.h fips.c
-fips.o: fips_locl.h
diff --git a/crypto/openssl/fips/aes/Makefile b/crypto/openssl/fips/aes/Makefile
deleted file mode 100644
index 7b8b3a2..0000000
--- a/crypto/openssl/fips/aes/Makefile
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# OpenSSL/fips/aes/Makefile
-#
-
-DIR= aes
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=fips_aesavs.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_aes_selftest.c
-LIBOBJ=fips_aes_selftest.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=
-HEADER=
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-fips_test:
- -find ../testvectors/aes/req -name '*.req' > testlist
- -rm -rf ../testvectors/aes/rsp
- mkdir ../testvectors/aes/rsp
- if [ -s testlist ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_aesavs -d testlist; fi
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) \
- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff testlist
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_aes_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_aes_selftest.o: ../../include/openssl/crypto.h
-fips_aes_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_aes_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_aes_selftest.o: ../../include/openssl/lhash.h
-fips_aes_selftest.o: ../../include/openssl/obj_mac.h
-fips_aes_selftest.o: ../../include/openssl/objects.h
-fips_aes_selftest.o: ../../include/openssl/opensslconf.h
-fips_aes_selftest.o: ../../include/openssl/opensslv.h
-fips_aes_selftest.o: ../../include/openssl/ossl_typ.h
-fips_aes_selftest.o: ../../include/openssl/safestack.h
-fips_aes_selftest.o: ../../include/openssl/stack.h
-fips_aes_selftest.o: ../../include/openssl/symhacks.h fips_aes_selftest.c
-fips_aesavs.o: ../../e_os.h ../../include/openssl/aes.h
-fips_aesavs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_aesavs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_aesavs.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_aesavs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_aesavs.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_aesavs.o: ../../include/openssl/objects.h
-fips_aesavs.o: ../../include/openssl/opensslconf.h
-fips_aesavs.o: ../../include/openssl/opensslv.h
-fips_aesavs.o: ../../include/openssl/ossl_typ.h
-fips_aesavs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_aesavs.o: ../../include/openssl/symhacks.h ../fips_utl.h fips_aesavs.c
diff --git a/crypto/openssl/fips/aes/fips_aes_selftest.c b/crypto/openssl/fips/aes/fips_aes_selftest.c
deleted file mode 100644
index 441bbc1..0000000
--- a/crypto/openssl/fips/aes/fips_aes_selftest.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-#include <openssl/evp.h>
-
-#ifdef OPENSSL_FIPS
-static struct
- {
- unsigned char key[16];
- unsigned char plaintext[16];
- unsigned char ciphertext[16];
- } tests[]=
- {
- {
- { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
- 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
- { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
- 0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF },
- { 0x69,0xC4,0xE0,0xD8,0x6A,0x7B,0x04,0x30,
- 0xD8,0xCD,0xB7,0x80,0x70,0xB4,0xC5,0x5A },
- },
- };
-
-void FIPS_corrupt_aes()
- {
- tests[0].key[0]++;
- }
-
-int FIPS_selftest_aes()
- {
- int n;
- int ret = 0;
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
-
- for(n=0 ; n < 1 ; ++n)
- {
- if (fips_cipher_test(&ctx, EVP_aes_128_ecb(),
- tests[n].key, NULL,
- tests[n].plaintext,
- tests[n].ciphertext,
- 16) <= 0)
- goto err;
- }
- ret = 1;
- err:
- EVP_CIPHER_CTX_cleanup(&ctx);
- if (ret == 0)
- FIPSerr(FIPS_F_FIPS_SELFTEST_AES,FIPS_R_SELFTEST_FAILED);
- return ret;
- }
-#endif
diff --git a/crypto/openssl/fips/aes/fips_aesavs.c b/crypto/openssl/fips/aes/fips_aesavs.c
deleted file mode 100644
index a3c8b40..0000000
--- a/crypto/openssl/fips/aes/fips_aesavs.c
+++ /dev/null
@@ -1,939 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2004 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.
- *
- */
-/*---------------------------------------------
- NIST AES Algorithm Validation Suite
- Test Program
-
- Donated to OpenSSL by:
- V-ONE Corporation
- 20250 Century Blvd, Suite 300
- Germantown, MD 20874
- U.S.A.
- ----------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-
-#include <openssl/err.h>
-#include "e_os.h"
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS AES support\n");
- return(0);
-}
-
-#else
-
-#include <openssl/fips.h>
-#include "fips_utl.h"
-
-#define AES_BLOCK_SIZE 16
-
-#define VERBOSE 0
-
-/*-----------------------------------------------*/
-
-static int AESTest(EVP_CIPHER_CTX *ctx,
- char *amode, int akeysz, unsigned char *aKey,
- unsigned char *iVec,
- int dir, /* 0 = decrypt, 1 = encrypt */
- unsigned char *plaintext, unsigned char *ciphertext, int len)
- {
- const EVP_CIPHER *cipher = NULL;
-
- if (strcasecmp(amode, "CBC") == 0)
- {
- switch (akeysz)
- {
- case 128:
- cipher = EVP_aes_128_cbc();
- break;
-
- case 192:
- cipher = EVP_aes_192_cbc();
- break;
-
- case 256:
- cipher = EVP_aes_256_cbc();
- break;
- }
-
- }
- else if (strcasecmp(amode, "ECB") == 0)
- {
- switch (akeysz)
- {
- case 128:
- cipher = EVP_aes_128_ecb();
- break;
-
- case 192:
- cipher = EVP_aes_192_ecb();
- break;
-
- case 256:
- cipher = EVP_aes_256_ecb();
- break;
- }
- }
- else if (strcasecmp(amode, "CFB128") == 0)
- {
- switch (akeysz)
- {
- case 128:
- cipher = EVP_aes_128_cfb128();
- break;
-
- case 192:
- cipher = EVP_aes_192_cfb128();
- break;
-
- case 256:
- cipher = EVP_aes_256_cfb128();
- break;
- }
-
- }
- else if (strncasecmp(amode, "OFB", 3) == 0)
- {
- switch (akeysz)
- {
- case 128:
- cipher = EVP_aes_128_ofb();
- break;
-
- case 192:
- cipher = EVP_aes_192_ofb();
- break;
-
- case 256:
- cipher = EVP_aes_256_ofb();
- break;
- }
- }
- else if(!strcasecmp(amode,"CFB1"))
- {
- switch (akeysz)
- {
- case 128:
- cipher = EVP_aes_128_cfb1();
- break;
-
- case 192:
- cipher = EVP_aes_192_cfb1();
- break;
-
- case 256:
- cipher = EVP_aes_256_cfb1();
- break;
- }
- }
- else if(!strcasecmp(amode,"CFB8"))
- {
- switch (akeysz)
- {
- case 128:
- cipher = EVP_aes_128_cfb8();
- break;
-
- case 192:
- cipher = EVP_aes_192_cfb8();
- break;
-
- case 256:
- cipher = EVP_aes_256_cfb8();
- break;
- }
- }
- else
- {
- printf("Unknown mode: %s\n", amode);
- return 0;
- }
- if (!cipher)
- {
- printf("Invalid key size: %d\n", akeysz);
- return 0;
- }
- if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
- return 0;
- if(!strcasecmp(amode,"CFB1"))
- M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
- if (dir)
- EVP_Cipher(ctx, ciphertext, plaintext, len);
- else
- EVP_Cipher(ctx, plaintext, ciphertext, len);
- return 1;
- }
-
-/*-----------------------------------------------*/
-char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
-char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB128"};
-enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB128};
-enum XCrypt {XDECRYPT, XENCRYPT};
-
-/*=============================*/
-/* Monte Carlo Tests */
-/*-----------------------------*/
-
-/*#define gb(a,b) (((a)[(b)/8] >> ((b)%8))&1)*/
-/*#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << ((b)%8)))|(!!(v) << ((b)%8)))*/
-
-#define gb(a,b) (((a)[(b)/8] >> (7-(b)%8))&1)
-#define sb(a,b,v) ((a)[(b)/8]=((a)[(b)/8]&~(1 << (7-(b)%8)))|(!!(v) << (7-(b)%8)))
-
-static int do_mct(char *amode,
- int akeysz, unsigned char *aKey,unsigned char *iVec,
- int dir, unsigned char *text, int len,
- FILE *rfp)
- {
- int ret = 0;
- unsigned char key[101][32];
- unsigned char iv[101][AES_BLOCK_SIZE];
- unsigned char ptext[1001][32];
- unsigned char ctext[1001][32];
- unsigned char ciphertext[64+4];
- int i, j, n, n1, n2;
- int imode = 0, nkeysz = akeysz/8;
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
-
- if (len > 32)
- {
- printf("\n>>>> Length exceeds 32 for %s %d <<<<\n\n",
- amode, akeysz);
- return -1;
- }
- for (imode = 0; imode < 6; ++imode)
- if (strcmp(amode, t_mode[imode]) == 0)
- break;
- if (imode == 6)
- {
- printf("Unrecognized mode: %s\n", amode);
- return -1;
- }
-
- memcpy(key[0], aKey, nkeysz);
- if (iVec)
- memcpy(iv[0], iVec, AES_BLOCK_SIZE);
- if (dir == XENCRYPT)
- memcpy(ptext[0], text, len);
- else
- memcpy(ctext[0], text, len);
- for (i = 0; i < 100; ++i)
- {
- /* printf("Iteration %d\n", i); */
- if (i > 0)
- {
- fprintf(rfp,"COUNT = %d\n",i);
- OutputValue("KEY",key[i],nkeysz,rfp,0);
- if (imode != ECB) /* ECB */
- OutputValue("IV",iv[i],AES_BLOCK_SIZE,rfp,0);
- /* Output Ciphertext | Plaintext */
- OutputValue(t_tag[dir^1],dir ? ptext[0] : ctext[0],len,rfp,
- imode == CFB1);
- }
- for (j = 0; j < 1000; ++j)
- {
- switch (imode)
- {
- case ECB:
- if (j == 0)
- { /* set up encryption */
- ret = AESTest(&ctx, amode, akeysz, key[i], NULL,
- dir, /* 0 = decrypt, 1 = encrypt */
- ptext[j], ctext[j], len);
- if (dir == XENCRYPT)
- memcpy(ptext[j+1], ctext[j], len);
- else
- memcpy(ctext[j+1], ptext[j], len);
- }
- else
- {
- if (dir == XENCRYPT)
- {
- EVP_Cipher(&ctx, ctext[j], ptext[j], len);
- memcpy(ptext[j+1], ctext[j], len);
- }
- else
- {
- EVP_Cipher(&ctx, ptext[j], ctext[j], len);
- memcpy(ctext[j+1], ptext[j], len);
- }
- }
- break;
-
- case CBC:
- case OFB:
- case CFB128:
- if (j == 0)
- {
- ret = AESTest(&ctx, amode, akeysz, key[i], iv[i],
- dir, /* 0 = decrypt, 1 = encrypt */
- ptext[j], ctext[j], len);
- if (dir == XENCRYPT)
- memcpy(ptext[j+1], iv[i], len);
- else
- memcpy(ctext[j+1], iv[i], len);
- }
- else
- {
- if (dir == XENCRYPT)
- {
- EVP_Cipher(&ctx, ctext[j], ptext[j], len);
- memcpy(ptext[j+1], ctext[j-1], len);
- }
- else
- {
- EVP_Cipher(&ctx, ptext[j], ctext[j], len);
- memcpy(ctext[j+1], ptext[j-1], len);
- }
- }
- break;
-
- case CFB8:
- if (j == 0)
- {
- ret = AESTest(&ctx, amode, akeysz, key[i], iv[i],
- dir, /* 0 = decrypt, 1 = encrypt */
- ptext[j], ctext[j], len);
- }
- else
- {
- if (dir == XENCRYPT)
- EVP_Cipher(&ctx, ctext[j], ptext[j], len);
- else
- EVP_Cipher(&ctx, ptext[j], ctext[j], len);
- }
- if (dir == XENCRYPT)
- {
- if (j < 16)
- memcpy(ptext[j+1], &iv[i][j], len);
- else
- memcpy(ptext[j+1], ctext[j-16], len);
- }
- else
- {
- if (j < 16)
- memcpy(ctext[j+1], &iv[i][j], len);
- else
- memcpy(ctext[j+1], ptext[j-16], len);
- }
- break;
-
- case CFB1:
- if(j == 0)
- {
-#if 0
- /* compensate for wrong endianness of input file */
- if(i == 0)
- ptext[0][0]<<=7;
-#endif
- ret = AESTest(&ctx,amode,akeysz,key[i],iv[i],dir,
- ptext[j], ctext[j], len);
- }
- else
- {
- if (dir == XENCRYPT)
- EVP_Cipher(&ctx, ctext[j], ptext[j], len);
- else
- EVP_Cipher(&ctx, ptext[j], ctext[j], len);
-
- }
- if(dir == XENCRYPT)
- {
- if(j < 128)
- sb(ptext[j+1],0,gb(iv[i],j));
- else
- sb(ptext[j+1],0,gb(ctext[j-128],0));
- }
- else
- {
- if(j < 128)
- sb(ctext[j+1],0,gb(iv[i],j));
- else
- sb(ctext[j+1],0,gb(ptext[j-128],0));
- }
- break;
- }
- }
- --j; /* reset to last of range */
- /* Output Ciphertext | Plaintext */
- OutputValue(t_tag[dir],dir ? ctext[j] : ptext[j],len,rfp,
- imode == CFB1);
- fprintf(rfp, "\n"); /* add separator */
-
- /* Compute next KEY */
- if (dir == XENCRYPT)
- {
- if (imode == CFB8)
- { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
- for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
- ciphertext[n1] = ctext[j-n2][0];
- }
- else if(imode == CFB1)
- {
- for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
- sb(ciphertext,n1,gb(ctext[j-n2],0));
- }
- else
- switch (akeysz)
- {
- case 128:
- memcpy(ciphertext, ctext[j], 16);
- break;
- case 192:
- memcpy(ciphertext, ctext[j-1]+8, 8);
- memcpy(ciphertext+8, ctext[j], 16);
- break;
- case 256:
- memcpy(ciphertext, ctext[j-1], 16);
- memcpy(ciphertext+16, ctext[j], 16);
- break;
- }
- }
- else
- {
- if (imode == CFB8)
- { /* ct = CT[j-15] || CT[j-14] || ... || CT[j] */
- for (n1 = 0, n2 = nkeysz-1; n1 < nkeysz; ++n1, --n2)
- ciphertext[n1] = ptext[j-n2][0];
- }
- else if(imode == CFB1)
- {
- for(n1=0,n2=akeysz-1 ; n1 < akeysz ; ++n1,--n2)
- sb(ciphertext,n1,gb(ptext[j-n2],0));
- }
- else
- switch (akeysz)
- {
- case 128:
- memcpy(ciphertext, ptext[j], 16);
- break;
- case 192:
- memcpy(ciphertext, ptext[j-1]+8, 8);
- memcpy(ciphertext+8, ptext[j], 16);
- break;
- case 256:
- memcpy(ciphertext, ptext[j-1], 16);
- memcpy(ciphertext+16, ptext[j], 16);
- break;
- }
- }
- /* Compute next key: Key[i+1] = Key[i] xor ct */
- for (n = 0; n < nkeysz; ++n)
- key[i+1][n] = key[i][n] ^ ciphertext[n];
-
- /* Compute next IV and text */
- if (dir == XENCRYPT)
- {
- switch (imode)
- {
- case ECB:
- memcpy(ptext[0], ctext[j], AES_BLOCK_SIZE);
- break;
- case CBC:
- case OFB:
- case CFB128:
- memcpy(iv[i+1], ctext[j], AES_BLOCK_SIZE);
- memcpy(ptext[0], ctext[j-1], AES_BLOCK_SIZE);
- break;
- case CFB8:
- /* IV[i+1] = ct */
- for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
- iv[i+1][n1] = ctext[j-n2][0];
- ptext[0][0] = ctext[j-16][0];
- break;
- case CFB1:
- for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
- sb(iv[i+1],n1,gb(ctext[j-n2],0));
- ptext[0][0]=ctext[j-128][0]&0x80;
- break;
- }
- }
- else
- {
- switch (imode)
- {
- case ECB:
- memcpy(ctext[0], ptext[j], AES_BLOCK_SIZE);
- break;
- case CBC:
- case OFB:
- case CFB128:
- memcpy(iv[i+1], ptext[j], AES_BLOCK_SIZE);
- memcpy(ctext[0], ptext[j-1], AES_BLOCK_SIZE);
- break;
- case CFB8:
- for (n1 = 0, n2 = 15; n1 < 16; ++n1, --n2)
- iv[i+1][n1] = ptext[j-n2][0];
- ctext[0][0] = ptext[j-16][0];
- break;
- case CFB1:
- for(n1=0,n2=127 ; n1 < 128 ; ++n1,--n2)
- sb(iv[i+1],n1,gb(ptext[j-n2],0));
- ctext[0][0]=ptext[j-128][0]&0x80;
- break;
- }
- }
- }
-
- return ret;
- }
-
-/*================================================*/
-/*----------------------------
- # Config info for v-one
- # AESVS MMT test data for ECB
- # State : Encrypt and Decrypt
- # Key Length : 256
- # Fri Aug 30 04:07:22 PM
- ----------------------------*/
-
-static int proc_file(char *rqfile, char *rspfile)
- {
- char afn[256], rfn[256];
- FILE *afp = NULL, *rfp = NULL;
- char ibuf[2048];
- char tbuf[2048];
- int ilen, len, ret = 0;
- char algo[8] = "";
- char amode[8] = "";
- char atest[8] = "";
- int akeysz = 0;
- unsigned char iVec[20], aKey[40];
- int dir = -1, err = 0, step = 0;
- unsigned char plaintext[2048];
- unsigned char ciphertext[2048];
- char *rp;
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
-
- if (!rqfile || !(*rqfile))
- {
- printf("No req file\n");
- return -1;
- }
- strcpy(afn, rqfile);
-
- if ((afp = fopen(afn, "r")) == NULL)
- {
- printf("Cannot open file: %s, %s\n",
- afn, strerror(errno));
- return -1;
- }
- if (!rspfile)
- {
- strcpy(rfn,afn);
- rp=strstr(rfn,"req/");
-#ifdef OPENSSL_SYS_WIN32
- if (!rp)
- rp=strstr(rfn,"req\\");
-#endif
- assert(rp);
- memcpy(rp,"rsp",3);
- rp = strstr(rfn, ".req");
- memcpy(rp, ".rsp", 4);
- rspfile = rfn;
- }
- if ((rfp = fopen(rspfile, "w")) == NULL)
- {
- printf("Cannot open file: %s, %s\n",
- rfn, strerror(errno));
- fclose(afp);
- afp = NULL;
- return -1;
- }
- while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
- {
- tidy_line(tbuf, ibuf);
- ilen = strlen(ibuf);
- /* printf("step=%d ibuf=%s",step,ibuf); */
- switch (step)
- {
- case 0: /* read preamble */
- if (ibuf[0] == '\n')
- { /* end of preamble */
- if ((*algo == '\0') ||
- (*amode == '\0') ||
- (akeysz == 0))
- {
- printf("Missing Algorithm, Mode or KeySize (%s/%s/%d)\n",
- algo,amode,akeysz);
- err = 1;
- }
- else
- {
- fputs(ibuf, rfp);
- ++ step;
- }
- }
- else if (ibuf[0] != '#')
- {
- printf("Invalid preamble item: %s\n", ibuf);
- err = 1;
- }
- else
- { /* process preamble */
- char *xp, *pp = ibuf+2;
- int n;
- if (akeysz)
- { /* insert current time & date */
- time_t rtim = time(0);
- fprintf(rfp, "# %s", ctime(&rtim));
- }
- else
- {
- fputs(ibuf, rfp);
- if (strncmp(pp, "AESVS ", 6) == 0)
- {
- strcpy(algo, "AES");
- /* get test type */
- pp += 6;
- xp = strchr(pp, ' ');
- n = xp-pp;
- strncpy(atest, pp, n);
- atest[n] = '\0';
- /* get mode */
- xp = strrchr(pp, ' '); /* get mode" */
- n = strlen(xp+1)-1;
- strncpy(amode, xp+1, n);
- amode[n] = '\0';
- /* amode[3] = '\0'; */
- if (VERBOSE)
- printf("Test = %s, Mode = %s\n", atest, amode);
- }
- else if (strncasecmp(pp, "Key Length : ", 13) == 0)
- {
- akeysz = atoi(pp+13);
- if (VERBOSE)
- printf("Key size = %d\n", akeysz);
- }
- }
- }
- break;
-
- case 1: /* [ENCRYPT] | [DECRYPT] */
- if (ibuf[0] == '[')
- {
- fputs(ibuf, rfp);
- ++step;
- if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
- dir = 1;
- else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
- dir = 0;
- else
- {
- printf("Invalid keyword: %s\n", ibuf);
- err = 1;
- }
- break;
- }
- else if (dir == -1)
- {
- err = 1;
- printf("Missing ENCRYPT/DECRYPT keyword\n");
- break;
- }
- else
- step = 2;
-
- case 2: /* KEY = xxxx */
- fputs(ibuf, rfp);
- if(*ibuf == '\n')
- break;
- if(!strncasecmp(ibuf,"COUNT = ",8))
- break;
-
- if (strncasecmp(ibuf, "KEY = ", 6) != 0)
- {
- printf("Missing KEY\n");
- err = 1;
- }
- else
- {
- len = hex2bin((char*)ibuf+6, aKey);
- if (len < 0)
- {
- printf("Invalid KEY\n");
- err =1;
- break;
- }
- PrintValue("KEY", aKey, len);
- if (strcmp(amode, "ECB") == 0)
- {
- memset(iVec, 0, sizeof(iVec));
- step = (dir)? 4: 5; /* no ivec for ECB */
- }
- else
- ++step;
- }
- break;
-
- case 3: /* IV = xxxx */
- fputs(ibuf, rfp);
- if (strncasecmp(ibuf, "IV = ", 5) != 0)
- {
- printf("Missing IV\n");
- err = 1;
- }
- else
- {
- len = hex2bin((char*)ibuf+5, iVec);
- if (len < 0)
- {
- printf("Invalid IV\n");
- err =1;
- break;
- }
- PrintValue("IV", iVec, len);
- step = (dir)? 4: 5;
- }
- break;
-
- case 4: /* PLAINTEXT = xxxx */
- fputs(ibuf, rfp);
- if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
- {
- printf("Missing PLAINTEXT\n");
- err = 1;
- }
- else
- {
- int nn = strlen(ibuf+12);
- if(!strcmp(amode,"CFB1"))
- len=bint2bin(ibuf+12,nn-1,plaintext);
- else
- len=hex2bin(ibuf+12, plaintext);
- if (len < 0)
- {
- printf("Invalid PLAINTEXT: %s", ibuf+12);
- err =1;
- break;
- }
- if (len >= (int)sizeof(plaintext))
- {
- printf("Buffer overflow\n");
- }
- PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
- if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */
- {
- if(do_mct(amode, akeysz, aKey, iVec,
- dir, (unsigned char*)plaintext, len,
- rfp) < 0)
- EXIT(1);
- }
- else
- {
- ret = AESTest(&ctx, amode, akeysz, aKey, iVec,
- dir, /* 0 = decrypt, 1 = encrypt */
- plaintext, ciphertext, len);
- OutputValue("CIPHERTEXT",ciphertext,len,rfp,
- !strcmp(amode,"CFB1"));
- }
- step = 6;
- }
- break;
-
- case 5: /* CIPHERTEXT = xxxx */
- fputs(ibuf, rfp);
- if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
- {
- printf("Missing KEY\n");
- err = 1;
- }
- else
- {
- if(!strcmp(amode,"CFB1"))
- len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
- else
- len = hex2bin(ibuf+13,ciphertext);
- if (len < 0)
- {
- printf("Invalid CIPHERTEXT\n");
- err =1;
- break;
- }
-
- PrintValue("CIPHERTEXT", ciphertext, len);
- if (strcmp(atest, "MCT") == 0) /* Monte Carlo Test */
- {
- do_mct(amode, akeysz, aKey, iVec,
- dir, ciphertext, len, rfp);
- }
- else
- {
- ret = AESTest(&ctx, amode, akeysz, aKey, iVec,
- dir, /* 0 = decrypt, 1 = encrypt */
- plaintext, ciphertext, len);
- OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
- !strcmp(amode,"CFB1"));
- }
- step = 6;
- }
- break;
-
- case 6:
- if (ibuf[0] != '\n')
- {
- err = 1;
- printf("Missing terminator\n");
- }
- else if (strcmp(atest, "MCT") != 0)
- { /* MCT already added terminating nl */
- fputs(ibuf, rfp);
- }
- step = 1;
- break;
- }
- }
- if (rfp)
- fclose(rfp);
- if (afp)
- fclose(afp);
- return err;
- }
-
-/*--------------------------------------------------
- Processes either a single file or
- a set of files whose names are passed in a file.
- A single file is specified as:
- aes_test -f xxx.req
- A set of files is specified as:
- aes_test -d xxxxx.xxx
- The default is: -d req.txt
---------------------------------------------------*/
-int main(int argc, char **argv)
- {
- char *rqlist = "req.txt", *rspfile = NULL;
- FILE *fp = NULL;
- char fn[250] = "", rfn[256] = "";
- int f_opt = 0, d_opt = 1;
-
-#ifdef OPENSSL_FIPS
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- EXIT(1);
- }
-#endif
- if (argc > 1)
- {
- if (strcasecmp(argv[1], "-d") == 0)
- {
- d_opt = 1;
- }
- else if (strcasecmp(argv[1], "-f") == 0)
- {
- f_opt = 1;
- d_opt = 0;
- }
- else
- {
- printf("Invalid parameter: %s\n", argv[1]);
- return 0;
- }
- if (argc < 3)
- {
- printf("Missing parameter\n");
- return 0;
- }
- if (d_opt)
- rqlist = argv[2];
- else
- {
- strcpy(fn, argv[2]);
- rspfile = argv[3];
- }
- }
- if (d_opt)
- { /* list of files (directory) */
- if (!(fp = fopen(rqlist, "r")))
- {
- printf("Cannot open req list file\n");
- return -1;
- }
- while (fgets(fn, sizeof(fn), fp))
- {
- strtok(fn, "\r\n");
- strcpy(rfn, fn);
- if (VERBOSE)
- printf("Processing: %s\n", rfn);
- if (proc_file(rfn, rspfile))
- {
- printf(">>> Processing failed for: %s <<<\n", rfn);
- EXIT(1);
- }
- }
- fclose(fp);
- }
- else /* single file */
- {
- if (VERBOSE)
- printf("Processing: %s\n", fn);
- if (proc_file(fn, rspfile))
- {
- printf(">>> Processing failed for: %s <<<\n", fn);
- }
- }
- EXIT(0);
- return 0;
- }
-
-#endif
diff --git a/crypto/openssl/fips/des/Makefile b/crypto/openssl/fips/des/Makefile
deleted file mode 100644
index ba1d095..0000000
--- a/crypto/openssl/fips/des/Makefile
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# OpenSSL/fips/des/Makefile
-#
-
-DIR= des
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= fips_desmovs.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_des_selftest.c
-LIBOBJ=fips_des_selftest.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=
-HEADER=
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-fips_test:
- -find ../testvectors/tdes/req -name '*.req' > testlist
- -rm -rf ../testvectors/tdes/rsp
- mkdir ../testvectors/tdes/rsp
- if [ -s testlist ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_desmovs -d testlist; fi
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) \
- $(SRC) $(TEST)
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff testlist
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_des_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_des_selftest.o: ../../include/openssl/crypto.h
-fips_des_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_des_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_des_selftest.o: ../../include/openssl/lhash.h
-fips_des_selftest.o: ../../include/openssl/obj_mac.h
-fips_des_selftest.o: ../../include/openssl/objects.h
-fips_des_selftest.o: ../../include/openssl/opensslconf.h
-fips_des_selftest.o: ../../include/openssl/opensslv.h
-fips_des_selftest.o: ../../include/openssl/ossl_typ.h
-fips_des_selftest.o: ../../include/openssl/safestack.h
-fips_des_selftest.o: ../../include/openssl/stack.h
-fips_des_selftest.o: ../../include/openssl/symhacks.h fips_des_selftest.c
-fips_desmovs.o: ../../e_os.h ../../include/openssl/asn1.h
-fips_desmovs.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_desmovs.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
-fips_desmovs.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
-fips_desmovs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_desmovs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_desmovs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-fips_desmovs.o: ../../include/openssl/opensslconf.h
-fips_desmovs.o: ../../include/openssl/opensslv.h
-fips_desmovs.o: ../../include/openssl/ossl_typ.h
-fips_desmovs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_desmovs.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-fips_desmovs.o: ../../include/openssl/ui_compat.h ../fips_utl.h fips_desmovs.c
diff --git a/crypto/openssl/fips/des/fips_des_selftest.c b/crypto/openssl/fips/des/fips_des_selftest.c
deleted file mode 100644
index 61c39ce..0000000
--- a/crypto/openssl/fips/des/fips_des_selftest.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-#include <openssl/evp.h>
-#include <openssl/opensslconf.h>
-
-#ifdef OPENSSL_FIPS
-
-static struct
- {
- unsigned char key[16];
- unsigned char plaintext[8];
- unsigned char ciphertext[8];
- } tests2[]=
- {
- {
- { 0x7c,0x4f,0x6e,0xf7,0xa2,0x04,0x16,0xec,
- 0x0b,0x6b,0x7c,0x9e,0x5e,0x19,0xa7,0xc4 },
- { 0x06,0xa7,0xd8,0x79,0xaa,0xce,0x69,0xef },
- { 0x4c,0x11,0x17,0x55,0xbf,0xc4,0x4e,0xfd }
- },
- {
- { 0x5d,0x9e,0x01,0xd3,0x25,0xc7,0x3e,0x34,
- 0x01,0x16,0x7c,0x85,0x23,0xdf,0xe0,0x68 },
- { 0x9c,0x50,0x09,0x0f,0x5e,0x7d,0x69,0x7e },
- { 0xd2,0x0b,0x18,0xdf,0xd9,0x0d,0x9e,0xff },
- }
- };
-
-static struct
- {
- unsigned char key[24];
- unsigned char plaintext[8];
- unsigned char ciphertext[8];
- } tests3[]=
- {
- {
- { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,
- 0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0 },
- { 0x8f,0x8f,0xbf,0x9b,0x5d,0x48,0xb4,0x1c },
- { 0x59,0x8c,0xe5,0xd3,0x6c,0xa2,0xea,0x1b },
- },
- {
- { 0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,0xFE,
- 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
- 0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4 },
- { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
- { 0x11,0x25,0xb0,0x35,0xbe,0xa0,0x82,0x86 },
- },
- };
-
-void FIPS_corrupt_des()
- {
- tests2[0].plaintext[0]++;
- }
-
-int FIPS_selftest_des()
- {
- int n, ret = 0;
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
- /* Encrypt/decrypt with 2-key 3DES and compare to known answers */
- for(n=0 ; n < 2 ; ++n)
- {
- if (!fips_cipher_test(&ctx, EVP_des_ede_ecb(),
- tests2[n].key, NULL,
- tests2[n].plaintext, tests2[n].ciphertext, 8))
- goto err;
- }
-
- /* Encrypt/decrypt with 3DES and compare to known answers */
- for(n=0 ; n < 2 ; ++n)
- {
- if (!fips_cipher_test(&ctx, EVP_des_ede3_ecb(),
- tests3[n].key, NULL,
- tests3[n].plaintext, tests3[n].ciphertext, 8))
- goto err;
- }
- ret = 1;
- err:
- EVP_CIPHER_CTX_cleanup(&ctx);
- if (ret == 0)
- FIPSerr(FIPS_F_FIPS_SELFTEST_DES,FIPS_R_SELFTEST_FAILED);
-
- return ret;
- }
-#endif
diff --git a/crypto/openssl/fips/des/fips_desmovs.c b/crypto/openssl/fips/des/fips_desmovs.c
deleted file mode 100644
index f96a5ca..0000000
--- a/crypto/openssl/fips/des/fips_desmovs.c
+++ /dev/null
@@ -1,702 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2004 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.
- *
- */
-/*---------------------------------------------
- NIST DES Modes of Operation Validation System
- Test Program
-
- Based on the AES Validation Suite, which was:
- Donated to OpenSSL by:
- V-ONE Corporation
- 20250 Century Blvd, Suite 300
- Germantown, MD 20874
- U.S.A.
- ----------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <ctype.h>
-#include <openssl/des.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-
-#include <openssl/err.h>
-#include "e_os.h"
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS DES support\n");
- return(0);
-}
-
-#else
-
-#include <openssl/fips.h>
-#include "fips_utl.h"
-
-#define DES_BLOCK_SIZE 8
-
-#define VERBOSE 0
-
-static int DESTest(EVP_CIPHER_CTX *ctx,
- char *amode, int akeysz, unsigned char *aKey,
- unsigned char *iVec,
- int dir, /* 0 = decrypt, 1 = encrypt */
- unsigned char *out, unsigned char *in, int len)
- {
- const EVP_CIPHER *cipher = NULL;
-
- if (akeysz != 192)
- {
- printf("Invalid key size: %d\n", akeysz);
- EXIT(1);
- }
-
- if (strcasecmp(amode, "CBC") == 0)
- cipher = EVP_des_ede3_cbc();
- else if (strcasecmp(amode, "ECB") == 0)
- cipher = EVP_des_ede3_ecb();
- else if (strcasecmp(amode, "CFB64") == 0)
- cipher = EVP_des_ede3_cfb64();
- else if (strncasecmp(amode, "OFB", 3) == 0)
- cipher = EVP_des_ede3_ofb();
- else if(!strcasecmp(amode,"CFB8"))
- cipher = EVP_des_ede3_cfb8();
- else if(!strcasecmp(amode,"CFB1"))
- cipher = EVP_des_ede3_cfb1();
- else
- {
- printf("Unknown mode: %s\n", amode);
- EXIT(1);
- }
-
- if (EVP_CipherInit_ex(ctx, cipher, NULL, aKey, iVec, dir) <= 0)
- return 0;
- if(!strcasecmp(amode,"CFB1"))
- M_EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS);
- EVP_Cipher(ctx, out, in, len);
-
- return 1;
- }
-#if 0
-static void DebugValue(char *tag, unsigned char *val, int len)
- {
- char obuf[2048];
- int olen;
- olen = bin2hex(val, len, obuf);
- printf("%s = %.*s\n", tag, olen, obuf);
- }
-#endif
-static void shiftin(unsigned char *dst,unsigned char *src,int nbits)
- {
- int n;
-
- /* move the bytes... */
- memmove(dst,dst+nbits/8,3*8-nbits/8);
- /* append new data */
- memcpy(dst+3*8-nbits/8,src,(nbits+7)/8);
- /* left shift the bits */
- if(nbits%8)
- for(n=0 ; n < 3*8 ; ++n)
- dst[n]=(dst[n] << (nbits%8))|(dst[n+1] >> (8-nbits%8));
- }
-
-/*-----------------------------------------------*/
-char *t_tag[2] = {"PLAINTEXT", "CIPHERTEXT"};
-char *t_mode[6] = {"CBC","ECB","OFB","CFB1","CFB8","CFB64"};
-enum Mode {CBC, ECB, OFB, CFB1, CFB8, CFB64};
-int Sizes[6]={64,64,64,1,8,64};
-
-static void do_mct(char *amode,
- int akeysz, int numkeys, unsigned char *akey,unsigned char *ivec,
- int dir, unsigned char *text, int len,
- FILE *rfp)
- {
- int i,imode;
- unsigned char nk[4*8]; /* longest key+8 */
- unsigned char text0[8];
-
- for (imode=0 ; imode < 6 ; ++imode)
- if(!strcmp(amode,t_mode[imode]))
- break;
- if (imode == 6)
- {
- printf("Unrecognized mode: %s\n", amode);
- EXIT(1);
- }
-
- for(i=0 ; i < 400 ; ++i)
- {
- int j;
- int n;
- int kp=akeysz/64;
- unsigned char old_iv[8];
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
-
- fprintf(rfp,"\nCOUNT = %d\n",i);
- if(kp == 1)
- OutputValue("KEY",akey,8,rfp,0);
- else
- for(n=0 ; n < kp ; ++n)
- {
- fprintf(rfp,"KEY%d",n+1);
- OutputValue("",akey+n*8,8,rfp,0);
- }
-
- if(imode != ECB)
- OutputValue("IV",ivec,8,rfp,0);
- OutputValue(t_tag[dir^1],text,len,rfp,imode == CFB1);
-#if 0
- /* compensate for endianness */
- if(imode == CFB1)
- text[0]<<=7;
-#endif
- memcpy(text0,text,8);
-
- for(j=0 ; j < 10000 ; ++j)
- {
- unsigned char old_text[8];
-
- memcpy(old_text,text,8);
- if(j == 0)
- {
- memcpy(old_iv,ivec,8);
- DESTest(&ctx,amode,akeysz,akey,ivec,dir,text,text,len);
- }
- else
- {
- memcpy(old_iv,ctx.iv,8);
- EVP_Cipher(&ctx,text,text,len);
- }
- if(j == 9999)
- {
- OutputValue(t_tag[dir],text,len,rfp,imode == CFB1);
- /* memcpy(ivec,text,8); */
- }
- /* DebugValue("iv",ctx.iv,8); */
- /* accumulate material for the next key */
- shiftin(nk,text,Sizes[imode]);
- /* DebugValue("nk",nk,24);*/
- if((dir && (imode == CFB1 || imode == CFB8 || imode == CFB64
- || imode == CBC)) || imode == OFB)
- memcpy(text,old_iv,8);
-
- if(!dir && (imode == CFB1 || imode == CFB8 || imode == CFB64))
- {
- /* the test specifies using the output of the raw DES operation
- which we don't have, so reconstruct it... */
- for(n=0 ; n < 8 ; ++n)
- text[n]^=old_text[n];
- }
- }
- for(n=0 ; n < 8 ; ++n)
- akey[n]^=nk[16+n];
- for(n=0 ; n < 8 ; ++n)
- akey[8+n]^=nk[8+n];
- for(n=0 ; n < 8 ; ++n)
- akey[16+n]^=nk[n];
- if(numkeys < 3)
- memcpy(&akey[2*8],akey,8);
- if(numkeys < 2)
- memcpy(&akey[8],akey,8);
- DES_set_odd_parity((DES_cblock *)akey);
- DES_set_odd_parity((DES_cblock *)(akey+8));
- DES_set_odd_parity((DES_cblock *)(akey+16));
- memcpy(ivec,ctx.iv,8);
-
- /* pointless exercise - the final text doesn't depend on the
- initial text in OFB mode, so who cares what it is? (Who
- designed these tests?) */
- if(imode == OFB)
- for(n=0 ; n < 8 ; ++n)
- text[n]=text0[n]^old_iv[n];
- }
- }
-
-static int proc_file(char *rqfile, char *rspfile)
- {
- char afn[256], rfn[256];
- FILE *afp = NULL, *rfp = NULL;
- char ibuf[2048], tbuf[2048];
- int ilen, len, ret = 0;
- char amode[8] = "";
- char atest[100] = "";
- int akeysz=0;
- unsigned char iVec[20], aKey[40];
- int dir = -1, err = 0, step = 0;
- unsigned char plaintext[2048];
- unsigned char ciphertext[2048];
- char *rp;
- EVP_CIPHER_CTX ctx;
- int numkeys=1;
- EVP_CIPHER_CTX_init(&ctx);
-
- if (!rqfile || !(*rqfile))
- {
- printf("No req file\n");
- return -1;
- }
- strcpy(afn, rqfile);
-
- if ((afp = fopen(afn, "r")) == NULL)
- {
- printf("Cannot open file: %s, %s\n",
- afn, strerror(errno));
- return -1;
- }
- if (!rspfile)
- {
- strcpy(rfn,afn);
- rp=strstr(rfn,"req/");
-#ifdef OPENSSL_SYS_WIN32
- if (!rp)
- rp=strstr(rfn,"req\\");
-#endif
- assert(rp);
- memcpy(rp,"rsp",3);
- rp = strstr(rfn, ".req");
- memcpy(rp, ".rsp", 4);
- rspfile = rfn;
- }
- if ((rfp = fopen(rspfile, "w")) == NULL)
- {
- printf("Cannot open file: %s, %s\n",
- rfn, strerror(errno));
- fclose(afp);
- afp = NULL;
- return -1;
- }
- while (!err && (fgets(ibuf, sizeof(ibuf), afp)) != NULL)
- {
- tidy_line(tbuf, ibuf);
- ilen = strlen(ibuf);
- /* printf("step=%d ibuf=%s",step,ibuf);*/
- if(step == 3 && !strcmp(amode,"ECB"))
- {
- memset(iVec, 0, sizeof(iVec));
- step = (dir)? 4: 5; /* no ivec for ECB */
- }
- switch (step)
- {
- case 0: /* read preamble */
- if (ibuf[0] == '\n')
- { /* end of preamble */
- if (*amode == '\0')
- {
- printf("Missing Mode\n");
- err = 1;
- }
- else
- {
- fputs(ibuf, rfp);
- ++ step;
- }
- }
- else if (ibuf[0] != '#')
- {
- printf("Invalid preamble item: %s\n", ibuf);
- err = 1;
- }
- else
- { /* process preamble */
- char *xp, *pp = ibuf+2;
- int n;
- if(*amode)
- { /* insert current time & date */
- time_t rtim = time(0);
- fprintf(rfp, "# %s", ctime(&rtim));
- }
- else
- {
- fputs(ibuf, rfp);
- if(!strncmp(pp,"INVERSE ",8) || !strncmp(pp,"DES ",4)
- || !strncmp(pp,"TDES ",5)
- || !strncmp(pp,"PERMUTATION ",12)
- || !strncmp(pp,"SUBSTITUTION ",13)
- || !strncmp(pp,"VARIABLE ",9))
- {
- /* get test type */
- if(!strncmp(pp,"DES ",4))
- pp+=4;
- else if(!strncmp(pp,"TDES ",5))
- pp+=5;
- xp = strchr(pp, ' ');
- n = xp-pp;
- strncpy(atest, pp, n);
- atest[n] = '\0';
- /* get mode */
- xp = strrchr(pp, ' '); /* get mode" */
- n = strlen(xp+1)-1;
- strncpy(amode, xp+1, n);
- amode[n] = '\0';
- /* amode[3] = '\0'; */
- if (VERBOSE)
- printf("Test=%s, Mode=%s\n",atest,amode);
- }
- }
- }
- break;
-
- case 1: /* [ENCRYPT] | [DECRYPT] */
- if(ibuf[0] == '\n')
- break;
- if (ibuf[0] == '[')
- {
- fputs(ibuf, rfp);
- ++step;
- if (strncasecmp(ibuf, "[ENCRYPT]", 9) == 0)
- dir = 1;
- else if (strncasecmp(ibuf, "[DECRYPT]", 9) == 0)
- dir = 0;
- else
- {
- printf("Invalid keyword: %s\n", ibuf);
- err = 1;
- }
- break;
- }
- else if (dir == -1)
- {
- err = 1;
- printf("Missing ENCRYPT/DECRYPT keyword\n");
- break;
- }
- else
- step = 2;
-
- case 2: /* KEY = xxxx */
- if(*ibuf == '\n')
- {
- fputs(ibuf, rfp);
- break;
- }
- if(!strncasecmp(ibuf,"COUNT = ",8))
- {
- fputs(ibuf, rfp);
- break;
- }
- if(!strncasecmp(ibuf,"COUNT=",6))
- {
- fputs(ibuf, rfp);
- break;
- }
- if(!strncasecmp(ibuf,"NumKeys = ",10))
- {
- numkeys=atoi(ibuf+10);
- break;
- }
-
- fputs(ibuf, rfp);
- if(!strncasecmp(ibuf,"KEY = ",6))
- {
- akeysz=64;
- len = hex2bin((char*)ibuf+6, aKey);
- if (len < 0)
- {
- printf("Invalid KEY\n");
- err=1;
- break;
- }
- PrintValue("KEY", aKey, len);
- ++step;
- }
- else if(!strncasecmp(ibuf,"KEYs = ",7))
- {
- akeysz=64*3;
- len=hex2bin(ibuf+7,aKey);
- if(len != 8)
- {
- printf("Invalid KEY\n");
- err=1;
- break;
- }
- memcpy(aKey+8,aKey,8);
- memcpy(aKey+16,aKey,8);
- ibuf[4]='\0';
- PrintValue("KEYs",aKey,len);
- ++step;
- }
- else if(!strncasecmp(ibuf,"KEY",3))
- {
- int n=ibuf[3]-'1';
-
- akeysz=64*3;
- len=hex2bin(ibuf+7,aKey+n*8);
- if(len != 8)
- {
- printf("Invalid KEY\n");
- err=1;
- break;
- }
- ibuf[4]='\0';
- PrintValue(ibuf,aKey,len);
- if(n == 2)
- ++step;
- }
- else
- {
- printf("Missing KEY\n");
- err = 1;
- }
- break;
-
- case 3: /* IV = xxxx */
- fputs(ibuf, rfp);
- if (strncasecmp(ibuf, "IV = ", 5) != 0)
- {
- printf("Missing IV\n");
- err = 1;
- }
- else
- {
- len = hex2bin((char*)ibuf+5, iVec);
- if (len < 0)
- {
- printf("Invalid IV\n");
- err =1;
- break;
- }
- PrintValue("IV", iVec, len);
- step = (dir)? 4: 5;
- }
- break;
-
- case 4: /* PLAINTEXT = xxxx */
- fputs(ibuf, rfp);
- if (strncasecmp(ibuf, "PLAINTEXT = ", 12) != 0)
- {
- printf("Missing PLAINTEXT\n");
- err = 1;
- }
- else
- {
- int nn = strlen(ibuf+12);
- if(!strcmp(amode,"CFB1"))
- len=bint2bin(ibuf+12,nn-1,plaintext);
- else
- len=hex2bin(ibuf+12, plaintext);
- if (len < 0)
- {
- printf("Invalid PLAINTEXT: %s", ibuf+12);
- err =1;
- break;
- }
- if (len >= (int)sizeof(plaintext))
- {
- printf("Buffer overflow\n");
- }
- PrintValue("PLAINTEXT", (unsigned char*)plaintext, len);
- if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */
- {
- do_mct(amode,akeysz,numkeys,aKey,iVec,dir,plaintext,len,rfp);
- }
- else
- {
- assert(dir == 1);
- ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
- dir, /* 0 = decrypt, 1 = encrypt */
- ciphertext, plaintext, len);
- OutputValue("CIPHERTEXT",ciphertext,len,rfp,
- !strcmp(amode,"CFB1"));
- }
- step = 6;
- }
- break;
-
- case 5: /* CIPHERTEXT = xxxx */
- fputs(ibuf, rfp);
- if (strncasecmp(ibuf, "CIPHERTEXT = ", 13) != 0)
- {
- printf("Missing KEY\n");
- err = 1;
- }
- else
- {
- if(!strcmp(amode,"CFB1"))
- len=bint2bin(ibuf+13,strlen(ibuf+13)-1,ciphertext);
- else
- len = hex2bin(ibuf+13,ciphertext);
- if (len < 0)
- {
- printf("Invalid CIPHERTEXT\n");
- err =1;
- break;
- }
-
- PrintValue("CIPHERTEXT", ciphertext, len);
- if (strcmp(atest, "Monte") == 0) /* Monte Carlo Test */
- {
- do_mct(amode, akeysz, numkeys, aKey, iVec,
- dir, ciphertext, len, rfp);
- }
- else
- {
- assert(dir == 0);
- ret = DESTest(&ctx, amode, akeysz, aKey, iVec,
- dir, /* 0 = decrypt, 1 = encrypt */
- plaintext, ciphertext, len);
- OutputValue("PLAINTEXT",(unsigned char *)plaintext,len,rfp,
- !strcmp(amode,"CFB1"));
- }
- step = 6;
- }
- break;
-
- case 6:
- if (ibuf[0] != '\n')
- {
- err = 1;
- printf("Missing terminator\n");
- }
- else if (strcmp(atest, "MCT") != 0)
- { /* MCT already added terminating nl */
- fputs(ibuf, rfp);
- }
- step = 1;
- break;
- }
- }
- if (rfp)
- fclose(rfp);
- if (afp)
- fclose(afp);
- return err;
- }
-
-/*--------------------------------------------------
- Processes either a single file or
- a set of files whose names are passed in a file.
- A single file is specified as:
- aes_test -f xxx.req
- A set of files is specified as:
- aes_test -d xxxxx.xxx
- The default is: -d req.txt
---------------------------------------------------*/
-int main(int argc, char **argv)
- {
- char *rqlist = "req.txt", *rspfile = NULL;
- FILE *fp = NULL;
- char fn[250] = "", rfn[256] = "";
- int f_opt = 0, d_opt = 1;
-
-#ifdef OPENSSL_FIPS
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- EXIT(1);
- }
-#endif
- if (argc > 1)
- {
- if (strcasecmp(argv[1], "-d") == 0)
- {
- d_opt = 1;
- }
- else if (strcasecmp(argv[1], "-f") == 0)
- {
- f_opt = 1;
- d_opt = 0;
- }
- else
- {
- printf("Invalid parameter: %s\n", argv[1]);
- return 0;
- }
- if (argc < 3)
- {
- printf("Missing parameter\n");
- return 0;
- }
- if (d_opt)
- rqlist = argv[2];
- else
- {
- strcpy(fn, argv[2]);
- rspfile = argv[3];
- }
- }
- if (d_opt)
- { /* list of files (directory) */
- if (!(fp = fopen(rqlist, "r")))
- {
- printf("Cannot open req list file\n");
- return -1;
- }
- while (fgets(fn, sizeof(fn), fp))
- {
- strtok(fn, "\r\n");
- strcpy(rfn, fn);
- printf("Processing: %s\n", rfn);
- if (proc_file(rfn, rspfile))
- {
- printf(">>> Processing failed for: %s <<<\n", rfn);
- EXIT(1);
- }
- }
- fclose(fp);
- }
- else /* single file */
- {
- if (VERBOSE)
- printf("Processing: %s\n", fn);
- if (proc_file(fn, rspfile))
- {
- printf(">>> Processing failed for: %s <<<\n", fn);
- }
- }
- EXIT(0);
- return 0;
- }
-
-#endif
diff --git a/crypto/openssl/fips/dh/Makefile b/crypto/openssl/fips/dh/Makefile
deleted file mode 100644
index 2d3833a..0000000
--- a/crypto/openssl/fips/dh/Makefile
+++ /dev/null
@@ -1,115 +0,0 @@
-#
-# OpenSSL/fips/dh/Makefile
-#
-
-DIR= dh
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_dh_check.c fips_dh_gen.c fips_dh_key.c fips_dh_lib.c
-LIBOBJ=fips_dh_check.o fips_dh_gen.o fips_dh_key.o fips_dh_lib.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=
-HEADER= $(EXHEADER)
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-fips_test:
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_dh_check.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_dh_check.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-fips_dh_check.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_dh_check.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dh_check.o: ../../include/openssl/opensslconf.h
-fips_dh_check.o: ../../include/openssl/opensslv.h
-fips_dh_check.o: ../../include/openssl/ossl_typ.h
-fips_dh_check.o: ../../include/openssl/safestack.h
-fips_dh_check.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_dh_check.o: fips_dh_check.c
-fips_dh_gen.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_dh_gen.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-fips_dh_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_dh_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dh_gen.o: ../../include/openssl/opensslconf.h
-fips_dh_gen.o: ../../include/openssl/opensslv.h
-fips_dh_gen.o: ../../include/openssl/ossl_typ.h
-fips_dh_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_dh_gen.o: ../../include/openssl/symhacks.h fips_dh_gen.c
-fips_dh_key.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_dh_key.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-fips_dh_key.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_dh_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dh_key.o: ../../include/openssl/opensslconf.h
-fips_dh_key.o: ../../include/openssl/opensslv.h
-fips_dh_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-fips_dh_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_dh_key.o: ../../include/openssl/symhacks.h fips_dh_key.c
-fips_dh_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_dh_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
-fips_dh_lib.o: ../../include/openssl/e_os2.h
-fips_dh_lib.o: ../../include/openssl/opensslconf.h
-fips_dh_lib.o: ../../include/openssl/opensslv.h
-fips_dh_lib.o: ../../include/openssl/ossl_typ.h
-fips_dh_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_dh_lib.o: ../../include/openssl/symhacks.h fips_dh_lib.c
diff --git a/crypto/openssl/fips/dh/dh_gen.c b/crypto/openssl/fips/dh/dh_gen.c
deleted file mode 100644
index 999e1de..0000000
--- a/crypto/openssl/fips/dh/dh_gen.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* crypto/dh/dh_gen.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.]
- */
-
-/* NB: These functions have been upgraded - the previous prototypes are in
- * dh_depr.c as wrappers to these ones.
- * - Geoff
- */
-
-#include <stdio.h>
-#include "cryptlib.h"
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-
-#ifndef OPENSSL_FIPS
-
-static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
-
-int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
- {
- if(ret->meth->generate_params)
- return ret->meth->generate_params(ret, prime_len, generator, cb);
- return dh_builtin_genparams(ret, prime_len, generator, cb);
- }
-
-/* We generate DH parameters as follows
- * find a prime q which is prime_len/2 bits long.
- * p=(2*q)+1 or (p-1)/2 = q
- * For this case, g is a generator if
- * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
- * Since the factors of p-1 are q and 2, we just need to check
- * g^2 mod p != 1 and g^q mod p != 1.
- *
- * Having said all that,
- * there is another special case method for the generators 2, 3 and 5.
- * for 2, p mod 24 == 11
- * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
- * for 5, p mod 10 == 3 or 7
- *
- * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
- * special generators and for answering some of my questions.
- *
- * I've implemented the second simple method :-).
- * Since DH should be using a safe prime (both p and q are prime),
- * this generator function can take a very very long time to run.
- */
-/* Actually there is no reason to insist that 'generator' be a generator.
- * It's just as OK (and in some sense better) to use a generator of the
- * order-q subgroup.
- */
-static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
- {
- BIGNUM *t1,*t2;
- int g,ok= -1;
- BN_CTX *ctx=NULL;
-
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
- BN_CTX_start(ctx);
- t1 = BN_CTX_get(ctx);
- t2 = BN_CTX_get(ctx);
- if (t1 == NULL || t2 == NULL) goto err;
-
- /* Make sure 'ret' has the necessary elements */
- if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
- if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
-
- if (generator <= 1)
- {
- DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
- goto err;
- }
- if (generator == DH_GENERATOR_2)
- {
- if (!BN_set_word(t1,24)) goto err;
- if (!BN_set_word(t2,11)) goto err;
- g=2;
- }
-#if 0 /* does not work for safe primes */
- else if (generator == DH_GENERATOR_3)
- {
- if (!BN_set_word(t1,12)) goto err;
- if (!BN_set_word(t2,5)) goto err;
- g=3;
- }
-#endif
- else if (generator == DH_GENERATOR_5)
- {
- if (!BN_set_word(t1,10)) goto err;
- if (!BN_set_word(t2,3)) goto err;
- /* BN_set_word(t3,7); just have to miss
- * out on these ones :-( */
- g=5;
- }
- else
- {
- /* in the general case, don't worry if 'generator' is a
- * generator or not: since we are using safe primes,
- * it will generate either an order-q or an order-2q group,
- * which both is OK */
- if (!BN_set_word(t1,2)) goto err;
- if (!BN_set_word(t2,1)) goto err;
- g=generator;
- }
-
- if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
- if(!BN_GENCB_call(cb, 3, 0)) goto err;
- if (!BN_set_word(ret->g,g)) goto err;
- ok=1;
-err:
- if (ok == -1)
- {
- DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
- ok=0;
- }
-
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- return ok;
- }
-
-#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_check.c b/crypto/openssl/fips/dh/fips_dh_check.c
deleted file mode 100644
index 7333f7c..0000000
--- a/crypto/openssl/fips/dh/fips_dh_check.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/* crypto/dh/dh_check.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 <stdio.h>
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-
-/* Check that p is a safe prime and
- * if g is 2, 3 or 5, check that is is a suitable generator
- * where
- * for 2, p mod 24 == 11
- * for 3, p mod 12 == 5
- * for 5, p mod 10 == 3 or 7
- * should hold.
- */
-
-#ifdef OPENSSL_FIPS
-
-int DH_check(const DH *dh, int *ret)
- {
- int ok=0;
- BN_CTX *ctx=NULL;
- BN_ULONG l;
- BIGNUM *q=NULL;
-
- *ret=0;
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
- q=BN_new();
- if (q == NULL) goto err;
-
- if (BN_is_word(dh->g,DH_GENERATOR_2))
- {
- l=BN_mod_word(dh->p,24);
- if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR;
- }
-#if 0
- else if (BN_is_word(dh->g,DH_GENERATOR_3))
- {
- l=BN_mod_word(dh->p,12);
- if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR;
- }
-#endif
- else if (BN_is_word(dh->g,DH_GENERATOR_5))
- {
- l=BN_mod_word(dh->p,10);
- if ((l != 3) && (l != 7))
- *ret|=DH_NOT_SUITABLE_GENERATOR;
- }
- else
- *ret|=DH_UNABLE_TO_CHECK_GENERATOR;
-
- if (!BN_is_prime_ex(dh->p,BN_prime_checks,ctx,NULL))
- *ret|=DH_CHECK_P_NOT_PRIME;
- else
- {
- if (!BN_rshift1(q,dh->p)) goto err;
- if (!BN_is_prime_ex(q,BN_prime_checks,ctx,NULL))
- *ret|=DH_CHECK_P_NOT_SAFE_PRIME;
- }
- ok=1;
-err:
- if (ctx != NULL) BN_CTX_free(ctx);
- if (q != NULL) BN_free(q);
- return(ok);
- }
-
-int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
- {
- int ok=0;
- BIGNUM *q=NULL;
-
- *ret=0;
- q=BN_new();
- if (q == NULL) goto err;
- BN_set_word(q,1);
- if (BN_cmp(pub_key,q) <= 0)
- *ret|=DH_CHECK_PUBKEY_TOO_SMALL;
- BN_copy(q,dh->p);
- BN_sub_word(q,1);
- if (BN_cmp(pub_key,q) >= 0)
- *ret|=DH_CHECK_PUBKEY_TOO_LARGE;
-
- ok = 1;
-err:
- if (q != NULL) BN_free(q);
- return(ok);
- }
-
-#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_gen.c b/crypto/openssl/fips/dh/fips_dh_gen.c
deleted file mode 100644
index d115f9d..0000000
--- a/crypto/openssl/fips/dh/fips_dh_gen.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* crypto/dh/dh_gen.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.]
- */
-
-/* NB: These functions have been upgraded - the previous prototypes are in
- * dh_depr.c as wrappers to these ones.
- * - Geoff
- */
-
-#include <stdio.h>
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-
-#ifdef OPENSSL_FIPS
-
-static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
-
-int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, BN_GENCB *cb)
- {
- if(ret->meth->generate_params)
- return ret->meth->generate_params(ret, prime_len, generator, cb);
- return dh_builtin_genparams(ret, prime_len, generator, cb);
- }
-
-/* We generate DH parameters as follows
- * find a prime q which is prime_len/2 bits long.
- * p=(2*q)+1 or (p-1)/2 = q
- * For this case, g is a generator if
- * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1.
- * Since the factors of p-1 are q and 2, we just need to check
- * g^2 mod p != 1 and g^q mod p != 1.
- *
- * Having said all that,
- * there is another special case method for the generators 2, 3 and 5.
- * for 2, p mod 24 == 11
- * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
- * for 5, p mod 10 == 3 or 7
- *
- * Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
- * special generators and for answering some of my questions.
- *
- * I've implemented the second simple method :-).
- * Since DH should be using a safe prime (both p and q are prime),
- * this generator function can take a very very long time to run.
- */
-/* Actually there is no reason to insist that 'generator' be a generator.
- * It's just as OK (and in some sense better) to use a generator of the
- * order-q subgroup.
- */
-static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb)
- {
- BIGNUM *t1,*t2;
- int g,ok= -1;
- BN_CTX *ctx=NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED);
- return 0;
- }
-
- if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
- {
- DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
-
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
- BN_CTX_start(ctx);
- t1 = BN_CTX_get(ctx);
- t2 = BN_CTX_get(ctx);
- if (t1 == NULL || t2 == NULL) goto err;
-
- /* Make sure 'ret' has the necessary elements */
- if(!ret->p && ((ret->p = BN_new()) == NULL)) goto err;
- if(!ret->g && ((ret->g = BN_new()) == NULL)) goto err;
-
- if (generator <= 1)
- {
- DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR);
- goto err;
- }
- if (generator == DH_GENERATOR_2)
- {
- if (!BN_set_word(t1,24)) goto err;
- if (!BN_set_word(t2,11)) goto err;
- g=2;
- }
-#if 0 /* does not work for safe primes */
- else if (generator == DH_GENERATOR_3)
- {
- if (!BN_set_word(t1,12)) goto err;
- if (!BN_set_word(t2,5)) goto err;
- g=3;
- }
-#endif
- else if (generator == DH_GENERATOR_5)
- {
- if (!BN_set_word(t1,10)) goto err;
- if (!BN_set_word(t2,3)) goto err;
- /* BN_set_word(t3,7); just have to miss
- * out on these ones :-( */
- g=5;
- }
- else
- {
- /* in the general case, don't worry if 'generator' is a
- * generator or not: since we are using safe primes,
- * it will generate either an order-q or an order-2q group,
- * which both is OK */
- if (!BN_set_word(t1,2)) goto err;
- if (!BN_set_word(t2,1)) goto err;
- g=generator;
- }
-
- if(!BN_generate_prime_ex(ret->p,prime_len,1,t1,t2,cb)) goto err;
- if(!BN_GENCB_call(cb, 3, 0)) goto err;
- if (!BN_set_word(ret->g,g)) goto err;
- ok=1;
-err:
- if (ok == -1)
- {
- DHerr(DH_F_DH_BUILTIN_GENPARAMS,ERR_R_BN_LIB);
- ok=0;
- }
-
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- return ok;
- }
-
-#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_key.c b/crypto/openssl/fips/dh/fips_dh_key.c
deleted file mode 100644
index d20fa91..0000000
--- a/crypto/openssl/fips/dh/fips_dh_key.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* crypto/dh/dh_key.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 <stdio.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#ifndef OPENSSL_NO_RAND
-#include <openssl/rand.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#include <openssl/fips.h>
-
-#ifdef OPENSSL_FIPS
-
-static int generate_key(DH *dh);
-static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
-static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
- const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx);
-static int dh_init(DH *dh);
-static int dh_finish(DH *dh);
-
-int DH_generate_key(DH *dh)
- {
- return dh->meth->generate_key(dh);
- }
-
-int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
- {
- return dh->meth->compute_key(key, pub_key, dh);
- }
-
-static const DH_METHOD dh_ossl = {
-"OpenSSL DH Method",
-generate_key,
-compute_key,
-dh_bn_mod_exp,
-dh_init,
-dh_finish,
-0,
-NULL
-};
-
-const DH_METHOD *DH_OpenSSL(void)
-{
- return &dh_ossl;
-}
-
-static int generate_key(DH *dh)
- {
- int ok=0;
- int generate_new_key=0;
- unsigned l;
- BN_CTX *ctx;
- BN_MONT_CTX *mont=NULL;
- BIGNUM *pub_key=NULL,*priv_key=NULL;
-
- if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
- {
- DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
- return 0;
- }
-
- ctx = BN_CTX_new();
- if (ctx == NULL) goto err;
-
- if (dh->priv_key == NULL)
- {
- priv_key=BN_new();
- if (priv_key == NULL) goto err;
- generate_new_key=1;
- }
- else
- priv_key=dh->priv_key;
-
- if (dh->pub_key == NULL)
- {
- pub_key=BN_new();
- if (pub_key == NULL) goto err;
- }
- else
- pub_key=dh->pub_key;
-
- if (dh->flags & DH_FLAG_CACHE_MONT_P)
- {
- mont = BN_MONT_CTX_set_locked(
- (BN_MONT_CTX **)&dh->method_mont_p,
- CRYPTO_LOCK_DH, dh->p, ctx);
- if (!mont)
- goto err;
- }
-
- if (generate_new_key)
- {
- l = dh->length ? dh->length : BN_num_bits(dh->p)-1; /* secret exponent length */
- if (!BN_rand(priv_key, l, 0, 0)) goto err;
- }
-
- {
- BIGNUM local_prk;
- BIGNUM *prk;
-
- if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- BN_init(&local_prk);
- prk = &local_prk;
- BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
- }
- else
- prk = priv_key;
-
- if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
- goto err;
- }
-
- dh->pub_key=pub_key;
- dh->priv_key=priv_key;
- ok=1;
-err:
- if (ok != 1)
- DHerr(DH_F_GENERATE_KEY,ERR_R_BN_LIB);
-
- if ((pub_key != NULL) && (dh->pub_key == NULL)) BN_free(pub_key);
- if ((priv_key != NULL) && (dh->priv_key == NULL)) BN_free(priv_key);
- BN_CTX_free(ctx);
- return(ok);
- }
-
-static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
- {
- BN_CTX *ctx;
- BN_MONT_CTX *mont=NULL;
- BIGNUM *tmp;
- int ret= -1;
-
- ctx = BN_CTX_new();
- if (ctx == NULL) goto err;
- BN_CTX_start(ctx);
- tmp = BN_CTX_get(ctx);
-
- if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS)
- {
- DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE);
- goto err;
- }
-
- if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
- {
- DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
-
- if (dh->priv_key == NULL)
- {
- DHerr(DH_F_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE);
- goto err;
- }
-
- if (dh->flags & DH_FLAG_CACHE_MONT_P)
- {
- mont = BN_MONT_CTX_set_locked(
- (BN_MONT_CTX **)&dh->method_mont_p,
- CRYPTO_LOCK_DH, dh->p, ctx);
- if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- /* XXX */
- BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME);
- }
- if (!mont)
- goto err;
- }
-
- if (!dh->meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key,dh->p,ctx,mont))
- {
- DHerr(DH_F_COMPUTE_KEY,ERR_R_BN_LIB);
- goto err;
- }
-
- ret=BN_bn2bin(tmp,key);
-err:
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- return(ret);
- }
-
-static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
- const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx)
- {
- /* If a is only one word long and constant time is false, use the faster
- * exponenentiation function.
- */
- if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0))
- {
- BN_ULONG A = a->d[0];
- return BN_mod_exp_mont_word(r,A,p,m,ctx,m_ctx);
- }
- else
- return BN_mod_exp_mont(r,a,p,m,ctx,m_ctx);
- }
-
-
-static int dh_init(DH *dh)
- {
- FIPS_selftest_check();
- dh->flags |= DH_FLAG_CACHE_MONT_P;
- return(1);
- }
-
-static int dh_finish(DH *dh)
- {
- if(dh->method_mont_p)
- BN_MONT_CTX_free((BN_MONT_CTX *)dh->method_mont_p);
- return(1);
- }
-
-#endif
-#endif
diff --git a/crypto/openssl/fips/dh/fips_dh_lib.c b/crypto/openssl/fips/dh/fips_dh_lib.c
deleted file mode 100644
index 4a822cf..0000000
--- a/crypto/openssl/fips/dh/fips_dh_lib.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* fips_dh_lib.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 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).
- *
- */
-
-#include <string.h>
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-
-/* Minimal FIPS versions of FIPS_dh_new() and FIPS_dh_free(): to
- * reduce external dependencies.
- */
-
-DH *FIPS_dh_new(void)
- {
- DH *ret;
- ret = OPENSSL_malloc(sizeof(DH));
- if (!ret)
- return NULL;
- memset(ret, 0, sizeof(DH));
- ret->meth = DH_OpenSSL();
- if (ret->meth->init)
- ret->meth->init(ret);
- return ret;
- }
-
-void FIPS_dh_free(DH *r)
- {
- if (!r)
- return;
- if (r->meth->finish)
- r->meth->finish(r);
- if (r->p != NULL) BN_clear_free(r->p);
- if (r->g != NULL) BN_clear_free(r->g);
- if (r->q != NULL) BN_clear_free(r->q);
- if (r->j != NULL) BN_clear_free(r->j);
- if (r->seed) OPENSSL_free(r->seed);
- if (r->counter != NULL) BN_clear_free(r->counter);
- if (r->pub_key != NULL) BN_clear_free(r->pub_key);
- if (r->priv_key != NULL) BN_clear_free(r->priv_key);
- OPENSSL_free(r);
- }
diff --git a/crypto/openssl/fips/dsa/Makefile b/crypto/openssl/fips/dsa/Makefile
deleted file mode 100644
index 251615e..0000000
--- a/crypto/openssl/fips/dsa/Makefile
+++ /dev/null
@@ -1,191 +0,0 @@
-#
-# OpenSSL/fips/dsa/Makefile
-#
-
-DIR= dsa
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=fips_dsatest.c fips_dssvs.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_dsa_ossl.c fips_dsa_gen.c fips_dsa_selftest.c fips_dsa_key.c \
- fips_dsa_lib.c fips_dsa_sign.c
-LIBOBJ=fips_dsa_ossl.o fips_dsa_gen.o fips_dsa_selftest.o fips_dsa_key.o \
- fips_dsa_lib.o fips_dsa_sign.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=
-HEADER= $(EXHEADER)
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-Q=../testvectors/dsa/req
-A=../testvectors/dsa/rsp
-
-fips_test:
- -rm -rf $A
- mkdir $A
- if [ -f $(Q)/PQGGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs pqg < $(Q)/PQGGen.req > $(A)/PQGGen.rsp; fi
- if [ -f $(Q)/KeyPair.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs keypair < $(Q)/KeyPair.req > $(A)/KeyPair.rsp; fi
- if [ -f $(Q)/SigGen.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs siggen < $(Q)/SigGen.req > $(A)/SigGen.rsp; fi
- if [ -f $(Q)/SigVer.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_dssvs sigver < $Q/SigVer.req > $A/SigVer.rsp; fi
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_dsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_dsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_dsa_gen.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_dsa_gen.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_dsa_gen.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dsa_gen.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-fips_dsa_gen.o: ../../include/openssl/opensslconf.h
-fips_dsa_gen.o: ../../include/openssl/opensslv.h
-fips_dsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-fips_dsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-fips_dsa_gen.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_dsa_gen.o: fips_dsa_gen.c
-fips_dsa_key.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_dsa_key.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_dsa_key.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_dsa_key.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_dsa_key.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dsa_key.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-fips_dsa_key.o: ../../include/openssl/opensslconf.h
-fips_dsa_key.o: ../../include/openssl/opensslv.h
-fips_dsa_key.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-fips_dsa_key.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_dsa_key.o: ../../include/openssl/symhacks.h ../fips_locl.h fips_dsa_key.c
-fips_dsa_lib.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_dsa_lib.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
-fips_dsa_lib.o: ../../include/openssl/e_os2.h
-fips_dsa_lib.o: ../../include/openssl/opensslconf.h
-fips_dsa_lib.o: ../../include/openssl/opensslv.h
-fips_dsa_lib.o: ../../include/openssl/ossl_typ.h
-fips_dsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_dsa_lib.o: ../../include/openssl/symhacks.h fips_dsa_lib.c
-fips_dsa_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_dsa_ossl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_dsa_ossl.o: ../../include/openssl/crypto.h ../../include/openssl/dsa.h
-fips_dsa_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-fips_dsa_ossl.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-fips_dsa_ossl.o: ../../include/openssl/engine.h ../../include/openssl/err.h
-fips_dsa_ossl.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_dsa_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_dsa_ossl.o: ../../include/openssl/objects.h
-fips_dsa_ossl.o: ../../include/openssl/opensslconf.h
-fips_dsa_ossl.o: ../../include/openssl/opensslv.h
-fips_dsa_ossl.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_dsa_ossl.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-fips_dsa_ossl.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-fips_dsa_ossl.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-fips_dsa_ossl.o: ../../include/openssl/x509_vfy.h fips_dsa_ossl.c
-fips_dsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_dsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_dsa_selftest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_dsa_selftest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_dsa_selftest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dsa_selftest.o: ../../include/openssl/obj_mac.h
-fips_dsa_selftest.o: ../../include/openssl/objects.h
-fips_dsa_selftest.o: ../../include/openssl/opensslconf.h
-fips_dsa_selftest.o: ../../include/openssl/opensslv.h
-fips_dsa_selftest.o: ../../include/openssl/ossl_typ.h
-fips_dsa_selftest.o: ../../include/openssl/safestack.h
-fips_dsa_selftest.o: ../../include/openssl/stack.h
-fips_dsa_selftest.o: ../../include/openssl/symhacks.h fips_dsa_selftest.c
-fips_dsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_dsa_sign.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_dsa_sign.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_dsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_dsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dsa_sign.o: ../../include/openssl/obj_mac.h
-fips_dsa_sign.o: ../../include/openssl/objects.h
-fips_dsa_sign.o: ../../include/openssl/opensslconf.h
-fips_dsa_sign.o: ../../include/openssl/opensslv.h
-fips_dsa_sign.o: ../../include/openssl/ossl_typ.h
-fips_dsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-fips_dsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_dsa_sign.o: fips_dsa_sign.c
-fips_dsatest.o: ../../e_os.h ../../include/openssl/asn1.h
-fips_dsatest.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
-fips_dsatest.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
-fips_dsatest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-fips_dsatest.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_dsatest.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-fips_dsatest.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
-fips_dsatest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_dsatest.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
-fips_dsatest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_dsatest.o: ../../include/openssl/objects.h
-fips_dsatest.o: ../../include/openssl/opensslconf.h
-fips_dsatest.o: ../../include/openssl/opensslv.h
-fips_dsatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_dsatest.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-fips_dsatest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-fips_dsatest.o: ../../include/openssl/symhacks.h ../../include/openssl/ui.h
-fips_dsatest.o: ../../include/openssl/ui_compat.h ../../include/openssl/x509.h
-fips_dsatest.o: ../../include/openssl/x509_vfy.h ../fips_utl.h fips_dsatest.c
-fips_dssvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_dssvs.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_dssvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_dssvs.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_dssvs.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_dssvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-fips_dssvs.o: ../../include/openssl/opensslconf.h
-fips_dssvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-fips_dssvs.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_dssvs.o: ../../include/openssl/symhacks.h ../fips_utl.h fips_dssvs.c
diff --git a/crypto/openssl/fips/dsa/fips_dsa_gen.c b/crypto/openssl/fips/dsa/fips_dsa_gen.c
deleted file mode 100644
index 0cecf34..0000000
--- a/crypto/openssl/fips/dsa/fips_dsa_gen.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/* crypto/dsa/dsa_gen.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.]
- */
-
-#undef GENUINE_DSA
-
-#ifdef GENUINE_DSA
-/* Parameter generation follows the original release of FIPS PUB 186,
- * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) */
-#define HASH EVP_sha()
-#else
-/* Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
- * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in
- * FIPS PUB 180-1) */
-#define HASH EVP_sha1()
-#endif
-
-#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
-
-#ifndef OPENSSL_NO_SHA
-
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/rand.h>
-#include <openssl/sha.h>
-#include <openssl/err.h>
-
-#ifdef OPENSSL_FIPS
-
-static int dsa_builtin_paramgen(DSA *ret, int bits,
- unsigned char *seed_in, int seed_len,
- int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
-
-int DSA_generate_parameters_ex(DSA *ret, int bits,
- unsigned char *seed_in, int seed_len,
- int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
- {
- if(ret->meth->dsa_paramgen)
- return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
- counter_ret, h_ret, cb);
- return dsa_builtin_paramgen(ret, bits, seed_in, seed_len,
- counter_ret, h_ret, cb);
- }
-
-static int dsa_builtin_paramgen(DSA *ret, int bits,
- unsigned char *seed_in, int seed_len,
- int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
- {
- int ok=0;
- unsigned char seed[SHA_DIGEST_LENGTH];
- unsigned char md[SHA_DIGEST_LENGTH];
- unsigned char buf[SHA_DIGEST_LENGTH],buf2[SHA_DIGEST_LENGTH];
- BIGNUM *r0,*W,*X,*c,*test;
- BIGNUM *g=NULL,*q=NULL,*p=NULL;
- BN_MONT_CTX *mont=NULL;
- int k,n=0,i,b,m=0;
- int counter=0;
- int r=0;
- BN_CTX *ctx=NULL;
- unsigned int h=2;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_DSA_BUILTIN_PARAMGEN,
- FIPS_R_FIPS_SELFTEST_FAILED);
- goto err;
- }
-
- if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
- {
- DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN, DSA_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
-
- if (bits < 512) bits=512;
- bits=(bits+63)/64*64;
-
- /* NB: seed_len == 0 is special case: copy generated seed to
- * seed_in if it is not NULL.
- */
- if (seed_len && (seed_len < 20))
- seed_in = NULL; /* seed buffer too small -- ignore */
- if (seed_len > 20)
- seed_len = 20; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
- * but our internal buffers are restricted to 160 bits*/
- if ((seed_in != NULL) && (seed_len == 20))
- {
- memcpy(seed,seed_in,seed_len);
- /* set seed_in to NULL to avoid it being copied back */
- seed_in = NULL;
- }
-
- if ((ctx=BN_CTX_new()) == NULL) goto err;
-
- if ((mont=BN_MONT_CTX_new()) == NULL) goto err;
-
- BN_CTX_start(ctx);
- r0 = BN_CTX_get(ctx);
- g = BN_CTX_get(ctx);
- W = BN_CTX_get(ctx);
- q = BN_CTX_get(ctx);
- X = BN_CTX_get(ctx);
- c = BN_CTX_get(ctx);
- p = BN_CTX_get(ctx);
- test = BN_CTX_get(ctx);
-
- if (!BN_lshift(test,BN_value_one(),bits-1))
- goto err;
-
- for (;;)
- {
- for (;;) /* find q */
- {
- int seed_is_random;
-
- /* step 1 */
- if(!BN_GENCB_call(cb, 0, m++))
- goto err;
-
- if (!seed_len)
- {
- RAND_pseudo_bytes(seed,SHA_DIGEST_LENGTH);
- seed_is_random = 1;
- }
- else
- {
- seed_is_random = 0;
- seed_len=0; /* use random seed if 'seed_in' turns out to be bad*/
- }
- memcpy(buf,seed,SHA_DIGEST_LENGTH);
- memcpy(buf2,seed,SHA_DIGEST_LENGTH);
- /* precompute "SEED + 1" for step 7: */
- for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
- {
- buf[i]++;
- if (buf[i] != 0) break;
- }
-
- /* step 2 */
- EVP_Digest(seed,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
- EVP_Digest(buf,SHA_DIGEST_LENGTH,buf2,NULL,HASH, NULL);
- for (i=0; i<SHA_DIGEST_LENGTH; i++)
- md[i]^=buf2[i];
-
- /* step 3 */
- md[0]|=0x80;
- md[SHA_DIGEST_LENGTH-1]|=0x01;
- if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,q)) goto err;
-
- /* step 4 */
- r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
- seed_is_random, cb);
- if (r > 0)
- break;
- if (r != 0)
- goto err;
-
- /* do a callback call */
- /* step 5 */
- }
-
- if(!BN_GENCB_call(cb, 2, 0)) goto err;
- if(!BN_GENCB_call(cb, 3, 0)) goto err;
-
- /* step 6 */
- counter=0;
- /* "offset = 2" */
-
- n=(bits-1)/160;
- b=(bits-1)-n*160;
-
- for (;;)
- {
- if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
- goto err;
-
- /* step 7 */
- BN_zero(W);
- /* now 'buf' contains "SEED + offset - 1" */
- for (k=0; k<=n; k++)
- {
- /* obtain "SEED + offset + k" by incrementing: */
- for (i=SHA_DIGEST_LENGTH-1; i >= 0; i--)
- {
- buf[i]++;
- if (buf[i] != 0) break;
- }
-
- EVP_Digest(buf,SHA_DIGEST_LENGTH,md,NULL,HASH, NULL);
-
- /* step 8 */
- if (!BN_bin2bn(md,SHA_DIGEST_LENGTH,r0))
- goto err;
- if (!BN_lshift(r0,r0,160*k)) goto err;
- if (!BN_add(W,W,r0)) goto err;
- }
-
- /* more of step 8 */
- if (!BN_mask_bits(W,bits-1)) goto err;
- if (!BN_copy(X,W)) goto err;
- if (!BN_add(X,X,test)) goto err;
-
- /* step 9 */
- if (!BN_lshift1(r0,q)) goto err;
- if (!BN_mod(c,X,r0,ctx)) goto err;
- if (!BN_sub(r0,c,BN_value_one())) goto err;
- if (!BN_sub(p,X,r0)) goto err;
-
- /* step 10 */
- if (BN_cmp(p,test) >= 0)
- {
- /* step 11 */
- r = BN_is_prime_fasttest_ex(p, DSS_prime_checks,
- ctx, 1, cb);
- if (r > 0)
- goto end; /* found it */
- if (r != 0)
- goto err;
- }
-
- /* step 13 */
- counter++;
- /* "offset = offset + n + 1" */
-
- /* step 14 */
- if (counter >= 4096) break;
- }
- }
-end:
- if(!BN_GENCB_call(cb, 2, 1))
- goto err;
-
- /* We now need to generate g */
- /* Set r0=(p-1)/q */
- if (!BN_sub(test,p,BN_value_one())) goto err;
- if (!BN_div(r0,NULL,test,q,ctx)) goto err;
-
- if (!BN_set_word(test,h)) goto err;
- if (!BN_MONT_CTX_set(mont,p,ctx)) goto err;
-
- for (;;)
- {
- /* g=test^r0%p */
- if (!BN_mod_exp_mont(g,test,r0,p,ctx,mont)) goto err;
- if (!BN_is_one(g)) break;
- if (!BN_add(test,test,BN_value_one())) goto err;
- h++;
- }
-
- if(!BN_GENCB_call(cb, 3, 1))
- goto err;
-
- ok=1;
-err:
- if (ok)
- {
- if(ret->p) BN_free(ret->p);
- if(ret->q) BN_free(ret->q);
- if(ret->g) BN_free(ret->g);
- ret->p=BN_dup(p);
- ret->q=BN_dup(q);
- ret->g=BN_dup(g);
- if (ret->p == NULL || ret->q == NULL || ret->g == NULL)
- {
- ok=0;
- goto err;
- }
- if (seed_in != NULL) memcpy(seed_in,seed,20);
- if (counter_ret != NULL) *counter_ret=counter;
- if (h_ret != NULL) *h_ret=h;
- }
- if(ctx)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (mont != NULL) BN_MONT_CTX_free(mont);
- return ok;
- }
-#endif
-#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsa_key.c b/crypto/openssl/fips/dsa/fips_dsa_key.c
deleted file mode 100644
index 9f21033..0000000
--- a/crypto/openssl/fips/dsa/fips_dsa_key.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* crypto/dsa/dsa_key.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 <stdio.h>
-#include <time.h>
-#ifndef OPENSSL_NO_SHA
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/fips.h>
-#include "fips_locl.h"
-
-#ifdef OPENSSL_FIPS
-
-static int fips_dsa_pairwise_fail = 0;
-
-void FIPS_corrupt_dsa_keygen(void)
- {
- fips_dsa_pairwise_fail = 1;
- }
-
-static int dsa_builtin_keygen(DSA *dsa);
-
-static int fips_check_dsa(DSA *dsa)
- {
- EVP_PKEY pk;
- unsigned char tbs[] = "DSA Pairwise Check Data";
- pk.type = EVP_PKEY_DSA;
- pk.pkey.dsa = dsa;
-
- if (!fips_pkey_signature_test(&pk, tbs, -1,
- NULL, 0, EVP_dss1(), 0, NULL))
- {
- FIPSerr(FIPS_F_FIPS_CHECK_DSA,FIPS_R_PAIRWISE_TEST_FAILED);
- fips_set_selftest_fail();
- return 0;
- }
- return 1;
- }
-
-int DSA_generate_key(DSA *dsa)
- {
- if(dsa->meth->dsa_keygen)
- return dsa->meth->dsa_keygen(dsa);
- return dsa_builtin_keygen(dsa);
- }
-
-static int dsa_builtin_keygen(DSA *dsa)
- {
- int ok=0;
- BN_CTX *ctx=NULL;
- BIGNUM *pub_key=NULL,*priv_key=NULL;
-
- if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
- {
- DSAerr(DSA_F_DSA_BUILTIN_KEYGEN, DSA_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
-
- if ((ctx=BN_CTX_new()) == NULL) goto err;
-
- if (dsa->priv_key == NULL)
- {
- if ((priv_key=BN_new()) == NULL) goto err;
- }
- else
- priv_key=dsa->priv_key;
-
- do
- if (!BN_rand_range(priv_key,dsa->q)) goto err;
- while (BN_is_zero(priv_key));
-
- if (dsa->pub_key == NULL)
- {
- if ((pub_key=BN_new()) == NULL) goto err;
- }
- else
- pub_key=dsa->pub_key;
-
- {
- BIGNUM local_prk;
- BIGNUM *prk;
-
- if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- BN_init(&local_prk);
- prk = &local_prk;
- BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
- }
- else
- prk = priv_key;
-
- if (!BN_mod_exp(pub_key,dsa->g,prk,dsa->p,ctx)) goto err;
- }
-
- dsa->priv_key=priv_key;
- dsa->pub_key=pub_key;
- if (fips_dsa_pairwise_fail)
- BN_add_word(dsa->pub_key, 1);
- if(!fips_check_dsa(dsa))
- goto err;
- ok=1;
-
-err:
- if ((pub_key != NULL) && (dsa->pub_key == NULL)) BN_free(pub_key);
- if ((priv_key != NULL) && (dsa->priv_key == NULL)) BN_free(priv_key);
- if (ctx != NULL) BN_CTX_free(ctx);
- return(ok);
- }
-#endif
-
-#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsa_lib.c b/crypto/openssl/fips/dsa/fips_dsa_lib.c
deleted file mode 100644
index 2545966..0000000
--- a/crypto/openssl/fips/dsa/fips_dsa_lib.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* fips_dsa_lib.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 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).
- *
- */
-
-#include <string.h>
-#include <openssl/dsa.h>
-#include <openssl/bn.h>
-
-/* Minimal FIPS versions of FIPS_dsa_new() and FIPS_dsa_free: to
- * reduce external dependencies.
- */
-
-DSA *FIPS_dsa_new(void)
- {
- DSA *ret;
- ret = OPENSSL_malloc(sizeof(DSA));
- if (!ret)
- return NULL;
- memset(ret, 0, sizeof(DSA));
- ret->meth = DSA_OpenSSL();
- if (ret->meth->init)
- ret->meth->init(ret);
- return ret;
- }
-
-void FIPS_dsa_free(DSA *r)
- {
- if (!r)
- return;
- if (r->meth->finish)
- r->meth->finish(r);
- if (r->p != NULL) BN_clear_free(r->p);
- if (r->q != NULL) BN_clear_free(r->q);
- if (r->g != NULL) BN_clear_free(r->g);
- if (r->pub_key != NULL) BN_clear_free(r->pub_key);
- if (r->priv_key != NULL) BN_clear_free(r->priv_key);
- if (r->kinv != NULL) BN_clear_free(r->kinv);
- if (r->r != NULL) BN_clear_free(r->r);
- OPENSSL_free(r);
- }
-
diff --git a/crypto/openssl/fips/dsa/fips_dsa_ossl.c b/crypto/openssl/fips/dsa/fips_dsa_ossl.c
deleted file mode 100644
index 50a6c13..0000000
--- a/crypto/openssl/fips/dsa/fips_dsa_ossl.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* crypto/dsa/dsa_ossl.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.]
- */
-
-/* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
-
-#include <stdio.h>
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/rand.h>
-#include <openssl/asn1.h>
-#include <openssl/err.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-#include <openssl/fips.h>
-
-#ifdef OPENSSL_FIPS
-
-static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa);
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp);
-static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig,
- DSA *dsa);
-static int dsa_init(DSA *dsa);
-static int dsa_finish(DSA *dsa);
-static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
- BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *in_mont);
-static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx);
-
-static const DSA_METHOD openssl_dsa_meth = {
-"OpenSSL FIPS DSA method",
-dsa_do_sign,
-dsa_sign_setup,
-dsa_do_verify,
-dsa_mod_exp,
-dsa_bn_mod_exp,
-dsa_init,
-dsa_finish,
-DSA_FLAG_FIPS_METHOD,
-NULL
-};
-#if 0
-int FIPS_dsa_check(struct dsa_st *dsa)
- {
- if(dsa->meth != &openssl_dsa_meth || dsa->meth->dsa_do_sign != dsa_do_sign
- || dsa->meth->dsa_sign_setup != dsa_sign_setup
- || dsa->meth->dsa_mod_exp != dsa_mod_exp
- || dsa->meth->bn_mod_exp != dsa_bn_mod_exp
- || dsa->meth->init != dsa_init
- || dsa->meth->finish != dsa_finish)
- {
- FIPSerr(FIPS_F_FIPS_DSA_CHECK,FIPS_R_NON_FIPS_METHOD);
- return 0;
- }
- return 1;
- }
-#endif
-
-const DSA_METHOD *DSA_OpenSSL(void)
-{
- return &openssl_dsa_meth;
-}
-
-static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA *dsa)
- {
- BIGNUM *kinv=NULL,*r=NULL,*s=NULL;
- BIGNUM m;
- BIGNUM xr;
- BN_CTX *ctx=NULL;
- int i,reason=ERR_R_BN_LIB;
- DSA_SIG *ret=NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_DSA_DO_SIGN,FIPS_R_FIPS_SELFTEST_FAILED);
- return NULL;
- }
-
- if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
- {
- DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_KEY_SIZE_TOO_SMALL);
- return NULL;
- }
-
- BN_init(&m);
- BN_init(&xr);
-
- if (!dsa->p || !dsa->q || !dsa->g)
- {
- reason=DSA_R_MISSING_PARAMETERS;
- goto err;
- }
-
- s=BN_new();
- if (s == NULL) goto err;
-
- i=BN_num_bytes(dsa->q); /* should be 20 */
- if ((dlen > i) || (dlen > 50))
- {
- reason=DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE;
- goto err;
- }
-
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
-
- if (!dsa->meth->dsa_sign_setup(dsa,ctx,&kinv,&r)) goto err;
-
- if (BN_bin2bn(dgst,dlen,&m) == NULL) goto err;
-
- /* Compute s = inv(k) (m + xr) mod q */
- if (!BN_mod_mul(&xr,dsa->priv_key,r,dsa->q,ctx)) goto err;/* s = xr */
- if (!BN_add(s, &xr, &m)) goto err; /* s = m + xr */
- if (BN_cmp(s,dsa->q) > 0)
- BN_sub(s,s,dsa->q);
- if (!BN_mod_mul(s,s,kinv,dsa->q,ctx)) goto err;
-
- ret= DSA_SIG_new();
- if (ret == NULL) goto err;
- ret->r = r;
- ret->s = s;
-
-err:
- if (!ret)
- {
- DSAerr(DSA_F_DSA_DO_SIGN,reason);
- BN_free(r);
- BN_free(s);
- }
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_clear_free(&m);
- BN_clear_free(&xr);
- if (kinv != NULL) /* dsa->kinv is NULL now if we used it */
- BN_clear_free(kinv);
- return(ret);
- }
-
-static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp)
- {
- BN_CTX *ctx;
- BIGNUM k,kq,*K,*kinv=NULL,*r=NULL;
- int ret=0;
-
- if (!dsa->p || !dsa->q || !dsa->g)
- {
- DSAerr(DSA_F_DSA_SIGN_SETUP,DSA_R_MISSING_PARAMETERS);
- return 0;
- }
-
- BN_init(&k);
- BN_init(&kq);
-
- if (ctx_in == NULL)
- {
- if ((ctx=BN_CTX_new()) == NULL) goto err;
- }
- else
- ctx=ctx_in;
-
- if ((r=BN_new()) == NULL) goto err;
-
- /* Get random k */
- do
- if (!BN_rand_range(&k, dsa->q)) goto err;
- while (BN_is_zero(&k));
- if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- BN_set_flags(&k, BN_FLG_CONSTTIME);
- }
-
- if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
- {
- if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
- CRYPTO_LOCK_DSA,
- dsa->p, ctx))
- goto err;
- }
-
- /* Compute r = (g^k mod p) mod q */
-
- if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0)
- {
- if (!BN_copy(&kq, &k)) goto err;
-
- /* We do not want timing information to leak the length of k,
- * so we compute g^k using an equivalent exponent of fixed length.
- *
- * (This is a kludge that we need because the BN_mod_exp_mont()
- * does not let us specify the desired timing behaviour.) */
-
- if (!BN_add(&kq, &kq, dsa->q)) goto err;
- if (BN_num_bits(&kq) <= BN_num_bits(dsa->q))
- {
- if (!BN_add(&kq, &kq, dsa->q)) goto err;
- }
-
- K = &kq;
- }
- else
- {
- K = &k;
- }
- if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,K,dsa->p,ctx,
- (BN_MONT_CTX *)dsa->method_mont_p)) goto err;
- if (!BN_mod(r,r,dsa->q,ctx)) goto err;
-
- /* Compute part of 's = inv(k) (m + xr) mod q' */
- if ((kinv=BN_mod_inverse(NULL,&k,dsa->q,ctx)) == NULL) goto err;
-
- if (*kinvp != NULL) BN_clear_free(*kinvp);
- *kinvp=kinv;
- kinv=NULL;
- if (*rp != NULL) BN_clear_free(*rp);
- *rp=r;
- ret=1;
-err:
- if (!ret)
- {
- DSAerr(DSA_F_DSA_SIGN_SETUP,ERR_R_BN_LIB);
- if (kinv != NULL) BN_clear_free(kinv);
- if (r != NULL) BN_clear_free(r);
- }
- if (ctx_in == NULL) BN_CTX_free(ctx);
- if (kinv != NULL) BN_clear_free(kinv);
- BN_clear_free(&k);
- BN_clear_free(&kq);
- return(ret);
- }
-
-static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DSA_SIG *sig,
- DSA *dsa)
- {
- BN_CTX *ctx;
- BIGNUM u1,u2,t1;
- BN_MONT_CTX *mont=NULL;
- int ret = -1;
-
- if (!dsa->p || !dsa->q || !dsa->g)
- {
- DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MISSING_PARAMETERS);
- return -1;
- }
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_DSA_DO_VERIFY,FIPS_R_FIPS_SELFTEST_FAILED);
- return -1;
- }
-
- if (BN_num_bits(dsa->q) != 160)
- {
- DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_BAD_Q_VALUE);
- return -1;
- }
-
- if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS)
- {
- DSAerr(DSA_F_DSA_DO_VERIFY,DSA_R_MODULUS_TOO_LARGE);
- return -1;
- }
-
- if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS))
- {
- DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL);
- return -1;
- }
-
- BN_init(&u1);
- BN_init(&u2);
- BN_init(&t1);
-
- if ((ctx=BN_CTX_new()) == NULL) goto err;
-
- if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
- {
- ret = 0;
- goto err;
- }
- if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
- {
- ret = 0;
- goto err;
- }
-
- /* Calculate W = inv(S) mod Q
- * save W in u2 */
- if ((BN_mod_inverse(&u2,sig->s,dsa->q,ctx)) == NULL) goto err;
-
- /* save M in u1 */
- if (BN_bin2bn(dgst,dgst_len,&u1) == NULL) goto err;
-
- /* u1 = M * w mod q */
- if (!BN_mod_mul(&u1,&u1,&u2,dsa->q,ctx)) goto err;
-
- /* u2 = r * w mod q */
- if (!BN_mod_mul(&u2,sig->r,&u2,dsa->q,ctx)) goto err;
-
-
- if (dsa->flags & DSA_FLAG_CACHE_MONT_P)
- {
- mont = BN_MONT_CTX_set_locked(
- (BN_MONT_CTX **)&dsa->method_mont_p,
- CRYPTO_LOCK_DSA, dsa->p, ctx);
- if (!mont)
- goto err;
- }
-
-#if 0
- {
- BIGNUM t2;
-
- BN_init(&t2);
- /* v = ( g^u1 * y^u2 mod p ) mod q */
- /* let t1 = g ^ u1 mod p */
- if (!BN_mod_exp_mont(&t1,dsa->g,&u1,dsa->p,ctx,mont)) goto err;
- /* let t2 = y ^ u2 mod p */
- if (!BN_mod_exp_mont(&t2,dsa->pub_key,&u2,dsa->p,ctx,mont)) goto err;
- /* let u1 = t1 * t2 mod p */
- if (!BN_mod_mul(&u1,&t1,&t2,dsa->p,ctx)) goto err_bn;
- BN_free(&t2);
- }
- /* let u1 = u1 mod q */
- if (!BN_mod(&u1,&u1,dsa->q,ctx)) goto err;
-#else
- {
- if (!dsa->meth->dsa_mod_exp(dsa, &t1,dsa->g,&u1,dsa->pub_key,&u2,
- dsa->p,ctx,mont)) goto err;
- /* BN_copy(&u1,&t1); */
- /* let u1 = u1 mod q */
- if (!BN_mod(&u1,&t1,dsa->q,ctx)) goto err;
- }
-#endif
- /* V is now in u1. If the signature is correct, it will be
- * equal to R. */
- ret=(BN_ucmp(&u1, sig->r) == 0);
-
- err:
- if (ret != 1) DSAerr(DSA_F_DSA_DO_VERIFY,ERR_R_BN_LIB);
- if (ctx != NULL) BN_CTX_free(ctx);
- BN_free(&u1);
- BN_free(&u2);
- BN_free(&t1);
- return(ret);
- }
-
-static int dsa_init(DSA *dsa)
-{
- FIPS_selftest_check();
- dsa->flags|=DSA_FLAG_CACHE_MONT_P;
- return(1);
-}
-
-static int dsa_finish(DSA *dsa)
-{
- if(dsa->method_mont_p)
- BN_MONT_CTX_free((BN_MONT_CTX *)dsa->method_mont_p);
- return(1);
-}
-
-static int dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
- BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *in_mont)
-{
- return BN_mod_exp2_mont(rr, a1, p1, a2, p2, m, ctx, in_mont);
-}
-
-static int dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx,
- BN_MONT_CTX *m_ctx)
-{
- return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
-}
-
-#else /* ndef OPENSSL_FIPS */
-
-static void *dummy=&dummy;
-
-#endif /* ndef OPENSSL_FIPS */
diff --git a/crypto/openssl/fips/dsa/fips_dsa_selftest.c b/crypto/openssl/fips/dsa/fips_dsa_selftest.c
deleted file mode 100644
index 6880760..0000000
--- a/crypto/openssl/fips/dsa/fips_dsa_selftest.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/* crypto/dsa/dsatest.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 <string.h>
-#include <openssl/crypto.h>
-#include <openssl/dsa.h>
-#include <openssl/fips.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-
-#ifdef OPENSSL_FIPS
-
-/* seed, out_p, out_q, out_g are taken the NIST test vectors */
-
-static unsigned char seed[20] = {
- 0x77, 0x8f, 0x40, 0x74, 0x6f, 0x66, 0xbe, 0x33, 0xce, 0xbe, 0x99, 0x34,
- 0x4c, 0xfc, 0xf3, 0x28, 0xaa, 0x70, 0x2d, 0x3a
- };
-
-static unsigned char out_p[] = {
- 0xf7, 0x7c, 0x1b, 0x83, 0xd8, 0xe8, 0x5c, 0x7f, 0x85, 0x30, 0x17, 0x57,
- 0x21, 0x95, 0xfe, 0x26, 0x04, 0xeb, 0x47, 0x4c, 0x3a, 0x4a, 0x81, 0x4b,
- 0x71, 0x2e, 0xed, 0x6e, 0x4f, 0x3d, 0x11, 0x0f, 0x7c, 0xfe, 0x36, 0x43,
- 0x51, 0xd9, 0x81, 0x39, 0x17, 0xdf, 0x62, 0xf6, 0x9c, 0x01, 0xa8, 0x69,
- 0x71, 0xdd, 0x29, 0x7f, 0x47, 0xe6, 0x65, 0xa6, 0x22, 0xe8, 0x6a, 0x12,
- 0x2b, 0xc2, 0x81, 0xff, 0x32, 0x70, 0x2f, 0x9e, 0xca, 0x53, 0x26, 0x47,
- 0x0f, 0x59, 0xd7, 0x9e, 0x2c, 0xa5, 0x07, 0xc4, 0x49, 0x52, 0xa3, 0xe4,
- 0x6b, 0x04, 0x00, 0x25, 0x49, 0xe2, 0xe6, 0x7f, 0x28, 0x78, 0x97, 0xb8,
- 0x3a, 0x32, 0x14, 0x38, 0xa2, 0x51, 0x33, 0x22, 0x44, 0x7e, 0xd7, 0xef,
- 0x45, 0xdb, 0x06, 0x4a, 0xd2, 0x82, 0x4a, 0x82, 0x2c, 0xb1, 0xd7, 0xd8,
- 0xb6, 0x73, 0x00, 0x4d, 0x94, 0x77, 0x94, 0xef
- };
-
-static unsigned char out_q[] = {
- 0xd4, 0x0a, 0xac, 0x9f, 0xbd, 0x8c, 0x80, 0xc2, 0x38, 0x7e, 0x2e, 0x0c,
- 0x52, 0x5c, 0xea, 0x34, 0xa1, 0x83, 0x32, 0xf3
- };
-
-static unsigned char out_g[] = {
- 0x34, 0x73, 0x8b, 0x57, 0x84, 0x8e, 0x55, 0xbf, 0x57, 0xcc, 0x41, 0xbb,
- 0x5e, 0x2b, 0xd5, 0x42, 0xdd, 0x24, 0x22, 0x2a, 0x09, 0xea, 0x26, 0x1e,
- 0x17, 0x65, 0xcb, 0x1a, 0xb3, 0x12, 0x44, 0xa3, 0x9e, 0x99, 0xe9, 0x63,
- 0xeb, 0x30, 0xb1, 0x78, 0x7b, 0x09, 0x40, 0x30, 0xfa, 0x83, 0xc2, 0x35,
- 0xe1, 0xc4, 0x2d, 0x74, 0x1a, 0xb1, 0x83, 0x54, 0xd8, 0x29, 0xf4, 0xcf,
- 0x7f, 0x6f, 0x67, 0x1c, 0x36, 0x49, 0xee, 0x6c, 0xa2, 0x3c, 0x2d, 0x6a,
- 0xe9, 0xd3, 0x9a, 0xf6, 0x57, 0x78, 0x6f, 0xfd, 0x33, 0xcd, 0x3c, 0xed,
- 0xfd, 0xd4, 0x41, 0xe6, 0x5c, 0x8b, 0xe0, 0x68, 0x31, 0x47, 0x47, 0xaf,
- 0x12, 0xa7, 0xf9, 0x32, 0x0d, 0x94, 0x15, 0x48, 0xd0, 0x54, 0x85, 0xb2,
- 0x04, 0xb5, 0x4d, 0xd4, 0x9d, 0x05, 0x22, 0x25, 0xd9, 0xfd, 0x6c, 0x36,
- 0xef, 0xbe, 0x69, 0x6c, 0x55, 0xf4, 0xee, 0xec
- };
-
-static const unsigned char str1[]="12345678901234567890";
-
-void FIPS_corrupt_dsa()
- {
- ++seed[0];
- }
-
-int FIPS_selftest_dsa()
- {
- DSA *dsa=NULL;
- int counter,i,j, ret = 0;
- unsigned int slen;
- unsigned char buf[256];
- unsigned long h;
- EVP_MD_CTX mctx;
- EVP_PKEY pk;
-
- EVP_MD_CTX_init(&mctx);
-
- dsa = FIPS_dsa_new();
-
- if(dsa == NULL)
- goto err;
- if(!DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,NULL))
- goto err;
- if (counter != 378)
- goto err;
- if (h != 2)
- goto err;
- i=BN_bn2bin(dsa->q,buf);
- j=sizeof(out_q);
- if (i != j || memcmp(buf,out_q,i) != 0)
- goto err;
-
- i=BN_bn2bin(dsa->p,buf);
- j=sizeof(out_p);
- if (i != j || memcmp(buf,out_p,i) != 0)
- goto err;
-
- i=BN_bn2bin(dsa->g,buf);
- j=sizeof(out_g);
- if (i != j || memcmp(buf,out_g,i) != 0)
- goto err;
- DSA_generate_key(dsa);
- pk.type = EVP_PKEY_DSA;
- pk.pkey.dsa = dsa;
-
- if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
- goto err;
- if (!EVP_SignUpdate(&mctx, str1, 20))
- goto err;
- if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
- goto err;
-
- if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
- goto err;
- if (!EVP_VerifyUpdate(&mctx, str1, 20))
- goto err;
- if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
- goto err;
-
- ret = 1;
-
- err:
- EVP_MD_CTX_cleanup(&mctx);
- if (dsa)
- FIPS_dsa_free(dsa);
- if (ret == 0)
- FIPSerr(FIPS_F_FIPS_SELFTEST_DSA,FIPS_R_SELFTEST_FAILED);
- return ret;
- }
-#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsa_sign.c b/crypto/openssl/fips/dsa/fips_dsa_sign.c
deleted file mode 100644
index 7a4d51d..0000000
--- a/crypto/openssl/fips/dsa/fips_dsa_sign.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* fips_dsa_sign.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 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).
- *
- */
-
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/dsa.h>
-#include <openssl/err.h>
-#include <openssl/sha.h>
-#include <openssl/bn.h>
-
-#ifdef OPENSSL_FIPS
-
-/* FIPS versions of DSA_sign() and DSA_verify().
- * These include a tiny ASN1 encoder/decoder to handle the specific
- * case of a DSA signature.
- */
-
-#if 0
-int FIPS_dsa_size(DSA *r)
- {
- int ilen;
- ilen = BN_num_bytes(r->q);
- if (ilen > 20)
- return -1;
- /* If MSB set need padding byte */
- ilen ++;
- /* Also need 2 bytes INTEGER header for r and s plus
- * 2 bytes SEQUENCE header making 6 in total.
- */
- return ilen * 2 + 6;
- }
-#endif
-
-/* Tiny ASN1 encoder for DSA_SIG structure. We can assume r, s smaller than
- * 0x80 octets as by the DSA standards they will be less than 2^160
- */
-
-int FIPS_dsa_sig_encode(unsigned char *out, DSA_SIG *sig)
- {
- int rlen, slen, rpad, spad, seqlen;
- rlen = BN_num_bytes(sig->r);
- if (rlen > 20)
- return -1;
- if (BN_num_bits(sig->r) & 0x7)
- rpad = 0;
- else
- rpad = 1;
- slen = BN_num_bytes(sig->s);
- if (slen > 20)
- return -1;
- if (BN_num_bits(sig->s) & 0x7)
- spad = 0;
- else
- spad = 1;
- /* Length of SEQUENCE, (1 tag + 1 len octet) * 2 + content octets */
- seqlen = rlen + rpad + slen + spad + 4;
- /* Actual encoded length: include SEQUENCE header */
- if (!out)
- return seqlen + 2;
-
- /* Output SEQUENCE header */
- *out++ = V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED;
- *out++ = (unsigned char)seqlen;
-
- /* Output r */
- *out++ = V_ASN1_INTEGER;
- *out++ = (unsigned char)(rlen + rpad);
- if (rpad)
- *out++ = 0;
- BN_bn2bin(sig->r, out);
- out += rlen;
-
- /* Output s */
- *out++ = V_ASN1_INTEGER;
- *out++ = (unsigned char)(slen + spad);
- if (spad)
- *out++ = 0;
- BN_bn2bin(sig->s, out);
- return seqlen + 2;
- }
-
-/* Companion DSA_SIG decoder */
-
-int FIPS_dsa_sig_decode(DSA_SIG *sig, const unsigned char *in, int inlen)
- {
- int seqlen, rlen, slen;
- const unsigned char *rbin;
- /* Sanity check */
-
- /* Need SEQUENCE tag */
- if (*in++ != (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
- return 0;
- /* Get length octet */
- seqlen = *in++;
- /* Check sensible length value */
- if (seqlen < 4 || seqlen > 0x7F)
- return 0;
- /* Check INTEGER tag */
- if (*in++ != V_ASN1_INTEGER)
- return 0;
- rlen = *in++;
- seqlen -= 2 + rlen;
- /* Check sensible seqlen value */
- if (seqlen < 2)
- return 0;
- rbin = in;
- in += rlen;
- /* Check INTEGER tag */
- if (*in++ != V_ASN1_INTEGER)
- return 0;
- slen = *in++;
- /* Remaining bytes of SEQUENCE should exactly match
- * encoding of s
- */
- if (seqlen != (slen + 2))
- return 0;
- if (!sig->r && !(sig->r = BN_new()))
- return 0;
- if (!sig->s && !(sig->s = BN_new()))
- return 0;
- if (!BN_bin2bn(rbin, rlen, sig->r))
- return 0;
- if (!BN_bin2bn(in, slen, sig->s))
- return 0;
- return 1;
- }
-
-static int fips_dsa_sign(int type, const unsigned char *x, int y,
- unsigned char *sig, unsigned int *siglen, EVP_MD_SVCTX *sv)
- {
- DSA *dsa = sv->key;
- unsigned char dig[EVP_MAX_MD_SIZE];
- unsigned int dlen;
- DSA_SIG *s;
- EVP_DigestFinal_ex(sv->mctx, dig, &dlen);
- s=dsa->meth->dsa_do_sign(dig,dlen,dsa);
- OPENSSL_cleanse(dig, dlen);
- if (s == NULL)
- {
- *siglen=0;
- return 0;
- }
- *siglen= FIPS_dsa_sig_encode(sig, s);
- DSA_SIG_free(s);
- if (*siglen < 0)
- return 0;
- return 1;
- }
-
-static int fips_dsa_verify(int type, const unsigned char *x, int y,
- const unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)
- {
- DSA *dsa = sv->key;
- DSA_SIG *s;
- int ret=-1;
- unsigned char dig[EVP_MAX_MD_SIZE];
- unsigned int dlen;
-
- s = DSA_SIG_new();
- if (s == NULL)
- return ret;
- if (!FIPS_dsa_sig_decode(s,sigbuf,siglen))
- goto err;
- EVP_DigestFinal_ex(sv->mctx, dig, &dlen);
- ret=dsa->meth->dsa_do_verify(dig,dlen,s,dsa);
- OPENSSL_cleanse(dig, dlen);
-err:
- DSA_SIG_free(s);
- return ret;
- }
-
-static int init(EVP_MD_CTX *ctx)
- { return SHA1_Init(ctx->md_data); }
-
-static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
- { return SHA1_Update(ctx->md_data,data,count); }
-
-static int final(EVP_MD_CTX *ctx,unsigned char *md)
- { return SHA1_Final(md,ctx->md_data); }
-
-static const EVP_MD dss1_md=
- {
- NID_dsa,
- NID_dsaWithSHA1,
- SHA_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
- init,
- update,
- final,
- NULL,
- NULL,
- (evp_sign_method *)fips_dsa_sign,
- (evp_verify_method *)fips_dsa_verify,
- {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, EVP_PKEY_DSA4,0},
- SHA_CBLOCK,
- sizeof(EVP_MD *)+sizeof(SHA_CTX),
- };
-
-const EVP_MD *EVP_dss1(void)
- {
- return(&dss1_md);
- }
-#endif
diff --git a/crypto/openssl/fips/dsa/fips_dsatest.c b/crypto/openssl/fips/dsa/fips_dsatest.c
deleted file mode 100644
index 1aec089..0000000
--- a/crypto/openssl/fips/dsa/fips_dsatest.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/* crypto/dsa/dsatest.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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "e_os.h"
-
-#include <openssl/crypto.h>
-#include <openssl/rand.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
-#endif
-
-
-#if defined(OPENSSL_NO_DSA) || !defined(OPENSSL_FIPS)
-int main(int argc, char *argv[])
-{
- printf("No FIPS DSA support\n");
- return(0);
-}
-#else
-#include <openssl/dsa.h>
-#include <openssl/fips.h>
-#include <openssl/fips_rand.h>
-#include <openssl/dsa.h>
-
-#ifdef OPENSSL_SYS_WIN16
-#define MS_CALLBACK _far _loadds
-#else
-#define MS_CALLBACK
-#endif
-
-#include "fips_utl.h"
-
-static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb);
-
-/* seed, out_p, out_q, out_g are taken from the earlier validation test
- * vectors.
- */
-
-static unsigned char seed[20] = {
- 0x1c, 0xfb, 0xa9, 0x6c, 0xf7, 0x95, 0xb3, 0x2e, 0x01, 0x01, 0x3c, 0x8d,
- 0x7f, 0x6e, 0xf4, 0x59, 0xcc, 0x2f, 0x19, 0x59
- };
-
-static unsigned char out_p[] = {
- 0xc2, 0x3c, 0x48, 0x31, 0x7e, 0x3b, 0x4e, 0x5d, 0x3c, 0x93, 0x78, 0x60,
- 0x5c, 0xf2, 0x60, 0xbb, 0x5a, 0xfa, 0x7f, 0x17, 0xf9, 0x26, 0x69, 0x46,
- 0xe7, 0x07, 0xbb, 0x3b, 0x2e, 0xc4, 0xb5, 0x66, 0xf7, 0x4d, 0xae, 0x9b,
- 0x8f, 0xf0, 0x42, 0xea, 0xb3, 0xa0, 0x7e, 0x81, 0x85, 0x89, 0xe6, 0xb0,
- 0x29, 0x03, 0x6b, 0xcc, 0xfb, 0x8e, 0x46, 0x15, 0x4d, 0xc1, 0x69, 0xd8,
- 0x2f, 0xef, 0x5c, 0x8b, 0x29, 0x32, 0x41, 0xbd, 0x13, 0x72, 0x3d, 0xac,
- 0x81, 0xcc, 0x86, 0x6c, 0x06, 0x5d, 0x51, 0xa1, 0xa5, 0x07, 0x0c, 0x3e,
- 0xbe, 0xdd, 0xf4, 0x6e, 0xa8, 0xed, 0xb4, 0x2f, 0xbd, 0x3e, 0x64, 0xea,
- 0xee, 0x92, 0xec, 0x51, 0xe1, 0x0d, 0xab, 0x25, 0x45, 0xae, 0x55, 0x21,
- 0x4d, 0xd6, 0x96, 0x6f, 0xe6, 0xaa, 0xd3, 0xca, 0x87, 0x92, 0xb1, 0x1c,
- 0x3c, 0xaf, 0x29, 0x09, 0x8b, 0xc6, 0xed, 0xe1
- };
-
-static unsigned char out_q[] = {
- 0xae, 0x0a, 0x8c, 0xfb, 0x80, 0xe1, 0xc6, 0xd1, 0x09, 0x0f, 0x26, 0xde,
- 0x91, 0x53, 0xc2, 0x8b, 0x2b, 0x0f, 0xde, 0x7f
- };
-
-static unsigned char out_g[] = {
- 0x0d, 0x7d, 0x92, 0x74, 0x10, 0xf6, 0xa4, 0x43, 0x86, 0x9a, 0xd1, 0xd9,
- 0x56, 0x00, 0xbc, 0x18, 0x97, 0x99, 0x4e, 0x9a, 0x93, 0xfb, 0x00, 0x3d,
- 0x6c, 0xa0, 0x1b, 0x95, 0x6b, 0xbd, 0xf7, 0x7a, 0xbc, 0x36, 0x3f, 0x3d,
- 0xb9, 0xbf, 0xf9, 0x91, 0x37, 0x68, 0xd1, 0xb9, 0x1e, 0xfe, 0x7f, 0x10,
- 0xc0, 0x6a, 0xcd, 0x5f, 0xc1, 0x65, 0x1a, 0xb8, 0xe7, 0xab, 0xb5, 0xc6,
- 0x8d, 0xb7, 0x86, 0xad, 0x3a, 0xbf, 0x6b, 0x7b, 0x0a, 0x66, 0xbe, 0xd5,
- 0x58, 0x23, 0x16, 0x48, 0x83, 0x29, 0xb6, 0xa7, 0x64, 0xc7, 0x08, 0xbe,
- 0x55, 0x4c, 0x6f, 0xcb, 0x34, 0xc1, 0x73, 0xb0, 0x39, 0x68, 0x52, 0xdf,
- 0x27, 0x7f, 0x32, 0xbc, 0x2b, 0x0d, 0x63, 0xed, 0x75, 0x3e, 0xb5, 0x54,
- 0xac, 0xc8, 0x20, 0x2a, 0x73, 0xe8, 0x29, 0x51, 0x03, 0x77, 0xe8, 0xc9,
- 0x61, 0x32, 0x25, 0xaf, 0x21, 0x5b, 0x6e, 0xda
- };
-
-
-static const unsigned char str1[]="12345678901234567890";
-
-static const char rnd_seed[] = "string to make the random number generator think it has entropy";
-
-int main(int argc, char **argv)
- {
- DSA *dsa=NULL;
- EVP_PKEY pk;
- int counter,ret=0,i,j;
- unsigned int slen;
- unsigned char buf[256];
- unsigned long h;
- BN_GENCB cb;
- EVP_MD_CTX mctx;
- BN_GENCB_set(&cb, dsa_cb, stderr);
- EVP_MD_CTX_init(&mctx);
-
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- EXIT(1);
- }
-
- fprintf(stderr,"test generation of DSA parameters\n");
-
- dsa = FIPS_dsa_new();
- DSA_generate_parameters_ex(dsa, 1024,seed,20,&counter,&h,&cb);
-
- fprintf(stderr,"seed\n");
- for (i=0; i<20; i+=4)
- {
- fprintf(stderr,"%02X%02X%02X%02X ",
- seed[i],seed[i+1],seed[i+2],seed[i+3]);
- }
- fprintf(stderr,"\ncounter=%d h=%ld\n",counter,h);
-
- if (dsa == NULL) goto end;
- if (counter != 16)
- {
- fprintf(stderr,"counter should be 105\n");
- goto end;
- }
- if (h != 2)
- {
- fprintf(stderr,"h should be 2\n");
- goto end;
- }
-
- i=BN_bn2bin(dsa->q,buf);
- j=sizeof(out_q);
- if ((i != j) || (memcmp(buf,out_q,i) != 0))
- {
- fprintf(stderr,"q value is wrong\n");
- goto end;
- }
-
- i=BN_bn2bin(dsa->p,buf);
- j=sizeof(out_p);
- if ((i != j) || (memcmp(buf,out_p,i) != 0))
- {
- fprintf(stderr,"p value is wrong\n");
- goto end;
- }
-
- i=BN_bn2bin(dsa->g,buf);
- j=sizeof(out_g);
- if ((i != j) || (memcmp(buf,out_g,i) != 0))
- {
- fprintf(stderr,"g value is wrong\n");
- goto end;
- }
- DSA_generate_key(dsa);
- pk.type = EVP_PKEY_DSA;
- pk.pkey.dsa = dsa;
-
- if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
- goto end;
- if (!EVP_SignUpdate(&mctx, str1, 20))
- goto end;
- if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
- goto end;
-
- if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
- goto end;
- if (!EVP_VerifyUpdate(&mctx, str1, 20))
- goto end;
- if (EVP_VerifyFinal(&mctx, buf, slen, &pk) != 1)
- goto end;
-
- ret = 1;
-
-end:
- if (!ret)
- do_print_errors();
- if (dsa != NULL) FIPS_dsa_free(dsa);
- EVP_MD_CTX_cleanup(&mctx);
-#if 0
- CRYPTO_mem_leaks(bio_err);
-#endif
- EXIT(!ret);
- return(!ret);
- }
-
-static int cb_exit(int ec)
- {
- EXIT(ec);
- return(0); /* To keep some compilers quiet */
- }
-
-static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *cb)
- {
- char c='*';
- static int ok=0,num=0;
-
- if (p == 0) { c='.'; num++; };
- if (p == 1) c='+';
- if (p == 2) { c='*'; ok++; }
- if (p == 3) c='\n';
- fwrite(&c,1, 1, cb->arg);
- fflush(cb->arg);
-
- if (!ok && (p == 0) && (num > 1))
- {
- fprintf(cb->arg,"error in dsatest\n");
- cb_exit(1);
- }
- return 1;
- }
-#endif
diff --git a/crypto/openssl/fips/dsa/fips_dssvs.c b/crypto/openssl/fips/dsa/fips_dssvs.c
deleted file mode 100644
index 45f4e1c..0000000
--- a/crypto/openssl/fips/dsa/fips_dssvs.c
+++ /dev/null
@@ -1,537 +0,0 @@
-#include <openssl/opensslconf.h>
-
-#ifndef OPENSSL_FIPS
-#include <stdio.h>
-
-int main(int argc, char **argv)
-{
- printf("No FIPS DSA support\n");
- return(0);
-}
-#else
-
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/fips.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "fips_utl.h"
-
-static void pbn(const char *name, BIGNUM *bn)
- {
- int len, i;
- unsigned char *tmp;
- len = BN_num_bytes(bn);
- tmp = OPENSSL_malloc(len);
- if (!tmp)
- {
- fprintf(stderr, "Memory allocation error\n");
- return;
- }
- BN_bn2bin(bn, tmp);
- printf("%s = ", name);
- for (i = 0; i < len; i++)
- printf("%02X", tmp[i]);
- fputs("\n", stdout);
- OPENSSL_free(tmp);
- return;
- }
-
-static void primes()
- {
- char buf[10240];
- char lbuf[10240];
- char *keyword, *value;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- fputs(buf,stdout);
- if (!parse_line(&keyword, &value, lbuf, buf))
- continue;
- if(!strcmp(keyword,"Prime"))
- {
- BIGNUM *pp;
-
- pp=BN_new();
- do_hex2bn(&pp,value);
- printf("result= %c\n",
- BN_is_prime_ex(pp,20,NULL,NULL) ? 'P' : 'F');
- }
- }
- }
-
-static void pqg()
- {
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- int nmod=0;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- if (!parse_line(&keyword, &value, lbuf, buf))
- {
- fputs(buf,stdout);
- continue;
- }
- if(!strcmp(keyword,"[mod"))
- nmod=atoi(value);
- else if(!strcmp(keyword,"N"))
- {
- int n=atoi(value);
-
- printf("[mod = %d]\n\n",nmod);
-
- while(n--)
- {
- unsigned char seed[20];
- DSA *dsa;
- int counter;
- unsigned long h;
- dsa = FIPS_dsa_new();
-
- if (!DSA_generate_parameters_ex(dsa, nmod,seed,0,&counter,&h,NULL))
- {
- do_print_errors();
- exit(1);
- }
- pbn("P",dsa->p);
- pbn("Q",dsa->q);
- pbn("G",dsa->g);
- pv("Seed",seed,20);
- printf("c = %d\n",counter);
- printf("H = %lx\n",h);
- putc('\n',stdout);
- }
- }
- else
- fputs(buf,stdout);
- }
- }
-
-static void pqgver()
- {
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- BIGNUM *p = NULL, *q = NULL, *g = NULL;
- int counter, counter2;
- unsigned long h, h2;
- DSA *dsa=NULL;
- int nmod=0;
- unsigned char seed[1024];
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- if (!parse_line(&keyword, &value, lbuf, buf))
- {
- fputs(buf,stdout);
- continue;
- }
- fputs(buf, stdout);
- if(!strcmp(keyword,"[mod"))
- nmod=atoi(value);
- else if(!strcmp(keyword,"P"))
- p=hex2bn(value);
- else if(!strcmp(keyword,"Q"))
- q=hex2bn(value);
- else if(!strcmp(keyword,"G"))
- g=hex2bn(value);
- else if(!strcmp(keyword,"Seed"))
- {
- int slen = hex2bin(value, seed);
- if (slen != 20)
- {
- fprintf(stderr, "Seed parse length error\n");
- exit (1);
- }
- }
- else if(!strcmp(keyword,"c"))
- counter =atoi(buf+4);
- else if(!strcmp(keyword,"H"))
- {
- h = atoi(value);
- if (!p || !q || !g)
- {
- fprintf(stderr, "Parse Error\n");
- exit (1);
- }
- dsa = FIPS_dsa_new();
- if (!DSA_generate_parameters_ex(dsa, nmod,seed,20 ,&counter2,&h2,NULL))
- {
- do_print_errors();
- exit(1);
- }
- if (BN_cmp(dsa->p, p) || BN_cmp(dsa->q, q) || BN_cmp(dsa->g, g)
- || (counter != counter2) || (h != h2))
- printf("Result = F\n");
- else
- printf("Result = P\n");
- BN_free(p);
- BN_free(q);
- BN_free(g);
- p = NULL;
- q = NULL;
- g = NULL;
- FIPS_dsa_free(dsa);
- dsa = NULL;
- }
- }
- }
-
-/* Keypair verification routine. NB: this isn't part of the standard FIPS140-2
- * algorithm tests. It is an additional test to perform sanity checks on the
- * output of the KeyPair test.
- */
-
-static int dss_paramcheck(int nmod, BIGNUM *p, BIGNUM *q, BIGNUM *g,
- BN_CTX *ctx)
- {
- BIGNUM *rem = NULL;
- if (BN_num_bits(p) != nmod)
- return 0;
- if (BN_num_bits(q) != 160)
- return 0;
- if (BN_is_prime_ex(p, BN_prime_checks, ctx, NULL) != 1)
- return 0;
- if (BN_is_prime_ex(q, BN_prime_checks, ctx, NULL) != 1)
- return 0;
- rem = BN_new();
- if (!BN_mod(rem, p, q, ctx) || !BN_is_one(rem)
- || (BN_cmp(g, BN_value_one()) <= 0)
- || !BN_mod_exp(rem, g, q, p, ctx) || !BN_is_one(rem))
- {
- BN_free(rem);
- return 0;
- }
- /* Todo: check g */
- BN_free(rem);
- return 1;
- }
-
-static void keyver()
- {
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- BIGNUM *p = NULL, *q = NULL, *g = NULL, *X = NULL, *Y = NULL;
- BIGNUM *Y2;
- BN_CTX *ctx = NULL;
- int nmod=0, paramcheck = 0;
-
- ctx = BN_CTX_new();
- Y2 = BN_new();
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- if (!parse_line(&keyword, &value, lbuf, buf))
- {
- fputs(buf,stdout);
- continue;
- }
- if(!strcmp(keyword,"[mod"))
- {
- if (p)
- BN_free(p);
- p = NULL;
- if (q)
- BN_free(q);
- q = NULL;
- if (g)
- BN_free(g);
- g = NULL;
- paramcheck = 0;
- nmod=atoi(value);
- }
- else if(!strcmp(keyword,"P"))
- p=hex2bn(value);
- else if(!strcmp(keyword,"Q"))
- q=hex2bn(value);
- else if(!strcmp(keyword,"G"))
- g=hex2bn(value);
- else if(!strcmp(keyword,"X"))
- X=hex2bn(value);
- else if(!strcmp(keyword,"Y"))
- {
- Y=hex2bn(value);
- if (!p || !q || !g || !X || !Y)
- {
- fprintf(stderr, "Parse Error\n");
- exit (1);
- }
- pbn("P",p);
- pbn("Q",q);
- pbn("G",g);
- pbn("X",X);
- pbn("Y",Y);
- if (!paramcheck)
- {
- if (dss_paramcheck(nmod, p, q, g, ctx))
- paramcheck = 1;
- else
- paramcheck = -1;
- }
- if (paramcheck != 1)
- printf("Result = F\n");
- else
- {
- if (!BN_mod_exp(Y2, g, X, p, ctx) || BN_cmp(Y2, Y))
- printf("Result = F\n");
- else
- printf("Result = P\n");
- }
- BN_free(X);
- BN_free(Y);
- X = NULL;
- Y = NULL;
- }
- }
- if (p)
- BN_free(p);
- if (q)
- BN_free(q);
- if (g)
- BN_free(g);
- if (Y2)
- BN_free(Y2);
- }
-
-static void keypair()
- {
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- int nmod=0;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- if (!parse_line(&keyword, &value, lbuf, buf))
- {
- fputs(buf,stdout);
- continue;
- }
- if(!strcmp(keyword,"[mod"))
- nmod=atoi(value);
- else if(!strcmp(keyword,"N"))
- {
- DSA *dsa;
- int n=atoi(value);
-
- printf("[mod = %d]\n\n",nmod);
- dsa = FIPS_dsa_new();
- if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
- {
- do_print_errors();
- exit(1);
- }
- pbn("P",dsa->p);
- pbn("Q",dsa->q);
- pbn("G",dsa->g);
- putc('\n',stdout);
-
- while(n--)
- {
- if (!DSA_generate_key(dsa))
- {
- do_print_errors();
- exit(1);
- }
-
- pbn("X",dsa->priv_key);
- pbn("Y",dsa->pub_key);
- putc('\n',stdout);
- }
- }
- }
- }
-
-static void siggen()
- {
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- int nmod=0;
- DSA *dsa=NULL;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- if (!parse_line(&keyword, &value, lbuf, buf))
- {
- fputs(buf,stdout);
- continue;
- }
- if(!strcmp(keyword,"[mod"))
- {
- nmod=atoi(value);
- printf("[mod = %d]\n\n",nmod);
- if (dsa)
- FIPS_dsa_free(dsa);
- dsa = FIPS_dsa_new();
- if (!DSA_generate_parameters_ex(dsa, nmod,NULL,0,NULL,NULL,NULL))
- {
- do_print_errors();
- exit(1);
- }
- pbn("P",dsa->p);
- pbn("Q",dsa->q);
- pbn("G",dsa->g);
- putc('\n',stdout);
- }
- else if(!strcmp(keyword,"Msg"))
- {
- unsigned char msg[1024];
- unsigned char sbuf[60];
- unsigned int slen;
- int n;
- EVP_PKEY pk;
- EVP_MD_CTX mctx;
- DSA_SIG *sig;
- EVP_MD_CTX_init(&mctx);
-
- n=hex2bin(value,msg);
- pv("Msg",msg,n);
-
- if (!DSA_generate_key(dsa))
- {
- do_print_errors();
- exit(1);
- }
- pk.type = EVP_PKEY_DSA;
- pk.pkey.dsa = dsa;
- pbn("Y",dsa->pub_key);
-
- EVP_SignInit_ex(&mctx, EVP_dss1(), NULL);
- EVP_SignUpdate(&mctx, msg, n);
- EVP_SignFinal(&mctx, sbuf, &slen, &pk);
-
- sig = DSA_SIG_new();
- FIPS_dsa_sig_decode(sig, sbuf, slen);
-
- pbn("R",sig->r);
- pbn("S",sig->s);
- putc('\n',stdout);
- DSA_SIG_free(sig);
- EVP_MD_CTX_cleanup(&mctx);
- }
- }
- if (dsa)
- FIPS_dsa_free(dsa);
- }
-
-static void sigver()
- {
- DSA *dsa=NULL;
- char buf[1024];
- char lbuf[1024];
- unsigned char msg[1024];
- char *keyword, *value;
- int nmod=0, n=0;
- DSA_SIG sg, *sig = &sg;
-
- sig->r = NULL;
- sig->s = NULL;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- if (!parse_line(&keyword, &value, lbuf, buf))
- {
- fputs(buf,stdout);
- continue;
- }
- if(!strcmp(keyword,"[mod"))
- {
- nmod=atoi(value);
- if(dsa)
- FIPS_dsa_free(dsa);
- dsa=FIPS_dsa_new();
- }
- else if(!strcmp(keyword,"P"))
- dsa->p=hex2bn(value);
- else if(!strcmp(keyword,"Q"))
- dsa->q=hex2bn(value);
- else if(!strcmp(keyword,"G"))
- {
- dsa->g=hex2bn(value);
-
- printf("[mod = %d]\n\n",nmod);
- pbn("P",dsa->p);
- pbn("Q",dsa->q);
- pbn("G",dsa->g);
- putc('\n',stdout);
- }
- else if(!strcmp(keyword,"Msg"))
- {
- n=hex2bin(value,msg);
- pv("Msg",msg,n);
- }
- else if(!strcmp(keyword,"Y"))
- dsa->pub_key=hex2bn(value);
- else if(!strcmp(keyword,"R"))
- sig->r=hex2bn(value);
- else if(!strcmp(keyword,"S"))
- {
- EVP_MD_CTX mctx;
- EVP_PKEY pk;
- unsigned char sigbuf[60];
- unsigned int slen;
- int r;
- EVP_MD_CTX_init(&mctx);
- pk.type = EVP_PKEY_DSA;
- pk.pkey.dsa = dsa;
- sig->s=hex2bn(value);
-
- pbn("Y",dsa->pub_key);
- pbn("R",sig->r);
- pbn("S",sig->s);
-
- slen = FIPS_dsa_sig_encode(sigbuf, sig);
- EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL);
- EVP_VerifyUpdate(&mctx, msg, n);
- r = EVP_VerifyFinal(&mctx, sigbuf, slen, &pk);
- EVP_MD_CTX_cleanup(&mctx);
-
- printf("Result = %c\n", r == 1 ? 'P' : 'F');
- putc('\n',stdout);
- }
- }
- }
-
-int main(int argc,char **argv)
- {
- if(argc != 2)
- {
- fprintf(stderr,"%s [prime|pqg|pqgver|keypair|siggen|sigver]\n",argv[0]);
- exit(1);
- }
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- exit(1);
- }
- if(!strcmp(argv[1],"prime"))
- primes();
- else if(!strcmp(argv[1],"pqg"))
- pqg();
- else if(!strcmp(argv[1],"pqgver"))
- pqgver();
- else if(!strcmp(argv[1],"keypair"))
- keypair();
- else if(!strcmp(argv[1],"keyver"))
- keyver();
- else if(!strcmp(argv[1],"siggen"))
- siggen();
- else if(!strcmp(argv[1],"sigver"))
- sigver();
- else
- {
- fprintf(stderr,"Don't know how to %s.\n",argv[1]);
- exit(1);
- }
-
- return 0;
- }
-
-#endif
diff --git a/crypto/openssl/fips/fips-nodiff.txt b/crypto/openssl/fips/fips-nodiff.txt
deleted file mode 100644
index fb2944b..0000000
--- a/crypto/openssl/fips/fips-nodiff.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-KeyPair.rsp
-PQGGen.rsp
-SigGen.rsp
-SigGen15.rsp
-SigGenPSS.rsp
-SigGenRSA.rsp
-SigGenPSS.rsp
diff --git a/crypto/openssl/fips/fips.c b/crypto/openssl/fips/fips.c
deleted file mode 100644
index 7dcc344..0000000
--- a/crypto/openssl/fips/fips.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-
-#include <openssl/rand.h>
-#include <openssl/fips_rand.h>
-#include <openssl/err.h>
-#include <openssl/bio.h>
-#include <openssl/hmac.h>
-#include <openssl/rsa.h>
-#include <string.h>
-#include <limits.h>
-#include "fips_locl.h"
-
-#ifdef OPENSSL_FIPS
-
-#include <openssl/fips.h>
-
-#ifndef PATH_MAX
-#define PATH_MAX 1024
-#endif
-
-static int fips_selftest_fail;
-static int fips_mode;
-static const void *fips_rand_check;
-
-static void fips_set_mode(int onoff)
- {
- int owning_thread = fips_is_owning_thread();
-
- if (fips_is_started())
- {
- if (!owning_thread) fips_w_lock();
- fips_mode = onoff;
- if (!owning_thread) fips_w_unlock();
- }
- }
-
-static void fips_set_rand_check(const void *rand_check)
- {
- int owning_thread = fips_is_owning_thread();
-
- if (fips_is_started())
- {
- if (!owning_thread) fips_w_lock();
- fips_rand_check = rand_check;
- if (!owning_thread) fips_w_unlock();
- }
- }
-
-int FIPS_mode(void)
- {
- int ret = 0;
- int owning_thread = fips_is_owning_thread();
-
- if (fips_is_started())
- {
- if (!owning_thread) fips_r_lock();
- ret = fips_mode;
- if (!owning_thread) fips_r_unlock();
- }
- return ret;
- }
-
-const void *FIPS_rand_check(void)
- {
- const void *ret = 0;
- int owning_thread = fips_is_owning_thread();
-
- if (fips_is_started())
- {
- if (!owning_thread) fips_r_lock();
- ret = fips_rand_check;
- if (!owning_thread) fips_r_unlock();
- }
- return ret;
- }
-
-int FIPS_selftest_failed(void)
- {
- int ret = 0;
- if (fips_is_started())
- {
- int owning_thread = fips_is_owning_thread();
-
- if (!owning_thread) fips_r_lock();
- ret = fips_selftest_fail;
- if (!owning_thread) fips_r_unlock();
- }
- return ret;
- }
-
-/* Selftest failure fatal exit routine. This will be called
- * during *any* cryptographic operation. It has the minimum
- * overhead possible to avoid too big a performance hit.
- */
-
-void FIPS_selftest_check(void)
- {
- if (fips_selftest_fail)
- {
- OpenSSLDie(__FILE__,__LINE__, "FATAL FIPS SELFTEST FAILURE");
- }
- }
-
-void fips_set_selftest_fail(void)
- {
- fips_selftest_fail = 1;
- }
-
-int FIPS_selftest()
- {
-
- return FIPS_selftest_sha1()
- && FIPS_selftest_hmac()
- && FIPS_selftest_aes()
- && FIPS_selftest_des()
- && FIPS_selftest_rsa()
- && FIPS_selftest_dsa();
- }
-
-extern const void *FIPS_text_start(), *FIPS_text_end();
-extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
-unsigned char FIPS_signature [20] = { 0 };
-static const char FIPS_hmac_key[]="etaonrishdlcupfm";
-
-unsigned int FIPS_incore_fingerprint(unsigned char *sig,unsigned int len)
- {
- const unsigned char *p1 = FIPS_text_start();
- const unsigned char *p2 = FIPS_text_end();
- const unsigned char *p3 = FIPS_rodata_start;
- const unsigned char *p4 = FIPS_rodata_end;
- HMAC_CTX c;
-
- HMAC_CTX_init(&c);
- HMAC_Init(&c,FIPS_hmac_key,strlen(FIPS_hmac_key),EVP_sha1());
-
- /* detect overlapping regions */
- if (p1<=p3 && p2>=p3)
- p3=p1, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
- else if (p3<=p1 && p4>=p1)
- p3=p3, p4=p2>p4?p2:p4, p1=NULL, p2=NULL;
-
- if (p1)
- HMAC_Update(&c,p1,(size_t)p2-(size_t)p1);
-
- if (FIPS_signature>=p3 && FIPS_signature<p4)
- {
- /* "punch" hole */
- HMAC_Update(&c,p3,(size_t)FIPS_signature-(size_t)p3);
- p3 = FIPS_signature+sizeof(FIPS_signature);
- if (p3<p4)
- HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
- }
- else
- HMAC_Update(&c,p3,(size_t)p4-(size_t)p3);
-
- HMAC_Final(&c,sig,&len);
- HMAC_CTX_cleanup(&c);
-
- return len;
- }
-
-int FIPS_check_incore_fingerprint(void)
- {
- unsigned char sig[EVP_MAX_MD_SIZE];
- unsigned int len;
-#if defined(__sgi) && (defined(__mips) || defined(mips))
- extern int __dso_displacement[];
-#else
- extern int OPENSSL_NONPIC_relocated;
-#endif
-
- if (FIPS_text_start()==NULL)
- {
- FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_UNSUPPORTED_PLATFORM);
- return 0;
- }
-
- len=FIPS_incore_fingerprint (sig,sizeof(sig));
-
- if (len!=sizeof(FIPS_signature) ||
- memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
- {
- if (FIPS_signature>=FIPS_rodata_start && FIPS_signature<FIPS_rodata_end)
- FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING);
-#if defined(__sgi) && (defined(__mips) || defined(mips))
- else if (__dso_displacement!=NULL)
-#else
- else if (OPENSSL_NONPIC_relocated)
-#endif
- FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED);
- else
- FIPSerr(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT,FIPS_R_FINGERPRINT_DOES_NOT_MATCH);
- return 0;
- }
-
- return 1;
- }
-
-int FIPS_mode_set(int onoff)
- {
- int fips_set_owning_thread();
- int fips_clear_owning_thread();
- int ret = 0;
-
- fips_w_lock();
- fips_set_started();
- fips_set_owning_thread();
-
- if(onoff)
- {
- unsigned char buf[48];
-
- fips_selftest_fail = 0;
-
- /* Don't go into FIPS mode twice, just so we can do automagic
- seeding */
- if(FIPS_mode())
- {
- FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_FIPS_MODE_ALREADY_SET);
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
-
-#ifdef OPENSSL_IA32_SSE2
- if ((OPENSSL_ia32cap & (1<<25|1<<26)) != (1<<25|1<<26))
- {
- FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_UNSUPPORTED_PLATFORM);
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
-#endif
-
- if(fips_signature_witness() != FIPS_signature)
- {
- FIPSerr(FIPS_F_FIPS_MODE_SET,FIPS_R_CONTRADICTING_EVIDENCE);
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
-
- if(!FIPS_check_incore_fingerprint())
- {
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
-
- /* Perform RNG KAT before seeding */
- if (!FIPS_selftest_rng())
- {
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
-
- /* automagically seed PRNG if not already seeded */
- if(!FIPS_rand_status())
- {
- if(RAND_bytes(buf,sizeof buf) <= 0)
- {
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
- FIPS_rand_set_key(buf,32);
- FIPS_rand_seed(buf+32,16);
- }
-
- /* now switch into FIPS mode */
- fips_set_rand_check(FIPS_rand_method());
- RAND_set_rand_method(FIPS_rand_method());
- if(FIPS_selftest())
- fips_set_mode(1);
- else
- {
- fips_selftest_fail = 1;
- ret = 0;
- goto end;
- }
- ret = 1;
- goto end;
- }
- fips_set_mode(0);
- fips_selftest_fail = 0;
- ret = 1;
-end:
- fips_clear_owning_thread();
- fips_w_unlock();
- return ret;
- }
-
-void fips_w_lock(void) { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); }
-void fips_w_unlock(void) { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); }
-void fips_r_lock(void) { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); }
-void fips_r_unlock(void) { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); }
-
-static int fips_started = 0;
-static unsigned long fips_thread = 0;
-
-void fips_set_started(void)
- {
- fips_started = 1;
- }
-
-int fips_is_started(void)
- {
- return fips_started;
- }
-
-int fips_is_owning_thread(void)
- {
- int ret = 0;
-
- if (fips_is_started())
- {
- CRYPTO_r_lock(CRYPTO_LOCK_FIPS2);
- if (fips_thread != 0 && fips_thread == CRYPTO_thread_id())
- ret = 1;
- CRYPTO_r_unlock(CRYPTO_LOCK_FIPS2);
- }
- return ret;
- }
-
-int fips_set_owning_thread(void)
- {
- int ret = 0;
-
- if (fips_is_started())
- {
- CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
- if (fips_thread == 0)
- {
- fips_thread = CRYPTO_thread_id();
- ret = 1;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
- }
- return ret;
- }
-
-int fips_clear_owning_thread(void)
- {
- int ret = 0;
-
- if (fips_is_started())
- {
- CRYPTO_w_lock(CRYPTO_LOCK_FIPS2);
- if (fips_thread == CRYPTO_thread_id())
- {
- fips_thread = 0;
- ret = 1;
- }
- CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
- }
- return ret;
- }
-
-unsigned char *fips_signature_witness(void)
- {
- extern unsigned char FIPS_signature[];
- return FIPS_signature;
- }
-
-/* Generalized public key test routine. Signs and verifies the data
- * supplied in tbs using mesage digest md and setting option digest
- * flags md_flags. If the 'kat' parameter is not NULL it will
- * additionally check the signature matches it: a known answer test
- * The string "fail_str" is used for identification purposes in case
- * of failure.
- */
-
-int fips_pkey_signature_test(EVP_PKEY *pkey,
- const unsigned char *tbs, int tbslen,
- const unsigned char *kat, unsigned int katlen,
- const EVP_MD *digest, unsigned int md_flags,
- const char *fail_str)
- {
- int ret = 0;
- unsigned char sigtmp[256], *sig = sigtmp;
- unsigned int siglen;
- EVP_MD_CTX mctx;
- EVP_MD_CTX_init(&mctx);
-
- if ((pkey->type == EVP_PKEY_RSA)
- && (RSA_size(pkey->pkey.rsa) > sizeof(sigtmp)))
- {
- sig = OPENSSL_malloc(RSA_size(pkey->pkey.rsa));
- if (!sig)
- {
- FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,ERR_R_MALLOC_FAILURE);
- return 0;
- }
- }
-
- if (tbslen == -1)
- tbslen = strlen((char *)tbs);
-
- if (md_flags)
- M_EVP_MD_CTX_set_flags(&mctx, md_flags);
-
- if (!EVP_SignInit_ex(&mctx, digest, NULL))
- goto error;
- if (!EVP_SignUpdate(&mctx, tbs, tbslen))
- goto error;
- if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
- goto error;
-
- if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
- goto error;
-
- if (!EVP_VerifyInit_ex(&mctx, digest, NULL))
- goto error;
- if (!EVP_VerifyUpdate(&mctx, tbs, tbslen))
- goto error;
- ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
-
- error:
- if (sig != sigtmp)
- OPENSSL_free(sig);
- EVP_MD_CTX_cleanup(&mctx);
- if (ret != 1)
- {
- FIPSerr(FIPS_F_FIPS_PKEY_SIGNATURE_TEST,FIPS_R_TEST_FAILURE);
- if (fail_str)
- ERR_add_error_data(2, "Type=", fail_str);
- return 0;
- }
- return 1;
- }
-
-/* Generalized symmetric cipher test routine. Encrypt data, verify result
- * against known answer, decrypt and compare with original plaintext.
- */
-
-int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
- const unsigned char *key,
- const unsigned char *iv,
- const unsigned char *plaintext,
- const unsigned char *ciphertext,
- int len)
- {
- unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
- unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
- OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
- if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1) <= 0)
- return 0;
- EVP_Cipher(ctx, citmp, plaintext, len);
- if (memcmp(citmp, ciphertext, len))
- return 0;
- if (EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 0) <= 0)
- return 0;
- EVP_Cipher(ctx, pltmp, citmp, len);
- if (memcmp(pltmp, plaintext, len))
- return 0;
- return 1;
- }
-
-#if 0
-/* The purpose of this is to ensure the error code exists and the function
- * name is to keep the error checking script quiet
- */
-void hash_final(void)
- {
- FIPSerr(FIPS_F_HASH_FINAL,FIPS_R_NON_FIPS_METHOD);
- }
-#endif
-
-
-#endif
diff --git a/crypto/openssl/fips/fips.h b/crypto/openssl/fips/fips.h
deleted file mode 100644
index 42bdcf2..0000000
--- a/crypto/openssl/fips/fips.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <openssl/opensslconf.h>
-
-#ifndef OPENSSL_FIPS
-#error FIPS is disabled.
-#endif
-
-#ifdef OPENSSL_FIPS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct dsa_st;
-struct evp_pkey_st;
-struct env_md_st;
-struct evp_cipher_st;
-struct evp_cipher_ctx_st;
-
-int FIPS_mode_set(int onoff);
-int FIPS_mode(void);
-const void *FIPS_rand_check(void);
-int FIPS_selftest_failed(void);
-void FIPS_selftest_check(void);
-void FIPS_corrupt_sha1(void);
-int FIPS_selftest_sha1(void);
-void FIPS_corrupt_aes(void);
-int FIPS_selftest_aes(void);
-void FIPS_corrupt_des(void);
-int FIPS_selftest_des(void);
-void FIPS_corrupt_rsa(void);
-void FIPS_corrupt_rsa_keygen(void);
-int FIPS_selftest_rsa(void);
-void FIPS_corrupt_dsa(void);
-void FIPS_corrupt_dsa_keygen(void);
-int FIPS_selftest_dsa(void);
-void FIPS_corrupt_rng(void);
-void FIPS_rng_stick(void);
-int FIPS_selftest_rng(void);
-int FIPS_selftest_hmac(void);
-
-int fips_pkey_signature_test(struct evp_pkey_st *pkey,
- const unsigned char *tbs, int tbslen,
- const unsigned char *kat, unsigned int katlen,
- const struct env_md_st *digest, unsigned int md_flags,
- const char *fail_str);
-
-int fips_cipher_test(struct evp_cipher_ctx_st *ctx,
- const struct evp_cipher_st *cipher,
- const unsigned char *key,
- const unsigned char *iv,
- const unsigned char *plaintext,
- const unsigned char *ciphertext,
- int len);
-
-/* BEGIN ERROR CODES */
-/* The following lines are auto generated by the script mkerr.pl. Any changes
- * made after this point may be overwritten when the script is next run.
- */
-void ERR_load_FIPS_strings(void);
-
-/* Error codes for the FIPS functions. */
-
-/* Function codes. */
-#define FIPS_F_DH_BUILTIN_GENPARAMS 100
-#define FIPS_F_DSA_BUILTIN_PARAMGEN 101
-#define FIPS_F_DSA_DO_SIGN 102
-#define FIPS_F_DSA_DO_VERIFY 103
-#define FIPS_F_EVP_CIPHERINIT_EX 124
-#define FIPS_F_EVP_DIGESTINIT_EX 125
-#define FIPS_F_FIPS_CHECK_DSA 104
-#define FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT 105
-#define FIPS_F_FIPS_CHECK_RSA 106
-#define FIPS_F_FIPS_DSA_CHECK 107
-#define FIPS_F_FIPS_MODE_SET 108
-#define FIPS_F_FIPS_PKEY_SIGNATURE_TEST 109
-#define FIPS_F_FIPS_SELFTEST_AES 110
-#define FIPS_F_FIPS_SELFTEST_DES 111
-#define FIPS_F_FIPS_SELFTEST_DSA 112
-#define FIPS_F_FIPS_SELFTEST_HMAC 113
-#define FIPS_F_FIPS_SELFTEST_RNG 114
-#define FIPS_F_FIPS_SELFTEST_SHA1 115
-#define FIPS_F_HASH_FINAL 123
-#define FIPS_F_RSA_BUILTIN_KEYGEN 116
-#define FIPS_F_RSA_EAY_PRIVATE_DECRYPT 117
-#define FIPS_F_RSA_EAY_PRIVATE_ENCRYPT 118
-#define FIPS_F_RSA_EAY_PUBLIC_DECRYPT 119
-#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT 120
-#define FIPS_F_RSA_X931_GENERATE_KEY_EX 121
-#define FIPS_F_SSLEAY_RAND_BYTES 122
-
-/* Reason codes. */
-#define FIPS_R_CANNOT_READ_EXE 103
-#define FIPS_R_CANNOT_READ_EXE_DIGEST 104
-#define FIPS_R_CONTRADICTING_EVIDENCE 114
-#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH 105
-#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH 110
-#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED 111
-#define FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING 112
-#define FIPS_R_FIPS_MODE_ALREADY_SET 102
-#define FIPS_R_FIPS_SELFTEST_FAILED 106
-#define FIPS_R_INVALID_KEY_LENGTH 109
-#define FIPS_R_KEY_TOO_SHORT 108
-#define FIPS_R_NON_FIPS_METHOD 100
-#define FIPS_R_PAIRWISE_TEST_FAILED 107
-#define FIPS_R_RSA_DECRYPT_ERROR 115
-#define FIPS_R_RSA_ENCRYPT_ERROR 116
-#define FIPS_R_SELFTEST_FAILED 101
-#define FIPS_R_TEST_FAILURE 117
-#define FIPS_R_UNSUPPORTED_PLATFORM 113
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/crypto/openssl/fips/fips_canister.c b/crypto/openssl/fips/fips_canister.c
deleted file mode 100644
index 17446618..0000000
--- a/crypto/openssl/fips/fips_canister.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
- * and usage in source and binary forms are granted according to the
- * OpenSSL license.
- */
-
-#include <stdio.h>
-#if defined(__DECC)
-# include <c_asm.h>
-# pragma __nostandard
-#endif
-
-#include "e_os.h"
-
-#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
-# if (defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
- (defined(__sgi) && (defined(__mips) || defined(mips))) || \
- (defined(__osf__) && defined(__alpha)) || \
- (defined(__linux) && (defined(__arm) || defined(__arm__))) || \
- (defined(__i386) || defined(__i386__)) || \
- (defined(__x86_64) || defined(__x86_64__)) || \
- defined(__ANDROID__) || \
- (defined(vax) || defined(__vax__))
-# define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
-# endif
-#endif
-
-#if defined(__xlC__) && __xlC__>=0x600 && (defined(_POWER) || defined(_ARCH_PPC))
-static void *instruction_pointer_xlc(void);
-# pragma mc_func instruction_pointer_xlc {\
- "7c0802a6" /* mflr r0 */ \
- "48000005" /* bl $+4 */ \
- "7c6802a6" /* mflr r3 */ \
- "7c0803a6" /* mtlr r0 */ }
-# pragma reg_killed_by instruction_pointer_xlc gr0 gr3
-# define INSTRUCTION_POINTER_IMPLEMENTED(ret) (ret=instruction_pointer_xlc());
-#endif
-
-#ifdef FIPS_START
-#define FIPS_ref_point FIPS_text_start
-/* Some compilers put string literals into a separate segment. As we
- * are mostly interested to hash AES tables in .rodata, we declare
- * reference points accordingly. In case you wonder, the values are
- * big-endian encoded variable names, just to prevent these arrays
- * from being merged by linker. */
-const unsigned int FIPS_rodata_start[]=
- { 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
-#else
-#define FIPS_ref_point FIPS_text_end
-const unsigned int FIPS_rodata_end[]=
- { 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b };
-#endif
-
-/*
- * I declare reference function as static in order to avoid certain
- * pitfalls in -dynamic linker behaviour...
- */
-static void *instruction_pointer(void)
-{ void *ret=NULL;
-/* These are ABI-neutral CPU-specific snippets. ABI-neutrality means
- * that they are designed to work under any OS running on particular
- * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in
- * this function. */
-#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
- INSTRUCTION_POINTER_IMPLEMENTED(ret);
-#elif defined(__GNUC__) && __GNUC__>=2
-# if defined(__alpha) || defined(__alpha__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- __asm __volatile ( "br %0,1f\n1:" : "=r"(ret) );
-# elif defined(__i386) || defined(__i386__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- __asm __volatile ( "call 1f\n1: popl %0" : "=r"(ret) );
- ret = (void *)((size_t)ret&~3UL); /* align for better performance */
-# elif defined(__ia64) || defined(__ia64__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- __asm __volatile ( "mov %0=ip" : "=r"(ret) );
-# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- __asm __volatile ( "blr %%r0,%0\n\tnop" : "=r"(ret) );
- ret = (void *)((size_t)ret&~3UL); /* mask privilege level */
-# elif defined(__mips) || defined(__mips__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- void *scratch;
- __asm __volatile ( "move %1,$31\n\t" /* save ra */
- "bal .+8; nop\n\t"
- "move %0,$31\n\t"
- "move $31,%1" /* restore ra */
- : "=r"(ret),"=r"(scratch) );
-# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
- defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
- defined(__PPC64__) || defined(__powerpc64__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- void *scratch;
- __asm __volatile ( "mfspr %1,8\n\t" /* save lr */
- "bl $+4\n\t"
- "mfspr %0,8\n\t" /* mflr ret */
- "mtspr 8,%1" /* restore lr */
- : "=r"(ret),"=r"(scratch) );
-# elif defined(__s390__) || defined(__s390x__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- __asm __volatile ( "bras %0,1f\n1:" : "=r"(ret) );
- ret = (void *)((size_t)ret&~3UL);
-# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- void *scratch;
- __asm __volatile ( "mov %%o7,%1\n\t"
- "call .+8; nop\n\t"
- "mov %%o7,%0\n\t"
- "mov %1,%%o7"
- : "=r"(ret),"=r"(scratch) );
-# elif defined(__x86_64) || defined(__x86_64__)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- __asm __volatile ( "leaq 0(%%rip),%0" : "=r"(ret) );
- ret = (void *)((size_t)ret&~3UL); /* align for better performance */
-# endif
-#elif defined(__DECC) && defined(__alpha)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- ret = (void *)(size_t)asm("br %v0,1f\n1:");
-#elif defined(_MSC_VER) && defined(_M_IX86)
-# define INSTRUCTION_POINTER_IMPLEMENTED
- void *scratch;
- _asm {
- call self
- self: pop eax
- mov scratch,eax
- }
- ret = (void *)((size_t)scratch&~3UL);
-#endif
- return ret;
-}
-
-/*
- * This function returns pointer to an instruction in the vicinity of
- * its entry point, but not outside this object module. This guarantees
- * that sequestered code is covered...
- */
-void *FIPS_ref_point()
-{
-#if defined(INSTRUCTION_POINTER_IMPLEMENTED)
- return instruction_pointer();
-/* Below we essentially cover vendor compilers which do not support
- * inline assembler... */
-#elif defined(_AIX)
- struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
- return p->ip;
-#elif defined(_HPUX_SOURCE)
-# if defined(__hppa) || defined(__hppa__)
- struct { void *i[4]; } *p = (void *)FIPS_ref_point;
-
- if (sizeof(p) == 8) /* 64-bit */
- return p->i[2];
- else if ((size_t)p & 2)
- { p = (void *)((size_t)p&~3UL);
- return p->i[0];
- }
- else
- return (void *)p;
-# elif defined(__ia64) || defined(__ia64__)
- struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
- return (void *)(size_t)p->ip;
-# endif
-#elif (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
- /* applies to both alpha and ia64 */
- struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
- return (void *)(size_t)p->ip;
-#elif defined(__VOS__)
- /* applies to both pa-risc and ia32 */
- struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
- return p->ip;
-#elif defined(_WIN32)
-# if defined(_WIN64) && defined(_M_IA64)
- struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
- return p->ip;
-# else
- return (void *)FIPS_ref_point;
-# endif
-/*
- * In case you wonder why there is no #ifdef __linux. All Linux targets
- * are GCC-based and therefore are covered by instruction_pointer above
- * [well, some are covered by by the one below]...
- */
-#elif defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
- return (void *)instruction_pointer;
-#else
- return NULL;
-#endif
-}
diff --git a/crypto/openssl/fips/fips_locl.h b/crypto/openssl/fips/fips_locl.h
deleted file mode 100644
index b3ea289..0000000
--- a/crypto/openssl/fips/fips_locl.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#ifdef OPENSSL_FIPS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void fips_w_lock(void);
-void fips_w_unlock(void);
-void fips_r_lock(void);
-void fips_r_unlock(void);
-int fips_is_started(void);
-void fips_set_started(void);
-int fips_is_owning_thread(void);
-int fips_set_owning_thread(void);
-void fips_set_selftest_fail(void);
-int fips_clear_owning_thread(void);
-unsigned char *fips_signature_witness(void);
-int fips_check_rsa(RSA *rsa);
-
-#define FIPS_MAX_CIPHER_TEST_SIZE 16
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/crypto/openssl/fips/fips_premain.c b/crypto/openssl/fips/fips_premain.c
deleted file mode 100644
index 165d2c5..0000000
--- a/crypto/openssl/fips/fips_premain.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
- * and usage in source and binary forms are granted according to the
- * OpenSSL license.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#if defined(__unix) || defined(__unix__)
-#include <unistd.h>
-#endif
-
-#ifndef FINGERPRINT_PREMAIN_DSO_LOAD
-
-#if defined(__GNUC__) && __GNUC__>=2
- void FINGERPRINT_premain(void) __attribute__((constructor));
- /* Most commonly this results in pointer to premain to be dropped
- * to .ctors segment, which is traversed by GCC crtbegin.o upon
- * program startup. Except on a.out OpenBSD where it results in
- * _GLOBAL_$I$premain() {premain();} being auto-generated by
- * compiler... But one way or another this is believed to cover
- * *all* GCC targets. */
-#elif defined(_MSC_VER)
-# ifdef _WINDLL
- __declspec(dllexport) /* this is essentially cosmetics... */
-# endif
- void FINGERPRINT_premain(void);
- static int premain_wrapper(void) { FINGERPRINT_premain(); return 0; }
-# ifdef _WIN64
-# pragma section(".CRT$XCU",read)
- __declspec(allocate(".CRT$XCU"))
-# else
-# pragma data_seg(".CRT$XCU")
-# endif
- static int (*p)(void) = premain_wrapper;
- /* This results in pointer to premain to appear in .CRT segment,
- * which is traversed by Visual C run-time initialization code.
- * This applies to both Win32 and [all flavors of] Win64. */
-# pragma data_seg()
-#elif defined(__SUNPRO_C)
- void FINGERPRINT_premain(void);
-# pragma init(FINGERPRINT_premain)
- /* This results in a call to premain to appear in .init segment. */
-#elif defined(__DECC) && (defined(__VMS) || defined(VMS))
- void FINGERPRINT_premain(void);
-# pragma __nostandard
- globaldef { "LIB$INITIALIZ" } readonly _align (LONGWORD)
- int spare[8] = {0};
- globaldef { "LIB$INITIALIZE" } readonly _align (LONGWORD)
- void (*x_FINGERPRINT_premain)(void) = FINGERPRINT_premain;
- /* Refer to LIB$INITIALIZE to ensure it exists in the image. */
- int lib$initialize();
- globaldef int (*lib_init_ref)() = lib$initialize;
-# pragma __standard
-#elif 0
- The rest has to be taken care of through command line:
-
- -Wl,-init,FINGERPRINT_premain on OSF1 and IRIX
- -Wl,+init,FINGERPRINT_premain on HP-UX
- -Wl,-binitfini:FINGERPRINT_premain on AIX
-
- On ELF platforms this results in a call to premain to appear in
- .init segment...
-#endif
-
-#ifndef HMAC_SHA1_SIG
-#define HMAC_SHA1_SIG "?have to make sure this string is unique"
-#endif
-
-static const unsigned char FINGERPRINT_ascii_value[40] = HMAC_SHA1_SIG;
-
-#define atox(c) ((c)>='a'?((c)-'a'+10):((c)>='A'?(c)-'A'+10:(c)-'0'))
-
-extern const void *FIPS_text_start(), *FIPS_text_end();
-extern const unsigned char FIPS_rodata_start[], FIPS_rodata_end[];
-extern unsigned char FIPS_signature[20];
-extern unsigned int FIPS_incore_fingerprint(unsigned char *,unsigned int);
-
-/*
- * As name suggests this code is executed prior main(). We use this
- * opportunity to fingerprint sequestered code in virtual address
- * space of target application.
- */
-void FINGERPRINT_premain(void)
-{ unsigned char sig[sizeof(FIPS_signature)];
- const unsigned char * volatile p=FINGERPRINT_ascii_value;
- unsigned int len=sizeof(sig),i;
-
- /* "volatilization" is done to disengage unwanted optimization... */
- if (*((volatile unsigned char *)p)=='?')
- { if (FIPS_text_start()==NULL)
- { fprintf(stderr,"FIPS_text_start() returns NULL\n");
- _exit(1);
- }
-#if defined(DEBUG_FINGERPRINT_PREMAIN)
- fprintf(stderr,".text:%p+%d=%p\n",FIPS_text_start(),
- (int)((size_t)FIPS_text_end()-(size_t)FIPS_text_start()),
- FIPS_text_end());
- fprintf(stderr,".rodata:%p+%d=%p\n",FIPS_rodata_start,
- (int)((size_t)FIPS_rodata_end-(size_t)FIPS_rodata_start),
- FIPS_rodata_end);
-#endif
-
- len=FIPS_incore_fingerprint(sig,sizeof(sig));
-
- if (len!=sizeof(sig))
- { fprintf(stderr,"fingerprint length mismatch: %u\n",len);
- _exit(1);
- }
-
- for (i=0;i<len;i++) printf("%02x",sig[i]);
- printf("\n");
- fflush(stdout);
- _exit(0);
- }
- else if (FIPS_signature[0]=='\0') do
- { for (i=0;i<sizeof(FIPS_signature);i++,p+=2)
- FIPS_signature[i] = (atox(p[0])<<4)|atox(p[1]);
-
-#if defined(DEBUG_FINGERPRINT_PREMAIN)
- if (getenv("OPENSSL_FIPS")==NULL) break;
-
- len=FIPS_incore_fingerprint(sig,sizeof(sig));
-
- if (memcmp(FIPS_signature,sig,sizeof(FIPS_signature)))
- { fprintf(stderr,"FINGERPRINT_premain: FIPS_signature mismatch\n");
- _exit(1);
- }
-#endif
- } while(0);
-}
-
-#else
-
-#include <openssl/bio.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-
-int main(int argc,char *argv[])
-{ DSO *dso;
- DSO_FUNC_TYPE func;
- BIO *bio_err;
-
- if (argc < 2)
- { fprintf (stderr,"usage: %s libcrypto.dso\n",argv[0]);
- return 1;
- }
-
- if ((bio_err=BIO_new(BIO_s_file())) == NULL)
- { fprintf (stderr,"unable to allocate BIO\n");
- return 1;
- }
- BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
- ERR_load_crypto_strings();
-
- dso = DSO_load(NULL,argv[1],NULL,DSO_FLAG_NO_NAME_TRANSLATION);
- if (dso == NULL)
- { ERR_print_errors(bio_err);
- return 1;
- }
-
- /* This is not normally reached, because FINGERPRINT_premain should
- * have executed and terminated application already upon DSO_load... */
- func = DSO_bind_func(dso,"FINGERPRINT_premain");
- if (func == NULL)
- { ERR_print_errors(bio_err);
- return 1;
- }
-
- (*func)();
-
- return 0;
-}
-
-#endif
diff --git a/crypto/openssl/fips/fips_premain.c.sha1 b/crypto/openssl/fips/fips_premain.c.sha1
deleted file mode 100644
index c16f964..0000000
--- a/crypto/openssl/fips/fips_premain.c.sha1
+++ /dev/null
@@ -1 +0,0 @@
-HMAC-SHA1(fips_premain.c)= 9e5ddba185ac446e0cf36fcf8e1b3acffe5d0b2c
diff --git a/crypto/openssl/fips/fips_test_suite.c b/crypto/openssl/fips/fips_test_suite.c
deleted file mode 100644
index 2bc0ba9..0000000
--- a/crypto/openssl/fips/fips_test_suite.c
+++ /dev/null
@@ -1,579 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 The OpenSSL Project. All rights reserved.
- *
- *
- * This command is intended as a test driver for the FIPS-140 testing
- * lab performing FIPS-140 validation. It demonstrates the use of the
- * OpenSSL library ito perform a variety of common cryptographic
- * functions. A power-up self test is demonstrated by deliberately
- * pointing to an invalid executable hash
- *
- * Contributed by Steve Marquess.
- *
- */
-#include <stdio.h>
-#include <assert.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include <openssl/aes.h>
-#include <openssl/des.h>
-#include <openssl/hmac.h>
-#include <openssl/err.h>
-
-#include <openssl/bn.h>
-#include <openssl/rand.h>
-#include <openssl/sha.h>
-
-
-#ifndef OPENSSL_FIPS
-int main(int argc, char *argv[])
- {
- printf("No FIPS support\n");
- return(0);
- }
-#else
-
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-#include <openssl/dh.h>
-
-#include <openssl/fips.h>
-#include "fips_utl.h"
-
-/* AES: encrypt and decrypt known plaintext, verify result matches original plaintext
-*/
-static int FIPS_aes_test(void)
- {
- int ret = 0;
- unsigned char pltmp[16];
- unsigned char citmp[16];
- unsigned char key[16] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
- unsigned char plaintext[16] = "etaonrishdlcu";
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
- if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 1) <= 0)
- goto err;
- EVP_Cipher(&ctx, citmp, plaintext, 16);
- if (EVP_CipherInit_ex(&ctx, EVP_aes_128_ecb(),NULL, key, NULL, 0) <= 0)
- goto err;
- EVP_Cipher(&ctx, pltmp, citmp, 16);
- if (memcmp(pltmp, plaintext, 16))
- goto err;
- ret = 1;
- err:
- EVP_CIPHER_CTX_cleanup(&ctx);
- return ret;
- }
-
-static int FIPS_des3_test(void)
- {
- int ret = 0;
- unsigned char pltmp[8];
- unsigned char citmp[8];
- unsigned char key[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,
- 19,20,21,22,23,24};
- unsigned char plaintext[] = { 'e', 't', 'a', 'o', 'n', 'r', 'i', 's' };
- EVP_CIPHER_CTX ctx;
- EVP_CIPHER_CTX_init(&ctx);
- if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 1) <= 0)
- goto err;
- EVP_Cipher(&ctx, citmp, plaintext, 8);
- if (EVP_CipherInit_ex(&ctx, EVP_des_ede3_ecb(),NULL, key, NULL, 0) <= 0)
- goto err;
- EVP_Cipher(&ctx, pltmp, citmp, 8);
- if (memcmp(pltmp, plaintext, 8))
- goto err;
- ret = 1;
- err:
- EVP_CIPHER_CTX_cleanup(&ctx);
- return ret;
- }
-
-/*
- * DSA: generate keys and sign, verify input plaintext.
- */
-static int FIPS_dsa_test(int bad)
- {
- DSA *dsa = NULL;
- EVP_PKEY pk;
- unsigned char dgst[] = "etaonrishdlc";
- unsigned char buf[60];
- unsigned int slen;
- int r = 0;
- EVP_MD_CTX mctx;
-
- ERR_clear_error();
- EVP_MD_CTX_init(&mctx);
- dsa = FIPS_dsa_new();
- if (!dsa)
- goto end;
- if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
- goto end;
- if (!DSA_generate_key(dsa))
- goto end;
- if (bad)
- BN_add_word(dsa->pub_key, 1);
-
- pk.type = EVP_PKEY_DSA;
- pk.pkey.dsa = dsa;
-
- if (!EVP_SignInit_ex(&mctx, EVP_dss1(), NULL))
- goto end;
- if (!EVP_SignUpdate(&mctx, dgst, sizeof(dgst) - 1))
- goto end;
- if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
- goto end;
-
- if (!EVP_VerifyInit_ex(&mctx, EVP_dss1(), NULL))
- goto end;
- if (!EVP_VerifyUpdate(&mctx, dgst, sizeof(dgst) - 1))
- goto end;
- r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
- end:
- EVP_MD_CTX_cleanup(&mctx);
- if (dsa)
- FIPS_dsa_free(dsa);
- if (r != 1)
- return 0;
- return 1;
- }
-
-/*
- * RSA: generate keys and sign, verify input plaintext.
- */
-static int FIPS_rsa_test(int bad)
- {
- RSA *key;
- unsigned char input_ptext[] = "etaonrishdlc";
- unsigned char buf[256];
- unsigned int slen;
- BIGNUM *bn;
- EVP_MD_CTX mctx;
- EVP_PKEY pk;
- int r = 0;
-
- ERR_clear_error();
- EVP_MD_CTX_init(&mctx);
- key = FIPS_rsa_new();
- bn = BN_new();
- if (!key || !bn)
- return 0;
- BN_set_word(bn, 65537);
- if (!RSA_generate_key_ex(key, 1024,bn,NULL))
- return 0;
- BN_free(bn);
- if (bad)
- BN_add_word(key->n, 1);
-
- pk.type = EVP_PKEY_RSA;
- pk.pkey.rsa = key;
-
- if (!EVP_SignInit_ex(&mctx, EVP_sha1(), NULL))
- goto end;
- if (!EVP_SignUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
- goto end;
- if (!EVP_SignFinal(&mctx, buf, &slen, &pk))
- goto end;
-
- if (!EVP_VerifyInit_ex(&mctx, EVP_sha1(), NULL))
- goto end;
- if (!EVP_VerifyUpdate(&mctx, input_ptext, sizeof(input_ptext) - 1))
- goto end;
- r = EVP_VerifyFinal(&mctx, buf, slen, &pk);
- end:
- EVP_MD_CTX_cleanup(&mctx);
- if (key)
- FIPS_rsa_free(key);
- if (r != 1)
- return 0;
- return 1;
- }
-
-/* SHA1: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_sha1_test()
- {
- unsigned char digest[SHA_DIGEST_LENGTH] =
- { 0x11, 0xf1, 0x9a, 0x3a, 0xec, 0x1a, 0x1e, 0x8e, 0x65, 0xd4, 0x9a, 0x38, 0x0c, 0x8b, 0x1e, 0x2c, 0xe8, 0xb3, 0xc5, 0x18 };
- unsigned char str[] = "etaonrishd";
-
- unsigned char md[SHA_DIGEST_LENGTH];
-
- ERR_clear_error();
- if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha1(), NULL)) return 0;
- if (memcmp(md,digest,sizeof(md)))
- return 0;
- return 1;
- }
-
-/* SHA256: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_sha256_test()
- {
- unsigned char digest[SHA256_DIGEST_LENGTH] =
- {0xf5, 0x53, 0xcd, 0xb8, 0xcf, 0x1, 0xee, 0x17, 0x9b, 0x93, 0xc9, 0x68, 0xc0, 0xea, 0x40, 0x91,
- 0x6, 0xec, 0x8e, 0x11, 0x96, 0xc8, 0x5d, 0x1c, 0xaf, 0x64, 0x22, 0xe6, 0x50, 0x4f, 0x47, 0x57};
- unsigned char str[] = "etaonrishd";
-
- unsigned char md[SHA256_DIGEST_LENGTH];
-
- ERR_clear_error();
- if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha256(), NULL)) return 0;
- if (memcmp(md,digest,sizeof(md)))
- return 0;
- return 1;
- }
-
-/* SHA512: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_sha512_test()
- {
- unsigned char digest[SHA512_DIGEST_LENGTH] =
- {0x99, 0xc9, 0xe9, 0x5b, 0x88, 0xd4, 0x78, 0x88, 0xdf, 0x88, 0x5f, 0x94, 0x71, 0x64, 0x28, 0xca,
- 0x16, 0x1f, 0x3d, 0xf4, 0x1f, 0xf3, 0x0f, 0xc5, 0x03, 0x99, 0xb2, 0xd0, 0xe7, 0x0b, 0x94, 0x4a,
- 0x45, 0xd2, 0x6c, 0x4f, 0x20, 0x06, 0xef, 0x71, 0xa9, 0x25, 0x7f, 0x24, 0xb1, 0xd9, 0x40, 0x22,
- 0x49, 0x54, 0x10, 0xc2, 0x22, 0x9d, 0x27, 0xfe, 0xbd, 0xd6, 0xd6, 0xeb, 0x2d, 0x42, 0x1d, 0xa3};
- unsigned char str[] = "etaonrishd";
-
- unsigned char md[SHA512_DIGEST_LENGTH];
-
- ERR_clear_error();
- if (!EVP_Digest(str,sizeof(str) - 1,md, NULL, EVP_sha512(), NULL)) return 0;
- if (memcmp(md,digest,sizeof(md)))
- return 0;
- return 1;
- }
-
-/* HMAC-SHA1: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_hmac_sha1_test()
- {
- unsigned char key[] = "etaonrishd";
- unsigned char iv[] = "Sample text";
- unsigned char kaval[EVP_MAX_MD_SIZE] =
- {0x73, 0xf7, 0xa0, 0x48, 0xf8, 0x94, 0xed, 0xdd, 0x0a, 0xea, 0xea, 0x56, 0x1b, 0x61, 0x2e, 0x70,
- 0xb2, 0xfb, 0xec, 0xc6};
-
- unsigned char out[EVP_MAX_MD_SIZE];
- unsigned int outlen;
-
- ERR_clear_error();
- if (!HMAC(EVP_sha1(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
- if (memcmp(out,kaval,outlen))
- return 0;
- return 1;
- }
-
-/* HMAC-SHA224: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_hmac_sha224_test()
- {
- unsigned char key[] = "etaonrishd";
- unsigned char iv[] = "Sample text";
- unsigned char kaval[EVP_MAX_MD_SIZE] =
- {0x75, 0x58, 0xd5, 0xbd, 0x55, 0x6d, 0x87, 0x0f, 0x75, 0xff, 0xbe, 0x1c, 0xb2, 0xf0, 0x20, 0x35,
- 0xe5, 0x62, 0x49, 0xb6, 0x94, 0xb9, 0xfc, 0x65, 0x34, 0x33, 0x3a, 0x19};
-
- unsigned char out[EVP_MAX_MD_SIZE];
- unsigned int outlen;
-
- ERR_clear_error();
- if (!HMAC(EVP_sha224(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
- if (memcmp(out,kaval,outlen))
- return 0;
- return 1;
- }
-
-/* HMAC-SHA256: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_hmac_sha256_test()
- {
- unsigned char key[] = "etaonrishd";
- unsigned char iv[] = "Sample text";
- unsigned char kaval[EVP_MAX_MD_SIZE] =
- {0xe9, 0x17, 0xc1, 0x7b, 0x4c, 0x6b, 0x77, 0xda, 0xd2, 0x30, 0x36, 0x02, 0xf5, 0x72, 0x33, 0x87,
- 0x9f, 0xc6, 0x6e, 0x7b, 0x7e, 0xa8, 0xea, 0xaa, 0x9f, 0xba, 0xee, 0x51, 0xff, 0xda, 0x24, 0xf4};
-
- unsigned char out[EVP_MAX_MD_SIZE];
- unsigned int outlen;
-
- ERR_clear_error();
- if (!HMAC(EVP_sha256(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
- if (memcmp(out,kaval,outlen))
- return 0;
- return 1;
- }
-
-/* HMAC-SHA384: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_hmac_sha384_test()
- {
- unsigned char key[] = "etaonrishd";
- unsigned char iv[] = "Sample text";
- unsigned char kaval[EVP_MAX_MD_SIZE] =
- {0xb2, 0x9d, 0x40, 0x58, 0x32, 0xc4, 0xe3, 0x31, 0xb6, 0x63, 0x08, 0x26, 0x99, 0xef, 0x3b, 0x10,
- 0xe2, 0xdf, 0xf8, 0xff, 0xc6, 0xe1, 0x03, 0x29, 0x81, 0x2a, 0x1b, 0xac, 0xb0, 0x07, 0x39, 0x08,
- 0xf3, 0x91, 0x35, 0x11, 0x76, 0xd6, 0x4c, 0x20, 0xfb, 0x4d, 0xc3, 0xf3, 0xb8, 0x9b, 0x88, 0x1c};
-
- unsigned char out[EVP_MAX_MD_SIZE];
- unsigned int outlen;
-
- ERR_clear_error();
- if (!HMAC(EVP_sha384(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
- if (memcmp(out,kaval,outlen))
- return 0;
- return 1;
- }
-
-/* HMAC-SHA512: generate hash of known digest value and compare to known
- precomputed correct hash
-*/
-static int FIPS_hmac_sha512_test()
- {
- unsigned char key[] = "etaonrishd";
- unsigned char iv[] = "Sample text";
- unsigned char kaval[EVP_MAX_MD_SIZE] =
- {0xcd, 0x3e, 0xb9, 0x51, 0xb8, 0xbc, 0x7f, 0x9a, 0x23, 0xaf, 0xf3, 0x77, 0x59, 0x85, 0xa9, 0xe6,
- 0xf7, 0xd1, 0x51, 0x96, 0x17, 0xe0, 0x92, 0xd8, 0xa6, 0x3b, 0xc1, 0xad, 0x7e, 0x24, 0xca, 0xb1,
- 0xd7, 0x79, 0x0a, 0xa5, 0xea, 0x2c, 0x02, 0x58, 0x0b, 0xa6, 0x52, 0x6b, 0x61, 0x7f, 0xeb, 0x9c,
- 0x47, 0x86, 0x5d, 0x74, 0x2b, 0x88, 0xdf, 0xee, 0x46, 0x69, 0x96, 0x3d, 0xa6, 0xd9, 0x2a, 0x53};
-
- unsigned char out[EVP_MAX_MD_SIZE];
- unsigned int outlen;
-
- ERR_clear_error();
- if (!HMAC(EVP_sha512(),key,sizeof(key)-1,iv,sizeof(iv)-1,out,&outlen)) return 0;
- if (memcmp(out,kaval,outlen))
- return 0;
- return 1;
- }
-
-
-/* DH: generate shared parameters
-*/
-static int dh_test()
- {
- DH *dh;
- ERR_clear_error();
- dh = FIPS_dh_new();
- if (!dh)
- return 0;
- if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
- return 0;
- FIPS_dh_free(dh);
- return 1;
- }
-
-/* Zeroize
-*/
-static int Zeroize()
- {
- RSA *key;
- BIGNUM *bn;
- unsigned char userkey[16] =
- { 0x48, 0x50, 0xf0, 0xa3, 0x3a, 0xed, 0xd3, 0xaf, 0x6e, 0x47, 0x7f, 0x83, 0x02, 0xb1, 0x09, 0x68 };
- size_t i;
- int n;
-
- key = FIPS_rsa_new();
- bn = BN_new();
- if (!key || !bn)
- return 0;
- BN_set_word(bn, 65537);
- if (!RSA_generate_key_ex(key, 1024,bn,NULL))
- return 0;
- BN_free(bn);
-
- n = BN_num_bytes(key->d);
- printf(" Generated %d byte RSA private key\n", n);
- printf("\tBN key before overwriting:\n");
- do_bn_print(stdout, key->d);
- BN_rand(key->d,n*8,-1,0);
- printf("\tBN key after overwriting:\n");
- do_bn_print(stdout, key->d);
-
- printf("\tchar buffer key before overwriting: \n\t\t");
- for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
- printf("\n");
- RAND_bytes(userkey, sizeof userkey);
- printf("\tchar buffer key after overwriting: \n\t\t");
- for(i = 0; i < sizeof(userkey); i++) printf("%02x", userkey[i]);
- printf("\n");
-
- return 1;
- }
-
-static int Error;
-static const char * Fail(const char *msg)
- {
- do_print_errors();
- Error++;
- return msg;
- }
-
-static void test_msg(const char *msg, int result)
- {
- printf("%s...%s\n", msg, result ? "successful" : Fail("Failed!"));
- }
-
-int main(int argc,char **argv)
- {
-
- int do_corrupt_rsa_keygen = 0, do_corrupt_dsa_keygen = 0;
- int bad_rsa = 0, bad_dsa = 0;
- int do_rng_stick = 0;
- int no_exit = 0;
-
- printf("\tFIPS-mode test application\n\n");
-
- /* Load entropy from external file, if any */
- RAND_load_file(".rnd", 1024);
-
- if (argv[1]) {
- /* Corrupted KAT tests */
- if (!strcmp(argv[1], "aes")) {
- FIPS_corrupt_aes();
- printf("AES encryption/decryption with corrupted KAT...\n");
- } else if (!strcmp(argv[1], "des")) {
- FIPS_corrupt_des();
- printf("DES3-ECB encryption/decryption with corrupted KAT...\n");
- } else if (!strcmp(argv[1], "dsa")) {
- FIPS_corrupt_dsa();
- printf("DSA key generation and signature validation with corrupted KAT...\n");
- } else if (!strcmp(argv[1], "rsa")) {
- FIPS_corrupt_rsa();
- printf("RSA key generation and signature validation with corrupted KAT...\n");
- } else if (!strcmp(argv[1], "rsakey")) {
- printf("RSA key generation and signature validation with corrupted key...\n");
- bad_rsa = 1;
- no_exit = 1;
- } else if (!strcmp(argv[1], "rsakeygen")) {
- do_corrupt_rsa_keygen = 1;
- no_exit = 1;
- printf("RSA key generation and signature validation with corrupted keygen...\n");
- } else if (!strcmp(argv[1], "dsakey")) {
- printf("DSA key generation and signature validation with corrupted key...\n");
- bad_dsa = 1;
- no_exit = 1;
- } else if (!strcmp(argv[1], "dsakeygen")) {
- do_corrupt_dsa_keygen = 1;
- no_exit = 1;
- printf("DSA key generation and signature validation with corrupted keygen...\n");
- } else if (!strcmp(argv[1], "sha1")) {
- FIPS_corrupt_sha1();
- printf("SHA-1 hash with corrupted KAT...\n");
- } else if (!strcmp(argv[1], "rng")) {
- FIPS_corrupt_rng();
- } else if (!strcmp(argv[1], "rngstick")) {
- do_rng_stick = 1;
- no_exit = 1;
- printf("RNG test with stuck continuous test...\n");
- } else {
- printf("Bad argument \"%s\"\n", argv[1]);
- exit(1);
- }
- if (!no_exit) {
- if (!FIPS_mode_set(1)) {
- do_print_errors();
- printf("Power-up self test failed\n");
- exit(1);
- }
- printf("Power-up self test successful\n");
- exit(0);
- }
- }
-
- /* Non-Approved cryptographic operation
- */
- printf("1. Non-Approved cryptographic operation test...\n");
- test_msg("\ta. Included algorithm (D-H)...", dh_test());
-
- /* Power-up self test
- */
- ERR_clear_error();
- test_msg("2. Automatic power-up self test", FIPS_mode_set(1));
- if (!FIPS_mode())
- exit(1);
- if (do_corrupt_dsa_keygen)
- FIPS_corrupt_dsa_keygen();
- if (do_corrupt_rsa_keygen)
- FIPS_corrupt_rsa_keygen();
- if (do_rng_stick)
- FIPS_rng_stick();
-
- /* AES encryption/decryption
- */
- test_msg("3. AES encryption/decryption", FIPS_aes_test());
-
- /* RSA key generation and encryption/decryption
- */
- test_msg("4. RSA key generation and encryption/decryption",
- FIPS_rsa_test(bad_rsa));
-
- /* DES-CBC encryption/decryption
- */
- test_msg("5. DES-ECB encryption/decryption", FIPS_des3_test());
-
- /* DSA key generation and signature validation
- */
- test_msg("6. DSA key generation and signature validation",
- FIPS_dsa_test(bad_dsa));
-
- /* SHA-1 hash
- */
- test_msg("7a. SHA-1 hash", FIPS_sha1_test());
-
- /* SHA-256 hash
- */
- test_msg("7b. SHA-256 hash", FIPS_sha256_test());
-
- /* SHA-512 hash
- */
- test_msg("7c. SHA-512 hash", FIPS_sha512_test());
-
- /* HMAC-SHA-1 hash
- */
- test_msg("7d. HMAC-SHA-1 hash", FIPS_hmac_sha1_test());
-
- /* HMAC-SHA-224 hash
- */
- test_msg("7e. HMAC-SHA-224 hash", FIPS_hmac_sha224_test());
-
- /* HMAC-SHA-256 hash
- */
- test_msg("7f. HMAC-SHA-256 hash", FIPS_hmac_sha256_test());
-
- /* HMAC-SHA-384 hash
- */
- test_msg("7g. HMAC-SHA-384 hash", FIPS_hmac_sha384_test());
-
- /* HMAC-SHA-512 hash
- */
- test_msg("7h. HMAC-SHA-512 hash", FIPS_hmac_sha512_test());
-
- /* Non-Approved cryptographic operation
- */
- printf("8. Non-Approved cryptographic operation test...\n");
- printf("\ta. Included algorithm (D-H)...%s\n",
- dh_test() ? "successful as expected"
- : Fail("failed INCORRECTLY!") );
-
- /* Zeroization
- */
- printf("9. Zero-ization...\n\t%s\n",
- Zeroize() ? "successful as expected"
- : Fail("failed INCORRECTLY!") );
-
- printf("\nAll tests completed with %d errors\n", Error);
- return Error ? 1 : 0;
- }
-
-#endif
diff --git a/crypto/openssl/fips/fips_utl.h b/crypto/openssl/fips/fips_utl.h
deleted file mode 100644
index 85d9e12..0000000
--- a/crypto/openssl/fips/fips_utl.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2007 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.
- *
- */
-
-void do_print_errors(void);
-int hex2bin(const char *in, unsigned char *out);
-unsigned char *hex2bin_m(const char *in, long *plen);
-int do_hex2bn(BIGNUM **pr, const char *in);
-int do_bn_print(FILE *out, BIGNUM *bn);
-int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn);
-int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf);
-BIGNUM *hex2bn(const char *in);
-int bin2hex(const unsigned char *in,int len,char *out);
-void pv(const char *tag,const unsigned char *val,int len);
-int tidy_line(char *linebuf, char *olinebuf);
-int bint2bin(const char *in, int len, unsigned char *out);
-int bin2bint(const unsigned char *in,int len,char *out);
-void PrintValue(char *tag, unsigned char *val, int len);
-void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode);
-
-void do_print_errors(void)
- {
- const char *file, *data;
- int line, flags;
- unsigned long l;
- while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)))
- {
- fprintf(stderr, "ERROR:%lx:lib=%d,func=%d,reason=%d"
- ":file=%s:line=%d:%s\n",
- l, ERR_GET_LIB(l), ERR_GET_FUNC(l), ERR_GET_REASON(l),
- file, line, flags & ERR_TXT_STRING ? data : "");
- }
- }
-
-int hex2bin(const char *in, unsigned char *out)
- {
- int n1, n2;
- unsigned char ch;
-
- for (n1=0,n2=0 ; in[n1] && in[n1] != '\n' ; )
- { /* first byte */
- if ((in[n1] >= '0') && (in[n1] <= '9'))
- ch = in[n1++] - '0';
- else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
- ch = in[n1++] - 'A' + 10;
- else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
- ch = in[n1++] - 'a' + 10;
- else
- return -1;
- if(!in[n1])
- {
- out[n2++]=ch;
- break;
- }
- out[n2] = ch << 4;
- /* second byte */
- if ((in[n1] >= '0') && (in[n1] <= '9'))
- ch = in[n1++] - '0';
- else if ((in[n1] >= 'A') && (in[n1] <= 'F'))
- ch = in[n1++] - 'A' + 10;
- else if ((in[n1] >= 'a') && (in[n1] <= 'f'))
- ch = in[n1++] - 'a' + 10;
- else
- return -1;
- out[n2++] |= ch;
- }
- return n2;
- }
-
-unsigned char *hex2bin_m(const char *in, long *plen)
- {
- unsigned char *p;
- p = OPENSSL_malloc((strlen(in) + 1)/2);
- *plen = hex2bin(in, p);
- return p;
- }
-
-int do_hex2bn(BIGNUM **pr, const char *in)
- {
- unsigned char *p;
- long plen;
- int r = 0;
- p = hex2bin_m(in, &plen);
- if (!p)
- return 0;
- if (!*pr)
- *pr = BN_new();
- if (!*pr)
- return 0;
- if (BN_bin2bn(p, plen, *pr))
- r = 1;
- OPENSSL_free(p);
- return r;
- }
-
-int do_bn_print(FILE *out, BIGNUM *bn)
- {
- int len, i;
- unsigned char *tmp;
- len = BN_num_bytes(bn);
- if (len == 0)
- {
- fputs("00", out);
- return 1;
- }
-
- tmp = OPENSSL_malloc(len);
- if (!tmp)
- {
- fprintf(stderr, "Memory allocation error\n");
- return 0;
- }
- BN_bn2bin(bn, tmp);
- for (i = 0; i < len; i++)
- fprintf(out, "%02x", tmp[i]);
- OPENSSL_free(tmp);
- return 1;
- }
-
-int do_bn_print_name(FILE *out, const char *name, BIGNUM *bn)
- {
- int r;
- fprintf(out, "%s = ", name);
- r = do_bn_print(out, bn);
- if (!r)
- return 0;
- fputs("\n", out);
- return 1;
- }
-
-int parse_line(char **pkw, char **pval, char *linebuf, char *olinebuf)
- {
- char *keyword, *value, *p, *q;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
-
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no '=' exit */
- if (!p)
- return 0;
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
-
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- *pkw = keyword;
- *pval = value;
- return 1;
- }
-
-BIGNUM *hex2bn(const char *in)
- {
- BIGNUM *p=NULL;
-
- if (!do_hex2bn(&p, in))
- return NULL;
-
- return p;
- }
-
-int bin2hex(const unsigned char *in,int len,char *out)
- {
- int n1, n2;
- unsigned char ch;
-
- for (n1=0,n2=0 ; n1 < len ; ++n1)
- {
- ch=in[n1] >> 4;
- if (ch <= 0x09)
- out[n2++]=ch+'0';
- else
- out[n2++]=ch-10+'a';
- ch=in[n1] & 0x0f;
- if(ch <= 0x09)
- out[n2++]=ch+'0';
- else
- out[n2++]=ch-10+'a';
- }
- out[n2]='\0';
- return n2;
- }
-
-void pv(const char *tag,const unsigned char *val,int len)
- {
- char obuf[2048];
-
- bin2hex(val,len,obuf);
- printf("%s = %s\n",tag,obuf);
- }
-
-/* To avoid extensive changes to test program at this stage just convert
- * the input line into an acceptable form. Keyword lines converted to form
- * "keyword = value\n" no matter what white space present, all other lines
- * just have leading and trailing space removed.
- */
-
-int tidy_line(char *linebuf, char *olinebuf)
- {
- char *keyword, *value, *p, *q;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no '=' just chop leading, trailing ws */
- if (!p)
- {
- p = keyword + strlen(keyword) - 1;
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
- strcpy(olinebuf, keyword);
- strcat(olinebuf, "\n");
- return 1;
- }
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
-
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- strcpy(olinebuf, keyword);
- strcat(olinebuf, " = ");
- strcat(olinebuf, value);
- strcat(olinebuf, "\n");
-
- return 1;
- }
-
-/* NB: this return the number of _bits_ read */
-int bint2bin(const char *in, int len, unsigned char *out)
- {
- int n;
-
- memset(out,0,len);
- for(n=0 ; n < len ; ++n)
- if(in[n] == '1')
- out[n/8]|=(0x80 >> (n%8));
- return len;
- }
-
-int bin2bint(const unsigned char *in,int len,char *out)
- {
- int n;
-
- for(n=0 ; n < len ; ++n)
- out[n]=(in[n/8]&(0x80 >> (n%8))) ? '1' : '0';
- return n;
- }
-
-/*-----------------------------------------------*/
-
-void PrintValue(char *tag, unsigned char *val, int len)
-{
-#if VERBOSE
- char obuf[2048];
- int olen;
- olen = bin2hex(val, len, obuf);
- printf("%s = %.*s\n", tag, olen, obuf);
-#endif
-}
-
-void OutputValue(char *tag, unsigned char *val, int len, FILE *rfp,int bitmode)
- {
- char obuf[2048];
- int olen;
-
- if(bitmode)
- olen=bin2bint(val,len,obuf);
- else
- olen=bin2hex(val,len,obuf);
-
- fprintf(rfp, "%s = %.*s\n", tag, olen, obuf);
-#if VERBOSE
- printf("%s = %.*s\n", tag, olen, obuf);
-#endif
- }
-
diff --git a/crypto/openssl/fips/fipsalgtest.pl b/crypto/openssl/fips/fipsalgtest.pl
deleted file mode 100755
index 851cc98..0000000
--- a/crypto/openssl/fips/fipsalgtest.pl
+++ /dev/null
@@ -1,887 +0,0 @@
-#!/usr/bin/perl -w
-# Perl utility to run or verify FIPS 140-2 CMVP algorithm tests based on the
-# pathnames of input algorithm test files actually present (the unqualified
-# file names are consistent but the pathnames are not).
-#
-
-# FIPS test definitions
-# List of all the unqualified file names we expect and command lines to run
-
-# DSA tests
-my @fips_dsa_test_list = (
-
- "DSA",
-
- [ "PQGGen", "fips_dssvs pqg" ],
- [ "KeyPair", "fips_dssvs keypair" ],
- [ "SigGen", "fips_dssvs siggen" ],
- [ "SigVer", "fips_dssvs sigver" ]
-
-);
-
-my @fips_dsa_pqgver_test_list = (
-
- [ "PQGVer", "fips_dssvs pqgver" ]
-
-);
-
-# RSA tests
-
-my @fips_rsa_test_list = (
-
- "RSA",
-
- [ "SigGen15", "fips_rsastest" ],
- [ "SigVer15", "fips_rsavtest" ],
- [ "SigVerRSA", "fips_rsavtest -x931" ],
- [ "KeyGenRSA", "fips_rsagtest" ],
- [ "SigGenRSA", "fips_rsastest -x931" ]
-
-);
-
-# Special cases for PSS. The filename itself is
-# not sufficient to determine the test. Addditionally we
-# need to examine the file contents to determine the salt length
-# In these cases the test filename has (saltlen) appended.
-
-# RSA PSS salt length 0 tests
-
-my @fips_rsa_pss0_test_list = (
-
- [ "SigGenPSS(0)", "fips_rsastest -saltlen 0" ],
- [ "SigVerPSS(0)", "fips_rsavtest -saltlen 0" ]
-
-);
-
-# RSA PSS salt length 62 tests
-
-my @fips_rsa_pss62_test_list = (
- [ "SigGenPSS(62)", "fips_rsastest -saltlen 62" ],
- [ "SigVerPSS(62)", "fips_rsavtest -saltlen 62" ]
-
-);
-
-# SHA tests
-
-my @fips_sha_test_list = (
-
- "SHA",
-
- [ "SHA1LongMsg", "fips_shatest" ],
- [ "SHA1Monte", "fips_shatest" ],
- [ "SHA1ShortMsg", "fips_shatest" ],
- [ "SHA224LongMsg", "fips_shatest" ],
- [ "SHA224Monte", "fips_shatest" ],
- [ "SHA224ShortMsg", "fips_shatest" ],
- [ "SHA256LongMsg", "fips_shatest" ],
- [ "SHA256Monte", "fips_shatest" ],
- [ "SHA256ShortMsg", "fips_shatest" ],
- [ "SHA384LongMsg", "fips_shatest" ],
- [ "SHA384Monte", "fips_shatest" ],
- [ "SHA384ShortMsg", "fips_shatest" ],
- [ "SHA512LongMsg", "fips_shatest" ],
- [ "SHA512Monte", "fips_shatest" ],
- [ "SHA512ShortMsg", "fips_shatest" ]
-
-);
-
-# HMAC
-
-my @fips_hmac_test_list = (
-
- "HMAC",
-
- [ "HMAC", "fips_hmactest" ]
-
-);
-
-# RAND tests, AES version
-
-my @fips_rand_aes_test_list = (
-
- "RAND (AES)",
-
- [ "ANSI931_AES128MCT", "fips_rngvs mct" ],
- [ "ANSI931_AES192MCT", "fips_rngvs mct" ],
- [ "ANSI931_AES256MCT", "fips_rngvs mct" ],
- [ "ANSI931_AES128VST", "fips_rngvs vst" ],
- [ "ANSI931_AES192VST", "fips_rngvs vst" ],
- [ "ANSI931_AES256VST", "fips_rngvs vst" ]
-
-);
-
-# RAND tests, DES2 version
-
-my @fips_rand_des2_test_list = (
-
- "RAND (DES2)",
-
- [ "ANSI931_TDES2MCT", "fips_rngvs mct" ],
- [ "ANSI931_TDES2VST", "fips_rngvs vst" ]
-
-);
-
-# AES tests
-
-my @fips_aes_test_list = (
-
- "AES",
-
- [ "CBCGFSbox128", "fips_aesavs -f" ],
- [ "CBCGFSbox192", "fips_aesavs -f" ],
- [ "CBCGFSbox256", "fips_aesavs -f" ],
- [ "CBCKeySbox128", "fips_aesavs -f" ],
- [ "CBCKeySbox192", "fips_aesavs -f" ],
- [ "CBCKeySbox256", "fips_aesavs -f" ],
- [ "CBCMCT128", "fips_aesavs -f" ],
- [ "CBCMCT192", "fips_aesavs -f" ],
- [ "CBCMCT256", "fips_aesavs -f" ],
- [ "CBCMMT128", "fips_aesavs -f" ],
- [ "CBCMMT192", "fips_aesavs -f" ],
- [ "CBCMMT256", "fips_aesavs -f" ],
- [ "CBCVarKey128", "fips_aesavs -f" ],
- [ "CBCVarKey192", "fips_aesavs -f" ],
- [ "CBCVarKey256", "fips_aesavs -f" ],
- [ "CBCVarTxt128", "fips_aesavs -f" ],
- [ "CBCVarTxt192", "fips_aesavs -f" ],
- [ "CBCVarTxt256", "fips_aesavs -f" ],
- [ "CFB128GFSbox128", "fips_aesavs -f" ],
- [ "CFB128GFSbox192", "fips_aesavs -f" ],
- [ "CFB128GFSbox256", "fips_aesavs -f" ],
- [ "CFB128KeySbox128", "fips_aesavs -f" ],
- [ "CFB128KeySbox192", "fips_aesavs -f" ],
- [ "CFB128KeySbox256", "fips_aesavs -f" ],
- [ "CFB128MCT128", "fips_aesavs -f" ],
- [ "CFB128MCT192", "fips_aesavs -f" ],
- [ "CFB128MCT256", "fips_aesavs -f" ],
- [ "CFB128MMT128", "fips_aesavs -f" ],
- [ "CFB128MMT192", "fips_aesavs -f" ],
- [ "CFB128MMT256", "fips_aesavs -f" ],
- [ "CFB128VarKey128", "fips_aesavs -f" ],
- [ "CFB128VarKey192", "fips_aesavs -f" ],
- [ "CFB128VarKey256", "fips_aesavs -f" ],
- [ "CFB128VarTxt128", "fips_aesavs -f" ],
- [ "CFB128VarTxt192", "fips_aesavs -f" ],
- [ "CFB128VarTxt256", "fips_aesavs -f" ],
- [ "CFB8GFSbox128", "fips_aesavs -f" ],
- [ "CFB8GFSbox192", "fips_aesavs -f" ],
- [ "CFB8GFSbox256", "fips_aesavs -f" ],
- [ "CFB8KeySbox128", "fips_aesavs -f" ],
- [ "CFB8KeySbox192", "fips_aesavs -f" ],
- [ "CFB8KeySbox256", "fips_aesavs -f" ],
- [ "CFB8MCT128", "fips_aesavs -f" ],
- [ "CFB8MCT192", "fips_aesavs -f" ],
- [ "CFB8MCT256", "fips_aesavs -f" ],
- [ "CFB8MMT128", "fips_aesavs -f" ],
- [ "CFB8MMT192", "fips_aesavs -f" ],
- [ "CFB8MMT256", "fips_aesavs -f" ],
- [ "CFB8VarKey128", "fips_aesavs -f" ],
- [ "CFB8VarKey192", "fips_aesavs -f" ],
- [ "CFB8VarKey256", "fips_aesavs -f" ],
- [ "CFB8VarTxt128", "fips_aesavs -f" ],
- [ "CFB8VarTxt192", "fips_aesavs -f" ],
- [ "CFB8VarTxt256", "fips_aesavs -f" ],
-
- [ "ECBGFSbox128", "fips_aesavs -f" ],
- [ "ECBGFSbox192", "fips_aesavs -f" ],
- [ "ECBGFSbox256", "fips_aesavs -f" ],
- [ "ECBKeySbox128", "fips_aesavs -f" ],
- [ "ECBKeySbox192", "fips_aesavs -f" ],
- [ "ECBKeySbox256", "fips_aesavs -f" ],
- [ "ECBMCT128", "fips_aesavs -f" ],
- [ "ECBMCT192", "fips_aesavs -f" ],
- [ "ECBMCT256", "fips_aesavs -f" ],
- [ "ECBMMT128", "fips_aesavs -f" ],
- [ "ECBMMT192", "fips_aesavs -f" ],
- [ "ECBMMT256", "fips_aesavs -f" ],
- [ "ECBVarKey128", "fips_aesavs -f" ],
- [ "ECBVarKey192", "fips_aesavs -f" ],
- [ "ECBVarKey256", "fips_aesavs -f" ],
- [ "ECBVarTxt128", "fips_aesavs -f" ],
- [ "ECBVarTxt192", "fips_aesavs -f" ],
- [ "ECBVarTxt256", "fips_aesavs -f" ],
- [ "OFBGFSbox128", "fips_aesavs -f" ],
- [ "OFBGFSbox192", "fips_aesavs -f" ],
- [ "OFBGFSbox256", "fips_aesavs -f" ],
- [ "OFBKeySbox128", "fips_aesavs -f" ],
- [ "OFBKeySbox192", "fips_aesavs -f" ],
- [ "OFBKeySbox256", "fips_aesavs -f" ],
- [ "OFBMCT128", "fips_aesavs -f" ],
- [ "OFBMCT192", "fips_aesavs -f" ],
- [ "OFBMCT256", "fips_aesavs -f" ],
- [ "OFBMMT128", "fips_aesavs -f" ],
- [ "OFBMMT192", "fips_aesavs -f" ],
- [ "OFBMMT256", "fips_aesavs -f" ],
- [ "OFBVarKey128", "fips_aesavs -f" ],
- [ "OFBVarKey192", "fips_aesavs -f" ],
- [ "OFBVarKey256", "fips_aesavs -f" ],
- [ "OFBVarTxt128", "fips_aesavs -f" ],
- [ "OFBVarTxt192", "fips_aesavs -f" ],
- [ "OFBVarTxt256", "fips_aesavs -f" ]
-
-);
-
-my @fips_aes_cfb1_test_list = (
-
- # AES CFB1 tests
-
- [ "CFB1GFSbox128", "fips_aesavs -f" ],
- [ "CFB1GFSbox192", "fips_aesavs -f" ],
- [ "CFB1GFSbox256", "fips_aesavs -f" ],
- [ "CFB1KeySbox128", "fips_aesavs -f" ],
- [ "CFB1KeySbox192", "fips_aesavs -f" ],
- [ "CFB1KeySbox256", "fips_aesavs -f" ],
- [ "CFB1MCT128", "fips_aesavs -f" ],
- [ "CFB1MCT192", "fips_aesavs -f" ],
- [ "CFB1MCT256", "fips_aesavs -f" ],
- [ "CFB1MMT128", "fips_aesavs -f" ],
- [ "CFB1MMT192", "fips_aesavs -f" ],
- [ "CFB1MMT256", "fips_aesavs -f" ],
- [ "CFB1VarKey128", "fips_aesavs -f" ],
- [ "CFB1VarKey192", "fips_aesavs -f" ],
- [ "CFB1VarKey256", "fips_aesavs -f" ],
- [ "CFB1VarTxt128", "fips_aesavs -f" ],
- [ "CFB1VarTxt192", "fips_aesavs -f" ],
- [ "CFB1VarTxt256", "fips_aesavs -f" ]
-
-);
-
-# Triple DES tests
-
-my @fips_des3_test_list = (
-
- "Triple DES",
-
- [ "TCBCinvperm", "fips_desmovs -f" ],
- [ "TCBCMMT1", "fips_desmovs -f" ],
- [ "TCBCMMT2", "fips_desmovs -f" ],
- [ "TCBCMMT3", "fips_desmovs -f" ],
- [ "TCBCMonte1", "fips_desmovs -f" ],
- [ "TCBCMonte2", "fips_desmovs -f" ],
- [ "TCBCMonte3", "fips_desmovs -f" ],
- [ "TCBCpermop", "fips_desmovs -f" ],
- [ "TCBCsubtab", "fips_desmovs -f" ],
- [ "TCBCvarkey", "fips_desmovs -f" ],
- [ "TCBCvartext", "fips_desmovs -f" ],
- [ "TCFB64invperm", "fips_desmovs -f" ],
- [ "TCFB64MMT1", "fips_desmovs -f" ],
- [ "TCFB64MMT2", "fips_desmovs -f" ],
- [ "TCFB64MMT3", "fips_desmovs -f" ],
- [ "TCFB64Monte1", "fips_desmovs -f" ],
- [ "TCFB64Monte2", "fips_desmovs -f" ],
- [ "TCFB64Monte3", "fips_desmovs -f" ],
- [ "TCFB64permop", "fips_desmovs -f" ],
- [ "TCFB64subtab", "fips_desmovs -f" ],
- [ "TCFB64varkey", "fips_desmovs -f" ],
- [ "TCFB64vartext", "fips_desmovs -f" ],
- [ "TCFB8invperm", "fips_desmovs -f" ],
- [ "TCFB8MMT1", "fips_desmovs -f" ],
- [ "TCFB8MMT2", "fips_desmovs -f" ],
- [ "TCFB8MMT3", "fips_desmovs -f" ],
- [ "TCFB8Monte1", "fips_desmovs -f" ],
- [ "TCFB8Monte2", "fips_desmovs -f" ],
- [ "TCFB8Monte3", "fips_desmovs -f" ],
- [ "TCFB8permop", "fips_desmovs -f" ],
- [ "TCFB8subtab", "fips_desmovs -f" ],
- [ "TCFB8varkey", "fips_desmovs -f" ],
- [ "TCFB8vartext", "fips_desmovs -f" ],
- [ "TECBinvperm", "fips_desmovs -f" ],
- [ "TECBMMT1", "fips_desmovs -f" ],
- [ "TECBMMT2", "fips_desmovs -f" ],
- [ "TECBMMT3", "fips_desmovs -f" ],
- [ "TECBMonte1", "fips_desmovs -f" ],
- [ "TECBMonte2", "fips_desmovs -f" ],
- [ "TECBMonte3", "fips_desmovs -f" ],
- [ "TECBpermop", "fips_desmovs -f" ],
- [ "TECBsubtab", "fips_desmovs -f" ],
- [ "TECBvarkey", "fips_desmovs -f" ],
- [ "TECBvartext", "fips_desmovs -f" ],
- [ "TOFBinvperm", "fips_desmovs -f" ],
- [ "TOFBMMT1", "fips_desmovs -f" ],
- [ "TOFBMMT2", "fips_desmovs -f" ],
- [ "TOFBMMT3", "fips_desmovs -f" ],
- [ "TOFBMonte1", "fips_desmovs -f" ],
- [ "TOFBMonte2", "fips_desmovs -f" ],
- [ "TOFBMonte3", "fips_desmovs -f" ],
- [ "TOFBpermop", "fips_desmovs -f" ],
- [ "TOFBsubtab", "fips_desmovs -f" ],
- [ "TOFBvarkey", "fips_desmovs -f" ],
- [ "TOFBvartext", "fips_desmovs -f" ]
-
-);
-
-my @fips_des3_cfb1_test_list = (
-
- # DES3 CFB1 tests
-
- [ "TCFB1invperm", "fips_desmovs -f" ],
- [ "TCFB1MMT1", "fips_desmovs -f" ],
- [ "TCFB1MMT2", "fips_desmovs -f" ],
- [ "TCFB1MMT3", "fips_desmovs -f" ],
- [ "TCFB1Monte1", "fips_desmovs -f" ],
- [ "TCFB1Monte2", "fips_desmovs -f" ],
- [ "TCFB1Monte3", "fips_desmovs -f" ],
- [ "TCFB1permop", "fips_desmovs -f" ],
- [ "TCFB1subtab", "fips_desmovs -f" ],
- [ "TCFB1varkey", "fips_desmovs -f" ],
- [ "TCFB1vartext", "fips_desmovs -f" ],
-
-);
-
-# Verification special cases.
-# In most cases the output of a test is deterministic and
-# it can be compared to a known good result. A few involve
-# the genration and use of random keys and the output will
-# be different each time. In thoses cases we perform special tests
-# to simply check their consistency. For example signature generation
-# output will be run through signature verification to see if all outputs
-# show as valid.
-#
-
-my %verify_special = (
- "PQGGen" => "fips_dssvs pqgver",
- "KeyPair" => "fips_dssvs keyver",
- "SigGen" => "fips_dssvs sigver",
- "SigGen15" => "fips_rsavtest",
- "SigGenRSA" => "fips_rsavtest -x931",
- "SigGenPSS(0)" => "fips_rsavtest -saltlen 0",
- "SigGenPSS(62)" => "fips_rsavtest -saltlen 62",
-);
-
-my $win32 = $^O =~ m/mswin/i;
-my $onedir = 0;
-my $filter = "";
-my $tvdir;
-my $tprefix;
-my $shwrap_prefix;
-my $debug = 0;
-my $quiet = 0;
-my $notest = 0;
-my $verify = 1;
-my $rspdir = "rsp";
-my $ignore_missing = 0;
-my $ignore_bogus = 0;
-my $bufout = '';
-my $list_tests = 0;
-
-my %fips_enabled = (
- dsa => 1,
- "dsa-pqgver" => 0,
- rsa => 1,
- "rsa-pss0" => 0,
- "rsa-pss62" => 1,
- sha => 1,
- hmac => 1,
- "rand-aes" => 1,
- "rand-des2" => 0,
- aes => 1,
- "aes-cfb1" => 0,
- des3 => 1,
- "des3-cfb1" => 0
-);
-
-foreach (@ARGV) {
- if ( $_ eq "--win32" ) {
- $win32 = 1;
- }
- elsif ( $_ eq "--onedir" ) {
- $onedir = 1;
- }
- elsif ( $_ eq "--debug" ) {
- $debug = 1;
- }
- elsif ( $_ eq "--ignore-missing" ) {
- $ignore_missing = 1;
- }
- elsif ( $_ eq "--ignore-bogus" ) {
- $ignore_bogus = 1;
- }
- elsif ( $_ eq "--generate" ) {
- $verify = 0;
- }
- elsif ( $_ eq "--notest" ) {
- $notest = 1;
- }
- elsif ( $_ eq "--quiet" ) {
- $quiet = 1;
- }
- elsif (/--dir=(.*)$/) {
- $tvdir = $1;
- }
- elsif (/--rspdir=(.*)$/) {
- $rspdir = $1;
- }
- elsif (/--tprefix=(.*)$/) {
- $tprefix = $1;
- }
- elsif (/--shwrap_prefix=(.*)$/) {
- $shwrap_prefix = $1;
- }
- elsif (/^--(enable|disable)-(.*)$/) {
- if ( !exists $fips_enabled{$2} ) {
- print STDERR "Unknown test $2\n";
- }
- if ( $1 eq "enable" ) {
- $fips_enabled{$2} = 1;
- }
- else {
- $fips_enabled{$2} = 0;
- }
- }
- elsif (/--filter=(.*)$/) {
- $filter = $1;
- }
- elsif (/^--list-tests$/) {
- $list_tests = 1;
- }
- else {
- Help();
- exit(1);
- }
-}
-
-my @fips_test_list;
-
-push @fips_test_list, @fips_dsa_test_list if $fips_enabled{"dsa"};
-push @fips_test_list, @fips_dsa_pqgver_test_list if $fips_enabled{"dsa-pqgver"};
-push @fips_test_list, @fips_rsa_test_list if $fips_enabled{"rsa"};
-push @fips_test_list, @fips_rsa_pss0_test_list if $fips_enabled{"rsa-pss0"};
-push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"};
-push @fips_test_list, @fips_sha_test_list if $fips_enabled{"sha"};
-push @fips_test_list, @fips_hmac_test_list if $fips_enabled{"hmac"};
-push @fips_test_list, @fips_rand_aes_test_list if $fips_enabled{"rand-aes"};
-push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"};
-push @fips_test_list, @fips_aes_test_list if $fips_enabled{"aes"};
-push @fips_test_list, @fips_aes_cfb1_test_list if $fips_enabled{"aes-cfb1"};
-push @fips_test_list, @fips_des3_test_list if $fips_enabled{"des3"};
-push @fips_test_list, @fips_des3_cfb1_test_list if $fips_enabled{"des3-cfb1"};
-
-if ($list_tests) {
- my ( $test, $en );
- print "=====TEST LIST=====\n";
- foreach $test ( sort keys %fips_enabled ) {
- $en = $fips_enabled{$test};
- $test =~ tr/[a-z]/[A-Z]/;
- printf "%-10s %s\n", $test, $en ? "enabled" : "disabled";
- }
- exit(0);
-}
-
-foreach (@fips_test_list) {
- next unless ref($_);
- my $nm = $_->[0];
- $_->[2] = "";
- $_->[3] = "";
- print STDERR "Duplicate test $nm\n" if exists $fips_tests{$nm};
- $fips_tests{$nm} = $_;
-}
-
-$tvdir = "." unless defined $tvdir;
-
-if ($win32) {
- if ( !defined $tprefix ) {
- if ($onedir) {
- $tprefix = ".\\";
- }
- else {
- $tprefix = "..\\out32dll\\";
- }
- }
-}
-else {
- if ($onedir) {
- $tprefix = "./" unless defined $tprefix;
- $shwrap_prefix = "./" unless defined $shwrap_prefix;
- }
- else {
- $tprefix = "../test/" unless defined $tprefix;
- $shwrap_prefix = "../util/" unless defined $shwrap_prefix;
- }
-}
-
-sanity_check_exe( $win32, $tprefix, $shwrap_prefix );
-
-my $cmd_prefix = $win32 ? "" : "${shwrap_prefix}shlib_wrap.sh ";
-
-find_files( $filter, $tvdir );
-
-sanity_check_files();
-
-my ( $runerr, $cmperr, $cmpok, $scheckrunerr, $scheckerr, $scheckok, $skipcnt )
- = ( 0, 0, 0, 0, 0, 0, 0 );
-
-exit(0) if $notest;
-
-run_tests( $verify, $win32, $tprefix, $filter, $tvdir );
-
-if ($verify) {
- print "ALGORITHM TEST VERIFY SUMMARY REPORT:\n";
- print "Tests skipped due to missing files: $skipcnt\n";
- print "Algorithm test program execution failures: $runerr\n";
- print "Test comparisons successful: $cmpok\n";
- print "Test comparisons failed: $cmperr\n";
- print "Test sanity checks successful: $scheckok\n";
- print "Test sanity checks failed: $scheckerr\n";
- print "Sanity check program execution failures: $scheckrunerr\n";
-
- if ( $runerr || $cmperr || $scheckrunerr || $scheckerr ) {
- print "***TEST FAILURE***\n";
- }
- else {
- print "***ALL TESTS SUCCESSFUL***\n";
- }
-}
-else {
- print "ALGORITHM TEST SUMMARY REPORT:\n";
- print "Tests skipped due to missing files: $skipcnt\n";
- print "Algorithm test program execution failures: $runerr\n";
-
- if ($runerr) {
- print "***TEST FAILURE***\n";
- }
- else {
- print "***ALL TESTS SUCCESSFUL***\n";
- }
-}
-
-#--------------------------------
-sub Help {
- ( my $cmd ) = ( $0 =~ m#([^/]+)$# );
- print <<EOF;
-$cmd: generate run CMVP algorithm tests
- --debug Enable debug output
- --dir=<dirname> Optional root for *.req file search
- --filter=<regexp>
- --onedir <dirname> Assume all components in current directory
- --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "rsp"
- --shwrap_prefix=<prefix>
- --tprefix=<prefix>
- --ignore-bogus Ignore duplicate or bogus files
- --ignore-missing Ignore missing test files
- --quiet Shhh....
- --generate Generate algorithm test output
- --win32 Win32 environment
- --enable-<alg> Enable algorithm set <alg>.
- --disable-<alg> Disable algorithm set <alg>.
- Where <alg> can be one of:
-EOF
-
-while (my ($key, $value) = each %fips_enabled)
- {
- printf "\t\t%-20s(%s by default)\n", $key ,
- $value ? "enabled" : "disabled";
- }
-}
-
-# Sanity check to see if all necessary executables exist
-
-sub sanity_check_exe {
- my ( $win32, $tprefix, $shwrap_prefix ) = @_;
- my %exe_list;
- my $bad = 0;
- $exe_list{ $shwrap_prefix . "shlib_wrap.sh" } = 1 unless $win32;
- foreach (@fips_test_list) {
- next unless ref($_);
- my $cmd = $_->[1];
- $cmd =~ s/ .*$//;
- $cmd = $tprefix . $cmd;
- $cmd .= ".exe" if $win32;
- $exe_list{$cmd} = 1;
- }
-
- foreach ( sort keys %exe_list ) {
- if ( !-f $_ ) {
- print STDERR "ERROR: can't find executable $_\n";
- $bad = 1;
- }
- }
- if ($bad) {
- print STDERR "FATAL ERROR: executables missing\n";
- exit(1);
- }
- elsif ($debug) {
- print STDERR "Executable sanity check passed OK\n";
- }
-}
-
-# Search for all request and response files
-
-sub find_files {
- my ( $filter, $dir ) = @_;
- my ( $dirh, $testname );
- opendir( $dirh, $dir );
- while ( $_ = readdir($dirh) ) {
- next if ( $_ eq "." || $_ eq ".." );
- $_ = "$dir/$_";
- if ( -f "$_" ) {
- if (/\/([^\/]*)\.rsp$/) {
- $testname = fix_pss( $1, $_ );
- if ( exists $fips_tests{$testname} ) {
- if ( $fips_tests{$testname}->[3] eq "" ) {
- $fips_tests{$testname}->[3] = $_;
- }
- else {
- print STDERR
-"WARNING: duplicate response file $_ for test $testname\n";
- $nbogus++;
- }
- }
- else {
- print STDERR "WARNING: bogus file $_\n";
- $nbogus++;
- }
- }
- next unless /$filter.*\.req$/i;
- if (/\/([^\/]*)\.req$/) {
- $testname = fix_pss( $1, $_ );
- if ( exists $fips_tests{$testname} ) {
- if ( $fips_tests{$testname}->[2] eq "" ) {
- $fips_tests{$testname}->[2] = $_;
- }
- else {
- print STDERR
-"WARNING: duplicate request file $_ for test $testname\n";
- $nbogus++;
- }
-
- }
- elsif ( !/SHAmix\.req$/ ) {
- print STDERR "WARNING: unrecognized filename $_\n";
- $nbogus++;
- }
- }
- }
- elsif ( -d "$_" ) {
- find_files( $filter, $_ );
- }
- }
- closedir($dirh);
-}
-
-sub fix_pss {
- my ( $test, $path ) = @_;
- my $sl = "";
- local $_;
- if ( $test =~ /PSS/ ) {
- open( IN, $path ) || die "Can't Open File $path";
- while (<IN>) {
- if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i) {
- $sl = $1;
- last;
- }
- }
- close IN;
- if ( $sl eq "" ) {
- print STDERR "WARNING: No Salt length detected for file $path\n";
- }
- else {
- return $test . "($sl)";
- }
- }
- return $test;
-}
-
-sub sanity_check_files {
- my $bad = 0;
- foreach (@fips_test_list) {
- next unless ref($_);
- my ( $tst, $cmd, $req, $resp ) = @$_;
-
- #print STDERR "FILES $tst, $cmd, $req, $resp\n";
- if ( $req eq "" ) {
- print STDERR "WARNING: missing request file for $tst\n";
- $bad = 1;
- next;
- }
- if ( $verify && $resp eq "" ) {
- print STDERR "WARNING: no response file for test $tst\n";
- $bad = 1;
- }
- elsif ( !$verify && $resp ne "" ) {
- print STDERR "WARNING: response file $resp will be overwritten\n";
- }
- }
- if ($bad) {
- print STDERR "ERROR: test vector file set not complete\n";
- exit(1) unless $ignore_missing;
- }
- if ($nbogus) {
- print STDERR
- "ERROR: $nbogus bogus or duplicate request and response files\n";
- exit(1) unless $ignore_bogus;
- }
- if ( $debug && !$nbogus && !$bad ) {
- print STDERR "test vector file set complete\n";
- }
-}
-
-sub run_tests {
- my ( $verify, $win32, $tprefix, $filter, $tvdir ) = @_;
- my ( $tname, $tref );
- my $bad = 0;
- foreach (@fips_test_list) {
- if ( !ref($_) ) {
- print "Running $_ tests\n" unless $quiet;
- next;
- }
- my ( $tname, $tcmd, $req, $rsp ) = @$_;
- my $out = $rsp;
- if ($verify) {
- $out =~ s/\.rsp$/.tst/;
- }
- if ( $req eq "" ) {
- print STDERR
- "WARNING: Request file for $tname missing: test skipped\n";
- $skipcnt++;
- next;
- }
- if ( $verify && $rsp eq "" ) {
- print STDERR
- "WARNING: Response file for $tname missing: test skipped\n";
- $skipcnt++;
- next;
- }
- elsif ( !$verify ) {
- if ( $rsp ne "" ) {
- print STDERR "WARNING: Response file for $tname deleted\n";
- unlink $rsp;
- }
- $out = $req;
- $out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|;
- my $outdir = $out;
- $outdir =~ s|/[^/]*$||;
- if ( !-d $outdir ) {
- print STDERR "DEBUG: Creating directory $outdir\n" if $debug;
- mkdir($outdir) || die "Can't create directory $outdir";
- }
- }
- my $cmd = "$cmd_prefix$tprefix$tcmd ";
- if ( $tcmd =~ /-f$/ ) {
- $cmd .= "\"$req\" \"$out\"";
- }
- else {
- $cmd .= "<\"$req\" >\"$out\"";
- }
- print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify );
- system($cmd);
- if ( $? != 0 ) {
- print STDERR
- "WARNING: error executing test $tname for command: $cmd\n";
- $runerr++;
- next;
- }
- if ($verify) {
- if ( exists $verify_special{$tname} ) {
- my $vout = $rsp;
- $vout =~ s/\.rsp$/.ver/;
- $tcmd = $verify_special{$tname};
- $cmd = "$cmd_prefix$tprefix$tcmd ";
- $cmd .= "<\"$out\" >\"$vout\"";
- system($cmd);
- if ( $? != 0 ) {
- print STDERR
- "WARNING: error executing verify test $tname $cmd\n";
- $scheckrunerr++;
- next;
- }
- my ( $fcount, $pcount ) = ( 0, 0 );
- open VER, "$vout";
- while (<VER>) {
- if (/^Result\s*=\s*(\S*)\s*$/i)
-
- {
- if ( $1 eq "F" ) {
- $fcount++;
- }
- else {
- $pcount++;
- }
- }
- }
- close VER;
-
- unlink $vout;
- if ( $fcount || $debug ) {
- print STDERR "DEBUG: $tname, Pass=$pcount, Fail=$fcount\n";
- }
- if ( $fcount || !$pcount ) {
- $scheckerr++;
- }
- else {
- $scheckok++;
- }
-
- }
- elsif ( !cmp_file( $tname, $rsp, $out ) ) {
- $cmperr++;
- }
- else {
- $cmpok++;
- }
- unlink $out;
- }
- }
-}
-
-sub cmp_file {
- my ( $tname, $rsp, $tst ) = @_;
- my ( $rspf, $tstf );
- my ( $rspline, $tstline );
- if ( !open( $rspf, $rsp ) ) {
- print STDERR "ERROR: can't open request file $rsp\n";
- return 0;
- }
- if ( !open( $tstf, $tst ) ) {
- print STDERR "ERROR: can't open output file $tst\n";
- return 0;
- }
- for ( ; ; ) {
- $rspline = next_line($rspf);
- $tstline = next_line($tstf);
- if ( !defined($rspline) && !defined($tstline) ) {
- print STDERR "DEBUG: $tname file comparison OK\n" if $debug;
- return 1;
- }
- if ( !defined($rspline) ) {
- print STDERR "ERROR: $tname EOF on $rsp\n";
- return 0;
- }
- if ( !defined($tstline) ) {
- print STDERR "ERROR: $tname EOF on $tst\n";
- return 0;
- }
-
- # Workaround for bug in RAND des2 test output */
- if ( $tstline =~ /^Key2 =/ && $rspline =~ /^Key1 =/ ) {
- $rspline =~ s/^Key1/Key2/;
- }
-
- if ( $tstline ne $rspline ) {
- print STDERR "ERROR: $tname mismatch:\n";
- print STDERR "\t \"$tstline\" != \"$rspline\"\n";
- return 0;
- }
- }
- return 1;
-}
-
-sub next_line {
- my ($in) = @_;
-
- while (<$in>) {
- chomp;
-
- # Delete comments
- s/#.*$//;
-
- # Ignore blank lines
- next if (/^\s*$/);
-
- # Translate multiple space into one
- s/\s+/ /g;
- # Delete trailing whitespace
- s/\s+$//;
- return $_;
- }
- return undef;
-}
diff --git a/crypto/openssl/fips/fipsld b/crypto/openssl/fips/fipsld
deleted file mode 100755
index 8c26c85..0000000
--- a/crypto/openssl/fips/fipsld
+++ /dev/null
@@ -1,178 +0,0 @@
-#!/bin/sh -e
-#
-# Copyright (c) 2005-2007 The OpenSSL Project.
-#
-# Depending on output file name, the script either embeds fingerprint
-# into libcrypto.so or static application. "Static" refers to static
-# libcrypto.a, not [necessarily] application per se.
-#
-# Even though this script is called fipsld, it expects C compiler
-# command line syntax and $FIPSLD_CC or $CC environment variable set
-# and can even be used to compile source files.
-
-#set -x
-
-CC=${FIPSLD_CC:-${CC}}
-[ -n "${CC}" ] || { echo '$CC is not defined'; exit 1; }
-
-# Initially -c wasn't intended to be interpreted here, but it might
-# make life easier for those who want to build FIPS-ified applications
-# with minimal [if any] modifications to their Makefiles...
-( while [ "x$1" != "x" -a "x$1" != "x-c" -a "x$1" != "x-E" ]; do shift; done;
- [ $# -ge 1 ]
-) && exec ${CC} "$@"
-
-TARGET=`(while [ "x$1" != "x" -a "x$1" != "x-o" ]; do shift; done; echo $2)`
-
-# If using an auto-tooled (autoconf/automake/libtool) project,
-# configure will fail when testing the compiler or even performing
-# simple checks. Pass-through to compiler directly if application is
-# is not being linked with libcrypto, allowing auto-tooled applications
-# to utilize fipsld (e.g. CC=/usr/local/ssl/bin/fipsld FIPSLD_CC=gcc
-# ./configure && make). But keep in mind[!] that if certified code
-# resides in a shared library, then fipsld *may not* be used and
-# end-developer should not modify application configuration and build
-# procedures. This is because in-core fingerprint and associated
-# procedures are already embedded into and executed in shared library
-# context.
-case `basename "${TARGET}"` in
-libcrypto*|libfips*|*.dll) ;;
-*) case "$*" in
- *libcrypto.a*|*-lcrypto*|*fipscanister.o*) ;;
- *) exec ${CC} "$@" ;;
- esac
-esac
-
-[ -n "${TARGET}" ] || { echo 'no -o specified'; exit 1; }
-
-# Turn on debugging output?
-( while [ "x$1" != "x" -a "x$1" != "x-DDEBUG_FINGERPRINT_PREMAIN" ]; do shift; done;
- [ $# -ge 1 ]
-) && set -x
-
-THERE="`echo $0 | sed -e 's|[^/]*$||'`"..
-
-# fipscanister.o can appear in command line
-CANISTER_O=`(while [ "x$1" != "x" ]; do case "$1" in *fipscanister.o) echo $1; exit;; esac; shift; done)`
-if [ -z "${CANISTER_O}" ]; then
- # If set, FIPSLIBDIR is location of installed validated FIPS module
- if [ -n "${FIPSLIBDIR}" ]; then
- CANISTER_O="${FIPSLIBDIR}/fipscanister.o"
- elif [ -f "${THERE}/fips/fipscanister.o" ]; then
- CANISTER_O="${THERE}/fips/fipscanister.o"
- elif [ -f "${THERE}/lib/fipscanister.o" ]; then
- CANISTER_O="${THERE}/lib/fipscanister.o"
- fi
- CANISTER_O_CMD="${CANISTER_O}"
-fi
-[ -f ${CANISTER_O} ] || { echo "unable to find ${CANISTER_O}"; exit 1; }
-
-PREMAIN_C=`dirname "${CANISTER_O}"`/fips_premain.c
-
-HMAC_KEY="etaonrishdlcupfm"
-
-case "`(uname -s) 2>/dev/null`" in
-OSF1|IRIX*) _WL_PREMAIN="-Wl,-init,FINGERPRINT_premain" ;;
-HP-UX) _WL_PREMAIN="-Wl,+init,FINGERPRINT_premain" ;;
-AIX) _WL_PREMAIN="-Wl,-binitfini:FINGERPRINT_premain,-bnoobjreorder";;
-Darwin) ( while [ "x$1" != "x" -a "x$1" != "x-dynamiclib" ]; do shift; done;
- [ $# -ge 1 ]
- ) && _WL_PREMAIN="-Wl,-init,_FINGERPRINT_premain" ;;
-esac
-
-case "${TARGET}" in
-[!/]*) TARGET=./${TARGET} ;;
-esac
-
-case `basename "${TARGET}"` in
-lib*|*.dll) # must be linking a shared lib...
- # Shared lib creation can be taking place in the source
- # directory only, but fipscanister.o can reside elsewhere...
- FINGERTYPE="${THERE}/fips/fips_standalone_sha1"
-
- # verify fipspremain.c against its detached signature...
- ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
- diff -w "${PREMAIN_C}.sha1" - || \
- { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
- # verify fipscanister.o against its detached signature...
- ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
- diff -w "${CANISTER_O}.sha1" - || \
- { echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
-
- # Temporarily remove fipscanister.o from libcrypto.a!
- # We are required to use the standalone copy...
- if [ -f "${THERE}/libcrypto.a" ]; then
- if ar d "${THERE}/libcrypto.a" fipscanister.o; then
- (ranlib "${THERE}/libcrypto.a") 2>/dev/null || :
- trap 'ar r "${THERE}/libcrypto.a" "${CANISTER_O}";
- (ranlib "${THERE}/libcrypto.a") 2>/dev/null || :;
- sleep 1;
- touch -c "${TARGET}"' 0
- fi
- fi
-
- /bin/rm -f "${TARGET}"
- ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
- "${PREMAIN_C}" \
- ${_WL_PREMAIN} "$@"
-
- # generate signature...
- if [ -z "${FIPS_SIG}" ]; then
- SIG=`"${THERE}/fips/fips_premain_dso" "${TARGET}"`
- else
- SIG=`"${FIPS_SIG}" -dso "${TARGET}"`
- fi
- /bin/rm -f "${TARGET}"
- if [ -z "${SIG}" ]; then
- echo "unable to collect signature"; exit 1
- fi
-
- # recompile with signature...
- ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
- -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
- ${_WL_PREMAIN} "$@"
- ;;
-
-*) # must be linking statically...
- # Static linking can be taking place either in the source
- # directory or off the installed binary target destination.
- if [ -x "${THERE}/fips/fips_standalone_sha1" ]; then
- FINGERTYPE="${THERE}/fips/fips_standalone_sha1"
- else # Installed tree is expected to contain
- # lib/fipscanister.o, lib/fipscanister.o.sha1 and
- # lib/fips_premain.c [not to mention bin/openssl].
- FINGERTYPE="${THERE}/bin/openssl sha1 -hmac ${HMAC_KEY}"
- fi
-
- # verify fipscanister.o against its detached signature...
- ${FINGERTYPE} "${CANISTER_O}" | sed "s/(.*\//(/" | \
- diff -w "${CANISTER_O}.sha1" - || \
- { echo "${CANISTER_O} fingerprint mismatch"; exit 1; }
-
- # verify fips_premain.c against its detached signature...
- ${FINGERTYPE} "${PREMAIN_C}" | sed "s/(.*\//(/" | \
- diff -w "${PREMAIN_C}.sha1" - || \
- { echo "${PREMAIN_C} fingerprint mismatch"; exit 1; }
-
- /bin/rm -f "${TARGET}"
- ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
- "${PREMAIN_C}" \
- ${_WL_PREMAIN} "$@"
-
- # generate signature...
- if [ -z "${FIPS_SIG}" ]; then
- SIG=`"${TARGET}"`
- else
- SIG=`"${FIPS_SIG}" -exe "${TARGET}"`
- fi
- /bin/rm -f "${TARGET}"
- if [ -z "${SIG}" ]; then
- echo "unable to collect signature"; exit 1
- fi
-
- # recompile with signature...
- ${CC} ${CANISTER_O_CMD:+"${CANISTER_O_CMD}"} \
- -DHMAC_SHA1_SIG=\"${SIG}\" "${PREMAIN_C}" \
- ${_WL_PREMAIN} "$@"
- ;;
-esac
diff --git a/crypto/openssl/fips/fipstests.sh b/crypto/openssl/fips/fipstests.sh
deleted file mode 100755
index a351446..0000000
--- a/crypto/openssl/fips/fipstests.sh
+++ /dev/null
@@ -1,400 +0,0 @@
-#!/bin/sh
-
-# Test vector run script
-# Auto generated by mkfipsscr.pl script
-# Do not edit
-
-
-echo Running tests in "./testvectors/AES/req"
-rm -rf "./testvectors/AES/rsp"
-mkdir "./testvectors/AES/rsp"
-
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox128.req" "./testvectors/AES/rsp/CBCGFSbox128.rsp" || { echo "./testvectors/AES/req/CBCGFSbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox192.req" "./testvectors/AES/rsp/CBCGFSbox192.rsp" || { echo "./testvectors/AES/req/CBCGFSbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCGFSbox256.req" "./testvectors/AES/rsp/CBCGFSbox256.rsp" || { echo "./testvectors/AES/req/CBCGFSbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox128.req" "./testvectors/AES/rsp/CBCKeySbox128.rsp" || { echo "./testvectors/AES/req/CBCKeySbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox192.req" "./testvectors/AES/rsp/CBCKeySbox192.rsp" || { echo "./testvectors/AES/req/CBCKeySbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCKeySbox256.req" "./testvectors/AES/rsp/CBCKeySbox256.rsp" || { echo "./testvectors/AES/req/CBCKeySbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT128.req" "./testvectors/AES/rsp/CBCMCT128.rsp" || { echo "./testvectors/AES/req/CBCMCT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT192.req" "./testvectors/AES/rsp/CBCMCT192.rsp" || { echo "./testvectors/AES/req/CBCMCT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMCT256.req" "./testvectors/AES/rsp/CBCMCT256.rsp" || { echo "./testvectors/AES/req/CBCMCT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT128.req" "./testvectors/AES/rsp/CBCMMT128.rsp" || { echo "./testvectors/AES/req/CBCMMT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT192.req" "./testvectors/AES/rsp/CBCMMT192.rsp" || { echo "./testvectors/AES/req/CBCMMT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCMMT256.req" "./testvectors/AES/rsp/CBCMMT256.rsp" || { echo "./testvectors/AES/req/CBCMMT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey128.req" "./testvectors/AES/rsp/CBCVarKey128.rsp" || { echo "./testvectors/AES/req/CBCVarKey128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey192.req" "./testvectors/AES/rsp/CBCVarKey192.rsp" || { echo "./testvectors/AES/req/CBCVarKey192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarKey256.req" "./testvectors/AES/rsp/CBCVarKey256.rsp" || { echo "./testvectors/AES/req/CBCVarKey256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt128.req" "./testvectors/AES/rsp/CBCVarTxt128.rsp" || { echo "./testvectors/AES/req/CBCVarTxt128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt192.req" "./testvectors/AES/rsp/CBCVarTxt192.rsp" || { echo "./testvectors/AES/req/CBCVarTxt192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CBCVarTxt256.req" "./testvectors/AES/rsp/CBCVarTxt256.rsp" || { echo "./testvectors/AES/req/CBCVarTxt256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox128.req" "./testvectors/AES/rsp/CFB128GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox192.req" "./testvectors/AES/rsp/CFB128GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128GFSbox256.req" "./testvectors/AES/rsp/CFB128GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB128GFSbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox128.req" "./testvectors/AES/rsp/CFB128KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox192.req" "./testvectors/AES/rsp/CFB128KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128KeySbox256.req" "./testvectors/AES/rsp/CFB128KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB128KeySbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT128.req" "./testvectors/AES/rsp/CFB128MCT128.rsp" || { echo "./testvectors/AES/req/CFB128MCT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT192.req" "./testvectors/AES/rsp/CFB128MCT192.rsp" || { echo "./testvectors/AES/req/CFB128MCT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MCT256.req" "./testvectors/AES/rsp/CFB128MCT256.rsp" || { echo "./testvectors/AES/req/CFB128MCT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT128.req" "./testvectors/AES/rsp/CFB128MMT128.rsp" || { echo "./testvectors/AES/req/CFB128MMT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT192.req" "./testvectors/AES/rsp/CFB128MMT192.rsp" || { echo "./testvectors/AES/req/CFB128MMT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128MMT256.req" "./testvectors/AES/rsp/CFB128MMT256.rsp" || { echo "./testvectors/AES/req/CFB128MMT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey128.req" "./testvectors/AES/rsp/CFB128VarKey128.rsp" || { echo "./testvectors/AES/req/CFB128VarKey128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey192.req" "./testvectors/AES/rsp/CFB128VarKey192.rsp" || { echo "./testvectors/AES/req/CFB128VarKey192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarKey256.req" "./testvectors/AES/rsp/CFB128VarKey256.rsp" || { echo "./testvectors/AES/req/CFB128VarKey256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt128.req" "./testvectors/AES/rsp/CFB128VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt192.req" "./testvectors/AES/rsp/CFB128VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB128VarTxt256.req" "./testvectors/AES/rsp/CFB128VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB128VarTxt256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox128.req" "./testvectors/AES/rsp/CFB1GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox192.req" "./testvectors/AES/rsp/CFB1GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1GFSbox256.req" "./testvectors/AES/rsp/CFB1GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB1GFSbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox128.req" "./testvectors/AES/rsp/CFB1KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox192.req" "./testvectors/AES/rsp/CFB1KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1KeySbox256.req" "./testvectors/AES/rsp/CFB1KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB1KeySbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT128.req" "./testvectors/AES/rsp/CFB1MCT128.rsp" || { echo "./testvectors/AES/req/CFB1MCT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT192.req" "./testvectors/AES/rsp/CFB1MCT192.rsp" || { echo "./testvectors/AES/req/CFB1MCT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MCT256.req" "./testvectors/AES/rsp/CFB1MCT256.rsp" || { echo "./testvectors/AES/req/CFB1MCT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT128.req" "./testvectors/AES/rsp/CFB1MMT128.rsp" || { echo "./testvectors/AES/req/CFB1MMT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT192.req" "./testvectors/AES/rsp/CFB1MMT192.rsp" || { echo "./testvectors/AES/req/CFB1MMT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1MMT256.req" "./testvectors/AES/rsp/CFB1MMT256.rsp" || { echo "./testvectors/AES/req/CFB1MMT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey128.req" "./testvectors/AES/rsp/CFB1VarKey128.rsp" || { echo "./testvectors/AES/req/CFB1VarKey128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey192.req" "./testvectors/AES/rsp/CFB1VarKey192.rsp" || { echo "./testvectors/AES/req/CFB1VarKey192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarKey256.req" "./testvectors/AES/rsp/CFB1VarKey256.rsp" || { echo "./testvectors/AES/req/CFB1VarKey256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt128.req" "./testvectors/AES/rsp/CFB1VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt192.req" "./testvectors/AES/rsp/CFB1VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB1VarTxt256.req" "./testvectors/AES/rsp/CFB1VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB1VarTxt256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox128.req" "./testvectors/AES/rsp/CFB8GFSbox128.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox192.req" "./testvectors/AES/rsp/CFB8GFSbox192.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8GFSbox256.req" "./testvectors/AES/rsp/CFB8GFSbox256.rsp" || { echo "./testvectors/AES/req/CFB8GFSbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox128.req" "./testvectors/AES/rsp/CFB8KeySbox128.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox192.req" "./testvectors/AES/rsp/CFB8KeySbox192.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8KeySbox256.req" "./testvectors/AES/rsp/CFB8KeySbox256.rsp" || { echo "./testvectors/AES/req/CFB8KeySbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT128.req" "./testvectors/AES/rsp/CFB8MCT128.rsp" || { echo "./testvectors/AES/req/CFB8MCT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT192.req" "./testvectors/AES/rsp/CFB8MCT192.rsp" || { echo "./testvectors/AES/req/CFB8MCT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MCT256.req" "./testvectors/AES/rsp/CFB8MCT256.rsp" || { echo "./testvectors/AES/req/CFB8MCT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT128.req" "./testvectors/AES/rsp/CFB8MMT128.rsp" || { echo "./testvectors/AES/req/CFB8MMT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT192.req" "./testvectors/AES/rsp/CFB8MMT192.rsp" || { echo "./testvectors/AES/req/CFB8MMT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8MMT256.req" "./testvectors/AES/rsp/CFB8MMT256.rsp" || { echo "./testvectors/AES/req/CFB8MMT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey128.req" "./testvectors/AES/rsp/CFB8VarKey128.rsp" || { echo "./testvectors/AES/req/CFB8VarKey128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey192.req" "./testvectors/AES/rsp/CFB8VarKey192.rsp" || { echo "./testvectors/AES/req/CFB8VarKey192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarKey256.req" "./testvectors/AES/rsp/CFB8VarKey256.rsp" || { echo "./testvectors/AES/req/CFB8VarKey256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt128.req" "./testvectors/AES/rsp/CFB8VarTxt128.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt192.req" "./testvectors/AES/rsp/CFB8VarTxt192.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/CFB8VarTxt256.req" "./testvectors/AES/rsp/CFB8VarTxt256.rsp" || { echo "./testvectors/AES/req/CFB8VarTxt256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox128.req" "./testvectors/AES/rsp/ECBGFSbox128.rsp" || { echo "./testvectors/AES/req/ECBGFSbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox192.req" "./testvectors/AES/rsp/ECBGFSbox192.rsp" || { echo "./testvectors/AES/req/ECBGFSbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBGFSbox256.req" "./testvectors/AES/rsp/ECBGFSbox256.rsp" || { echo "./testvectors/AES/req/ECBGFSbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox128.req" "./testvectors/AES/rsp/ECBKeySbox128.rsp" || { echo "./testvectors/AES/req/ECBKeySbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox192.req" "./testvectors/AES/rsp/ECBKeySbox192.rsp" || { echo "./testvectors/AES/req/ECBKeySbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBKeySbox256.req" "./testvectors/AES/rsp/ECBKeySbox256.rsp" || { echo "./testvectors/AES/req/ECBKeySbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT128.req" "./testvectors/AES/rsp/ECBMCT128.rsp" || { echo "./testvectors/AES/req/ECBMCT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT192.req" "./testvectors/AES/rsp/ECBMCT192.rsp" || { echo "./testvectors/AES/req/ECBMCT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMCT256.req" "./testvectors/AES/rsp/ECBMCT256.rsp" || { echo "./testvectors/AES/req/ECBMCT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT128.req" "./testvectors/AES/rsp/ECBMMT128.rsp" || { echo "./testvectors/AES/req/ECBMMT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT192.req" "./testvectors/AES/rsp/ECBMMT192.rsp" || { echo "./testvectors/AES/req/ECBMMT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBMMT256.req" "./testvectors/AES/rsp/ECBMMT256.rsp" || { echo "./testvectors/AES/req/ECBMMT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey128.req" "./testvectors/AES/rsp/ECBVarKey128.rsp" || { echo "./testvectors/AES/req/ECBVarKey128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey192.req" "./testvectors/AES/rsp/ECBVarKey192.rsp" || { echo "./testvectors/AES/req/ECBVarKey192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarKey256.req" "./testvectors/AES/rsp/ECBVarKey256.rsp" || { echo "./testvectors/AES/req/ECBVarKey256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt128.req" "./testvectors/AES/rsp/ECBVarTxt128.rsp" || { echo "./testvectors/AES/req/ECBVarTxt128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt192.req" "./testvectors/AES/rsp/ECBVarTxt192.rsp" || { echo "./testvectors/AES/req/ECBVarTxt192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/ECBVarTxt256.req" "./testvectors/AES/rsp/ECBVarTxt256.rsp" || { echo "./testvectors/AES/req/ECBVarTxt256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox128.req" "./testvectors/AES/rsp/OFBGFSbox128.rsp" || { echo "./testvectors/AES/req/OFBGFSbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox192.req" "./testvectors/AES/rsp/OFBGFSbox192.rsp" || { echo "./testvectors/AES/req/OFBGFSbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBGFSbox256.req" "./testvectors/AES/rsp/OFBGFSbox256.rsp" || { echo "./testvectors/AES/req/OFBGFSbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox128.req" "./testvectors/AES/rsp/OFBKeySbox128.rsp" || { echo "./testvectors/AES/req/OFBKeySbox128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox192.req" "./testvectors/AES/rsp/OFBKeySbox192.rsp" || { echo "./testvectors/AES/req/OFBKeySbox192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBKeySbox256.req" "./testvectors/AES/rsp/OFBKeySbox256.rsp" || { echo "./testvectors/AES/req/OFBKeySbox256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT128.req" "./testvectors/AES/rsp/OFBMCT128.rsp" || { echo "./testvectors/AES/req/OFBMCT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT192.req" "./testvectors/AES/rsp/OFBMCT192.rsp" || { echo "./testvectors/AES/req/OFBMCT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMCT256.req" "./testvectors/AES/rsp/OFBMCT256.rsp" || { echo "./testvectors/AES/req/OFBMCT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT128.req" "./testvectors/AES/rsp/OFBMMT128.rsp" || { echo "./testvectors/AES/req/OFBMMT128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT192.req" "./testvectors/AES/rsp/OFBMMT192.rsp" || { echo "./testvectors/AES/req/OFBMMT192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBMMT256.req" "./testvectors/AES/rsp/OFBMMT256.rsp" || { echo "./testvectors/AES/req/OFBMMT256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey128.req" "./testvectors/AES/rsp/OFBVarKey128.rsp" || { echo "./testvectors/AES/req/OFBVarKey128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey192.req" "./testvectors/AES/rsp/OFBVarKey192.rsp" || { echo "./testvectors/AES/req/OFBVarKey192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarKey256.req" "./testvectors/AES/rsp/OFBVarKey256.rsp" || { echo "./testvectors/AES/req/OFBVarKey256.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt128.req" "./testvectors/AES/rsp/OFBVarTxt128.rsp" || { echo "./testvectors/AES/req/OFBVarTxt128.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt192.req" "./testvectors/AES/rsp/OFBVarTxt192.rsp" || { echo "./testvectors/AES/req/OFBVarTxt192.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_aesavs -f "./testvectors/AES/req/OFBVarTxt256.req" "./testvectors/AES/rsp/OFBVarTxt256.rsp" || { echo "./testvectors/AES/req/OFBVarTxt256.req failure" ; exit 1
-}
-
-echo Running tests in "./testvectors/DSA/req"
-rm -rf "./testvectors/DSA/rsp"
-mkdir "./testvectors/DSA/rsp"
-
-../util/shlib_wrap.sh ../test/fips_dssvs keypair < "./testvectors/DSA/req/KeyPair.req" > "./testvectors/DSA/rsp/KeyPair.rsp" || { echo "./testvectors/DSA/req/KeyPair.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_dssvs pqg < "./testvectors/DSA/req/PQGGen.req" > "./testvectors/DSA/rsp/PQGGen.rsp" || { echo "./testvectors/DSA/req/PQGGen.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_dssvs siggen < "./testvectors/DSA/req/SigGen.req" > "./testvectors/DSA/rsp/SigGen.rsp" || { echo "./testvectors/DSA/req/SigGen.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_dssvs sigver < "./testvectors/DSA/req/SigVer.req" > "./testvectors/DSA/rsp/SigVer.rsp" || { echo "./testvectors/DSA/req/SigVer.req failure" ; exit 1; }
-
-echo Running tests in "./testvectors/HMAC/req"
-rm -rf "./testvectors/HMAC/rsp"
-mkdir "./testvectors/HMAC/rsp"
-
-../util/shlib_wrap.sh ../test/fips_hmactest < "./testvectors/HMAC/req/HMAC.req" > "./testvectors/HMAC/rsp/HMAC.rsp" || { echo "./testvectors/HMAC/req/HMAC.req failure" ; exit 1; }
-
-echo Running tests in "./testvectors/RNG/req"
-rm -rf "./testvectors/RNG/rsp"
-mkdir "./testvectors/RNG/rsp"
-
-../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES128MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES128MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES128MCT.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES128VST.req" > "./testvectors/RNG/rsp/ANSI931_AES128VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES128VST.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES192MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES192MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES192MCT.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES192VST.req" > "./testvectors/RNG/rsp/ANSI931_AES192VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES192VST.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rngvs mct < "./testvectors/RNG/req/ANSI931_AES256MCT.req" > "./testvectors/RNG/rsp/ANSI931_AES256MCT.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES256MCT.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rngvs vst < "./testvectors/RNG/req/ANSI931_AES256VST.req" > "./testvectors/RNG/rsp/ANSI931_AES256VST.rsp" || { echo "./testvectors/RNG/req/ANSI931_AES256VST.req failure" ; exit 1; }
-
-echo Running tests in "./testvectors/RSA/req"
-rm -rf "./testvectors/RSA/rsp"
-mkdir "./testvectors/RSA/rsp"
-
-../util/shlib_wrap.sh ../test/fips_rsagtest < "./testvectors/RSA/req/KeyGenRSA.req" > "./testvectors/RSA/rsp/KeyGenRSA.rsp" || { echo "./testvectors/RSA/req/KeyGenRSA.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rsastest < "./testvectors/RSA/req/SigGen15.req" > "./testvectors/RSA/rsp/SigGen15.rsp" || { echo "./testvectors/RSA/req/SigGen15.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rsastest -saltlen 0 < "./testvectors/RSA/req/SigGenPSS.req" > "./testvectors/RSA/rsp/SigGenPSS.rsp" || { echo "./testvectors/RSA/req/SigGenPSS.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rsastest -x931 < "./testvectors/RSA/req/SigGenRSA.req" > "./testvectors/RSA/rsp/SigGenRSA.rsp" || { echo "./testvectors/RSA/req/SigGenRSA.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rsavtest < "./testvectors/RSA/req/SigVer15.req" > "./testvectors/RSA/rsp/SigVer15.rsp" || { echo "./testvectors/RSA/req/SigVer15.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rsavtest -saltlen 0 < "./testvectors/RSA/req/SigVerPSS.req" > "./testvectors/RSA/rsp/SigVerPSS.rsp" || { echo "./testvectors/RSA/req/SigVerPSS.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_rsavtest -x931 < "./testvectors/RSA/req/SigVerRSA.req" > "./testvectors/RSA/rsp/SigVerRSA.rsp" || { echo "./testvectors/RSA/req/SigVerRSA.req failure" ; exit 1; }
-
-echo Running tests in "./testvectors/SHA/req"
-rm -rf "./testvectors/SHA/rsp"
-mkdir "./testvectors/SHA/rsp"
-
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1LongMsg.req" > "./testvectors/SHA/rsp/SHA1LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA1LongMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1Monte.req" > "./testvectors/SHA/rsp/SHA1Monte.rsp" || { echo "./testvectors/SHA/req/SHA1Monte.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA1ShortMsg.req" > "./testvectors/SHA/rsp/SHA1ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA1ShortMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224LongMsg.req" > "./testvectors/SHA/rsp/SHA224LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA224LongMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224Monte.req" > "./testvectors/SHA/rsp/SHA224Monte.rsp" || { echo "./testvectors/SHA/req/SHA224Monte.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA224ShortMsg.req" > "./testvectors/SHA/rsp/SHA224ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA224ShortMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256LongMsg.req" > "./testvectors/SHA/rsp/SHA256LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA256LongMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256Monte.req" > "./testvectors/SHA/rsp/SHA256Monte.rsp" || { echo "./testvectors/SHA/req/SHA256Monte.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA256ShortMsg.req" > "./testvectors/SHA/rsp/SHA256ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA256ShortMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384LongMsg.req" > "./testvectors/SHA/rsp/SHA384LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA384LongMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384Monte.req" > "./testvectors/SHA/rsp/SHA384Monte.rsp" || { echo "./testvectors/SHA/req/SHA384Monte.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA384ShortMsg.req" > "./testvectors/SHA/rsp/SHA384ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA384ShortMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512LongMsg.req" > "./testvectors/SHA/rsp/SHA512LongMsg.rsp" || { echo "./testvectors/SHA/req/SHA512LongMsg.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512Monte.req" > "./testvectors/SHA/rsp/SHA512Monte.rsp" || { echo "./testvectors/SHA/req/SHA512Monte.req failure" ; exit 1; }
-../util/shlib_wrap.sh ../test/fips_shatest < "./testvectors/SHA/req/SHA512ShortMsg.req" > "./testvectors/SHA/rsp/SHA512ShortMsg.rsp" || { echo "./testvectors/SHA/req/SHA512ShortMsg.req failure" ; exit 1; }
-
-echo Running tests in "./testvectors/TDES/req"
-rm -rf "./testvectors/TDES/rsp"
-mkdir "./testvectors/TDES/rsp"
-
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCinvperm.req" "./testvectors/TDES/rsp/TCBCinvperm.rsp" || { echo "./testvectors/TDES/req/TCBCinvperm.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT1.req" "./testvectors/TDES/rsp/TCBCMMT1.rsp" || { echo "./testvectors/TDES/req/TCBCMMT1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT2.req" "./testvectors/TDES/rsp/TCBCMMT2.rsp" || { echo "./testvectors/TDES/req/TCBCMMT2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMMT3.req" "./testvectors/TDES/rsp/TCBCMMT3.rsp" || { echo "./testvectors/TDES/req/TCBCMMT3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte1.req" "./testvectors/TDES/rsp/TCBCMonte1.rsp" || { echo "./testvectors/TDES/req/TCBCMonte1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte2.req" "./testvectors/TDES/rsp/TCBCMonte2.rsp" || { echo "./testvectors/TDES/req/TCBCMonte2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCMonte3.req" "./testvectors/TDES/rsp/TCBCMonte3.rsp" || { echo "./testvectors/TDES/req/TCBCMonte3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCpermop.req" "./testvectors/TDES/rsp/TCBCpermop.rsp" || { echo "./testvectors/TDES/req/TCBCpermop.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCsubtab.req" "./testvectors/TDES/rsp/TCBCsubtab.rsp" || { echo "./testvectors/TDES/req/TCBCsubtab.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCvarkey.req" "./testvectors/TDES/rsp/TCBCvarkey.rsp" || { echo "./testvectors/TDES/req/TCBCvarkey.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCBCvartext.req" "./testvectors/TDES/rsp/TCBCvartext.rsp" || { echo "./testvectors/TDES/req/TCBCvartext.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64invperm.req" "./testvectors/TDES/rsp/TCFB64invperm.rsp" || { echo "./testvectors/TDES/req/TCFB64invperm.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT1.req" "./testvectors/TDES/rsp/TCFB64MMT1.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT2.req" "./testvectors/TDES/rsp/TCFB64MMT2.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64MMT3.req" "./testvectors/TDES/rsp/TCFB64MMT3.rsp" || { echo "./testvectors/TDES/req/TCFB64MMT3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte1.req" "./testvectors/TDES/rsp/TCFB64Monte1.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte2.req" "./testvectors/TDES/rsp/TCFB64Monte2.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64Monte3.req" "./testvectors/TDES/rsp/TCFB64Monte3.rsp" || { echo "./testvectors/TDES/req/TCFB64Monte3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64permop.req" "./testvectors/TDES/rsp/TCFB64permop.rsp" || { echo "./testvectors/TDES/req/TCFB64permop.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64subtab.req" "./testvectors/TDES/rsp/TCFB64subtab.rsp" || { echo "./testvectors/TDES/req/TCFB64subtab.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64varkey.req" "./testvectors/TDES/rsp/TCFB64varkey.rsp" || { echo "./testvectors/TDES/req/TCFB64varkey.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB64vartext.req" "./testvectors/TDES/rsp/TCFB64vartext.rsp" || { echo "./testvectors/TDES/req/TCFB64vartext.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8invperm.req" "./testvectors/TDES/rsp/TCFB8invperm.rsp" || { echo "./testvectors/TDES/req/TCFB8invperm.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT1.req" "./testvectors/TDES/rsp/TCFB8MMT1.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT2.req" "./testvectors/TDES/rsp/TCFB8MMT2.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8MMT3.req" "./testvectors/TDES/rsp/TCFB8MMT3.rsp" || { echo "./testvectors/TDES/req/TCFB8MMT3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte1.req" "./testvectors/TDES/rsp/TCFB8Monte1.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte2.req" "./testvectors/TDES/rsp/TCFB8Monte2.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8Monte3.req" "./testvectors/TDES/rsp/TCFB8Monte3.rsp" || { echo "./testvectors/TDES/req/TCFB8Monte3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8permop.req" "./testvectors/TDES/rsp/TCFB8permop.rsp" || { echo "./testvectors/TDES/req/TCFB8permop.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8subtab.req" "./testvectors/TDES/rsp/TCFB8subtab.rsp" || { echo "./testvectors/TDES/req/TCFB8subtab.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8varkey.req" "./testvectors/TDES/rsp/TCFB8varkey.rsp" || { echo "./testvectors/TDES/req/TCFB8varkey.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TCFB8vartext.req" "./testvectors/TDES/rsp/TCFB8vartext.rsp" || { echo "./testvectors/TDES/req/TCFB8vartext.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBinvperm.req" "./testvectors/TDES/rsp/TECBinvperm.rsp" || { echo "./testvectors/TDES/req/TECBinvperm.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT1.req" "./testvectors/TDES/rsp/TECBMMT1.rsp" || { echo "./testvectors/TDES/req/TECBMMT1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT2.req" "./testvectors/TDES/rsp/TECBMMT2.rsp" || { echo "./testvectors/TDES/req/TECBMMT2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMMT3.req" "./testvectors/TDES/rsp/TECBMMT3.rsp" || { echo "./testvectors/TDES/req/TECBMMT3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte1.req" "./testvectors/TDES/rsp/TECBMonte1.rsp" || { echo "./testvectors/TDES/req/TECBMonte1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte2.req" "./testvectors/TDES/rsp/TECBMonte2.rsp" || { echo "./testvectors/TDES/req/TECBMonte2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBMonte3.req" "./testvectors/TDES/rsp/TECBMonte3.rsp" || { echo "./testvectors/TDES/req/TECBMonte3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBpermop.req" "./testvectors/TDES/rsp/TECBpermop.rsp" || { echo "./testvectors/TDES/req/TECBpermop.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBsubtab.req" "./testvectors/TDES/rsp/TECBsubtab.rsp" || { echo "./testvectors/TDES/req/TECBsubtab.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBvarkey.req" "./testvectors/TDES/rsp/TECBvarkey.rsp" || { echo "./testvectors/TDES/req/TECBvarkey.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TECBvartext.req" "./testvectors/TDES/rsp/TECBvartext.rsp" || { echo "./testvectors/TDES/req/TECBvartext.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBinvperm.req" "./testvectors/TDES/rsp/TOFBinvperm.rsp" || { echo "./testvectors/TDES/req/TOFBinvperm.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT1.req" "./testvectors/TDES/rsp/TOFBMMT1.rsp" || { echo "./testvectors/TDES/req/TOFBMMT1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT2.req" "./testvectors/TDES/rsp/TOFBMMT2.rsp" || { echo "./testvectors/TDES/req/TOFBMMT2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMMT3.req" "./testvectors/TDES/rsp/TOFBMMT3.rsp" || { echo "./testvectors/TDES/req/TOFBMMT3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte1.req" "./testvectors/TDES/rsp/TOFBMonte1.rsp" || { echo "./testvectors/TDES/req/TOFBMonte1.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte2.req" "./testvectors/TDES/rsp/TOFBMonte2.rsp" || { echo "./testvectors/TDES/req/TOFBMonte2.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBMonte3.req" "./testvectors/TDES/rsp/TOFBMonte3.rsp" || { echo "./testvectors/TDES/req/TOFBMonte3.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBpermop.req" "./testvectors/TDES/rsp/TOFBpermop.rsp" || { echo "./testvectors/TDES/req/TOFBpermop.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBsubtab.req" "./testvectors/TDES/rsp/TOFBsubtab.rsp" || { echo "./testvectors/TDES/req/TOFBsubtab.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBvarkey.req" "./testvectors/TDES/rsp/TOFBvarkey.rsp" || { echo "./testvectors/TDES/req/TOFBvarkey.req failure" ; exit 1
-}
-../util/shlib_wrap.sh ../test/fips_desmovs -f "./testvectors/TDES/req/TOFBvartext.req" "./testvectors/TDES/rsp/TOFBvartext.rsp" || { echo "./testvectors/TDES/req/TOFBvartext.req failure" ; exit 1
-}
diff --git a/crypto/openssl/fips/hmac/Makefile b/crypto/openssl/fips/hmac/Makefile
deleted file mode 100644
index be230ad..0000000
--- a/crypto/openssl/fips/hmac/Makefile
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# OpenSSL/fips/hmac/Makefile
-#
-
-DIR= hmac
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST=fips_hmactest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_hmac.c fips_hmac_selftest.c
-LIBOBJ=fips_hmac.o fips_hmac_selftest.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=
-HEADER= $(EXHEADER)
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-Q=../testvectors/hmac/req
-A=../testvectors/hmac/rsp
-
-fips_test:
- -rm -rf $(A)
- mkdir $(A)
- if [ -f $(Q)/HMAC.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_hmactest < $(Q)/HMAC.req > $(A)/HMAC.rsp; fi
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_hmac.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_hmac.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-fips_hmac.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_hmac.o: ../../include/openssl/hmac.h ../../include/openssl/obj_mac.h
-fips_hmac.o: ../../include/openssl/objects.h
-fips_hmac.o: ../../include/openssl/opensslconf.h
-fips_hmac.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-fips_hmac.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_hmac.o: ../../include/openssl/symhacks.h fips_hmac.c
-fips_hmac_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_hmac_selftest.o: ../../include/openssl/crypto.h
-fips_hmac_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_hmac_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_hmac_selftest.o: ../../include/openssl/hmac.h
-fips_hmac_selftest.o: ../../include/openssl/lhash.h
-fips_hmac_selftest.o: ../../include/openssl/obj_mac.h
-fips_hmac_selftest.o: ../../include/openssl/objects.h
-fips_hmac_selftest.o: ../../include/openssl/opensslconf.h
-fips_hmac_selftest.o: ../../include/openssl/opensslv.h
-fips_hmac_selftest.o: ../../include/openssl/ossl_typ.h
-fips_hmac_selftest.o: ../../include/openssl/safestack.h
-fips_hmac_selftest.o: ../../include/openssl/stack.h
-fips_hmac_selftest.o: ../../include/openssl/symhacks.h fips_hmac_selftest.c
-fips_hmactest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_hmactest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_hmactest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-fips_hmactest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-fips_hmactest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-fips_hmactest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_hmactest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
-fips_hmactest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_hmactest.o: ../../include/openssl/objects.h
-fips_hmactest.o: ../../include/openssl/opensslconf.h
-fips_hmactest.o: ../../include/openssl/opensslv.h
-fips_hmactest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_hmactest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-fips_hmactest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_hmactest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-fips_hmactest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_hmactest.c
diff --git a/crypto/openssl/fips/hmac/fips_hmac.c b/crypto/openssl/fips/hmac/fips_hmac.c
deleted file mode 100644
index 69a10da..0000000
--- a/crypto/openssl/fips/hmac/fips_hmac.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* crypto/hmac/hmac.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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <openssl/hmac.h>
-#include <openssl/fips.h>
-
-#ifdef OPENSSL_FIPS
-
-void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
- const EVP_MD *md, ENGINE *impl)
- {
- int i,j,reset=0;
- unsigned char pad[HMAC_MAX_MD_CBLOCK];
-
- if (md != NULL)
- {
- reset=1;
- ctx->md=md;
- }
- else
- md=ctx->md;
-
- if (key != NULL)
- {
- if (FIPS_mode() && !(md->flags & EVP_MD_FLAG_FIPS)
- && (!(ctx->md_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
- || !(ctx->i_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)
- || !(ctx->o_ctx.flags & EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)))
- OpenSSLDie(__FILE__,__LINE__,
- "HMAC: digest not allowed in FIPS mode");
-
- reset=1;
- j=M_EVP_MD_block_size(md);
- OPENSSL_assert(j <= (int)sizeof ctx->key);
- if (j < len)
- {
- EVP_DigestInit_ex(&ctx->md_ctx,md, impl);
- EVP_DigestUpdate(&ctx->md_ctx,key,len);
- EVP_DigestFinal_ex(&(ctx->md_ctx),ctx->key,
- &ctx->key_length);
- }
- else
- {
- OPENSSL_assert(len <= (int)sizeof ctx->key);
- memcpy(ctx->key,key,len);
- ctx->key_length=len;
- }
- if(ctx->key_length != HMAC_MAX_MD_CBLOCK)
- memset(&ctx->key[ctx->key_length], 0,
- HMAC_MAX_MD_CBLOCK - ctx->key_length);
- }
-
- if (reset)
- {
- for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
- pad[i]=0x36^ctx->key[i];
- EVP_DigestInit_ex(&ctx->i_ctx,md, impl);
- EVP_DigestUpdate(&ctx->i_ctx,pad,M_EVP_MD_block_size(md));
-
- for (i=0; i<HMAC_MAX_MD_CBLOCK; i++)
- pad[i]=0x5c^ctx->key[i];
- EVP_DigestInit_ex(&ctx->o_ctx,md, impl);
- EVP_DigestUpdate(&ctx->o_ctx,pad,M_EVP_MD_block_size(md));
- }
- EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->i_ctx);
- }
-
-void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
- const EVP_MD *md)
- {
- if(key && md)
- HMAC_CTX_init(ctx);
- HMAC_Init_ex(ctx,key,len,md, NULL);
- }
-
-void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
- {
- EVP_DigestUpdate(&ctx->md_ctx,data,len);
- }
-
-void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
- {
- int j;
- unsigned int i;
- unsigned char buf[EVP_MAX_MD_SIZE];
-
- j=M_EVP_MD_block_size(ctx->md);
-
- EVP_DigestFinal_ex(&ctx->md_ctx,buf,&i);
- EVP_MD_CTX_copy_ex(&ctx->md_ctx,&ctx->o_ctx);
- EVP_DigestUpdate(&ctx->md_ctx,buf,i);
- EVP_DigestFinal_ex(&ctx->md_ctx,md,len);
- }
-
-void HMAC_CTX_init(HMAC_CTX *ctx)
- {
- EVP_MD_CTX_init(&ctx->i_ctx);
- EVP_MD_CTX_init(&ctx->o_ctx);
- EVP_MD_CTX_init(&ctx->md_ctx);
- }
-
-void HMAC_CTX_cleanup(HMAC_CTX *ctx)
- {
- EVP_MD_CTX_cleanup(&ctx->i_ctx);
- EVP_MD_CTX_cleanup(&ctx->o_ctx);
- EVP_MD_CTX_cleanup(&ctx->md_ctx);
- memset(ctx,0,sizeof *ctx);
- }
-
-unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
- const unsigned char *d, size_t n, unsigned char *md,
- unsigned int *md_len)
- {
- HMAC_CTX c;
- static unsigned char m[EVP_MAX_MD_SIZE];
-
- if (md == NULL) md=m;
- HMAC_CTX_init(&c);
- HMAC_Init(&c,key,key_len,evp_md);
- HMAC_Update(&c,d,n);
- HMAC_Final(&c,md,md_len);
- HMAC_CTX_cleanup(&c);
- return(md);
- }
-
-void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags)
- {
- M_EVP_MD_CTX_set_flags(&ctx->i_ctx, flags);
- M_EVP_MD_CTX_set_flags(&ctx->o_ctx, flags);
- M_EVP_MD_CTX_set_flags(&ctx->md_ctx, flags);
- }
-
-#endif
-
diff --git a/crypto/openssl/fips/hmac/fips_hmac_selftest.c b/crypto/openssl/fips/hmac/fips_hmac_selftest.c
deleted file mode 100644
index 73455ff..0000000
--- a/crypto/openssl/fips/hmac/fips_hmac_selftest.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2005 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.
- *
- */
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-#include <openssl/hmac.h>
-
-#ifdef OPENSSL_FIPS
-typedef struct {
- const EVP_MD *(*alg)(void);
- const char *key, *iv;
- unsigned char kaval[EVP_MAX_MD_SIZE];
-} HMAC_KAT;
-
-static const HMAC_KAT vector[] = {
- { EVP_sha1,
- /* from http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf */
- "0123456789:;<=>?@ABC",
- "Sample #2",
- { 0x09,0x22,0xd3,0x40,0x5f,0xaa,0x3d,0x19,
- 0x4f,0x82,0xa4,0x58,0x30,0x73,0x7d,0x5c,
- 0xc6,0xc7,0x5d,0x24 }
- },
- { EVP_sha224,
- /* just keep extending the above... */
- "0123456789:;<=>?@ABC",
- "Sample #2",
- { 0xdd,0xef,0x0a,0x40,0xcb,0x7d,0x50,0xfb,
- 0x6e,0xe6,0xce,0xa1,0x20,0xba,0x26,0xaa,
- 0x08,0xf3,0x07,0x75,0x87,0xb8,0xad,0x1b,
- 0x8c,0x8d,0x12,0xc7 }
- },
- { EVP_sha256,
- "0123456789:;<=>?@ABC",
- "Sample #2",
- { 0xb8,0xf2,0x0d,0xb5,0x41,0xea,0x43,0x09,
- 0xca,0x4e,0xa9,0x38,0x0c,0xd0,0xe8,0x34,
- 0xf7,0x1f,0xbe,0x91,0x74,0xa2,0x61,0x38,
- 0x0d,0xc1,0x7e,0xae,0x6a,0x34,0x51,0xd9 }
- },
- { EVP_sha384,
- "0123456789:;<=>?@ABC",
- "Sample #2",
- { 0x08,0xbc,0xb0,0xda,0x49,0x1e,0x87,0xad,
- 0x9a,0x1d,0x6a,0xce,0x23,0xc5,0x0b,0xf6,
- 0xb7,0x18,0x06,0xa5,0x77,0xcd,0x49,0x04,
- 0x89,0xf1,0xe6,0x23,0x44,0x51,0x51,0x9f,
- 0x85,0x56,0x80,0x79,0x0c,0xbd,0x4d,0x50,
- 0xa4,0x5f,0x29,0xe3,0x93,0xf0,0xe8,0x7f }
- },
- { EVP_sha512,
- "0123456789:;<=>?@ABC",
- "Sample #2",
- { 0x80,0x9d,0x44,0x05,0x7c,0x5b,0x95,0x41,
- 0x05,0xbd,0x04,0x13,0x16,0xdb,0x0f,0xac,
- 0x44,0xd5,0xa4,0xd5,0xd0,0x89,0x2b,0xd0,
- 0x4e,0x86,0x64,0x12,0xc0,0x90,0x77,0x68,
- 0xf1,0x87,0xb7,0x7c,0x4f,0xae,0x2c,0x2f,
- 0x21,0xa5,0xb5,0x65,0x9a,0x4f,0x4b,0xa7,
- 0x47,0x02,0xa3,0xde,0x9b,0x51,0xf1,0x45,
- 0xbd,0x4f,0x25,0x27,0x42,0x98,0x99,0x05 }
- },
-};
-
-int FIPS_selftest_hmac()
- {
- size_t n;
- unsigned int outlen;
- unsigned char out[EVP_MAX_MD_SIZE];
- const EVP_MD *md;
- const HMAC_KAT *t;
-
- for(n=0,t=vector; n<sizeof(vector)/sizeof(vector[0]); n++,t++)
- {
- md = (*t->alg)();
- HMAC(md,t->key,strlen(t->key),
- (const unsigned char *)t->iv,strlen(t->iv),
- out,&outlen);
-
- if(memcmp(out,t->kaval,outlen))
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_HMAC,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
- }
- return 1;
- }
-#endif
diff --git a/crypto/openssl/fips/hmac/fips_hmactest.c b/crypto/openssl/fips/hmac/fips_hmactest.c
deleted file mode 100644
index 69ebf68..0000000
--- a/crypto/openssl/fips/hmac/fips_hmactest.c
+++ /dev/null
@@ -1,328 +0,0 @@
-/* fips_hmactest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005 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).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-
-#include <openssl/x509v3.h>
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS HMAC support\n");
- return(0);
-}
-
-#else
-
-#include <openssl/fips.h>
-#include "fips_utl.h"
-
-static int hmac_test(const EVP_MD *md, FILE *out, FILE *in);
-static int print_hmac(const EVP_MD *md, FILE *out,
- unsigned char *Key, int Klen,
- unsigned char *Msg, int Msglen, int Tlen);
-
-int main(int argc, char **argv)
- {
- FILE *in = NULL, *out = NULL;
-
- int ret = 1;
-
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- goto end;
- }
-
- if (argc == 1)
- in = stdin;
- else
- in = fopen(argv[1], "r");
-
- if (argc < 2)
- out = stdout;
- else
- out = fopen(argv[2], "w");
-
- if (!in)
- {
- fprintf(stderr, "FATAL input initialization error\n");
- goto end;
- }
-
- if (!out)
- {
- fprintf(stderr, "FATAL output initialization error\n");
- goto end;
- }
-
- if (!hmac_test(EVP_sha1(), out, in))
- {
- fprintf(stderr, "FATAL hmac file processing error\n");
- goto end;
- }
- else
- ret = 0;
-
- end:
-
- if (ret)
- do_print_errors();
-
- if (in && (in != stdin))
- fclose(in);
- if (out && (out != stdout))
- fclose(out);
-
- return ret;
-
- }
-
-#define HMAC_TEST_MAXLINELEN 1024
-
-int hmac_test(const EVP_MD *md, FILE *out, FILE *in)
- {
- char *linebuf, *olinebuf, *p, *q;
- char *keyword, *value;
- unsigned char *Key = NULL, *Msg = NULL;
- int Count, Klen, Tlen;
- long Keylen, Msglen;
- int ret = 0;
- int lnum = 0;
-
- olinebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
- linebuf = OPENSSL_malloc(HMAC_TEST_MAXLINELEN);
-
- if (!linebuf || !olinebuf)
- goto error;
-
- Count = -1;
- Klen = -1;
- Tlen = -1;
-
- while (fgets(olinebuf, HMAC_TEST_MAXLINELEN, in))
- {
- lnum++;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
-
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no = or starts with [ (for [L=20] line) just copy */
- if (!p)
- {
- if (fputs(olinebuf, out) < 0)
- goto error;
- continue;
- }
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
-
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- if (!strcmp(keyword,"[L") && *p==']')
- {
- switch (atoi(value))
- {
- case 20: md=EVP_sha1(); break;
- case 28: md=EVP_sha224(); break;
- case 32: md=EVP_sha256(); break;
- case 48: md=EVP_sha384(); break;
- case 64: md=EVP_sha512(); break;
- default: goto parse_error;
- }
- }
- else if (!strcmp(keyword, "Count"))
- {
- if (Count != -1)
- goto parse_error;
- Count = atoi(value);
- if (Count < 0)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Klen"))
- {
- if (Klen != -1)
- goto parse_error;
- Klen = atoi(value);
- if (Klen < 0)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Tlen"))
- {
- if (Tlen != -1)
- goto parse_error;
- Tlen = atoi(value);
- if (Tlen < 0)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Msg"))
- {
- if (Msg)
- goto parse_error;
- Msg = hex2bin_m(value, &Msglen);
- if (!Msg)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Key"))
- {
- if (Key)
- goto parse_error;
- Key = hex2bin_m(value, &Keylen);
- if (!Key)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Mac"))
- continue;
- else
- goto parse_error;
-
- fputs(olinebuf, out);
-
- if (Key && Msg && (Tlen > 0) && (Klen > 0))
- {
- if (!print_hmac(md, out, Key, Klen, Msg, Msglen, Tlen))
- goto error;
- OPENSSL_free(Key);
- Key = NULL;
- OPENSSL_free(Msg);
- Msg = NULL;
- Klen = -1;
- Tlen = -1;
- Count = -1;
- }
-
- }
-
-
- ret = 1;
-
-
- error:
-
- if (olinebuf)
- OPENSSL_free(olinebuf);
- if (linebuf)
- OPENSSL_free(linebuf);
- if (Key)
- OPENSSL_free(Key);
- if (Msg)
- OPENSSL_free(Msg);
-
- return ret;
-
- parse_error:
-
- fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
-
- goto error;
-
- }
-
-static int print_hmac(const EVP_MD *emd, FILE *out,
- unsigned char *Key, int Klen,
- unsigned char *Msg, int Msglen, int Tlen)
- {
- int i, mdlen;
- unsigned char md[EVP_MAX_MD_SIZE];
- if (!HMAC(emd, Key, Klen, Msg, Msglen, md,
- (unsigned int *)&mdlen))
- {
- fputs("Error calculating HMAC\n", stderr);
- return 0;
- }
- if (Tlen > mdlen)
- {
- fputs("Parameter error, Tlen > HMAC length\n", stderr);
- return 0;
- }
- fputs("Mac = ", out);
- for (i = 0; i < Tlen; i++)
- fprintf(out, "%02x", md[i]);
- fputs("\n", out);
- return 1;
- }
-
-#endif
diff --git a/crypto/openssl/fips/mkfipsscr.pl b/crypto/openssl/fips/mkfipsscr.pl
deleted file mode 100755
index 361641d..0000000
--- a/crypto/openssl/fips/mkfipsscr.pl
+++ /dev/null
@@ -1,657 +0,0 @@
-#!/usr/local/bin/perl -w
-# Quick & dirty utility to generate a script for executing the
-# FIPS 140-2 CMVP algorithm tests based on the pathnames of
-# input algorithm test files actually present (the unqualified
-# file names are consistent but the pathnames are not).
-#
-
-# List of all the unqualified file names we expect.
-my %fips_tests = (
-
-# FIPS test definitions
-
-# DSA tests
-
-"PQGGen" => "fips_dssvs pqg",
-"KeyPair" => "fips_dssvs keypair",
-"SigGen" => "fips_dssvs siggen",
-"SigVer" => "fips_dssvs sigver",
-
-# SHA tests
-
-"SHA1LongMsg" => "fips_shatest",
-"SHA1Monte" => "fips_shatest",
-"SHA1ShortMsg" => "fips_shatest",
-"SHA224LongMsg" => "fips_shatest",
-"SHA224Monte" => "fips_shatest",
-"SHA224ShortMsg" => "fips_shatest",
-"SHA256LongMsg" => "fips_shatest",
-"SHA256Monte" => "fips_shatest",
-"SHA256ShortMsg" => "fips_shatest",
-"SHA384LongMsg" => "fips_shatest",
-"SHA384Monte" => "fips_shatest",
-"SHA384ShortMsg" => "fips_shatest",
-"SHA512LongMsg" => "fips_shatest",
-"SHA512Monte" => "fips_shatest",
-"SHA512ShortMsg" => "fips_shatest",
-
-# HMAC
-
-"HMAC" => "fips_hmactest",
-
-# RAND tests
-
-"ANSI931_AES128MCT" => "fips_rngvs mct",
-"ANSI931_AES192MCT" => "fips_rngvs mct",
-"ANSI931_AES256MCT" => "fips_rngvs mct",
-"ANSI931_AES128VST" => "fips_rngvs vst",
-"ANSI931_AES192VST" => "fips_rngvs vst",
-"ANSI931_AES256VST" => "fips_rngvs vst",
-
-# RSA tests
-
-"SigGen15" => "fips_rsastest",
-"SigVer15" => "fips_rsavtest",
-"SigGenPSS" => "fips_rsastest -saltlen SALT",
-"SigVerPSS" => "fips_rsavtest -saltlen SALT",
-"SigGenRSA" => "fips_rsastest -x931",
-"SigVerRSA" => "fips_rsavtest -x931",
-"KeyGenRSA" => "fips_rsagtest",
-
-# AES tests
-
-"CBCGFSbox128" => "fips_aesavs -f",
-"CBCGFSbox192" => "fips_aesavs -f",
-"CBCGFSbox256" => "fips_aesavs -f",
-"CBCKeySbox128" => "fips_aesavs -f",
-"CBCKeySbox192" => "fips_aesavs -f",
-"CBCKeySbox256" => "fips_aesavs -f",
-"CBCMCT128" => "fips_aesavs -f",
-"CBCMCT192" => "fips_aesavs -f",
-"CBCMCT256" => "fips_aesavs -f",
-"CBCMMT128" => "fips_aesavs -f",
-"CBCMMT192" => "fips_aesavs -f",
-"CBCMMT256" => "fips_aesavs -f",
-"CBCVarKey128" => "fips_aesavs -f",
-"CBCVarKey192" => "fips_aesavs -f",
-"CBCVarKey256" => "fips_aesavs -f",
-"CBCVarTxt128" => "fips_aesavs -f",
-"CBCVarTxt192" => "fips_aesavs -f",
-"CBCVarTxt256" => "fips_aesavs -f",
-"CFB128GFSbox128" => "fips_aesavs -f",
-"CFB128GFSbox192" => "fips_aesavs -f",
-"CFB128GFSbox256" => "fips_aesavs -f",
-"CFB128KeySbox128" => "fips_aesavs -f",
-"CFB128KeySbox192" => "fips_aesavs -f",
-"CFB128KeySbox256" => "fips_aesavs -f",
-"CFB128MCT128" => "fips_aesavs -f",
-"CFB128MCT192" => "fips_aesavs -f",
-"CFB128MCT256" => "fips_aesavs -f",
-"CFB128MMT128" => "fips_aesavs -f",
-"CFB128MMT192" => "fips_aesavs -f",
-"CFB128MMT256" => "fips_aesavs -f",
-"CFB128VarKey128" => "fips_aesavs -f",
-"CFB128VarKey192" => "fips_aesavs -f",
-"CFB128VarKey256" => "fips_aesavs -f",
-"CFB128VarTxt128" => "fips_aesavs -f",
-"CFB128VarTxt192" => "fips_aesavs -f",
-"CFB128VarTxt256" => "fips_aesavs -f",
-"CFB8GFSbox128" => "fips_aesavs -f",
-"CFB8GFSbox192" => "fips_aesavs -f",
-"CFB8GFSbox256" => "fips_aesavs -f",
-"CFB8KeySbox128" => "fips_aesavs -f",
-"CFB8KeySbox192" => "fips_aesavs -f",
-"CFB8KeySbox256" => "fips_aesavs -f",
-"CFB8MCT128" => "fips_aesavs -f",
-"CFB8MCT192" => "fips_aesavs -f",
-"CFB8MCT256" => "fips_aesavs -f",
-"CFB8MMT128" => "fips_aesavs -f",
-"CFB8MMT192" => "fips_aesavs -f",
-"CFB8MMT256" => "fips_aesavs -f",
-"CFB8VarKey128" => "fips_aesavs -f",
-"CFB8VarKey192" => "fips_aesavs -f",
-"CFB8VarKey256" => "fips_aesavs -f",
-"CFB8VarTxt128" => "fips_aesavs -f",
-"CFB8VarTxt192" => "fips_aesavs -f",
-"CFB8VarTxt256" => "fips_aesavs -f",
-#"CFB1GFSbox128" => "fips_aesavs -f",
-#"CFB1GFSbox192" => "fips_aesavs -f",
-#"CFB1GFSbox256" => "fips_aesavs -f",
-#"CFB1KeySbox128" => "fips_aesavs -f",
-#"CFB1KeySbox192" => "fips_aesavs -f",
-#"CFB1KeySbox256" => "fips_aesavs -f",
-#"CFB1MCT128" => "fips_aesavs -f",
-#"CFB1MCT192" => "fips_aesavs -f",
-#"CFB1MCT256" => "fips_aesavs -f",
-#"CFB1MMT128" => "fips_aesavs -f",
-#"CFB1MMT192" => "fips_aesavs -f",
-#"CFB1MMT256" => "fips_aesavs -f",
-#"CFB1VarKey128" => "fips_aesavs -f",
-#"CFB1VarKey192" => "fips_aesavs -f",
-#"CFB1VarKey256" => "fips_aesavs -f",
-#"CFB1VarTxt128" => "fips_aesavs -f",
-#"CFB1VarTxt192" => "fips_aesavs -f",
-#"CFB1VarTxt256" => "fips_aesavs -f",
-"ECBGFSbox128" => "fips_aesavs -f",
-"ECBGFSbox192" => "fips_aesavs -f",
-"ECBGFSbox256" => "fips_aesavs -f",
-"ECBKeySbox128" => "fips_aesavs -f",
-"ECBKeySbox192" => "fips_aesavs -f",
-"ECBKeySbox256" => "fips_aesavs -f",
-"ECBMCT128" => "fips_aesavs -f",
-"ECBMCT192" => "fips_aesavs -f",
-"ECBMCT256" => "fips_aesavs -f",
-"ECBMMT128" => "fips_aesavs -f",
-"ECBMMT192" => "fips_aesavs -f",
-"ECBMMT256" => "fips_aesavs -f",
-"ECBVarKey128" => "fips_aesavs -f",
-"ECBVarKey192" => "fips_aesavs -f",
-"ECBVarKey256" => "fips_aesavs -f",
-"ECBVarTxt128" => "fips_aesavs -f",
-"ECBVarTxt192" => "fips_aesavs -f",
-"ECBVarTxt256" => "fips_aesavs -f",
-"OFBGFSbox128" => "fips_aesavs -f",
-"OFBGFSbox192" => "fips_aesavs -f",
-"OFBGFSbox256" => "fips_aesavs -f",
-"OFBKeySbox128" => "fips_aesavs -f",
-"OFBKeySbox192" => "fips_aesavs -f",
-"OFBKeySbox256" => "fips_aesavs -f",
-"OFBMCT128" => "fips_aesavs -f",
-"OFBMCT192" => "fips_aesavs -f",
-"OFBMCT256" => "fips_aesavs -f",
-"OFBMMT128" => "fips_aesavs -f",
-"OFBMMT192" => "fips_aesavs -f",
-"OFBMMT256" => "fips_aesavs -f",
-"OFBVarKey128" => "fips_aesavs -f",
-"OFBVarKey192" => "fips_aesavs -f",
-"OFBVarKey256" => "fips_aesavs -f",
-"OFBVarTxt128" => "fips_aesavs -f",
-"OFBVarTxt192" => "fips_aesavs -f",
-"OFBVarTxt256" => "fips_aesavs -f",
-
-# Triple DES tests
-
-"TCBCinvperm" => "fips_desmovs -f",
-"TCBCMMT1" => "fips_desmovs -f",
-"TCBCMMT2" => "fips_desmovs -f",
-"TCBCMMT3" => "fips_desmovs -f",
-"TCBCMonte1" => "fips_desmovs -f",
-"TCBCMonte2" => "fips_desmovs -f",
-"TCBCMonte3" => "fips_desmovs -f",
-"TCBCpermop" => "fips_desmovs -f",
-"TCBCsubtab" => "fips_desmovs -f",
-"TCBCvarkey" => "fips_desmovs -f",
-"TCBCvartext" => "fips_desmovs -f",
-"TCFB64invperm" => "fips_desmovs -f",
-"TCFB64MMT1" => "fips_desmovs -f",
-"TCFB64MMT2" => "fips_desmovs -f",
-"TCFB64MMT3" => "fips_desmovs -f",
-"TCFB64Monte1" => "fips_desmovs -f",
-"TCFB64Monte2" => "fips_desmovs -f",
-"TCFB64Monte3" => "fips_desmovs -f",
-"TCFB64permop" => "fips_desmovs -f",
-"TCFB64subtab" => "fips_desmovs -f",
-"TCFB64varkey" => "fips_desmovs -f",
-"TCFB64vartext" => "fips_desmovs -f",
-"TCFB8invperm" => "fips_desmovs -f",
-"TCFB8MMT1" => "fips_desmovs -f",
-"TCFB8MMT2" => "fips_desmovs -f",
-"TCFB8MMT3" => "fips_desmovs -f",
-"TCFB8Monte1" => "fips_desmovs -f",
-"TCFB8Monte2" => "fips_desmovs -f",
-"TCFB8Monte3" => "fips_desmovs -f",
-"TCFB8permop" => "fips_desmovs -f",
-"TCFB8subtab" => "fips_desmovs -f",
-"TCFB8varkey" => "fips_desmovs -f",
-"TCFB8vartext" => "fips_desmovs -f",
-"TECBinvperm" => "fips_desmovs -f",
-"TECBMMT1" => "fips_desmovs -f",
-"TECBMMT2" => "fips_desmovs -f",
-"TECBMMT3" => "fips_desmovs -f",
-"TECBMonte1" => "fips_desmovs -f",
-"TECBMonte2" => "fips_desmovs -f",
-"TECBMonte3" => "fips_desmovs -f",
-"TECBpermop" => "fips_desmovs -f",
-"TECBsubtab" => "fips_desmovs -f",
-"TECBvarkey" => "fips_desmovs -f",
-"TECBvartext" => "fips_desmovs -f",
-"TOFBinvperm" => "fips_desmovs -f",
-"TOFBMMT1" => "fips_desmovs -f",
-"TOFBMMT2" => "fips_desmovs -f",
-"TOFBMMT3" => "fips_desmovs -f",
-"TOFBMonte1" => "fips_desmovs -f",
-"TOFBMonte2" => "fips_desmovs -f",
-"TOFBMonte3" => "fips_desmovs -f",
-"TOFBpermop" => "fips_desmovs -f",
-"TOFBsubtab" => "fips_desmovs -f",
-"TOFBvarkey" => "fips_desmovs -f",
-"TOFBvartext" => "fips_desmovs -f",
-"TCBCinvperm" => "fips_desmovs -f",
-"TCBCMMT1" => "fips_desmovs -f",
-"TCBCMMT2" => "fips_desmovs -f",
-"TCBCMMT3" => "fips_desmovs -f",
-"TCBCMonte1" => "fips_desmovs -f",
-"TCBCMonte2" => "fips_desmovs -f",
-"TCBCMonte3" => "fips_desmovs -f",
-"TCBCpermop" => "fips_desmovs -f",
-"TCBCsubtab" => "fips_desmovs -f",
-"TCBCvarkey" => "fips_desmovs -f",
-"TCBCvartext" => "fips_desmovs -f",
-"TCFB64invperm" => "fips_desmovs -f",
-"TCFB64MMT1" => "fips_desmovs -f",
-"TCFB64MMT2" => "fips_desmovs -f",
-"TCFB64MMT3" => "fips_desmovs -f",
-"TCFB64Monte1" => "fips_desmovs -f",
-"TCFB64Monte2" => "fips_desmovs -f",
-"TCFB64Monte3" => "fips_desmovs -f",
-"TCFB64permop" => "fips_desmovs -f",
-"TCFB64subtab" => "fips_desmovs -f",
-"TCFB64varkey" => "fips_desmovs -f",
-"TCFB64vartext" => "fips_desmovs -f",
-"TCFB8invperm" => "fips_desmovs -f",
-"TCFB8MMT1" => "fips_desmovs -f",
-"TCFB8MMT2" => "fips_desmovs -f",
-"TCFB8MMT3" => "fips_desmovs -f",
-"TCFB8Monte1" => "fips_desmovs -f",
-"TCFB8Monte2" => "fips_desmovs -f",
-"TCFB8Monte3" => "fips_desmovs -f",
-"TCFB8permop" => "fips_desmovs -f",
-"TCFB8subtab" => "fips_desmovs -f",
-"TCFB8varkey" => "fips_desmovs -f",
-"TCFB8vartext" => "fips_desmovs -f",
-"TECBinvperm" => "fips_desmovs -f",
-"TECBMMT1" => "fips_desmovs -f",
-"TECBMMT2" => "fips_desmovs -f",
-"TECBMMT3" => "fips_desmovs -f",
-"TECBMonte1" => "fips_desmovs -f",
-"TECBMonte2" => "fips_desmovs -f",
-"TECBMonte3" => "fips_desmovs -f",
-"TECBpermop" => "fips_desmovs -f",
-"TECBsubtab" => "fips_desmovs -f",
-"TECBvarkey" => "fips_desmovs -f",
-"TECBvartext" => "fips_desmovs -f",
-"TOFBinvperm" => "fips_desmovs -f",
-"TOFBMMT1" => "fips_desmovs -f",
-"TOFBMMT2" => "fips_desmovs -f",
-"TOFBMMT3" => "fips_desmovs -f",
-"TOFBMonte1" => "fips_desmovs -f",
-"TOFBMonte2" => "fips_desmovs -f",
-"TOFBMonte3" => "fips_desmovs -f",
-"TOFBpermop" => "fips_desmovs -f",
-"TOFBsubtab" => "fips_desmovs -f",
-"TOFBvarkey" => "fips_desmovs -f",
-"TOFBvartext" => "fips_desmovs -f"
-
-);
-my %salt_names = (
-"SigVerPSS (salt 0)" => "SigVerPSS",
-"SigVerPSS (salt 62)" => "SigVerPSS",
-"SigGenPSS (salt 0)" => "SigGenPSS",
-"SigGenPSS (salt 62)" => "SigGenPSS",
-);
-
-
-my $win32 = $^O =~ m/mswin/i;
-my $onedir = 0;
-my $filter = "";
-my $tvdir;
-my $tprefix;
-my $shwrap_prefix;
-my $shwrap;
-my $rmcmd = "rm -rf";
-my $mkcmd = "mkdir";
-my $debug = 0;
-my $quiet = 0;
-my $rspdir = "rsp";
-my $rspignore = 0;
-my @bogus = (); # list of unmatched *.rsp files
-my $bufout = '';
-my $bufdir = '';
-my %_programs = (); # list of external programs to check
-
-foreach (@ARGV)
- {
- if ($_ eq "--win32")
- {
- $win32 = 1;
- }
- elsif ($_ eq "--onedir")
- {
- $onedir = 1;
- }
- elsif ($_ eq "--debug")
- {
- $debug = 1;
- }
- elsif ($_ eq "--quiet")
- {
- $quiet = 1;
- }
- elsif (/--dir=(.*)$/)
- {
- $tvdir = $1;
- }
- elsif (/--rspdir=(.*)$/)
- {
- $rspdir = $1;
- }
- elsif (/--noshwrap$/)
- {
- $shwrap = "";
- }
- elsif (/--rspignore$/)
- {
- $rspignore = 1;
- }
- elsif (/--tprefix=(.*)$/)
- {
- $tprefix = $1;
- }
- elsif (/--shwrap_prefix=(.*)$/)
- {
- $shwrap_prefix = $1;
- }
- elsif (/--filter=(.*)$/)
- {
- $filter = $1;
- }
- elsif (/--mkdir=(.*)$/)
- {
- $mkcmd = $1;
- }
- elsif (/--rm=(.*)$/)
- {
- $rmcmd = $1;
- }
- elsif (/--outfile=(.*)$/)
- {
- $outfile = $1;
- }
- else
- {
- &Help();
- exit(1);
- }
- }
-
-$tvdir = "." unless defined $tvdir;
-
-if ($win32)
- {
- if (!defined $tprefix)
- {
- if ($onedir)
- {
- $tprefix = ".\\";
- }
- else
- {
- $tprefix = "..\\out32dll\\";
- }
- }
-
- $bufinit .= <<END;
-\@echo off
-rem Test vector run script
-rem Auto generated by mkfipsscr.pl script
-rem Do not edit
-
-END
-
- }
-else
- {
- if ($onedir)
- {
- $tprefix = "./" unless defined $tprefix;
- $shwrap_prefix = "./" unless defined $shwrap_prefix;
- }
- else
- {
- $tprefix = "../test/" unless defined $tprefix;
- $shwrap_prefix = "../util/" unless defined $shwrap_prefix;
- }
-
- $shwrap = "${shwrap_prefix}shlib_wrap.sh " unless defined $shwrap;
-
- $bufinit .= <<END;
-#!/bin/sh
-
-# Test vector run script
-# Auto generated by mkfipsscr.pl script
-# Do not edit
-
-RM="$rmcmd"
-MKDIR="$mkcmd"
-TPREFIX=$tprefix
-END
-
- }
-my %fips_found;
-foreach (keys %fips_tests)
- {
- $fips_found{$_} = 0;
- }
-my %saltPSS;
-for (keys %salt_names)
- {
- $salt_found{$_} = 0;
- }
-
-recurse_test($win32, $tprefix, $filter, $tvdir);
-
-while (($key, $value) = each %salt_found)
- {
- &countentry($key, $value);
- delete $fips_found{$salt_names{$key}};
- }
-while (($key, $value) = each %fips_found)
- {
- &countentry($key, $value);
- }
-
-# If no fatal errors write out the script file
- $outfile = "fipstests.sh" unless defined $outfile;
- open(OUT, ">$outfile") || die "Error opening $outfile: $!";
- print OUT $bufinit;
- if (!$rspignore && @bogus)
- {
- print STDERR "ERROR: please remove bogus *.rsp files\n";
- print OUT <<EOF;
-echo $outfile generation failed due to presence of bogus *.rsp files
-EOF
- }
- else
- {
- print OUT $bufout;
- }
- close OUT;
-
-# Check for external programs
- for (keys %_programs)
- {
- s/ .*$//;
- -x $_ || print STDERR "WARNING: program $_ not found\n";
- }
-
-#--------------------------------
-sub Help {
-(my $cmd) = ($0 =~ m#([^/]+)$#);
- print <<EOF;
-$cmd: generate script for CMVP algorithm tests
- --debug Enable debug output
- --dir=<dirname> Optional root for *.req file search
- --filter=<regexp>
- --onedir <dirname> Assume all components in current directory
- --outfile=<filename> Optional name of output script, default fipstests.{sh|bat}
- --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "resp"
- --rspignore Ignore any bogus *.rsp files
- --shwrap_prefix=<prefix>
- --tprefix=<prefix>
- --quiet Shhh....
- --win32 Generate script for Win32 environment
-EOF
-}
-
-#--------------------------------
-sub countentry {
- my ($key,$value) = @_;
- if ($value == 0)
- {
- print STDERR "WARNING: test file $key not found\n" unless $quiet;
- }
- elsif ($value > 1)
- {
- print STDERR "WARNING: test file $key found $value times\n" unless $quiet;
- }
- else
- {
- print STDERR "Found test file $key\n" if $debug;
- }
- }
-
-#--------------------------------
-sub recurse_test
- {
- my ($win32, $tprefix, $filter, $dir) = @_;
- my $dirh;
- opendir($dirh, $dir);
- while ($_ = readdir($dirh))
- {
- next if ($_ eq "." || $_ eq "..");
- $_ = "$dir/$_";
- if (-f "$_")
- {
- if (/\/([^\/]*)\.rsp$/)
- {
- if (exists $fips_tests{$1})
- {
- $debug && print "DEBUG: $1 found, will be overwritten\n";
- }
- else
- {
- print STDERR "ERROR: bogus file $_\n";
- push @bogus, $_;
- }
- }
- next unless /$filter.*\.req$/i;
- if (/\/([^\/]*)\.req$/ && exists $fips_tests{$1})
- {
- $fips_found{$1}++;
- test_line($win32, $_, $tprefix, $1);
- }
- elsif (! /SHAmix\.req$/)
- {
- print STDERR "WARNING: unrecognized filename $_\n";
- }
- }
- elsif (-d "$_")
- {
- if (/$filter.*req$/i)
- {
- test_dir($win32, $_);
- }
- recurse_test($win32, $tprefix, $filter, $_);
- }
- }
- closedir($dirh);
- }
-
-#--------------------------------
-sub test_dir
- {
- my ($win32, $req) = @_;
- my $rsp = $req;
- $rsp =~ s/req$/$rspdir/;
- if ($win32)
- {
- $rsp =~ tr|/|\\|;
- $req =~ tr|/|\\|;
- $bufdir = <<END;
-
-echo Running tests in $req
-if exist "$rsp" rd /s /q "$rsp"
-md "$rsp"
-END
- }
- else
- {
- $bufdir = <<END;
-
-echo Running tests in "$req"
-\$RM "$rsp"
-\$MKDIR "$rsp"
-
-END
- }
- }
-
-#--------------------------------
-sub test_line
- {
- my ($win32, $req, $tprefix, $tnam) = @_;
- my $rsp = $req;
- my $tcmd = $fips_tests{$tnam};
-
- $bufout .= $bufdir;
- $bufdir = "";
-
- $rsp =~ s/req\/([^\/]*).req$/$rspdir\/$1.rsp/;
- if ($tcmd =~ /-f$/)
- {
- if ($win32)
- {
- $req =~ tr|/|\\|;
- $rsp =~ tr|/|\\|;
- $bufout .= "$tprefix$tcmd \"$req\" \"$rsp\"\n";
- $_programs{"$tprefix$tcmd.exe"} = 1;
- }
- else
- {
- $bufout .= <<END;
-${shwrap}\${TPREFIX}$tcmd "$req" "$rsp" || { echo "$req failure" ; exit 1
-}
-END
- $_programs{"${shwrap_prefix}shlib_wrap.sh"} = 1;
- $_programs{"$tprefix$tcmd"} = 1;
- }
- return;
- }
- if ($tcmd =~ /SALT$/)
- {
- open (IN, $req) || die "Can't Open File $req";
- my $saltlen;
- while (<IN>)
- {
- if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i)
- {
- my $sl = $1;
- print STDERR "$req salt length $sl\n" if $debug;
- $tcmd =~ s/SALT$/$sl/;
- $salt_found{"$tnam (salt $sl)"}++;
- last;
- }
- }
- close IN;
- if ($tcmd =~ /SALT$/)
- {
- die "Can't detect salt length for $req";
- }
- }
-
- if ($win32)
- {
- $req =~ tr|/|\\|;
- $rsp =~ tr|/|\\|;
- $bufout .= "$tprefix$tcmd < \"$req\" > \"$rsp\"\n";
- $_programs{"$tprefix$tcmd.exe"} = 1;
- }
- else
- {
- $bufout .= <<END;
-${shwrap}\${TPREFIX}$tcmd < "$req" > "$rsp" || { echo "$req failure" ; exit 1; }
-END
- $_programs{"$tprefix$tcmd"} = 1;
- }
- }
-
diff --git a/crypto/openssl/fips/openssl_fips_fingerprint b/crypto/openssl/fips/openssl_fips_fingerprint
deleted file mode 100755
index f59a67d..0000000
--- a/crypto/openssl/fips/openssl_fips_fingerprint
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-#
-# Check the library fingerprint and generate an executable fingerprint, or
-# return an error
-
-lib=$1
-exe=$2
-ext=${HMAC_EXT:-sha1}
-
-# deal with the case where we're run from within the build and OpenSSL is
-# not yet installed. Also, make sure LD_LIBRARY_PATH is properly set in
-# case shared libraries are built.
-if [ "X$TOP" != "X" ]
-then
- if test "$OSTYPE" = msdosdjgpp; then
- PATH="$TOP/apps;$TOP;$PATH"
- else
- PATH="$TOP/apps:$TOP:$PATH"
- fi
- LD_LIBRARY_PATH=$TOP; export LD_LIBRARY_PATH
-else
- LD_LIBRARY_PATH=.; export LD_LIBRARY_PATH
-fi
-
-echo "Checking library fingerprint for $lib"
-openssl sha1 -hmac etaonrishdlcupfm $lib | sed "s/(.*\//(/" | diff -w $lib.sha1 - || { echo "$libs fingerprint mismatch"; exit 1; }
-
-[ -x $exe.exe ] && exe=$exe.exe
-
-echo "Making fingerprint for $exe"
-openssl sha1 -hmac etaonrishdlcupfm -binary $exe > $exe.$ext || rm $exe.$ext
diff --git a/crypto/openssl/fips/rand/Makefile b/crypto/openssl/fips/rand/Makefile
deleted file mode 100644
index 20303c8..0000000
--- a/crypto/openssl/fips/rand/Makefile
+++ /dev/null
@@ -1,149 +0,0 @@
-#
-# OpenSSL/fips/rand/Makefile
-#
-
-DIR= rand
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= fips_randtest.c fips_rngvs.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_rand.c fips_rand_selftest.c
-LIBOBJ=fips_rand.o fips_rand_selftest.o
-
-SRC= $(LIBSRC)
-
-EXHEADER= fips_rand.h
-HEADER= $(EXHEADER)
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-Q=../testvectors/rng/req
-A=../testvectors/rng/rsp
-
-fips_test:
- -rm -rf $(A)
- mkdir $(A)
- if [ -f $(Q)/ANSI931_AES128MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES128MCT.req > $(A)/ANSI931_AES128MCT.rsp; fi
- if [ -f $(Q)/ANSI931_AES192MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES192MCT.req > $(A)/ANSI931_AES192MCT.rsp; fi
- if [ -f $(Q)/ANSI931_AES256MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES256MCT.req > $(A)/ANSI931_AES256MCT.rsp; fi
- if [ -f $(Q)/ANSI931_AES128VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES128VST.req > $(A)/ANSI931_AES128VST.rsp; fi
- if [ -f $(Q)/ANSI931_AES192VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES192VST.req > $(A)/ANSI931_AES192VST.rsp; fi
- if [ -f $(Q)/ANSI931_AES256VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES256VST.req > $(A)/ANSI931_AES256VST.rsp; fi
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_rand.o: ../../e_os.h ../../include/openssl/aes.h
-fips_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
-fips_rand.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-fips_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
-fips_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
-fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
-fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-fips_rand.o: ../fips_locl.h fips_rand.c
-fips_rand_selftest.o: ../../include/openssl/bio.h
-fips_rand_selftest.o: ../../include/openssl/crypto.h
-fips_rand_selftest.o: ../../include/openssl/des.h
-fips_rand_selftest.o: ../../include/openssl/des_old.h
-fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rand_selftest.o: ../../include/openssl/fips.h
-fips_rand_selftest.o: ../../include/openssl/fips_rand.h
-fips_rand_selftest.o: ../../include/openssl/lhash.h
-fips_rand_selftest.o: ../../include/openssl/opensslconf.h
-fips_rand_selftest.o: ../../include/openssl/opensslv.h
-fips_rand_selftest.o: ../../include/openssl/ossl_typ.h
-fips_rand_selftest.o: ../../include/openssl/rand.h
-fips_rand_selftest.o: ../../include/openssl/safestack.h
-fips_rand_selftest.o: ../../include/openssl/stack.h
-fips_rand_selftest.o: ../../include/openssl/symhacks.h
-fips_rand_selftest.o: ../../include/openssl/ui.h
-fips_rand_selftest.o: ../../include/openssl/ui_compat.h fips_rand_selftest.c
-fips_randtest.o: ../../e_os.h ../../include/openssl/bio.h
-fips_randtest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_randtest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-fips_randtest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_randtest.o: ../../include/openssl/fips_rand.h
-fips_randtest.o: ../../include/openssl/lhash.h
-fips_randtest.o: ../../include/openssl/opensslconf.h
-fips_randtest.o: ../../include/openssl/opensslv.h
-fips_randtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-fips_randtest.o: ../../include/openssl/safestack.h
-fips_randtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_randtest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-fips_randtest.o: ../fips_utl.h fips_randtest.c
-fips_rngvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rngvs.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_rngvs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-fips_rngvs.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
-fips_rngvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
-fips_rngvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
-fips_rngvs.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
-fips_rngvs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_rngvs.o: ../../include/openssl/fips_rand.h ../../include/openssl/lhash.h
-fips_rngvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-fips_rngvs.o: ../../include/openssl/opensslconf.h
-fips_rngvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
-fips_rngvs.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
-fips_rngvs.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-fips_rngvs.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_rngvs.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
-fips_rngvs.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-fips_rngvs.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rngvs.c
diff --git a/crypto/openssl/fips/rand/fips_rand.c b/crypto/openssl/fips/rand/fips_rand.c
deleted file mode 100644
index 9492b15..0000000
--- a/crypto/openssl/fips/rand/fips_rand.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2007 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 is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4.
- */
-
-#include "e_os.h"
-
-/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't
- be defined and gettimeofday() won't be declared with strict compilers
- like DEC C in ANSI C mode. */
-#ifndef _XOPEN_SOURCE_EXTENDED
-#define _XOPEN_SOURCE_EXTENDED 1
-#endif
-
-#include <openssl/rand.h>
-#include <openssl/aes.h>
-#include <openssl/err.h>
-#include <openssl/fips_rand.h>
-#ifndef OPENSSL_SYS_WIN32
-#include <sys/time.h>
-#endif
-#include <assert.h>
-#ifndef OPENSSL_SYS_WIN32
-# ifdef OPENSSL_UNISTD
-# include OPENSSL_UNISTD
-# else
-# include <unistd.h>
-# endif
-#endif
-#include <string.h>
-#include <openssl/fips.h>
-#include "fips_locl.h"
-
-#ifdef OPENSSL_FIPS
-
-void *OPENSSL_stderr(void);
-
-#define AES_BLOCK_LENGTH 16
-
-
-/* AES FIPS PRNG implementation */
-
-typedef struct
- {
- int seeded;
- int keyed;
- int test_mode;
- int second;
- int error;
- unsigned long counter;
- AES_KEY ks;
- int vpos;
- /* Temporary storage for key if it equals seed length */
- unsigned char tmp_key[AES_BLOCK_LENGTH];
- unsigned char V[AES_BLOCK_LENGTH];
- unsigned char DT[AES_BLOCK_LENGTH];
- unsigned char last[AES_BLOCK_LENGTH];
- } FIPS_PRNG_CTX;
-
-static FIPS_PRNG_CTX sctx;
-
-static int fips_prng_fail = 0;
-
-void FIPS_rng_stick(void)
- {
- fips_prng_fail = 1;
- }
-
-static void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
- {
- ctx->seeded = 0;
- ctx->keyed = 0;
- ctx->test_mode = 0;
- ctx->counter = 0;
- ctx->second = 0;
- ctx->error = 0;
- ctx->vpos = 0;
- OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH);
- OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY));
- }
-
-
-static int fips_set_prng_key(FIPS_PRNG_CTX *ctx,
- const unsigned char *key, FIPS_RAND_SIZE_T keylen)
- {
- FIPS_selftest_check();
- if (keylen != 16 && keylen != 24 && keylen != 32)
- {
- /* error: invalid key size */
- return 0;
- }
- AES_set_encrypt_key(key, keylen << 3, &ctx->ks);
- if (keylen == 16)
- {
- memcpy(ctx->tmp_key, key, 16);
- ctx->keyed = 2;
- }
- else
- ctx->keyed = 1;
- ctx->seeded = 0;
- ctx->second = 0;
- return 1;
- }
-
-static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx,
- const unsigned char *seed, FIPS_RAND_SIZE_T seedlen)
- {
- int i;
- if (!ctx->keyed)
- return 0;
- /* In test mode seed is just supplied data */
- if (ctx->test_mode)
- {
- if (seedlen != AES_BLOCK_LENGTH)
- return 0;
- memcpy(ctx->V, seed, AES_BLOCK_LENGTH);
- ctx->seeded = 1;
- return 1;
- }
- /* Outside test mode XOR supplied data with existing seed */
- for (i = 0; i < seedlen; i++)
- {
- ctx->V[ctx->vpos++] ^= seed[i];
- if (ctx->vpos == AES_BLOCK_LENGTH)
- {
- ctx->vpos = 0;
- /* Special case if first seed and key length equals
- * block size check key and seed do not match.
- */
- if (ctx->keyed == 2)
- {
- if (!memcmp(ctx->tmp_key, ctx->V, 16))
- {
- RANDerr(RAND_F_FIPS_SET_PRNG_SEED,
- RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY);
- return 0;
- }
- OPENSSL_cleanse(ctx->tmp_key, 16);
- ctx->keyed = 1;
- }
- ctx->seeded = 1;
- }
- }
- return 1;
- }
-
-static int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
- {
- if (ctx->keyed)
- {
- RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED);
- return 0;
- }
- ctx->test_mode = 1;
- return 1;
- }
-
-int FIPS_rand_test_mode(void)
- {
- return fips_set_test_mode(&sctx);
- }
-
-int FIPS_rand_set_dt(unsigned char *dt)
- {
- if (!sctx.test_mode)
- {
- RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE);
- return 0;
- }
- memcpy(sctx.DT, dt, AES_BLOCK_LENGTH);
- return 1;
- }
-
-static void fips_get_dt(FIPS_PRNG_CTX *ctx)
- {
-#ifdef OPENSSL_SYS_WIN32
- FILETIME ft;
-#else
- struct timeval tv;
-#endif
- unsigned char *buf = ctx->DT;
-
-#ifndef GETPID_IS_MEANINGLESS
- unsigned long pid;
-#endif
-
-#ifdef OPENSSL_SYS_WIN32
- GetSystemTimeAsFileTime(&ft);
- buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff);
- buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff);
- buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff);
- buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff);
- buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff);
- buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff);
- buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff);
- buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff);
-#else
- gettimeofday(&tv,NULL);
- buf[0] = (unsigned char) (tv.tv_sec & 0xff);
- buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff);
- buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff);
- buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff);
- buf[4] = (unsigned char) (tv.tv_usec & 0xff);
- buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff);
- buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff);
- buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff);
-#endif
- buf[8] = (unsigned char) (ctx->counter & 0xff);
- buf[9] = (unsigned char) ((ctx->counter >> 8) & 0xff);
- buf[10] = (unsigned char) ((ctx->counter >> 16) & 0xff);
- buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff);
-
- ctx->counter++;
-
-
-#ifndef GETPID_IS_MEANINGLESS
- pid=(unsigned long)getpid();
- buf[12] = (unsigned char) (pid & 0xff);
- buf[13] = (unsigned char) ((pid >> 8) & 0xff);
- buf[14] = (unsigned char) ((pid >> 16) & 0xff);
- buf[15] = (unsigned char) ((pid >> 24) & 0xff);
-#endif
- }
-
-static int fips_rand(FIPS_PRNG_CTX *ctx,
- unsigned char *out, FIPS_RAND_SIZE_T outlen)
- {
- unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH];
- unsigned char tmp[AES_BLOCK_LENGTH];
- int i;
- if (ctx->error)
- {
- RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR);
- return 0;
- }
- if (!ctx->keyed)
- {
- RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET);
- return 0;
- }
- if (!ctx->seeded)
- {
- RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED);
- return 0;
- }
- for (;;)
- {
- if (!ctx->test_mode)
- fips_get_dt(ctx);
- AES_encrypt(ctx->DT, I, &ctx->ks);
- for (i = 0; i < AES_BLOCK_LENGTH; i++)
- tmp[i] = I[i] ^ ctx->V[i];
- AES_encrypt(tmp, R, &ctx->ks);
- for (i = 0; i < AES_BLOCK_LENGTH; i++)
- tmp[i] = R[i] ^ I[i];
- AES_encrypt(tmp, ctx->V, &ctx->ks);
- /* Continuous PRNG test */
- if (ctx->second)
- {
- if (fips_prng_fail)
- memcpy(ctx->last, R, AES_BLOCK_LENGTH);
- if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH))
- {
- RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK);
- ctx->error = 1;
- fips_set_selftest_fail();
- return 0;
- }
- }
- memcpy(ctx->last, R, AES_BLOCK_LENGTH);
- if (!ctx->second)
- {
- ctx->second = 1;
- if (!ctx->test_mode)
- continue;
- }
-
- if (outlen <= AES_BLOCK_LENGTH)
- {
- memcpy(out, R, outlen);
- break;
- }
-
- memcpy(out, R, AES_BLOCK_LENGTH);
- out += AES_BLOCK_LENGTH;
- outlen -= AES_BLOCK_LENGTH;
- }
- return 1;
- }
-
-
-int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen)
- {
- int ret;
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- ret = fips_set_prng_key(&sctx, key, keylen);
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- return ret;
- }
-
-int FIPS_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen)
- {
- int ret;
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- ret = fips_set_prng_seed(&sctx, seed, seedlen);
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- return ret;
- }
-
-
-int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T count)
- {
- int ret;
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- ret = fips_rand(&sctx, out, count);
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- return ret;
- }
-
-int FIPS_rand_status(void)
- {
- int ret;
- CRYPTO_r_lock(CRYPTO_LOCK_RAND);
- ret = sctx.seeded;
- CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
- return ret;
- }
-
-void FIPS_rand_reset(void)
- {
- CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- fips_rand_prng_reset(&sctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
- }
-
-static void fips_do_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen)
- {
- FIPS_rand_seed(seed, seedlen);
- }
-
-static void fips_do_rand_add(const void *seed, FIPS_RAND_SIZE_T seedlen,
- double add_entropy)
- {
- FIPS_rand_seed(seed, seedlen);
- }
-
-static const RAND_METHOD rand_fips_meth=
- {
- fips_do_rand_seed,
- FIPS_rand_bytes,
- FIPS_rand_reset,
- fips_do_rand_add,
- FIPS_rand_bytes,
- FIPS_rand_status
- };
-
-const RAND_METHOD *FIPS_rand_method(void)
-{
- return &rand_fips_meth;
-}
-
-#endif
diff --git a/crypto/openssl/fips/rand/fips_rand.h b/crypto/openssl/fips/rand/fips_rand.h
deleted file mode 100644
index a175aaf..0000000
--- a/crypto/openssl/fips/rand/fips_rand.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#ifndef HEADER_FIPS_RAND_H
-#define HEADER_FIPS_RAND_H
-
-#include "des.h"
-
-#ifdef OPENSSL_FIPS
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen);
-int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
-int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen);
-
-int FIPS_rand_test_mode(void);
-void FIPS_rand_reset(void);
-int FIPS_rand_set_dt(unsigned char *dt);
-
-int FIPS_rand_status(void);
-
-const RAND_METHOD *FIPS_rand_method(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
diff --git a/crypto/openssl/fips/rand/fips_rand_selftest.c b/crypto/openssl/fips/rand/fips_rand_selftest.c
deleted file mode 100644
index 2194a76..0000000
--- a/crypto/openssl/fips/rand/fips_rand_selftest.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-#include <openssl/rand.h>
-#include <openssl/fips_rand.h>
-
-#ifdef OPENSSL_FIPS
-
-
-
-typedef struct
- {
- unsigned char DT[16];
- unsigned char V[16];
- unsigned char R[16];
- } AES_PRNG_TV;
-
-/* The following test vectors are taken directly from the RGNVS spec */
-
-static unsigned char aes_128_key[16] =
- {0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42,
- 0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02};
-
-static AES_PRNG_TV aes_128_tv[] = {
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9},
- /* V */
- {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55,
- 0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41}
- },
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfa},
- /* V */
- {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x7c,0x22,0x2c,0xf4,0xca,0x8f,0xa2,0x4c,
- 0x1c,0x9c,0xb6,0x41,0xa9,0xf3,0x22,0x0d}
- },
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfb},
- /* V */
- {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x8a,0xaa,0x00,0x39,0x66,0x67,0x5b,0xe5,
- 0x29,0x14,0x28,0x81,0xa9,0x4d,0x4e,0xc7}
- },
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfc},
- /* V */
- {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x88,0xdd,0xa4,0x56,0x30,0x24,0x23,0xe5,
- 0xf6,0x9d,0xa5,0x7e,0x7b,0x95,0xc7,0x3a}
- },
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfd},
- /* V */
- {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x05,0x25,0x92,0x46,0x61,0x79,0xd2,0xcb,
- 0x78,0xc4,0x0b,0x14,0x0a,0x5a,0x9a,0xc8}
- },
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x77},
- /* V */
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
- /* R */
- {0x0d,0xd5,0xa0,0x36,0x7a,0x59,0x26,0xbc,
- 0x48,0xd9,0x38,0xbf,0xf0,0x85,0x8f,0xea}
- },
- {
- /* DT */
- {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
- 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x78},
- /* V */
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
- /* R */
- {0xae,0x53,0x87,0xee,0x8c,0xd9,0x12,0xf5,
- 0x73,0x53,0xae,0x03,0xf9,0xd5,0x13,0x33}
- },
-};
-
-static unsigned char aes_192_key[24] =
- {0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e,
- 0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc,
- 0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b};
-
-static AES_PRNG_TV aes_192_tv[] = {
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b},
- /* V */
- {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef,
- 0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93}
- },
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4c},
- /* V */
- {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x92,0x8d,0xbe,0x07,0xdd,0xc7,0x58,0xc0,
- 0x6f,0x35,0x41,0x9b,0x17,0xc9,0xbd,0x9b}
- },
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4d},
- /* V */
- {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0xd5,0xde,0xf4,0x50,0xf3,0xb7,0x10,0x4e,
- 0xb8,0xc6,0xf8,0xcf,0xe2,0xb1,0xca,0xa2}
- },
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4e},
- /* V */
- {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0xce,0x29,0x08,0x43,0xfc,0x34,0x41,0xe7,
- 0x47,0x8f,0xb3,0x66,0x2b,0x46,0xb1,0xbb}
- },
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4f},
- /* V */
- {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0xb3,0x26,0x0f,0xf5,0xd6,0xca,0xa8,0xbf,
- 0x89,0xb8,0x5e,0x2f,0x22,0x56,0x92,0x2f}
- },
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xc9},
- /* V */
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
- /* R */
- {0x05,0xeb,0x18,0x52,0x34,0x43,0x00,0x43,
- 0x6e,0x5a,0xa5,0xfe,0x7b,0x32,0xc4,0x2d}
- },
- {
- /* DT */
- {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
- 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xca},
- /* V */
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
- /* R */
- {0x15,0x3c,0xe8,0xd1,0x04,0xc7,0xad,0x50,
- 0x0b,0xf0,0x07,0x16,0xe7,0x56,0x7a,0xea}
- },
-};
-
-static unsigned char aes_256_key[32] =
- {0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d,
- 0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f,
- 0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5,
- 0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb};
-
-static AES_PRNG_TV aes_256_tv[] = {
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88},
- /* V */
- {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc,
- 0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72}
- },
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x89},
- /* V */
- {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x6c,0xf4,0x42,0x5d,0xc7,0x04,0x1a,0x41,
- 0x28,0x2a,0x78,0xa9,0xb0,0x12,0xc4,0x95}
- },
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8a},
- /* V */
- {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x16,0x90,0xa4,0xff,0x7b,0x7e,0xb9,0x30,
- 0xdb,0x67,0x4b,0xac,0x2d,0xe1,0xd1,0x75}
- },
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8b},
- /* V */
- {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x14,0x6f,0xf5,0x95,0xa1,0x46,0x65,0x30,
- 0xbc,0x57,0xe2,0x4a,0xf7,0x45,0x62,0x05}
- },
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8c},
- /* V */
- {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
- /* R */
- {0x96,0xe2,0xb4,0x1e,0x66,0x5e,0x0f,0xa4,
- 0xc5,0xcd,0xa2,0x07,0xcc,0xb7,0x94,0x40}
- },
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x06},
- /* V */
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
- /* R */
- {0x61,0xce,0x1d,0x6a,0x48,0x75,0x97,0x28,
- 0x4b,0x41,0xde,0x18,0x44,0x4f,0x56,0xec}
- },
- {
- /* DT */
- {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
- 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x07},
- /* V */
- {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
- /* R */
- {0x52,0x89,0x59,0x79,0x2d,0xaa,0x28,0xb3,
- 0xb0,0x8a,0x3e,0x70,0xfa,0x71,0x59,0x84}
- },
-};
-
-
-void FIPS_corrupt_rng()
- {
- aes_192_tv[0].V[0]++;
- }
-
-#define fips_rand_test(key, tv) \
- do_rand_test(key, sizeof key, tv, sizeof(tv)/sizeof(AES_PRNG_TV))
-
-static int do_rand_test(unsigned char *key, int keylen,
- AES_PRNG_TV *tv, int ntv)
- {
- unsigned char R[16];
- int i;
- if (!FIPS_rand_set_key(key, keylen))
- return 0;
- for (i = 0; i < ntv; i++)
- {
- FIPS_rand_seed(tv[i].V, 16);
- FIPS_rand_set_dt(tv[i].DT);
- FIPS_rand_bytes(R, 16);
- if (memcmp(R, tv[i].R, 16))
- return 0;
- }
- return 1;
- }
-
-
-int FIPS_selftest_rng()
- {
- FIPS_rand_reset();
- if (!FIPS_rand_test_mode())
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
- if (!fips_rand_test(aes_128_key,aes_128_tv)
- || !fips_rand_test(aes_192_key, aes_192_tv)
- || !fips_rand_test(aes_256_key, aes_256_tv))
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
- FIPS_rand_reset();
- return 1;
- }
-
-#endif
diff --git a/crypto/openssl/fips/rand/fips_randtest.c b/crypto/openssl/fips/rand/fips_randtest.c
deleted file mode 100644
index 5582941..0000000
--- a/crypto/openssl/fips/rand/fips_randtest.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* 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.]
- */
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <openssl/rand.h>
-#include <openssl/fips_rand.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-
-#include "e_os.h"
-
-#ifndef OPENSSL_FIPS
-int main(int argc, char *argv[])
-{
- printf("No FIPS RAND support\n");
- return(0);
-}
-
-#else
-
-#include "fips_utl.h"
-
-typedef struct
- {
- unsigned char DT[16];
- unsigned char V[16];
- unsigned char R[16];
- } AES_PRNG_MCT;
-
-static unsigned char aes_128_mct_key[16] =
- {0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5,
- 0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48};
-
-static AES_PRNG_MCT aes_128_mct_tv = {
- /* DT */
- {0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b,
- 0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac},
- /* V */
- {0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97,
- 0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1},
- /* R */
- {0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb,
- 0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73}
-};
-
-static unsigned char aes_192_mct_key[24] =
- {0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73,
- 0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91,
- 0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a};
-
-static AES_PRNG_MCT aes_192_mct_tv = {
- /* DT */
- {0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9,
- 0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52},
- /* V */
- {0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64,
- 0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d},
- /* R */
- {0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21,
- 0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47}
-};
-
-static unsigned char aes_256_mct_key[32] =
- {0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a,
- 0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0,
- 0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d,
- 0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50};
-
-static AES_PRNG_MCT aes_256_mct_tv = {
- /* DT */
- {0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee,
- 0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c},
- /* V */
- {0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1,
- 0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca},
- /* R */
- {0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1,
- 0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d}
-};
-
-static void dump(const unsigned char *b,int n)
- {
- while(n-- > 0)
- {
- printf(" %02x",*b++);
- }
- }
-
-static void compare(const unsigned char *result,const unsigned char *expected,
- int n)
- {
- int i;
-
- for(i=0 ; i < n ; ++i)
- if(result[i] != expected[i])
- {
- puts("Random test failed, got:");
- dump(result,n);
- puts("\n expected:");
- dump(expected,n);
- putchar('\n');
- EXIT(1);
- }
- }
-
-
-static void run_test(unsigned char *key, int keylen, AES_PRNG_MCT *tv)
- {
- unsigned char buf[16], dt[16];
- int i, j;
- FIPS_rand_reset();
- FIPS_rand_test_mode();
- FIPS_rand_set_key(key, keylen);
- FIPS_rand_seed(tv->V, 16);
- memcpy(dt, tv->DT, 16);
- for (i = 0; i < 10000; i++)
- {
- FIPS_rand_set_dt(dt);
- FIPS_rand_bytes(buf, 16);
- /* Increment DT */
- for (j = 15; j >= 0; j--)
- {
- dt[j]++;
- if (dt[j])
- break;
- }
- }
-
- compare(buf,tv->R, 16);
- }
-
-int main()
- {
- run_test(aes_128_mct_key, 16, &aes_128_mct_tv);
- printf("FIPS PRNG test 1 done\n");
- run_test(aes_192_mct_key, 24, &aes_192_mct_tv);
- printf("FIPS PRNG test 2 done\n");
- run_test(aes_256_mct_key, 32, &aes_256_mct_tv);
- printf("FIPS PRNG test 3 done\n");
- return 0;
- }
-
-#endif
diff --git a/crypto/openssl/fips/rand/fips_rngvs.c b/crypto/openssl/fips/rand/fips_rngvs.c
deleted file mode 100644
index 80a8017..0000000
--- a/crypto/openssl/fips/rand/fips_rngvs.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Crude test driver for processing the VST and MCT testvector files
- * generated by the CMVP RNGVS product.
- *
- * Note the input files are assumed to have a _very_ specific format
- * as described in the NIST document "The Random Number Generator
- * Validation System (RNGVS)", May 25, 2004.
- *
- */
-#include <openssl/opensslconf.h>
-
-#ifndef OPENSSL_FIPS
-#include <stdio.h>
-
-int main(int argc, char **argv)
-{
- printf("No FIPS RNG support\n");
- return 0;
-}
-#else
-
-#include <openssl/bn.h>
-#include <openssl/dsa.h>
-#include <openssl/fips.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-#include <openssl/fips_rand.h>
-#include <openssl/x509v3.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "fips_utl.h"
-
-static void vst()
- {
- unsigned char *key = NULL;
- unsigned char *v = NULL;
- unsigned char *dt = NULL;
- unsigned char ret[16];
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- long i, keylen;
-
- keylen = 0;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- fputs(buf,stdout);
- if(!strncmp(buf,"[AES 128-Key]", 13))
- keylen = 16;
- else if(!strncmp(buf,"[AES 192-Key]", 13))
- keylen = 24;
- else if(!strncmp(buf,"[AES 256-Key]", 13))
- keylen = 32;
- if (!parse_line(&keyword, &value, lbuf, buf))
- continue;
- if(!strcmp(keyword,"Key"))
- {
- key=hex2bin_m(value,&i);
- if (i != keylen)
- {
- fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
- return;
- }
- }
- else if(!strcmp(keyword,"DT"))
- {
- dt=hex2bin_m(value,&i);
- if (i != 16)
- {
- fprintf(stderr, "Invalid DT length\n");
- return;
- }
- }
- else if(!strcmp(keyword,"V"))
- {
- v=hex2bin_m(value,&i);
- if (i != 16)
- {
- fprintf(stderr, "Invalid V length\n");
- return;
- }
-
- if (!key || !dt)
- {
- fprintf(stderr, "Missing key or DT\n");
- return;
- }
-
- FIPS_rand_set_key(key, keylen);
- FIPS_rand_seed(v,16);
- FIPS_rand_set_dt(dt);
- if (FIPS_rand_bytes(ret,16) <= 0)
- {
- fprintf(stderr, "Error getting PRNG value\n");
- return;
- }
-
- pv("R",ret,16);
- OPENSSL_free(key);
- key = NULL;
- OPENSSL_free(dt);
- dt = NULL;
- OPENSSL_free(v);
- v = NULL;
- }
- }
- }
-
-static void mct()
- {
- unsigned char *key = NULL;
- unsigned char *v = NULL;
- unsigned char *dt = NULL;
- unsigned char ret[16];
- char buf[1024];
- char lbuf[1024];
- char *keyword, *value;
- long i, keylen;
- int j;
-
- keylen = 0;
-
- while(fgets(buf,sizeof buf,stdin) != NULL)
- {
- fputs(buf,stdout);
- if(!strncmp(buf,"[AES 128-Key]", 13))
- keylen = 16;
- else if(!strncmp(buf,"[AES 192-Key]", 13))
- keylen = 24;
- else if(!strncmp(buf,"[AES 256-Key]", 13))
- keylen = 32;
- if (!parse_line(&keyword, &value, lbuf, buf))
- continue;
- if(!strcmp(keyword,"Key"))
- {
- key=hex2bin_m(value,&i);
- if (i != keylen)
- {
- fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
- return;
- }
- }
- else if(!strcmp(keyword,"DT"))
- {
- dt=hex2bin_m(value,&i);
- if (i != 16)
- {
- fprintf(stderr, "Invalid DT length\n");
- return;
- }
- }
- else if(!strcmp(keyword,"V"))
- {
- v=hex2bin_m(value,&i);
- if (i != 16)
- {
- fprintf(stderr, "Invalid V length\n");
- return;
- }
-
- if (!key || !dt)
- {
- fprintf(stderr, "Missing key or DT\n");
- return;
- }
-
- FIPS_rand_set_key(key, keylen);
- FIPS_rand_seed(v,16);
- for (i = 0; i < 10000; i++)
- {
- FIPS_rand_set_dt(dt);
- if (FIPS_rand_bytes(ret,16) <= 0)
- {
- fprintf(stderr, "Error getting PRNG value\n");
- return;
- }
- /* Increment DT */
- for (j = 15; j >= 0; j--)
- {
- dt[j]++;
- if (dt[j])
- break;
- }
- }
-
- pv("R",ret,16);
- OPENSSL_free(key);
- key = NULL;
- OPENSSL_free(dt);
- dt = NULL;
- OPENSSL_free(v);
- v = NULL;
- }
- }
- }
-
-int main(int argc,char **argv)
- {
- if(argc != 2)
- {
- fprintf(stderr,"%s [mct|vst]\n",argv[0]);
- exit(1);
- }
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- exit(1);
- }
- FIPS_rand_reset();
- if (!FIPS_rand_test_mode())
- {
- fprintf(stderr, "Error setting PRNG test mode\n");
- do_print_errors();
- exit(1);
- }
- if(!strcmp(argv[1],"mct"))
- mct();
- else if(!strcmp(argv[1],"vst"))
- vst();
- else
- {
- fprintf(stderr,"Don't know how to %s.\n",argv[1]);
- exit(1);
- }
-
- return 0;
- }
-#endif
diff --git a/crypto/openssl/fips/rsa/Makefile b/crypto/openssl/fips/rsa/Makefile
deleted file mode 100644
index da28c13..0000000
--- a/crypto/openssl/fips/rsa/Makefile
+++ /dev/null
@@ -1,215 +0,0 @@
-#
-# OpenSSL/fips/rsa/Makefile
-#
-
-DIR= rsa
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= fips_rsavtest.c fips_rsastest.c fips_rsagtest.c
-APPS=
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_rsa_eay.c fips_rsa_gen.c fips_rsa_selftest.c fips_rsa_x931g.c \
- fips_rsa_sign.c fips_rsa_lib.c
-LIBOBJ=fips_rsa_eay.o fips_rsa_gen.o fips_rsa_selftest.o fips_rsa_x931g.o \
- fips_rsa_sign.o fips_rsa_lib.o
-
-SRC= $(LIBSRC)
-
-EXHEADER=
-HEADER= $(EXHEADER)
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips FDIRS=$(DIR) sub_all)
-
-all: lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-Q=../testvectors/rsa/req
-A=../testvectors/rsa/rsp
-Q62=../testvectors/rsa_salt_62/req
-A62=../testvectors/rsa_salt_62/rsp
-
-fips_test:
- -rm -rf $(A) $(A62)
- mkdir $(A) $(A62)
- if [ -f $(Q)/SigGen15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest < $(Q)/SigGen15.req > $(A)/SigGen15.rsp; fi
- if [ -f $(Q)/SigVer15.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest < $(Q)/SigVer15.req > $(A)/SigVer15.rsp; fi
- if [ -f $(Q)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 0 < $(Q)/SigGenPSS.req > $(A)/SigGenPSS.rsp; fi
- if [ -f $(Q)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 0 < $(Q)/SigVerPSS.req > $(A)/SigVerPSS.rsp; fi
- if [ -f $(Q)/SigGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -x931 < $(Q)/SigGenRSA.req > $(A)/SigGenRSA.rsp; fi
- if [ -f $(Q)/SigVerRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -x931 < $(Q)/SigVerRSA.req > $(A)/SigVerRSA.rsp; fi
- if [ -f $(Q62)/SigGenPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsastest -saltlen 62 < $(Q62)/SigGenPSS.req >$(A62)/SigGenPSS.rsp; fi
- if [ -f $(Q62)/SigVerPSS.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsavtest -saltlen 62 <$(Q62)/SigVerPSS.req >$(A62)/SigVerPSS.rsp; fi
- if [ -f $(Q)/KeyGenRSA.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rsagtest < $(Q)/KeyGenRSA.req > $(A)/KeyGenRSA.rsp; fi
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_rsa_eay.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsa_eay.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_rsa_eay.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rsa_eay.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_rsa_eay.o: ../../include/openssl/opensslconf.h
-fips_rsa_eay.o: ../../include/openssl/opensslv.h
-fips_rsa_eay.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
-fips_rsa_eay.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-fips_rsa_eay.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_rsa_eay.o: fips_rsa_eay.c
-fips_rsa_gen.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsa_gen.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_rsa_gen.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rsa_gen.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_rsa_gen.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_rsa_gen.o: ../../include/openssl/objects.h
-fips_rsa_gen.o: ../../include/openssl/opensslconf.h
-fips_rsa_gen.o: ../../include/openssl/opensslv.h
-fips_rsa_gen.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
-fips_rsa_gen.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_rsa_gen.o: ../../include/openssl/symhacks.h ../fips_locl.h fips_rsa_gen.c
-fips_rsa_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsa_lib.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_rsa_lib.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rsa_lib.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_rsa_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_rsa_lib.o: ../../include/openssl/objects.h
-fips_rsa_lib.o: ../../include/openssl/opensslconf.h
-fips_rsa_lib.o: ../../include/openssl/opensslv.h
-fips_rsa_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
-fips_rsa_lib.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
-fips_rsa_lib.o: ../../include/openssl/symhacks.h fips_rsa_lib.c
-fips_rsa_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsa_selftest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_rsa_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rsa_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_rsa_selftest.o: ../../include/openssl/lhash.h
-fips_rsa_selftest.o: ../../include/openssl/obj_mac.h
-fips_rsa_selftest.o: ../../include/openssl/objects.h
-fips_rsa_selftest.o: ../../include/openssl/opensslconf.h
-fips_rsa_selftest.o: ../../include/openssl/opensslv.h
-fips_rsa_selftest.o: ../../include/openssl/ossl_typ.h
-fips_rsa_selftest.o: ../../include/openssl/rsa.h
-fips_rsa_selftest.o: ../../include/openssl/safestack.h
-fips_rsa_selftest.o: ../../include/openssl/stack.h
-fips_rsa_selftest.o: ../../include/openssl/symhacks.h fips_rsa_selftest.c
-fips_rsa_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsa_sign.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-fips_rsa_sign.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_rsa_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_rsa_sign.o: ../../include/openssl/obj_mac.h
-fips_rsa_sign.o: ../../include/openssl/objects.h
-fips_rsa_sign.o: ../../include/openssl/opensslconf.h
-fips_rsa_sign.o: ../../include/openssl/opensslv.h
-fips_rsa_sign.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
-fips_rsa_sign.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-fips_rsa_sign.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_rsa_sign.o: fips_rsa_sign.c
-fips_rsa_x931g.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsa_x931g.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
-fips_rsa_x931g.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_rsa_x931g.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_rsa_x931g.o: ../../include/openssl/opensslconf.h
-fips_rsa_x931g.o: ../../include/openssl/opensslv.h
-fips_rsa_x931g.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rsa.h
-fips_rsa_x931g.o: ../../include/openssl/safestack.h
-fips_rsa_x931g.o: ../../include/openssl/stack.h
-fips_rsa_x931g.o: ../../include/openssl/symhacks.h fips_rsa_x931g.c
-fips_rsagtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsagtest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_rsagtest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-fips_rsagtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-fips_rsagtest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-fips_rsagtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_rsagtest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
-fips_rsagtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_rsagtest.o: ../../include/openssl/objects.h
-fips_rsagtest.o: ../../include/openssl/opensslconf.h
-fips_rsagtest.o: ../../include/openssl/opensslv.h
-fips_rsagtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_rsagtest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-fips_rsagtest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-fips_rsagtest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-fips_rsagtest.o: ../../include/openssl/x509_vfy.h
-fips_rsagtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsagtest.c
-fips_rsastest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsastest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_rsastest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-fips_rsastest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-fips_rsastest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-fips_rsastest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_rsastest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
-fips_rsastest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_rsastest.o: ../../include/openssl/objects.h
-fips_rsastest.o: ../../include/openssl/opensslconf.h
-fips_rsastest.o: ../../include/openssl/opensslv.h
-fips_rsastest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_rsastest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-fips_rsastest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-fips_rsastest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-fips_rsastest.o: ../../include/openssl/x509_vfy.h
-fips_rsastest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsastest.c
-fips_rsavtest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_rsavtest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_rsavtest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-fips_rsavtest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-fips_rsavtest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-fips_rsavtest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_rsavtest.o: ../../include/openssl/fips.h ../../include/openssl/hmac.h
-fips_rsavtest.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
-fips_rsavtest.o: ../../include/openssl/objects.h
-fips_rsavtest.o: ../../include/openssl/opensslconf.h
-fips_rsavtest.o: ../../include/openssl/opensslv.h
-fips_rsavtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_rsavtest.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
-fips_rsavtest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-fips_rsavtest.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
-fips_rsavtest.o: ../../include/openssl/x509_vfy.h
-fips_rsavtest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rsavtest.c
diff --git a/crypto/openssl/fips/rsa/fips_rsa_eay.c b/crypto/openssl/fips/rsa/fips_rsa_eay.c
deleted file mode 100644
index 937a14e..0000000
--- a/crypto/openssl/fips/rsa/fips_rsa_eay.c
+++ /dev/null
@@ -1,934 +0,0 @@
-/* crypto/rsa/rsa_eay.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.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 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).
- *
- */
-
-#include <stdio.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-
-#if !defined(RSA_NULL) && defined(OPENSSL_FIPS)
-
-static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa,int padding);
-static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa,int padding);
-static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa,int padding);
-static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa,int padding);
-static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, BN_CTX *ctx);
-static int RSA_eay_init(RSA *rsa);
-static int RSA_eay_finish(RSA *rsa);
-static RSA_METHOD rsa_pkcs1_eay_meth={
- "Eric Young's PKCS#1 RSA",
- RSA_eay_public_encrypt,
- RSA_eay_public_decrypt, /* signature verification */
- RSA_eay_private_encrypt, /* signing */
- RSA_eay_private_decrypt,
- RSA_eay_mod_exp,
- BN_mod_exp_mont, /* XXX probably we should not use Montgomery if e == 3 */
- RSA_eay_init,
- RSA_eay_finish,
- RSA_FLAG_FIPS_METHOD, /* flags */
- NULL,
- 0, /* rsa_sign */
- 0, /* rsa_verify */
- NULL /* rsa_keygen */
- };
-
-const RSA_METHOD *RSA_PKCS1_SSLeay(void)
- {
- return(&rsa_pkcs1_eay_meth);
- }
-
-/* Usage example;
- * MONT_HELPER(rsa, bn_ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
- */
-#define MONT_HELPER(rsa, ctx, m, pre_cond, err_instr) \
- if((pre_cond) && ((rsa)->_method_mod_##m == NULL) && \
- !BN_MONT_CTX_set_locked(&((rsa)->_method_mod_##m), \
- CRYPTO_LOCK_RSA, \
- (rsa)->m, (ctx))) \
- err_instr
-
-static int RSA_eay_public_encrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding)
- {
- BIGNUM *f,*ret;
- int i,j,k,num=0,r= -1;
- unsigned char *buf=NULL;
- BN_CTX *ctx=NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
- goto err;
- }
-
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
- return -1;
- }
-
- if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE);
- return -1;
- }
-
- if (BN_ucmp(rsa->n, rsa->e) <= 0)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
- return -1;
- }
-
- /* for large moduli, enforce exponent limit */
- if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
- {
- if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE);
- return -1;
- }
- }
-
- if ((ctx=BN_CTX_new()) == NULL) goto err;
- BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
- ret = BN_CTX_get(ctx);
- num=BN_num_bytes(rsa->n);
- buf = OPENSSL_malloc(num);
- if (!f || !ret || !buf)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- switch (padding)
- {
- case RSA_PKCS1_PADDING:
- i=RSA_padding_add_PKCS1_type_2(buf,num,from,flen);
- break;
-#ifndef OPENSSL_NO_SHA
- case RSA_PKCS1_OAEP_PADDING:
- i=RSA_padding_add_PKCS1_OAEP(buf,num,from,flen,NULL,0);
- break;
-#endif
- case RSA_SSLV23_PADDING:
- i=RSA_padding_add_SSLv23(buf,num,from,flen);
- break;
- case RSA_NO_PADDING:
- i=RSA_padding_add_none(buf,num,from,flen);
- break;
- default:
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
- goto err;
- }
- if (i <= 0) goto err;
-
- if (BN_bin2bn(buf,num,f) == NULL) goto err;
-
- if (BN_ucmp(f, rsa->n) >= 0)
- {
- /* usually the padding functions would catch this */
- RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
- goto err;
- }
-
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
-
- if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
- rsa->_method_mod_n)) goto err;
-
- /* put in leading 0 bytes if the number is less than the
- * length of the modulus */
- j=BN_num_bytes(ret);
- i=BN_bn2bin(ret,&(to[num-j]));
- for (k=0; k<(num-i); k++)
- to[k]=0;
-
- r=num;
-err:
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (buf != NULL)
- {
- OPENSSL_cleanse(buf,num);
- OPENSSL_free(buf);
- }
- return(r);
- }
-
-static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
-{
- BN_BLINDING *ret;
- int got_write_lock = 0;
-
- CRYPTO_r_lock(CRYPTO_LOCK_RSA);
-
- if (rsa->blinding == NULL)
- {
- CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- got_write_lock = 1;
-
- if (rsa->blinding == NULL)
- rsa->blinding = RSA_setup_blinding(rsa, ctx);
- }
-
- ret = rsa->blinding;
- if (ret == NULL)
- goto err;
-
- if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id())
- {
- /* rsa->blinding is ours! */
-
- *local = 1;
- }
- else
- {
- /* resort to rsa->mt_blinding instead */
-
- *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
- * that the BN_BLINDING is shared, meaning that accesses
- * require locks, and that the blinding factor must be
- * stored outside the BN_BLINDING
- */
-
- if (rsa->mt_blinding == NULL)
- {
- if (!got_write_lock)
- {
- CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
- CRYPTO_w_lock(CRYPTO_LOCK_RSA);
- got_write_lock = 1;
- }
-
- if (rsa->mt_blinding == NULL)
- rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
- }
- ret = rsa->mt_blinding;
- }
-
- err:
- if (got_write_lock)
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
- else
- CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
- return ret;
-}
-
-static int rsa_blinding_convert(BN_BLINDING *b, int local, BIGNUM *f,
- BIGNUM *r, BN_CTX *ctx)
-{
- if (local)
- return BN_BLINDING_convert_ex(f, NULL, b, ctx);
- else
- {
- int ret;
- CRYPTO_r_lock(CRYPTO_LOCK_RSA_BLINDING);
- ret = BN_BLINDING_convert_ex(f, r, b, ctx);
- CRYPTO_r_unlock(CRYPTO_LOCK_RSA_BLINDING);
- return ret;
- }
-}
-
-static int rsa_blinding_invert(BN_BLINDING *b, int local, BIGNUM *f,
- BIGNUM *r, BN_CTX *ctx)
-{
- if (local)
- return BN_BLINDING_invert_ex(f, NULL, b, ctx);
- else
- {
- int ret;
- CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
- ret = BN_BLINDING_invert_ex(f, r, b, ctx);
- CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
- return ret;
- }
-}
-
-/* signing */
-static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding)
- {
- BIGNUM *f, *ret, *br, *res;
- int i,j,k,num=0,r= -1;
- unsigned char *buf=NULL;
- BN_CTX *ctx=NULL;
- int local_blinding = 0;
- BN_BLINDING *blinding = NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
- goto err;
- }
-
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
- return -1;
- }
-
- if ((ctx=BN_CTX_new()) == NULL) goto err;
- BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
- br = BN_CTX_get(ctx);
- ret = BN_CTX_get(ctx);
- num = BN_num_bytes(rsa->n);
- buf = OPENSSL_malloc(num);
- if(!f || !ret || !buf)
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- switch (padding)
- {
- case RSA_PKCS1_PADDING:
- i=RSA_padding_add_PKCS1_type_1(buf,num,from,flen);
- break;
- case RSA_X931_PADDING:
- i=RSA_padding_add_X931(buf,num,from,flen);
- break;
- case RSA_NO_PADDING:
- i=RSA_padding_add_none(buf,num,from,flen);
- break;
- case RSA_SSLV23_PADDING:
- default:
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
- goto err;
- }
- if (i <= 0) goto err;
-
- if (BN_bin2bn(buf,num,f) == NULL) goto err;
-
- if (BN_ucmp(f, rsa->n) >= 0)
- {
- /* usually the padding functions would catch this */
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
- goto err;
- }
-
- if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
- {
- blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
- if (blinding == NULL)
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- if (blinding != NULL)
- if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
- goto err;
-
- if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
- ((rsa->p != NULL) &&
- (rsa->q != NULL) &&
- (rsa->dmp1 != NULL) &&
- (rsa->dmq1 != NULL) &&
- (rsa->iqmp != NULL)) )
- {
- if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
- }
- else
- {
- BIGNUM local_d;
- BIGNUM *d = NULL;
-
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- BN_init(&local_d);
- d = &local_d;
- BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- }
- else
- d = rsa->d;
-
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
-
- if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
- rsa->_method_mod_n)) goto err;
- }
-
- if (blinding)
- if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
- goto err;
-
- if (padding == RSA_X931_PADDING)
- {
- BN_sub(f, rsa->n, ret);
- if (BN_cmp(ret, f))
- res = f;
- else
- res = ret;
- }
- else
- res = ret;
-
- /* put in leading 0 bytes if the number is less than the
- * length of the modulus */
- j=BN_num_bytes(res);
- i=BN_bn2bin(res,&(to[num-j]));
- for (k=0; k<(num-i); k++)
- to[k]=0;
-
- r=num;
-err:
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (buf != NULL)
- {
- OPENSSL_cleanse(buf,num);
- OPENSSL_free(buf);
- }
- return(r);
- }
-
-static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding)
- {
- BIGNUM *f, *ret, *br;
- int j,num=0,r= -1;
- unsigned char *p;
- unsigned char *buf=NULL;
- BN_CTX *ctx=NULL;
- int local_blinding = 0;
- BN_BLINDING *blinding = NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_RSA_EAY_PRIVATE_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
- goto err;
- }
-
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
- return -1;
- }
-
- if((ctx = BN_CTX_new()) == NULL) goto err;
- BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
- br = BN_CTX_get(ctx);
- ret = BN_CTX_get(ctx);
- num = BN_num_bytes(rsa->n);
- buf = OPENSSL_malloc(num);
- if(!f || !ret || !buf)
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- /* This check was for equality but PGP does evil things
- * and chops off the top '0' bytes */
- if (flen > num)
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
- goto err;
- }
-
- /* make data into a big number */
- if (BN_bin2bn(from,(int)flen,f) == NULL) goto err;
-
- if (BN_ucmp(f, rsa->n) >= 0)
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
- goto err;
- }
-
- if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
- {
- blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
- if (blinding == NULL)
- {
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
- goto err;
- }
- }
-
- if (blinding != NULL)
- if (!rsa_blinding_convert(blinding, local_blinding, f, br, ctx))
- goto err;
-
- /* do the decrypt */
- if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
- ((rsa->p != NULL) &&
- (rsa->q != NULL) &&
- (rsa->dmp1 != NULL) &&
- (rsa->dmq1 != NULL) &&
- (rsa->iqmp != NULL)) )
- {
- if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err;
- }
- else
- {
- BIGNUM local_d;
- BIGNUM *d = NULL;
-
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- d = &local_d;
- BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- }
- else
- d = rsa->d;
-
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
- if (!rsa->meth->bn_mod_exp(ret,f,d,rsa->n,ctx,
- rsa->_method_mod_n))
- goto err;
- }
-
- if (blinding)
- if (!rsa_blinding_invert(blinding, local_blinding, ret, br, ctx))
- goto err;
-
- p=buf;
- j=BN_bn2bin(ret,p); /* j is only used with no-padding mode */
-
- switch (padding)
- {
- case RSA_PKCS1_PADDING:
- r=RSA_padding_check_PKCS1_type_2(to,num,buf,j,num);
- break;
-#ifndef OPENSSL_NO_SHA
- case RSA_PKCS1_OAEP_PADDING:
- r=RSA_padding_check_PKCS1_OAEP(to,num,buf,j,num,NULL,0);
- break;
-#endif
- case RSA_SSLV23_PADDING:
- r=RSA_padding_check_SSLv23(to,num,buf,j,num);
- break;
- case RSA_NO_PADDING:
- r=RSA_padding_check_none(to,num,buf,j,num);
- break;
- default:
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
- goto err;
- }
- if (r < 0)
- RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
-
-err:
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (buf != NULL)
- {
- OPENSSL_cleanse(buf,num);
- OPENSSL_free(buf);
- }
- return(r);
- }
-
-/* signature verification */
-static int RSA_eay_public_decrypt(int flen, const unsigned char *from,
- unsigned char *to, RSA *rsa, int padding)
- {
- BIGNUM *f,*ret;
- int i,num=0,r= -1;
- unsigned char *p;
- unsigned char *buf=NULL;
- BN_CTX *ctx=NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_RSA_EAY_PUBLIC_DECRYPT,FIPS_R_FIPS_SELFTEST_FAILED);
- goto err;
- }
-
- if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_KEY_SIZE_TOO_SMALL);
- return -1;
- }
-
- if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE);
- return -1;
- }
-
- if (BN_ucmp(rsa->n, rsa->e) <= 0)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
- return -1;
- }
-
- /* for large moduli, enforce exponent limit */
- if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS)
- {
- if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE);
- return -1;
- }
- }
-
- if((ctx = BN_CTX_new()) == NULL) goto err;
- BN_CTX_start(ctx);
- f = BN_CTX_get(ctx);
- ret = BN_CTX_get(ctx);
- num=BN_num_bytes(rsa->n);
- buf = OPENSSL_malloc(num);
- if(!f || !ret || !buf)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- /* This check was for equality but PGP does evil things
- * and chops off the top '0' bytes */
- if (flen > num)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_GREATER_THAN_MOD_LEN);
- goto err;
- }
-
- if (BN_bin2bn(from,flen,f) == NULL) goto err;
-
- if (BN_ucmp(f, rsa->n) >= 0)
- {
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
- goto err;
- }
-
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
-
- if (!rsa->meth->bn_mod_exp(ret,f,rsa->e,rsa->n,ctx,
- rsa->_method_mod_n)) goto err;
-
- if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12))
- BN_sub(ret, rsa->n, ret);
-
- p=buf;
- i=BN_bn2bin(ret,p);
-
- switch (padding)
- {
- case RSA_PKCS1_PADDING:
- r=RSA_padding_check_PKCS1_type_1(to,num,buf,i,num);
- break;
- case RSA_X931_PADDING:
- r=RSA_padding_check_X931(to,num,buf,i,num);
- break;
- case RSA_NO_PADDING:
- r=RSA_padding_check_none(to,num,buf,i,num);
- break;
- default:
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_UNKNOWN_PADDING_TYPE);
- goto err;
- }
- if (r < 0)
- RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT,RSA_R_PADDING_CHECK_FAILED);
-
-err:
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (buf != NULL)
- {
- OPENSSL_cleanse(buf,num);
- OPENSSL_free(buf);
- }
- return(r);
- }
-
-static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)
- {
- BIGNUM *r1,*m1,*vrfy;
- BIGNUM local_dmp1,local_dmq1,local_c,local_r1;
- BIGNUM *dmp1,*dmq1,*c,*pr1;
- int bn_flags;
- int ret=0;
-
- BN_CTX_start(ctx);
- r1 = BN_CTX_get(ctx);
- m1 = BN_CTX_get(ctx);
- vrfy = BN_CTX_get(ctx);
-
- /* Make sure mod_inverse in montgomerey intialization use correct
- * BN_FLG_CONSTTIME flag.
- */
- bn_flags = rsa->p->flags;
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- rsa->p->flags |= BN_FLG_CONSTTIME;
- }
- MONT_HELPER(rsa, ctx, p, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
- /* We restore bn_flags back */
- rsa->p->flags = bn_flags;
-
- /* Make sure mod_inverse in montgomerey intialization use correct
- * BN_FLG_CONSTTIME flag.
- */
- bn_flags = rsa->q->flags;
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- rsa->q->flags |= BN_FLG_CONSTTIME;
- }
- MONT_HELPER(rsa, ctx, q, rsa->flags & RSA_FLAG_CACHE_PRIVATE, goto err);
- /* We restore bn_flags back */
- rsa->q->flags = bn_flags;
-
- MONT_HELPER(rsa, ctx, n, rsa->flags & RSA_FLAG_CACHE_PUBLIC, goto err);
-
- /* compute I mod q */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- c = &local_c;
- BN_with_flags(c, I, BN_FLG_CONSTTIME);
- if (!BN_mod(r1,c,rsa->q,ctx)) goto err;
- }
- else
- {
- if (!BN_mod(r1,I,rsa->q,ctx)) goto err;
- }
-
- /* compute r1^dmq1 mod q */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- dmq1 = &local_dmq1;
- BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME);
- }
- else
- dmq1 = rsa->dmq1;
- if (!rsa->meth->bn_mod_exp(m1,r1,dmq1,rsa->q,ctx,
- rsa->_method_mod_q)) goto err;
-
- /* compute I mod p */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- c = &local_c;
- BN_with_flags(c, I, BN_FLG_CONSTTIME);
- if (!BN_mod(r1,c,rsa->p,ctx)) goto err;
- }
- else
- {
- if (!BN_mod(r1,I,rsa->p,ctx)) goto err;
- }
-
- /* compute r1^dmp1 mod p */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- dmp1 = &local_dmp1;
- BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME);
- }
- else
- dmp1 = rsa->dmp1;
- if (!rsa->meth->bn_mod_exp(r0,r1,dmp1,rsa->p,ctx,
- rsa->_method_mod_p)) goto err;
-
- if (!BN_sub(r0,r0,m1)) goto err;
- /* This will help stop the size of r0 increasing, which does
- * affect the multiply if it optimised for a power of 2 size */
- if (BN_is_negative(r0))
- if (!BN_add(r0,r0,rsa->p)) goto err;
-
- if (!BN_mul(r1,r0,rsa->iqmp,ctx)) goto err;
-
- /* Turn BN_FLG_CONSTTIME flag on before division operation */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- pr1 = &local_r1;
- BN_with_flags(pr1, r1, BN_FLG_CONSTTIME);
- }
- else
- pr1 = r1;
- if (!BN_mod(r0,pr1,rsa->p,ctx)) goto err;
-
- /* If p < q it is occasionally possible for the correction of
- * adding 'p' if r0 is negative above to leave the result still
- * negative. This can break the private key operations: the following
- * second correction should *always* correct this rare occurrence.
- * This will *never* happen with OpenSSL generated keys because
- * they ensure p > q [steve]
- */
- if (BN_is_negative(r0))
- if (!BN_add(r0,r0,rsa->p)) goto err;
- if (!BN_mul(r1,r0,rsa->q,ctx)) goto err;
- if (!BN_add(r0,r1,m1)) goto err;
-
- if (rsa->e && rsa->n)
- {
- if (!rsa->meth->bn_mod_exp(vrfy,r0,rsa->e,rsa->n,ctx,rsa->_method_mod_n)) goto err;
- /* If 'I' was greater than (or equal to) rsa->n, the operation
- * will be equivalent to using 'I mod n'. However, the result of
- * the verify will *always* be less than 'n' so we don't check
- * for absolute equality, just congruency. */
- if (!BN_sub(vrfy, vrfy, I)) goto err;
- if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) goto err;
- if (BN_is_negative(vrfy))
- if (!BN_add(vrfy, vrfy, rsa->n)) goto err;
- if (!BN_is_zero(vrfy))
- {
- /* 'I' and 'vrfy' aren't congruent mod n. Don't leak
- * miscalculated CRT output, just do a raw (slower)
- * mod_exp and return that instead. */
-
- BIGNUM local_d;
- BIGNUM *d = NULL;
-
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- d = &local_d;
- BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- }
- else
- d = rsa->d;
- if (!rsa->meth->bn_mod_exp(r0,I,d,rsa->n,ctx,
- rsa->_method_mod_n)) goto err;
- }
- }
- ret=1;
-err:
- BN_CTX_end(ctx);
- return(ret);
- }
-
-static int RSA_eay_init(RSA *rsa)
- {
- FIPS_selftest_check();
- rsa->flags|=RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE;
- return(1);
- }
-
-static int RSA_eay_finish(RSA *rsa)
- {
- if (rsa->_method_mod_n != NULL)
- BN_MONT_CTX_free(rsa->_method_mod_n);
- if (rsa->_method_mod_p != NULL)
- BN_MONT_CTX_free(rsa->_method_mod_p);
- if (rsa->_method_mod_q != NULL)
- BN_MONT_CTX_free(rsa->_method_mod_q);
- return(1);
- }
-
-#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsa_gen.c b/crypto/openssl/fips/rsa/fips_rsa_gen.c
deleted file mode 100644
index 90aaa2f..0000000
--- a/crypto/openssl/fips/rsa/fips_rsa_gen.c
+++ /dev/null
@@ -1,310 +0,0 @@
-/* crypto/rsa/rsa_gen.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.]
- */
-
-
-/* NB: these functions have been "upgraded", the deprecated versions (which are
- * compatibility wrappers using these functions) are in rsa_depr.c.
- * - Geoff
- */
-
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-#include <openssl/crypto.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/fips.h>
-#include "fips_locl.h"
-
-#ifdef OPENSSL_FIPS
-
-static int fips_rsa_pairwise_fail = 0;
-
-void FIPS_corrupt_rsa_keygen(void)
- {
- fips_rsa_pairwise_fail = 1;
- }
-
-int fips_check_rsa(RSA *rsa)
- {
- const unsigned char tbs[] = "RSA Pairwise Check Data";
- unsigned char *ctbuf = NULL, *ptbuf = NULL;
- int len, ret = 0;
- EVP_PKEY pk;
- pk.type = EVP_PKEY_RSA;
- pk.pkey.rsa = rsa;
-
- /* Perform pairwise consistency signature test */
- if (!fips_pkey_signature_test(&pk, tbs, -1,
- NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1, NULL)
- || !fips_pkey_signature_test(&pk, tbs, -1,
- NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931, NULL)
- || !fips_pkey_signature_test(&pk, tbs, -1,
- NULL, 0, EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS, NULL))
- goto err;
- /* Now perform pairwise consistency encrypt/decrypt test */
- ctbuf = OPENSSL_malloc(RSA_size(rsa));
- if (!ctbuf)
- goto err;
-
- len = RSA_public_encrypt(sizeof(tbs) - 1, tbs, ctbuf, rsa, RSA_PKCS1_PADDING);
- if (len <= 0)
- goto err;
- /* Check ciphertext doesn't match plaintext */
- if ((len == (sizeof(tbs) - 1)) && !memcmp(tbs, ctbuf, len))
- goto err;
- ptbuf = OPENSSL_malloc(RSA_size(rsa));
-
- if (!ptbuf)
- goto err;
- len = RSA_private_decrypt(len, ctbuf, ptbuf, rsa, RSA_PKCS1_PADDING);
- if (len != (sizeof(tbs) - 1))
- goto err;
- if (memcmp(ptbuf, tbs, len))
- goto err;
-
- ret = 1;
-
- if (!ptbuf)
- goto err;
-
- err:
- if (ret == 0)
- {
- fips_set_selftest_fail();
- FIPSerr(FIPS_F_FIPS_CHECK_RSA,FIPS_R_PAIRWISE_TEST_FAILED);
- }
-
- if (ctbuf)
- OPENSSL_free(ctbuf);
- if (ptbuf)
- OPENSSL_free(ptbuf);
-
- return ret;
- }
-
-static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb);
-
-/* NB: this wrapper would normally be placed in rsa_lib.c and the static
- * implementation would probably be in rsa_eay.c. Nonetheless, is kept here so
- * that we don't introduce a new linker dependency. Eg. any application that
- * wasn't previously linking object code related to key-generation won't have to
- * now just because key-generation is part of RSA_METHOD. */
-int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
- {
- if(rsa->meth->rsa_keygen)
- return rsa->meth->rsa_keygen(rsa, bits, e_value, cb);
- return rsa_builtin_keygen(rsa, bits, e_value, cb);
- }
-
-static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb)
- {
- BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL,*tmp;
- BIGNUM local_r0,local_d,local_p;
- BIGNUM *pr0,*d,*p;
- int bitsp,bitsq,ok= -1,n=0;
- BN_CTX *ctx=NULL;
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_FIPS_SELFTEST_FAILED);
- return 0;
- }
-
- if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS))
- {
- FIPSerr(FIPS_F_RSA_BUILTIN_KEYGEN,FIPS_R_KEY_TOO_SHORT);
- return 0;
- }
-
- ctx=BN_CTX_new();
- if (ctx == NULL) goto err;
- BN_CTX_start(ctx);
- r0 = BN_CTX_get(ctx);
- r1 = BN_CTX_get(ctx);
- r2 = BN_CTX_get(ctx);
- r3 = BN_CTX_get(ctx);
- if (r3 == NULL) goto err;
-
- bitsp=(bits+1)/2;
- bitsq=bits-bitsp;
-
- /* We need the RSA components non-NULL */
- if(!rsa->n && ((rsa->n=BN_new()) == NULL)) goto err;
- if(!rsa->d && ((rsa->d=BN_new()) == NULL)) goto err;
- if(!rsa->e && ((rsa->e=BN_new()) == NULL)) goto err;
- if(!rsa->p && ((rsa->p=BN_new()) == NULL)) goto err;
- if(!rsa->q && ((rsa->q=BN_new()) == NULL)) goto err;
- if(!rsa->dmp1 && ((rsa->dmp1=BN_new()) == NULL)) goto err;
- if(!rsa->dmq1 && ((rsa->dmq1=BN_new()) == NULL)) goto err;
- if(!rsa->iqmp && ((rsa->iqmp=BN_new()) == NULL)) goto err;
-
- BN_copy(rsa->e, e_value);
-
- /* generate p and q */
- for (;;)
- {
- if(!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
- goto err;
- if (!BN_sub(r2,rsa->p,BN_value_one())) goto err;
- if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
- if (BN_is_one(r1)) break;
- if(!BN_GENCB_call(cb, 2, n++))
- goto err;
- }
- if(!BN_GENCB_call(cb, 3, 0))
- goto err;
- for (;;)
- {
- /* When generating ridiculously small keys, we can get stuck
- * continually regenerating the same prime values. Check for
- * this and bail if it happens 3 times. */
- unsigned int degenerate = 0;
- do
- {
- if(!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
- goto err;
- } while((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
- if(degenerate == 3)
- {
- ok = 0; /* we set our own err */
- RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,RSA_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
- if (!BN_sub(r2,rsa->q,BN_value_one())) goto err;
- if (!BN_gcd(r1,r2,rsa->e,ctx)) goto err;
- if (BN_is_one(r1))
- break;
- if(!BN_GENCB_call(cb, 2, n++))
- goto err;
- }
- if(!BN_GENCB_call(cb, 3, 1))
- goto err;
- if (BN_cmp(rsa->p,rsa->q) < 0)
- {
- tmp=rsa->p;
- rsa->p=rsa->q;
- rsa->q=tmp;
- }
-
- /* calculate n */
- if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx)) goto err;
-
- /* calculate d */
- if (!BN_sub(r1,rsa->p,BN_value_one())) goto err; /* p-1 */
- if (!BN_sub(r2,rsa->q,BN_value_one())) goto err; /* q-1 */
- if (!BN_mul(r0,r1,r2,ctx)) goto err; /* (p-1)(q-1) */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- pr0 = &local_r0;
- BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
- }
- else
- pr0 = r0;
- if (!BN_mod_inverse(rsa->d,rsa->e,pr0,ctx)) goto err; /* d */
-
- /* set up d for correct BN_FLG_CONSTTIME flag */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- d = &local_d;
- BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME);
- }
- else
- d = rsa->d;
-
- /* calculate d mod (p-1) */
- if (!BN_mod(rsa->dmp1,d,r1,ctx)) goto err;
-
- /* calculate d mod (q-1) */
- if (!BN_mod(rsa->dmq1,d,r2,ctx)) goto err;
-
- /* calculate inverse of q mod p */
- if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME))
- {
- p = &local_p;
- BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME);
- }
- else
- p = rsa->p;
- if (!BN_mod_inverse(rsa->iqmp,rsa->q,p,ctx)) goto err;
-
- if (fips_rsa_pairwise_fail)
- BN_add_word(rsa->n, 1);
-
- if(!fips_check_rsa(rsa))
- goto err;
-
- ok=1;
-err:
- if (ok == -1)
- {
- RSAerr(RSA_F_RSA_BUILTIN_KEYGEN,ERR_LIB_BN);
- ok=0;
- }
- if (ctx != NULL)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
-
- return ok;
- }
-
-#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsa_lib.c b/crypto/openssl/fips/rsa/fips_rsa_lib.c
deleted file mode 100644
index a37ad3e..0000000
--- a/crypto/openssl/fips/rsa/fips_rsa_lib.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* fips_rsa_sign.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 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).
- *
- */
-
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/bn.h>
-#include <openssl/err.h>
-
-/* Minimal FIPS versions of FIPS_rsa_new() and FIPS_rsa_free: to
- * reduce external dependencies.
- */
-
-RSA *FIPS_rsa_new(void)
- {
- RSA *ret;
- ret = OPENSSL_malloc(sizeof(RSA));
- if (!ret)
- return NULL;
- memset(ret, 0, sizeof(RSA));
- ret->meth = RSA_PKCS1_SSLeay();
- if (ret->meth->init)
- ret->meth->init(ret);
- return ret;
- }
-
-void FIPS_rsa_free(RSA *r)
- {
- if (!r)
- return;
- if (r->meth->finish)
- r->meth->finish(r);
- if (r->n != NULL) BN_clear_free(r->n);
- if (r->e != NULL) BN_clear_free(r->e);
- if (r->d != NULL) BN_clear_free(r->d);
- if (r->p != NULL) BN_clear_free(r->p);
- if (r->q != NULL) BN_clear_free(r->q);
- if (r->dmp1 != NULL) BN_clear_free(r->dmp1);
- if (r->dmq1 != NULL) BN_clear_free(r->dmq1);
- if (r->iqmp != NULL) BN_clear_free(r->iqmp);
- if (r->blinding != NULL) BN_BLINDING_free(r->blinding);
- if (r->mt_blinding != NULL) BN_BLINDING_free(r->mt_blinding);
- if (r->bignum_data != NULL) OPENSSL_free_locked(r->bignum_data);
- OPENSSL_free(r);
- }
-
diff --git a/crypto/openssl/fips/rsa/fips_rsa_selftest.c b/crypto/openssl/fips/rsa/fips_rsa_selftest.c
deleted file mode 100644
index bead61f..0000000
--- a/crypto/openssl/fips/rsa/fips_rsa_selftest.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003-2007 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.
- *
- */
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-#include <openssl/bn.h>
-#include <openssl/opensslconf.h>
-
-#ifdef OPENSSL_FIPS
-
-static unsigned char n[] =
-"\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
-"\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
-"\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
-"\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
-"\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
-"\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
-"\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
-"\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
-"\xCB";
-
-
-static int setrsakey(RSA *key)
- {
- static const unsigned char e[] = "\x11";
-
- static const unsigned char d[] =
-"\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
-"\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
-"\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
-"\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
-"\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
-"\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
-"\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
-"\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
-"\xC1";
-
- static const unsigned char p[] =
-"\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
-"\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
-"\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
-"\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
-"\x99";
-
- static const unsigned char q[] =
-"\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
-"\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
-"\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
-"\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
-"\x03";
-
- static const unsigned char dmp1[] =
-"\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
-"\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
-"\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
-"\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
-
- static const unsigned char dmq1[] =
-"\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
-"\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
-"\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
-"\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
-
- static const unsigned char iqmp[] =
-"\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
-"\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
-"\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
-"\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
-"\xF7";
-
- key->n = BN_bin2bn(n, sizeof(n)-1, key->n);
- key->e = BN_bin2bn(e, sizeof(e)-1, key->e);
- key->d = BN_bin2bn(d, sizeof(d)-1, key->d);
- key->p = BN_bin2bn(p, sizeof(p)-1, key->p);
- key->q = BN_bin2bn(q, sizeof(q)-1, key->q);
- key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1);
- key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1);
- key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp);
- return 1;
- }
-
-void FIPS_corrupt_rsa()
- {
- n[0]++;
- }
-
-/* Known Answer Test (KAT) data for the above RSA private key signing
- * kat_tbs.
- */
-
-static const unsigned char kat_tbs[] = "OpenSSL FIPS 140-2 Public Key RSA KAT";
-
-static const unsigned char kat_RSA_PSS_SHA1[] = {
- 0x2D, 0xAF, 0x6E, 0xC2, 0x98, 0xFB, 0x8A, 0xA1, 0xB9, 0x46, 0xDA, 0x0F,
- 0x01, 0x1E, 0x37, 0x93, 0xC2, 0x55, 0x27, 0xE4, 0x1D, 0xD2, 0x90, 0xBB,
- 0xF4, 0xBF, 0x4A, 0x74, 0x39, 0x51, 0xBB, 0xE8, 0x0C, 0xB7, 0xF8, 0xD3,
- 0xD1, 0xDF, 0xE7, 0xBE, 0x80, 0x05, 0xC3, 0xB5, 0xC7, 0x83, 0xD5, 0x4C,
- 0x7F, 0x49, 0xFB, 0x3F, 0x29, 0x9B, 0xE1, 0x12, 0x51, 0x60, 0xD0, 0xA7,
- 0x0D, 0xA9, 0x28, 0x56, 0x73, 0xD9, 0x07, 0xE3, 0x5E, 0x3F, 0x9B, 0xF5,
- 0xB6, 0xF3, 0xF2, 0x5E, 0x74, 0xC9, 0x83, 0x81, 0x47, 0xF0, 0xC5, 0x45,
- 0x0A, 0xE9, 0x8E, 0x38, 0xD7, 0x18, 0xC6, 0x2A, 0x0F, 0xF8, 0xB7, 0x31,
- 0xD6, 0x55, 0xE4, 0x66, 0x78, 0x81, 0xD4, 0xE6, 0xDB, 0x9F, 0xBA, 0xE8,
- 0x23, 0xB5, 0x7F, 0xDC, 0x08, 0xEA, 0xD5, 0x26, 0x1E, 0x20, 0x25, 0x84,
- 0x26, 0xC6, 0x79, 0xC9, 0x9B, 0x3D, 0x7E, 0xA9
-};
-
-static const unsigned char kat_RSA_PSS_SHA224[] = {
- 0x39, 0x4A, 0x6A, 0x20, 0xBC, 0xE9, 0x33, 0xED, 0xEF, 0xC5, 0x58, 0xA7,
- 0xFE, 0x81, 0xC4, 0x36, 0x50, 0x9A, 0x2C, 0x82, 0x98, 0x08, 0x95, 0xFA,
- 0xB1, 0x9E, 0xD2, 0x55, 0x61, 0x87, 0x21, 0x59, 0x87, 0x7B, 0x1F, 0x57,
- 0x30, 0x9D, 0x0D, 0x4A, 0x06, 0xEB, 0x52, 0x37, 0x55, 0x54, 0x1C, 0x89,
- 0x83, 0x75, 0x59, 0x65, 0x64, 0x90, 0x2E, 0x16, 0xCC, 0x86, 0x05, 0xEE,
- 0xB1, 0xE6, 0x7B, 0xBA, 0x16, 0x75, 0x0D, 0x0C, 0x64, 0x0B, 0xAB, 0x22,
- 0x15, 0x78, 0x6B, 0x6F, 0xA4, 0xFB, 0x77, 0x40, 0x64, 0x62, 0xD1, 0xB5,
- 0x37, 0x1E, 0xE0, 0x3D, 0xA8, 0xF9, 0xD2, 0xBD, 0xAA, 0x38, 0x24, 0x49,
- 0x58, 0xD2, 0x74, 0x85, 0xF4, 0xB5, 0x93, 0x8E, 0xF5, 0x03, 0xEA, 0x2D,
- 0xC8, 0x52, 0xFA, 0xCF, 0x7E, 0x35, 0xB0, 0x6A, 0xAF, 0x95, 0xC0, 0x00,
- 0x54, 0x76, 0x3D, 0x0C, 0x9C, 0xB2, 0xEE, 0xC0
-};
-
-static const unsigned char kat_RSA_PSS_SHA256[] = {
- 0x6D, 0x3D, 0xBE, 0x8F, 0x60, 0x6D, 0x25, 0x14, 0xF0, 0x31, 0xE3, 0x89,
- 0x00, 0x97, 0xFA, 0x99, 0x71, 0x28, 0xE5, 0x10, 0x25, 0x9A, 0xF3, 0x8F,
- 0x7B, 0xC5, 0xA8, 0x4A, 0x74, 0x51, 0x36, 0xE2, 0x8D, 0x7D, 0x73, 0x28,
- 0xC1, 0x77, 0xC6, 0x27, 0x97, 0x00, 0x8B, 0x00, 0xA3, 0x96, 0x73, 0x4E,
- 0x7D, 0x2E, 0x2C, 0x34, 0x68, 0x8C, 0x8E, 0xDF, 0x9D, 0x49, 0x47, 0x05,
- 0xAB, 0xF5, 0x01, 0xD6, 0x81, 0x47, 0x70, 0xF5, 0x1D, 0x6D, 0x26, 0xBA,
- 0x2F, 0x7A, 0x54, 0x53, 0x4E, 0xED, 0x71, 0xD9, 0x5A, 0xF3, 0xDA, 0xB6,
- 0x0B, 0x47, 0x34, 0xAF, 0x90, 0xDC, 0xC8, 0xD9, 0x6F, 0x56, 0xCD, 0x9F,
- 0x21, 0xB7, 0x7E, 0xAD, 0x7C, 0x2F, 0x75, 0x50, 0x47, 0x12, 0xE4, 0x6D,
- 0x5F, 0xB7, 0x01, 0xDF, 0xC3, 0x11, 0x6C, 0xA9, 0x9E, 0x49, 0xB9, 0xF6,
- 0x72, 0xF4, 0xF6, 0xEF, 0x88, 0x1E, 0x2D, 0x1C
-};
-
-static const unsigned char kat_RSA_PSS_SHA384[] = {
- 0x40, 0xFB, 0xA1, 0x21, 0xF4, 0xB2, 0x40, 0x9A, 0xB4, 0x31, 0xA8, 0xF2,
- 0xEC, 0x1C, 0xC4, 0xC8, 0x7C, 0x22, 0x65, 0x9C, 0x57, 0x45, 0xCD, 0x5E,
- 0x86, 0x00, 0xF7, 0x25, 0x78, 0xDE, 0xDC, 0x7A, 0x71, 0x44, 0x9A, 0xCD,
- 0xAA, 0x25, 0xF4, 0xB2, 0xFC, 0xF0, 0x75, 0xD9, 0x2F, 0x78, 0x23, 0x7F,
- 0x6F, 0x02, 0xEF, 0xC1, 0xAF, 0xA6, 0x28, 0x16, 0x31, 0xDC, 0x42, 0x6C,
- 0xB2, 0x44, 0xE5, 0x4D, 0x66, 0xA2, 0xE6, 0x71, 0xF3, 0xAC, 0x4F, 0xFB,
- 0x91, 0xCA, 0xF5, 0x70, 0xEF, 0x6B, 0x9D, 0xA4, 0xEF, 0xD9, 0x3D, 0x2F,
- 0x3A, 0xBE, 0x89, 0x38, 0x59, 0x01, 0xBA, 0xDA, 0x32, 0xAD, 0x42, 0x89,
- 0x98, 0x8B, 0x39, 0x44, 0xF0, 0xFC, 0x38, 0xAC, 0x87, 0x1F, 0xCA, 0x6F,
- 0x48, 0xF6, 0xAE, 0xD7, 0x45, 0xEE, 0xAE, 0x88, 0x0E, 0x60, 0xF4, 0x55,
- 0x48, 0x44, 0xEE, 0x1F, 0x90, 0x18, 0x4B, 0xF1
-};
-
-static const unsigned char kat_RSA_PSS_SHA512[] = {
- 0x07, 0x1E, 0xD8, 0xD5, 0x05, 0xE8, 0xE6, 0xE6, 0x57, 0xAE, 0x63, 0x8C,
- 0xC6, 0x83, 0xB7, 0xA0, 0x59, 0xBB, 0xF2, 0xC6, 0x8F, 0x12, 0x53, 0x9A,
- 0x9B, 0x54, 0x9E, 0xB3, 0xC1, 0x1D, 0x23, 0x4D, 0x51, 0xED, 0x9E, 0xDD,
- 0x4B, 0xF3, 0x46, 0x9B, 0x6B, 0xF6, 0x7C, 0x24, 0x60, 0x79, 0x23, 0x39,
- 0x01, 0x1C, 0x51, 0xCB, 0xD8, 0xE9, 0x9A, 0x01, 0x67, 0x5F, 0xFE, 0xD7,
- 0x7C, 0xE3, 0x7F, 0xED, 0xDB, 0x87, 0xBB, 0xF0, 0x3D, 0x78, 0x55, 0x61,
- 0x57, 0xE3, 0x0F, 0xE3, 0xD2, 0x9D, 0x0C, 0x2A, 0x20, 0xB0, 0x85, 0x13,
- 0xC5, 0x47, 0x34, 0x0D, 0x32, 0x15, 0xC8, 0xAE, 0x9A, 0x6A, 0x39, 0x63,
- 0x2D, 0x60, 0xF5, 0x4C, 0xDF, 0x8A, 0x48, 0x4B, 0xBF, 0xF4, 0xA8, 0xFE,
- 0x76, 0xF2, 0x32, 0x1B, 0x9C, 0x7C, 0xCA, 0xFE, 0x7F, 0x80, 0xC2, 0x88,
- 0x5C, 0x97, 0x70, 0xB4, 0x26, 0xC9, 0x14, 0x8B
-};
-
-static const unsigned char kat_RSA_SHA1[] = {
- 0x71, 0xEE, 0x1A, 0xC0, 0xFE, 0x01, 0x93, 0x54, 0x79, 0x5C, 0xF2, 0x4C,
- 0x4A, 0xFD, 0x1A, 0x05, 0x8F, 0x64, 0xB1, 0x6D, 0x61, 0x33, 0x8D, 0x9B,
- 0xE7, 0xFD, 0x60, 0xA3, 0x83, 0xB5, 0xA3, 0x51, 0x55, 0x77, 0x90, 0xCF,
- 0xDC, 0x22, 0x37, 0x8E, 0xD0, 0xE1, 0xAE, 0x09, 0xE3, 0x3D, 0x1E, 0xF8,
- 0x80, 0xD1, 0x8B, 0xC2, 0xEC, 0x0A, 0xD7, 0x6B, 0x88, 0x8B, 0x8B, 0xA1,
- 0x20, 0x22, 0xBE, 0x59, 0x5B, 0xE0, 0x23, 0x24, 0xA1, 0x49, 0x30, 0xBA,
- 0xA9, 0x9E, 0xE8, 0xB1, 0x8A, 0x62, 0x16, 0xBF, 0x4E, 0xCA, 0x2E, 0x4E,
- 0xBC, 0x29, 0xA8, 0x67, 0x13, 0xB7, 0x9F, 0x1D, 0x04, 0x44, 0xE5, 0x5F,
- 0x35, 0x07, 0x11, 0xBC, 0xED, 0x19, 0x37, 0x21, 0xCF, 0x23, 0x48, 0x1F,
- 0x72, 0x05, 0xDE, 0xE6, 0xE8, 0x7F, 0x33, 0x8A, 0x76, 0x4B, 0x2F, 0x95,
- 0xDF, 0xF1, 0x5F, 0x84, 0x80, 0xD9, 0x46, 0xB4
-};
-
-static const unsigned char kat_RSA_SHA224[] = {
- 0x62, 0xAA, 0x79, 0xA9, 0x18, 0x0E, 0x5F, 0x8C, 0xBB, 0xB7, 0x15, 0xF9,
- 0x25, 0xBB, 0xFA, 0xD4, 0x3A, 0x34, 0xED, 0x9E, 0xA0, 0xA9, 0x18, 0x8D,
- 0x5B, 0x55, 0x9A, 0x7E, 0x1E, 0x08, 0x08, 0x60, 0xC5, 0x1A, 0xC5, 0x89,
- 0x08, 0xE2, 0x1B, 0xBD, 0x62, 0x50, 0x17, 0x76, 0x30, 0x2C, 0x9E, 0xCD,
- 0xA4, 0x02, 0xAD, 0xB1, 0x6D, 0x44, 0x6D, 0xD5, 0xC6, 0x45, 0x41, 0xE5,
- 0xEE, 0x1F, 0x8D, 0x7E, 0x08, 0x16, 0xA6, 0xE1, 0x5E, 0x0B, 0xA9, 0xCC,
- 0xDB, 0x59, 0x55, 0x87, 0x09, 0x25, 0x70, 0x86, 0x84, 0x02, 0xC6, 0x3B,
- 0x0B, 0x44, 0x4C, 0x46, 0x95, 0xF4, 0xF8, 0x5A, 0x91, 0x28, 0x3E, 0xB2,
- 0x58, 0x2E, 0x06, 0x45, 0x49, 0xE0, 0x92, 0xE2, 0xC0, 0x66, 0xE6, 0x35,
- 0xD9, 0x79, 0x7F, 0x17, 0x5E, 0x02, 0x73, 0x04, 0x77, 0x82, 0xE6, 0xDC,
- 0x40, 0x21, 0x89, 0x8B, 0x37, 0x3E, 0x1E, 0x8D
-};
-
-static const unsigned char kat_RSA_SHA256[] = {
- 0x0D, 0x55, 0xE2, 0xAA, 0x81, 0xDB, 0x8E, 0x82, 0x05, 0x17, 0xA5, 0x23,
- 0xE7, 0x3B, 0x1D, 0xAF, 0xFB, 0x8C, 0xD0, 0x81, 0x20, 0x7B, 0xAA, 0x23,
- 0x92, 0x87, 0x8C, 0xD1, 0x53, 0x85, 0x16, 0xDC, 0xBE, 0xAD, 0x6F, 0x35,
- 0x98, 0x2D, 0x69, 0x84, 0xBF, 0xD9, 0x8A, 0x01, 0x17, 0x58, 0xB2, 0x6E,
- 0x2C, 0x44, 0x9B, 0x90, 0xF1, 0xFB, 0x51, 0xE8, 0x6A, 0x90, 0x2D, 0x18,
- 0x0E, 0xC0, 0x90, 0x10, 0x24, 0xA9, 0x1D, 0xB3, 0x58, 0x7A, 0x91, 0x30,
- 0xBE, 0x22, 0xC7, 0xD3, 0xEC, 0xC3, 0x09, 0x5D, 0xBF, 0xE2, 0x80, 0x3A,
- 0x7C, 0x85, 0xB4, 0xBC, 0xD1, 0xE9, 0xF0, 0x5C, 0xDE, 0x81, 0xA6, 0x38,
- 0xB8, 0x42, 0xBB, 0x86, 0xC5, 0x9D, 0xCE, 0x7C, 0x2C, 0xEE, 0xD1, 0xDA,
- 0x27, 0x48, 0x2B, 0xF5, 0xAB, 0xB9, 0xF7, 0x80, 0xD1, 0x90, 0x27, 0x90,
- 0xBD, 0x44, 0x97, 0x60, 0xCD, 0x57, 0xC0, 0x7A
-};
-
-static const unsigned char kat_RSA_SHA384[] = {
- 0x1D, 0xE3, 0x6A, 0xDD, 0x27, 0x4C, 0xC0, 0xA5, 0x27, 0xEF, 0xE6, 0x1F,
- 0xD2, 0x91, 0x68, 0x59, 0x04, 0xAE, 0xBD, 0x99, 0x63, 0x56, 0x47, 0xC7,
- 0x6F, 0x22, 0x16, 0x48, 0xD0, 0xF9, 0x18, 0xA9, 0xCA, 0xFA, 0x5D, 0x5C,
- 0xA7, 0x65, 0x52, 0x8A, 0xC8, 0x44, 0x7E, 0x86, 0x5D, 0xA9, 0xA6, 0x55,
- 0x65, 0x3E, 0xD9, 0x2D, 0x02, 0x38, 0xA8, 0x79, 0x28, 0x7F, 0xB6, 0xCF,
- 0x82, 0xDD, 0x7E, 0x55, 0xE1, 0xB1, 0xBC, 0xE2, 0x19, 0x2B, 0x30, 0xC2,
- 0x1B, 0x2B, 0xB0, 0x82, 0x46, 0xAC, 0x4B, 0xD1, 0xE2, 0x7D, 0xEB, 0x8C,
- 0xFF, 0x95, 0xE9, 0x6A, 0x1C, 0x3D, 0x4D, 0xBF, 0x8F, 0x8B, 0x9C, 0xCD,
- 0xEA, 0x85, 0xEE, 0x00, 0xDC, 0x1C, 0xA7, 0xEB, 0xD0, 0x8F, 0x99, 0xF1,
- 0x16, 0x28, 0x24, 0x64, 0x04, 0x39, 0x2D, 0x58, 0x1E, 0x37, 0xDC, 0x04,
- 0xBD, 0x31, 0xA2, 0x2F, 0xB3, 0x35, 0x56, 0xBF
-};
-
-static const unsigned char kat_RSA_SHA512[] = {
- 0x69, 0x52, 0x1B, 0x51, 0x5E, 0x06, 0xCA, 0x9B, 0x16, 0x51, 0x5D, 0xCF,
- 0x49, 0x25, 0x4A, 0xA1, 0x6A, 0x77, 0x4C, 0x36, 0x40, 0xF8, 0xB2, 0x9A,
- 0x15, 0xEA, 0x5C, 0xE5, 0xE6, 0x82, 0xE0, 0x86, 0x82, 0x6B, 0x32, 0xF1,
- 0x04, 0xC1, 0x5A, 0x1A, 0xED, 0x1E, 0x9A, 0xB6, 0x4C, 0x54, 0x9F, 0xD8,
- 0x8D, 0xCC, 0xAC, 0x8A, 0xBB, 0x9C, 0x82, 0x3F, 0xA6, 0x53, 0x62, 0xB5,
- 0x80, 0xE2, 0xBC, 0xDD, 0x67, 0x2B, 0xD9, 0x3F, 0xE4, 0x75, 0x92, 0x6B,
- 0xAF, 0x62, 0x7C, 0x52, 0xF0, 0xEE, 0x33, 0xDF, 0x1B, 0x1D, 0x47, 0xE6,
- 0x59, 0x56, 0xA5, 0xB9, 0x5C, 0xE6, 0x77, 0x78, 0x16, 0x63, 0x84, 0x05,
- 0x6F, 0x0E, 0x2B, 0x31, 0x9D, 0xF7, 0x7F, 0xB2, 0x64, 0x71, 0xE0, 0x2D,
- 0x3E, 0x62, 0xCE, 0xB5, 0x3F, 0x88, 0xDF, 0x2D, 0xAB, 0x98, 0x65, 0x91,
- 0xDF, 0x70, 0x14, 0xA5, 0x3F, 0x36, 0xAB, 0x84
-};
-
-static const unsigned char kat_RSA_X931_SHA1[] = {
- 0x86, 0xB4, 0x18, 0xBA, 0xD1, 0x80, 0xB6, 0x7C, 0x42, 0x45, 0x4D, 0xDF,
- 0xE9, 0x2D, 0xE1, 0x83, 0x5F, 0xB5, 0x2F, 0xC9, 0xCD, 0xC4, 0xB2, 0x75,
- 0x80, 0xA4, 0xF1, 0x4A, 0xE7, 0x83, 0x12, 0x1E, 0x1E, 0x14, 0xB8, 0xAC,
- 0x35, 0xE2, 0xAA, 0x0B, 0x5C, 0xF8, 0x38, 0x4D, 0x04, 0xEE, 0xA9, 0x97,
- 0x70, 0xFB, 0x5E, 0xE7, 0xB7, 0xE3, 0x62, 0x23, 0x4B, 0x38, 0xBE, 0xD6,
- 0x53, 0x15, 0xF7, 0xDF, 0x87, 0xB4, 0x0E, 0xCC, 0xB1, 0x1A, 0x11, 0x19,
- 0xEE, 0x51, 0xCC, 0x92, 0xDD, 0xBC, 0x63, 0x29, 0x63, 0x0C, 0x59, 0xD7,
- 0x6F, 0x4C, 0x3C, 0x37, 0x5B, 0x37, 0x03, 0x61, 0x7D, 0x24, 0x1C, 0x99,
- 0x48, 0xAF, 0x82, 0xFE, 0x32, 0x41, 0x9B, 0xB2, 0xDB, 0xEA, 0xED, 0x76,
- 0x8E, 0x6E, 0xCA, 0x7E, 0x4E, 0x14, 0xBA, 0x30, 0x84, 0x1C, 0xB3, 0x67,
- 0xA3, 0x29, 0x80, 0x70, 0x54, 0x68, 0x7D, 0x49
-};
-
-static const unsigned char kat_RSA_X931_SHA256[] = {
- 0x7E, 0xA2, 0x77, 0xFE, 0xB8, 0x54, 0x8A, 0xC7, 0x7F, 0x64, 0x54, 0x89,
- 0xE5, 0x52, 0x15, 0x8E, 0x52, 0x96, 0x4E, 0xA6, 0x58, 0x92, 0x1C, 0xDD,
- 0xEA, 0xA2, 0x2D, 0x5C, 0xD1, 0x62, 0x00, 0x49, 0x05, 0x95, 0x73, 0xCF,
- 0x16, 0x76, 0x68, 0xF6, 0xC6, 0x5E, 0x80, 0xB8, 0xB8, 0x7B, 0xC8, 0x9B,
- 0xC6, 0x53, 0x88, 0x26, 0x20, 0x88, 0x73, 0xB6, 0x13, 0xB8, 0xF0, 0x4B,
- 0x00, 0x85, 0xF3, 0xDD, 0x07, 0x50, 0xEB, 0x20, 0xC4, 0x38, 0x0E, 0x98,
- 0xAD, 0x4E, 0x49, 0x2C, 0xD7, 0x65, 0xA5, 0x19, 0x0E, 0x59, 0x01, 0xEC,
- 0x7E, 0x75, 0x89, 0x69, 0x2E, 0x63, 0x76, 0x85, 0x46, 0x8D, 0xA0, 0x8C,
- 0x33, 0x1D, 0x82, 0x8C, 0x03, 0xEA, 0x69, 0x88, 0x35, 0xA1, 0x42, 0xBD,
- 0x21, 0xED, 0x8D, 0xBC, 0xBC, 0xDB, 0x30, 0xFF, 0x86, 0xF0, 0x5B, 0xDC,
- 0xE3, 0xE2, 0xE8, 0x0A, 0x0A, 0x29, 0x94, 0x80
-};
-
-static const unsigned char kat_RSA_X931_SHA384[] = {
- 0x5C, 0x7D, 0x96, 0x35, 0xEC, 0x7E, 0x11, 0x38, 0xBB, 0x7B, 0xEC, 0x7B,
- 0xF2, 0x82, 0x8E, 0x99, 0xBD, 0xEF, 0xD8, 0xAE, 0xD7, 0x39, 0x37, 0xCB,
- 0xE6, 0x4F, 0x5E, 0x0A, 0x13, 0xE4, 0x2E, 0x40, 0xB9, 0xBE, 0x2E, 0xE3,
- 0xEF, 0x78, 0x83, 0x18, 0x44, 0x35, 0x9C, 0x8E, 0xD7, 0x4A, 0x63, 0xF6,
- 0x57, 0xC2, 0xB0, 0x08, 0x51, 0x73, 0xCF, 0xCA, 0x99, 0x66, 0xEE, 0x31,
- 0xD8, 0x69, 0xE9, 0xAB, 0x13, 0x27, 0x7B, 0x41, 0x1E, 0x6D, 0x8D, 0xF1,
- 0x3E, 0x9C, 0x35, 0x95, 0x58, 0xDD, 0x2B, 0xD5, 0xA0, 0x60, 0x41, 0x79,
- 0x24, 0x22, 0xE4, 0xB7, 0xBF, 0x47, 0x53, 0xF6, 0x34, 0xD5, 0x7C, 0xFF,
- 0x0E, 0x09, 0xEE, 0x2E, 0xE2, 0x37, 0xB9, 0xDE, 0xC5, 0x12, 0x44, 0x35,
- 0xEF, 0x01, 0xE6, 0x5E, 0x39, 0x31, 0x2D, 0x71, 0xA5, 0xDC, 0xC6, 0x6D,
- 0xE2, 0xCD, 0x85, 0xDB, 0x73, 0x82, 0x65, 0x28
-};
-
-static const unsigned char kat_RSA_X931_SHA512[] = {
- 0xA6, 0x65, 0xA2, 0x77, 0x4F, 0xB3, 0x86, 0xCB, 0x64, 0x3A, 0xC1, 0x63,
- 0xFC, 0xA1, 0xAA, 0xCB, 0x9B, 0x79, 0xDD, 0x4B, 0xE1, 0xD9, 0xDA, 0xAC,
- 0xE7, 0x47, 0x09, 0xB2, 0x11, 0x4B, 0x8A, 0xAA, 0x05, 0x9E, 0x77, 0xD7,
- 0x3A, 0xBD, 0x5E, 0x53, 0x09, 0x4A, 0xE6, 0x0F, 0x5E, 0xF9, 0x14, 0x28,
- 0xA0, 0x99, 0x74, 0x64, 0x70, 0x4E, 0xF2, 0xE3, 0xFA, 0xC7, 0xF8, 0xC5,
- 0x6E, 0x2B, 0x79, 0x96, 0x0D, 0x0C, 0xC8, 0x10, 0x34, 0x53, 0xD2, 0xAF,
- 0x17, 0x0E, 0xE0, 0xBF, 0x79, 0xF6, 0x04, 0x72, 0x10, 0xE0, 0xF6, 0xD0,
- 0xCE, 0x8A, 0x6F, 0xA1, 0x95, 0x89, 0xBF, 0x58, 0x8F, 0x46, 0x5F, 0x09,
- 0x9F, 0x09, 0xCA, 0x84, 0x15, 0x85, 0xE0, 0xED, 0x04, 0x2D, 0xFB, 0x7C,
- 0x36, 0x35, 0x21, 0x31, 0xC3, 0xFD, 0x92, 0x42, 0x11, 0x30, 0x71, 0x1B,
- 0x60, 0x83, 0x18, 0x88, 0xA3, 0xF5, 0x59, 0xC3
-};
-
-
-int FIPS_selftest_rsa()
- {
- int ret = 0;
- RSA *key = NULL;
- EVP_PKEY pk;
- key=FIPS_rsa_new();
- setrsakey(key);
- pk.type = EVP_PKEY_RSA;
- pk.pkey.rsa = key;
-
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_SHA1, sizeof(kat_RSA_SHA1),
- EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PKCS1,
- "RSA SHA1 PKCS#1"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_SHA224, sizeof(kat_RSA_SHA224),
- EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PKCS1,
- "RSA SHA224 PKCS#1"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_SHA256, sizeof(kat_RSA_SHA256),
- EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PKCS1,
- "RSA SHA256 PKCS#1"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_SHA384, sizeof(kat_RSA_SHA384),
- EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PKCS1,
- "RSA SHA384 PKCS#1"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_SHA512, sizeof(kat_RSA_SHA512),
- EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PKCS1,
- "RSA SHA512 PKCS#1"))
- goto err;
-
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_PSS_SHA1, sizeof(kat_RSA_PSS_SHA1),
- EVP_sha1(), EVP_MD_CTX_FLAG_PAD_PSS,
- "RSA SHA1 PSS"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_PSS_SHA224, sizeof(kat_RSA_PSS_SHA224),
- EVP_sha224(), EVP_MD_CTX_FLAG_PAD_PSS,
- "RSA SHA224 PSS"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_PSS_SHA256, sizeof(kat_RSA_PSS_SHA256),
- EVP_sha256(), EVP_MD_CTX_FLAG_PAD_PSS,
- "RSA SHA256 PSS"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_PSS_SHA384, sizeof(kat_RSA_PSS_SHA384),
- EVP_sha384(), EVP_MD_CTX_FLAG_PAD_PSS,
- "RSA SHA384 PSS"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_PSS_SHA512, sizeof(kat_RSA_PSS_SHA512),
- EVP_sha512(), EVP_MD_CTX_FLAG_PAD_PSS,
- "RSA SHA512 PSS"))
- goto err;
-
-
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_X931_SHA1, sizeof(kat_RSA_X931_SHA1),
- EVP_sha1(), EVP_MD_CTX_FLAG_PAD_X931,
- "RSA SHA1 X931"))
- goto err;
- /* NB: SHA224 not supported in X9.31 */
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_X931_SHA256, sizeof(kat_RSA_X931_SHA256),
- EVP_sha256(), EVP_MD_CTX_FLAG_PAD_X931,
- "RSA SHA256 X931"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_X931_SHA384, sizeof(kat_RSA_X931_SHA384),
- EVP_sha384(), EVP_MD_CTX_FLAG_PAD_X931,
- "RSA SHA384 X931"))
- goto err;
- if (!fips_pkey_signature_test(&pk, kat_tbs, sizeof(kat_tbs) - 1,
- kat_RSA_X931_SHA512, sizeof(kat_RSA_X931_SHA512),
- EVP_sha512(), EVP_MD_CTX_FLAG_PAD_X931,
- "RSA SHA512 X931"))
- goto err;
-
-
- ret = 1;
-
- err:
- FIPS_rsa_free(key);
- return ret;
- }
-
-#endif /* def OPENSSL_FIPS */
diff --git a/crypto/openssl/fips/rsa/fips_rsa_sign.c b/crypto/openssl/fips/rsa/fips_rsa_sign.c
deleted file mode 100644
index 3736462..0000000
--- a/crypto/openssl/fips/rsa/fips_rsa_sign.c
+++ /dev/null
@@ -1,554 +0,0 @@
-/* fips_rsa_sign.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 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).
- *
- */
-
-#include <string.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/err.h>
-#include <openssl/sha.h>
-
-#ifdef OPENSSL_FIPS
-
-/* FIPS versions of RSA_sign() and RSA_verify().
- * These will only have to deal with SHA* signatures and by including
- * pregenerated encodings all ASN1 dependencies can be avoided
- */
-
-/* Standard encodings including NULL parameter */
-
-static const unsigned char sha1_bin[] = {
- 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
- 0x00, 0x04, 0x14
-};
-
-static const unsigned char sha224_bin[] = {
- 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c
-};
-
-static const unsigned char sha256_bin[] = {
- 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
-};
-
-static const unsigned char sha384_bin[] = {
- 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30
-};
-
-static const unsigned char sha512_bin[] = {
- 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40
-};
-
-/* Alternate encodings with absent parameters. We don't generate signature
- * using this format but do tolerate received signatures of this form.
- */
-
-static unsigned char sha1_nn_bin[] = {
- 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04,
- 0x14
-};
-
-static unsigned char sha224_nn_bin[] = {
- 0x30, 0x2b, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x04, 0x04, 0x1c
-};
-
-static unsigned char sha256_nn_bin[] = {
- 0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x01, 0x04, 0x20
-};
-
-static unsigned char sha384_nn_bin[] = {
- 0x30, 0x3f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x02, 0x04, 0x30
-};
-
-static unsigned char sha512_nn_bin[] = {
- 0x30, 0x4f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
- 0x04, 0x02, 0x03, 0x04, 0x40
-};
-
-
-static const unsigned char *fips_digestinfo_encoding(int nid, unsigned int *len)
- {
- switch (nid)
- {
-
- case NID_sha1:
- *len = sizeof(sha1_bin);
- return sha1_bin;
-
- case NID_sha224:
- *len = sizeof(sha224_bin);
- return sha224_bin;
-
- case NID_sha256:
- *len = sizeof(sha256_bin);
- return sha256_bin;
-
- case NID_sha384:
- *len = sizeof(sha384_bin);
- return sha384_bin;
-
- case NID_sha512:
- *len = sizeof(sha512_bin);
- return sha512_bin;
-
- default:
- return NULL;
-
- }
- }
-
-static const unsigned char *fips_digestinfo_nn_encoding(int nid, unsigned int *len)
- {
- switch (nid)
- {
-
- case NID_sha1:
- *len = sizeof(sha1_nn_bin);
- return sha1_nn_bin;
-
- case NID_sha224:
- *len = sizeof(sha224_nn_bin);
- return sha224_nn_bin;
-
- case NID_sha256:
- *len = sizeof(sha256_nn_bin);
- return sha256_nn_bin;
-
- case NID_sha384:
- *len = sizeof(sha384_nn_bin);
- return sha384_nn_bin;
-
- case NID_sha512:
- *len = sizeof(sha512_nn_bin);
- return sha512_nn_bin;
-
- default:
- return NULL;
-
- }
- }
-
-static int fips_rsa_sign(int type, const unsigned char *x, unsigned int y,
- unsigned char *sigret, unsigned int *siglen, EVP_MD_SVCTX *sv)
- {
- int i=0,j,ret=0;
- unsigned int dlen;
- const unsigned char *der;
- unsigned int m_len;
- int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
- int rsa_pad_mode = 0;
- RSA *rsa = sv->key;
- /* Largest DigestInfo: 19 (max encoding) + max MD */
- unsigned char tmpdinfo[19 + EVP_MAX_MD_SIZE];
- unsigned char md[EVP_MAX_MD_SIZE + 1];
-
- EVP_DigestFinal_ex(sv->mctx, md, &m_len);
-
- if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign)
- {
- ret = rsa->meth->rsa_sign(type, md, m_len,
- sigret, siglen, rsa);
- goto done;
- }
-
- if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
- {
- int hash_id;
- memcpy(tmpdinfo, md, m_len);
- hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
- if (hash_id == -1)
- {
- RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
- return 0;
- }
- tmpdinfo[m_len] = (unsigned char)hash_id;
- i = m_len + 1;
- rsa_pad_mode = RSA_X931_PADDING;
- }
- else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
- {
-
- der = fips_digestinfo_encoding(type, &dlen);
-
- if (!der)
- {
- RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE);
- return 0;
- }
- memcpy(tmpdinfo, der, dlen);
- memcpy(tmpdinfo + dlen, md, m_len);
-
- i = dlen + m_len;
- rsa_pad_mode = RSA_PKCS1_PADDING;
-
- }
- else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
- {
- unsigned char *sbuf;
- int saltlen;
- i = RSA_size(rsa);
- sbuf = OPENSSL_malloc(RSA_size(rsa));
- saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
- if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
- saltlen = -1;
- else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
- saltlen = -2;
- if (!sbuf)
- {
- RSAerr(RSA_F_FIPS_RSA_SIGN,ERR_R_MALLOC_FAILURE);
- goto psserr;
- }
- if (!RSA_padding_add_PKCS1_PSS(rsa, sbuf, md,
- M_EVP_MD_CTX_md(sv->mctx), saltlen))
- goto psserr;
- j=rsa->meth->rsa_priv_enc(i,sbuf,sigret,rsa,RSA_NO_PADDING);
- if (j > 0)
- {
- ret=1;
- *siglen=j;
- }
- psserr:
- OPENSSL_cleanse(md,m_len);
- OPENSSL_cleanse(sbuf, i);
- OPENSSL_free(sbuf);
- return ret;
- }
-
- j=RSA_size(rsa);
- if (i > (j-RSA_PKCS1_PADDING_SIZE))
- {
- RSAerr(RSA_F_FIPS_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
- goto done;
- }
- /* NB: call underlying method directly to avoid FIPS blocking */
- j=rsa->meth->rsa_priv_enc(i,tmpdinfo,sigret,rsa,rsa_pad_mode);
- if (j > 0)
- {
- ret=1;
- *siglen=j;
- }
-
- done:
- OPENSSL_cleanse(tmpdinfo,i);
- OPENSSL_cleanse(md,m_len);
- return ret;
- }
-
-static int fips_rsa_verify(int dtype,
- const unsigned char *x, unsigned int y,
- unsigned char *sigbuf, unsigned int siglen, EVP_MD_SVCTX *sv)
- {
- int i,ret=0;
- unsigned int dlen, diglen;
- int pad_mode = sv->mctx->flags & EVP_MD_CTX_FLAG_PAD_MASK;
- int rsa_pad_mode = 0;
- unsigned char *s;
- const unsigned char *der;
- unsigned char dig[EVP_MAX_MD_SIZE];
- RSA *rsa = sv->key;
-
- if (siglen != (unsigned int)RSA_size(sv->key))
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH);
- return(0);
- }
-
- EVP_DigestFinal_ex(sv->mctx, dig, &diglen);
-
- if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify)
- {
- return rsa->meth->rsa_verify(dtype, dig, diglen,
- sigbuf, siglen, rsa);
- }
-
-
- s= OPENSSL_malloc((unsigned int)siglen);
- if (s == NULL)
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
- rsa_pad_mode = RSA_X931_PADDING;
- else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
- rsa_pad_mode = RSA_PKCS1_PADDING;
- else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
- rsa_pad_mode = RSA_NO_PADDING;
-
- /* NB: call underlying method directly to avoid FIPS blocking */
- i=rsa->meth->rsa_pub_dec((int)siglen,sigbuf,s, rsa, rsa_pad_mode);
-
- if (i <= 0) goto err;
-
- if (pad_mode == EVP_MD_CTX_FLAG_PAD_X931)
- {
- int hash_id;
- if (i != (int)(diglen + 1))
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
- goto err;
- }
- hash_id = RSA_X931_hash_id(M_EVP_MD_CTX_type(sv->mctx));
- if (hash_id == -1)
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
- goto err;
- }
- if (s[diglen] != (unsigned char)hash_id)
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
- goto err;
- }
- if (memcmp(s, dig, diglen))
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
- goto err;
- }
- ret = 1;
- }
- else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PKCS1)
- {
-
- der = fips_digestinfo_encoding(dtype, &dlen);
-
- if (!der)
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_UNKNOWN_ALGORITHM_TYPE);
- return(0);
- }
-
- /* Compare, DigestInfo length, DigestInfo header and finally
- * digest value itself
- */
-
- /* If length mismatch try alternate encoding */
- if (i != (int)(dlen + diglen))
- der = fips_digestinfo_nn_encoding(dtype, &dlen);
-
- if ((i != (int)(dlen + diglen)) || memcmp(der, s, dlen)
- || memcmp(s + dlen, dig, diglen))
- {
- RSAerr(RSA_F_FIPS_RSA_VERIFY,RSA_R_BAD_SIGNATURE);
- goto err;
- }
- ret = 1;
-
- }
- else if (pad_mode == EVP_MD_CTX_FLAG_PAD_PSS)
- {
- int saltlen;
- saltlen = M_EVP_MD_CTX_FLAG_PSS_SALT(sv->mctx);
- if (saltlen == EVP_MD_CTX_FLAG_PSS_MDLEN)
- saltlen = -1;
- else if (saltlen == EVP_MD_CTX_FLAG_PSS_MREC)
- saltlen = -2;
- ret = RSA_verify_PKCS1_PSS(rsa, dig, M_EVP_MD_CTX_md(sv->mctx),
- s, saltlen);
- if (ret < 0)
- ret = 0;
- }
-err:
- if (s != NULL)
- {
- OPENSSL_cleanse(s, siglen);
- OPENSSL_free(s);
- }
- return(ret);
- }
-
-#define EVP_PKEY_RSA_fips_method \
- (evp_sign_method *)fips_rsa_sign, \
- (evp_verify_method *)fips_rsa_verify, \
- {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
-
-static int init(EVP_MD_CTX *ctx)
- { return SHA1_Init(ctx->md_data); }
-
-static int update(EVP_MD_CTX *ctx,const void *data,size_t count)
- { return SHA1_Update(ctx->md_data,data,count); }
-
-static int final(EVP_MD_CTX *ctx,unsigned char *md)
- { return SHA1_Final(md,ctx->md_data); }
-
-static const EVP_MD sha1_md=
- {
- NID_sha1,
- NID_sha1WithRSAEncryption,
- SHA_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
- init,
- update,
- final,
- NULL,
- NULL,
- EVP_PKEY_RSA_fips_method,
- SHA_CBLOCK,
- sizeof(EVP_MD *)+sizeof(SHA_CTX),
- };
-
-const EVP_MD *EVP_sha1(void)
- {
- return(&sha1_md);
- }
-
-static int init224(EVP_MD_CTX *ctx)
- { return SHA224_Init(ctx->md_data); }
-static int init256(EVP_MD_CTX *ctx)
- { return SHA256_Init(ctx->md_data); }
-/*
- * Even though there're separate SHA224_[Update|Final], we call
- * SHA256 functions even in SHA224 context. This is what happens
- * there anyway, so we can spare few CPU cycles:-)
- */
-static int update256(EVP_MD_CTX *ctx,const void *data,size_t count)
- { return SHA256_Update(ctx->md_data,data,count); }
-static int final256(EVP_MD_CTX *ctx,unsigned char *md)
- { return SHA256_Final(md,ctx->md_data); }
-
-static const EVP_MD sha224_md=
- {
- NID_sha224,
- NID_sha224WithRSAEncryption,
- SHA224_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
- init224,
- update256,
- final256,
- NULL,
- NULL,
- EVP_PKEY_RSA_fips_method,
- SHA256_CBLOCK,
- sizeof(EVP_MD *)+sizeof(SHA256_CTX),
- };
-
-const EVP_MD *EVP_sha224(void)
- { return(&sha224_md); }
-
-static const EVP_MD sha256_md=
- {
- NID_sha256,
- NID_sha256WithRSAEncryption,
- SHA256_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
- init256,
- update256,
- final256,
- NULL,
- NULL,
- EVP_PKEY_RSA_fips_method,
- SHA256_CBLOCK,
- sizeof(EVP_MD *)+sizeof(SHA256_CTX),
- };
-
-const EVP_MD *EVP_sha256(void)
- { return(&sha256_md); }
-
-static int init384(EVP_MD_CTX *ctx)
- { return SHA384_Init(ctx->md_data); }
-static int init512(EVP_MD_CTX *ctx)
- { return SHA512_Init(ctx->md_data); }
-/* See comment in SHA224/256 section */
-static int update512(EVP_MD_CTX *ctx,const void *data,size_t count)
- { return SHA512_Update(ctx->md_data,data,count); }
-static int final512(EVP_MD_CTX *ctx,unsigned char *md)
- { return SHA512_Final(md,ctx->md_data); }
-
-static const EVP_MD sha384_md=
- {
- NID_sha384,
- NID_sha384WithRSAEncryption,
- SHA384_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
- init384,
- update512,
- final512,
- NULL,
- NULL,
- EVP_PKEY_RSA_fips_method,
- SHA512_CBLOCK,
- sizeof(EVP_MD *)+sizeof(SHA512_CTX),
- };
-
-const EVP_MD *EVP_sha384(void)
- { return(&sha384_md); }
-
-static const EVP_MD sha512_md=
- {
- NID_sha512,
- NID_sha512WithRSAEncryption,
- SHA512_DIGEST_LENGTH,
- EVP_MD_FLAG_FIPS|EVP_MD_FLAG_SVCTX,
- init512,
- update512,
- final512,
- NULL,
- NULL,
- EVP_PKEY_RSA_fips_method,
- SHA512_CBLOCK,
- sizeof(EVP_MD *)+sizeof(SHA512_CTX),
- };
-
-const EVP_MD *EVP_sha512(void)
- { return(&sha512_md); }
-
-#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsa_x931g.c b/crypto/openssl/fips/rsa/fips_rsa_x931g.c
deleted file mode 100644
index d9f9a81..0000000
--- a/crypto/openssl/fips/rsa/fips_rsa_x931g.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* crypto/rsa/rsa_gen.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 <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/rsa.h>
-#include <openssl/fips.h>
-
-#ifdef OPENSSL_FIPS
-
-extern int fips_check_rsa(RSA *rsa);
-
-
-/* X9.31 RSA key derivation and generation */
-
-int RSA_X931_derive_ex(RSA *rsa, BIGNUM *p1, BIGNUM *p2, BIGNUM *q1, BIGNUM *q2,
- const BIGNUM *Xp1, const BIGNUM *Xp2, const BIGNUM *Xp,
- const BIGNUM *Xq1, const BIGNUM *Xq2, const BIGNUM *Xq,
- const BIGNUM *e, BN_GENCB *cb)
- {
- BIGNUM *r0=NULL,*r1=NULL,*r2=NULL,*r3=NULL;
- BN_CTX *ctx=NULL,*ctx2=NULL;
-
- if (!rsa)
- goto err;
-
- ctx = BN_CTX_new();
- BN_CTX_start(ctx);
- if (!ctx)
- goto err;
-
- r0 = BN_CTX_get(ctx);
- r1 = BN_CTX_get(ctx);
- r2 = BN_CTX_get(ctx);
- r3 = BN_CTX_get(ctx);
-
- if (r3 == NULL)
- goto err;
- if (!rsa->e)
- {
- rsa->e = BN_dup(e);
- if (!rsa->e)
- goto err;
- }
- else
- e = rsa->e;
-
- /* If not all parameters present only calculate what we can.
- * This allows test programs to output selective parameters.
- */
-
- if (Xp && !rsa->p)
- {
- rsa->p = BN_new();
- if (!rsa->p)
- goto err;
-
- if (!BN_X931_derive_prime_ex(rsa->p, p1, p2,
- Xp, Xp1, Xp2, e, ctx, cb))
- goto err;
- }
-
- if (Xq && !rsa->q)
- {
- rsa->q = BN_new();
- if (!rsa->q)
- goto err;
- if (!BN_X931_derive_prime_ex(rsa->q, q1, q2,
- Xq, Xq1, Xq2, e, ctx, cb))
- goto err;
- }
-
- if (!rsa->p || !rsa->q)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- return 2;
- }
-
- /* Since both primes are set we can now calculate all remaining
- * components.
- */
-
- /* calculate n */
- rsa->n=BN_new();
- if (rsa->n == NULL)
- goto err;
- if (!BN_mul(rsa->n,rsa->p,rsa->q,ctx))
- goto err;
-
- /* calculate d */
- if (!BN_sub(r1,rsa->p,BN_value_one()))
- goto err; /* p-1 */
- if (!BN_sub(r2,rsa->q,BN_value_one()))
- goto err; /* q-1 */
- if (!BN_mul(r0,r1,r2,ctx))
- goto err; /* (p-1)(q-1) */
-
- if (!BN_gcd(r3, r1, r2, ctx))
- goto err;
-
- if (!BN_div(r0, NULL, r0, r3, ctx))
- goto err; /* LCM((p-1)(q-1)) */
-
- ctx2 = BN_CTX_new();
- if (!ctx2)
- goto err;
-
- rsa->d=BN_mod_inverse(NULL,rsa->e,r0,ctx2); /* d */
- if (rsa->d == NULL)
- goto err;
-
- /* calculate d mod (p-1) */
- rsa->dmp1=BN_new();
- if (rsa->dmp1 == NULL)
- goto err;
- if (!BN_mod(rsa->dmp1,rsa->d,r1,ctx))
- goto err;
-
- /* calculate d mod (q-1) */
- rsa->dmq1=BN_new();
- if (rsa->dmq1 == NULL)
- goto err;
- if (!BN_mod(rsa->dmq1,rsa->d,r2,ctx))
- goto err;
-
- /* calculate inverse of q mod p */
- rsa->iqmp=BN_mod_inverse(NULL,rsa->q,rsa->p,ctx2);
-
- err:
- if (ctx)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (ctx2)
- BN_CTX_free(ctx2);
- /* If this is set all calls successful */
- if (rsa->iqmp != NULL)
- return 1;
-
- return 0;
-
- }
-
-int RSA_X931_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e, BN_GENCB *cb)
- {
- int ok = 0;
- BIGNUM *Xp = NULL, *Xq = NULL;
- BN_CTX *ctx = NULL;
-
- if (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)
- {
- FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_KEY_TOO_SHORT);
- return 0;
- }
-
- if (bits & 0xff)
- {
- FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_INVALID_KEY_LENGTH);
- return 0;
- }
-
- if(FIPS_selftest_failed())
- {
- FIPSerr(FIPS_F_RSA_X931_GENERATE_KEY_EX,FIPS_R_FIPS_SELFTEST_FAILED);
- return 0;
- }
-
- ctx = BN_CTX_new();
- if (!ctx)
- goto error;
-
- BN_CTX_start(ctx);
- Xp = BN_CTX_get(ctx);
- Xq = BN_CTX_get(ctx);
- if (!BN_X931_generate_Xpq(Xp, Xq, bits, ctx))
- goto error;
-
- rsa->p = BN_new();
- rsa->q = BN_new();
- if (!rsa->p || !rsa->q)
- goto error;
-
- /* Generate two primes from Xp, Xq */
-
- if (!BN_X931_generate_prime_ex(rsa->p, NULL, NULL, NULL, NULL, Xp,
- e, ctx, cb))
- goto error;
-
- if (!BN_X931_generate_prime_ex(rsa->q, NULL, NULL, NULL, NULL, Xq,
- e, ctx, cb))
- goto error;
-
- /* Since rsa->p and rsa->q are valid this call will just derive
- * remaining RSA components.
- */
-
- if (!RSA_X931_derive_ex(rsa, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, e, cb))
- goto error;
-
- if(!fips_check_rsa(rsa))
- goto error;
-
- ok = 1;
-
- error:
- if (ctx)
- {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
-
- if (ok)
- return 1;
-
- return 0;
-
- }
-
-#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsagtest.c b/crypto/openssl/fips/rsa/fips_rsagtest.c
deleted file mode 100644
index 657e1b6..0000000
--- a/crypto/openssl/fips/rsa/fips_rsagtest.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/* fips_rsagtest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005,2007 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).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/x509v3.h>
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS RSA support\n");
- return(0);
-}
-
-#else
-
-#include <openssl/rsa.h>
-#include "fips_utl.h"
-
-int rsa_test(FILE *out, FILE *in);
-static int rsa_printkey1(FILE *out, RSA *rsa,
- BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
- BIGNUM *e);
-static int rsa_printkey2(FILE *out, RSA *rsa,
- BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq);
-
-int main(int argc, char **argv)
- {
- FILE *in = NULL, *out = NULL;
-
- int ret = 1;
-
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- goto end;
- }
-
- if (argc == 1)
- in = stdin;
- else
- in = fopen(argv[1], "r");
-
- if (argc < 2)
- out = stdout;
- else
- out = fopen(argv[2], "w");
-
- if (!in)
- {
- fprintf(stderr, "FATAL input initialization error\n");
- goto end;
- }
-
- if (!out)
- {
- fprintf(stderr, "FATAL output initialization error\n");
- goto end;
- }
-
- if (!rsa_test(out, in))
- {
- fprintf(stderr, "FATAL RSAGTEST file processing error\n");
- goto end;
- }
- else
- ret = 0;
-
- end:
-
- if (ret)
- do_print_errors();
-
- if (in && (in != stdin))
- fclose(in);
- if (out && (out != stdout))
- fclose(out);
-
- return ret;
-
- }
-
-#define RSA_TEST_MAXLINELEN 10240
-
-int rsa_test(FILE *out, FILE *in)
- {
- char *linebuf, *olinebuf, *p, *q;
- char *keyword, *value;
- RSA *rsa = NULL;
- BIGNUM *Xp1 = NULL, *Xp2 = NULL, *Xp = NULL;
- BIGNUM *Xq1 = NULL, *Xq2 = NULL, *Xq = NULL;
- BIGNUM *e = NULL;
- int ret = 0;
- int lnum = 0;
-
- olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
- linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
-
- if (!linebuf || !olinebuf)
- goto error;
-
- while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
- {
- lnum++;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
-
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no = or starts with [ (for [foo = bar] line) just copy */
- if (!p || *keyword=='[')
- {
- if (fputs(olinebuf, out) < 0)
- goto error;
- continue;
- }
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
-
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- if (!strcmp(keyword, "xp1"))
- {
- if (Xp1 || !do_hex2bn(&Xp1,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "xp2"))
- {
- if (Xp2 || !do_hex2bn(&Xp2,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "Xp"))
- {
- if (Xp || !do_hex2bn(&Xp,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "xq1"))
- {
- if (Xq1 || !do_hex2bn(&Xq1,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "xq2"))
- {
- if (Xq2 || !do_hex2bn(&Xq2,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "Xq"))
- {
- if (Xq || !do_hex2bn(&Xq,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "e"))
- {
- if (e || !do_hex2bn(&e,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "p1"))
- continue;
- else if (!strcmp(keyword, "p2"))
- continue;
- else if (!strcmp(keyword, "p"))
- continue;
- else if (!strcmp(keyword, "q1"))
- continue;
- else if (!strcmp(keyword, "q2"))
- continue;
- else if (!strcmp(keyword, "q"))
- continue;
- else if (!strcmp(keyword, "n"))
- continue;
- else if (!strcmp(keyword, "d"))
- continue;
- else
- goto parse_error;
-
- fputs(olinebuf, out);
-
- if (e && Xp1 && Xp2 && Xp)
- {
- rsa = FIPS_rsa_new();
- if (!rsa)
- goto error;
- if (!rsa_printkey1(out, rsa, Xp1, Xp2, Xp, e))
- goto error;
- BN_free(Xp1);
- Xp1 = NULL;
- BN_free(Xp2);
- Xp2 = NULL;
- BN_free(Xp);
- Xp = NULL;
- BN_free(e);
- e = NULL;
- }
-
- if (rsa && Xq1 && Xq2 && Xq)
- {
- if (!rsa_printkey2(out, rsa, Xq1, Xq2, Xq))
- goto error;
- BN_free(Xq1);
- Xq1 = NULL;
- BN_free(Xq2);
- Xq2 = NULL;
- BN_free(Xq);
- Xq = NULL;
- FIPS_rsa_free(rsa);
- rsa = NULL;
- }
- }
-
- ret = 1;
-
- error:
-
- if (olinebuf)
- OPENSSL_free(olinebuf);
- if (linebuf)
- OPENSSL_free(linebuf);
-
- if (Xp1)
- BN_free(Xp1);
- if (Xp2)
- BN_free(Xp2);
- if (Xp)
- BN_free(Xp);
- if (Xq1)
- BN_free(Xq1);
- if (Xq1)
- BN_free(Xq1);
- if (Xq2)
- BN_free(Xq2);
- if (Xq)
- BN_free(Xq);
- if (e)
- BN_free(e);
- if (rsa)
- FIPS_rsa_free(rsa);
-
- return ret;
-
- parse_error:
-
- fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
-
- goto error;
-
- }
-
-static int rsa_printkey1(FILE *out, RSA *rsa,
- BIGNUM *Xp1, BIGNUM *Xp2, BIGNUM *Xp,
- BIGNUM *e)
- {
- int ret = 0;
- BIGNUM *p1 = NULL, *p2 = NULL;
- p1 = BN_new();
- p2 = BN_new();
- if (!p1 || !p2)
- goto error;
-
- if (!RSA_X931_derive_ex(rsa, p1, p2, NULL, NULL, Xp1, Xp2, Xp,
- NULL, NULL, NULL, e, NULL))
- goto error;
-
- do_bn_print_name(out, "p1", p1);
- do_bn_print_name(out, "p2", p2);
- do_bn_print_name(out, "p", rsa->p);
-
- ret = 1;
-
- error:
- if (p1)
- BN_free(p1);
- if (p2)
- BN_free(p2);
-
- return ret;
- }
-
-static int rsa_printkey2(FILE *out, RSA *rsa,
- BIGNUM *Xq1, BIGNUM *Xq2, BIGNUM *Xq)
- {
- int ret = 0;
- BIGNUM *q1 = NULL, *q2 = NULL;
- q1 = BN_new();
- q2 = BN_new();
- if (!q1 || !q2)
- goto error;
-
- if (!RSA_X931_derive_ex(rsa, NULL, NULL, q1, q2, NULL, NULL, NULL,
- Xq1, Xq2, Xq, NULL, NULL))
- goto error;
-
- do_bn_print_name(out, "q1", q1);
- do_bn_print_name(out, "q2", q2);
- do_bn_print_name(out, "q", rsa->q);
- do_bn_print_name(out, "n", rsa->n);
- do_bn_print_name(out, "d", rsa->d);
-
- ret = 1;
-
- error:
- if (q1)
- BN_free(q1);
- if (q2)
- BN_free(q2);
-
- return ret;
- }
-
-#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsastest.c b/crypto/openssl/fips/rsa/fips_rsastest.c
deleted file mode 100644
index 452084f..0000000
--- a/crypto/openssl/fips/rsa/fips_rsastest.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* fips_rsastest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005 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).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/x509v3.h>
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS RSA support\n");
- return(0);
-}
-
-#else
-
-#include <openssl/rsa.h>
-#include "fips_utl.h"
-
-static int rsa_stest(FILE *out, FILE *in, int Saltlen);
-static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
- unsigned char *Msg, long Msglen, int Saltlen);
-
-int main(int argc, char **argv)
- {
- FILE *in = NULL, *out = NULL;
-
- int ret = 1, Saltlen = -1;
-
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- goto end;
- }
-
- if ((argc > 2) && !strcmp("-saltlen", argv[1]))
- {
- Saltlen = atoi(argv[2]);
- if (Saltlen < 0)
- {
- fprintf(stderr, "FATAL: Invalid salt length\n");
- goto end;
- }
- argc -= 2;
- argv += 2;
- }
- else if ((argc > 1) && !strcmp("-x931", argv[1]))
- {
- Saltlen = -2;
- argc--;
- argv++;
- }
-
- if (argc == 1)
- in = stdin;
- else
- in = fopen(argv[1], "r");
-
- if (argc < 2)
- out = stdout;
- else
- out = fopen(argv[2], "w");
-
- if (!in)
- {
- fprintf(stderr, "FATAL input initialization error\n");
- goto end;
- }
-
- if (!out)
- {
- fprintf(stderr, "FATAL output initialization error\n");
- goto end;
- }
-
- if (!rsa_stest(out, in, Saltlen))
- {
- fprintf(stderr, "FATAL RSASTEST file processing error\n");
- goto end;
- }
- else
- ret = 0;
-
- end:
-
- if (ret)
- do_print_errors();
-
- if (in && (in != stdin))
- fclose(in);
- if (out && (out != stdout))
- fclose(out);
-
- return ret;
-
- }
-
-#define RSA_TEST_MAXLINELEN 10240
-
-int rsa_stest(FILE *out, FILE *in, int Saltlen)
- {
- char *linebuf, *olinebuf, *p, *q;
- char *keyword, *value;
- RSA *rsa = NULL;
- const EVP_MD *dgst = NULL;
- unsigned char *Msg = NULL;
- long Msglen = -1;
- int keylen = -1, current_keylen = -1;
- int ret = 0;
- int lnum = 0;
-
- olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
- linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
-
- if (!linebuf || !olinebuf)
- goto error;
-
- while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
- {
- lnum++;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
-
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no = just copy */
- if (!p)
- {
- if (fputs(olinebuf, out) < 0)
- goto error;
- continue;
- }
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
-
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- /* Look for [mod = XXX] for key length */
-
- if (!strcmp(keyword, "[mod"))
- {
- p = value + strlen(value) - 1;
- if (*p != ']')
- goto parse_error;
- *p = 0;
- keylen = atoi(value);
- if (keylen < 0)
- goto parse_error;
- }
- else if (!strcmp(keyword, "SHAAlg"))
- {
- if (!strcmp(value, "SHA1"))
- dgst = EVP_sha1();
- else if (!strcmp(value, "SHA224"))
- dgst = EVP_sha224();
- else if (!strcmp(value, "SHA256"))
- dgst = EVP_sha256();
- else if (!strcmp(value, "SHA384"))
- dgst = EVP_sha384();
- else if (!strcmp(value, "SHA512"))
- dgst = EVP_sha512();
- else
- {
- fprintf(stderr,
- "FATAL: unsupported algorithm \"%s\"\n",
- value);
- goto parse_error;
- }
- }
- else if (!strcmp(keyword, "Msg"))
- {
- if (Msg)
- goto parse_error;
- if (strlen(value) & 1)
- *(--value) = '0';
- Msg = hex2bin_m(value, &Msglen);
- if (!Msg)
- goto parse_error;
- }
-
- fputs(olinebuf, out);
-
- /* If key length has changed, generate and output public
- * key components of new RSA private key.
- */
-
- if (keylen != current_keylen)
- {
- BIGNUM *bn_e;
- if (rsa)
- FIPS_rsa_free(rsa);
- rsa = FIPS_rsa_new();
- if (!rsa)
- goto error;
- bn_e = BN_new();
- if (!bn_e || !BN_set_word(bn_e, 0x1001))
- goto error;
- if (!RSA_X931_generate_key_ex(rsa, keylen, bn_e, NULL))
- goto error;
- BN_free(bn_e);
- fputs("n = ", out);
- do_bn_print(out, rsa->n);
- fputs("\ne = ", out);
- do_bn_print(out, rsa->e);
- fputs("\n", out);
- current_keylen = keylen;
- }
-
- if (Msg && dgst)
- {
- if (!rsa_printsig(out, rsa, dgst, Msg, Msglen,
- Saltlen))
- goto error;
- OPENSSL_free(Msg);
- Msg = NULL;
- }
-
- }
-
- ret = 1;
-
- error:
-
- if (olinebuf)
- OPENSSL_free(olinebuf);
- if (linebuf)
- OPENSSL_free(linebuf);
- if (rsa)
- FIPS_rsa_free(rsa);
-
- return ret;
-
- parse_error:
-
- fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
-
- goto error;
-
- }
-
-static int rsa_printsig(FILE *out, RSA *rsa, const EVP_MD *dgst,
- unsigned char *Msg, long Msglen, int Saltlen)
- {
- int ret = 0;
- unsigned char *sigbuf = NULL;
- int i, siglen;
- /* EVP_PKEY structure */
- EVP_PKEY pk;
- EVP_MD_CTX ctx;
- pk.type = EVP_PKEY_RSA;
- pk.pkey.rsa = rsa;
-
- siglen = RSA_size(rsa);
- sigbuf = OPENSSL_malloc(siglen);
- if (!sigbuf)
- goto error;
-
- EVP_MD_CTX_init(&ctx);
-
- if (Saltlen >= 0)
- {
- M_EVP_MD_CTX_set_flags(&ctx,
- EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16));
- }
- else if (Saltlen == -2)
- M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931);
- if (!EVP_SignInit_ex(&ctx, dgst, NULL))
- goto error;
- if (!EVP_SignUpdate(&ctx, Msg, Msglen))
- goto error;
- if (!EVP_SignFinal(&ctx, sigbuf, (unsigned int *)&siglen, &pk))
- goto error;
-
- EVP_MD_CTX_cleanup(&ctx);
-
- fputs("S = ", out);
-
- for (i = 0; i < siglen; i++)
- fprintf(out, "%02X", sigbuf[i]);
-
- fputs("\n", out);
-
- ret = 1;
-
- error:
-
- return ret;
- }
-#endif
diff --git a/crypto/openssl/fips/rsa/fips_rsavtest.c b/crypto/openssl/fips/rsa/fips_rsavtest.c
deleted file mode 100644
index aadab27..0000000
--- a/crypto/openssl/fips/rsa/fips_rsavtest.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/* fips_rsavtest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005 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).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/err.h>
-#include <openssl/x509v3.h>
-#include <openssl/bn.h>
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS RSA support\n");
- return(0);
-}
-
-#else
-
-#include <openssl/rsa.h>
-
-#include "fips_utl.h"
-
-int rsa_test(FILE *out, FILE *in, int saltlen);
-static int rsa_printver(FILE *out,
- BIGNUM *n, BIGNUM *e,
- const EVP_MD *dgst,
- unsigned char *Msg, long Msglen,
- unsigned char *S, long Slen, int Saltlen);
-
-int main(int argc, char **argv)
- {
- FILE *in = NULL, *out = NULL;
-
- int ret = 1;
- int Saltlen = -1;
-
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- goto end;
- }
-
- if ((argc > 2) && !strcmp("-saltlen", argv[1]))
- {
- Saltlen = atoi(argv[2]);
- if (Saltlen < 0)
- {
- fprintf(stderr, "FATAL: Invalid salt length\n");
- goto end;
- }
- argc -= 2;
- argv += 2;
- }
- else if ((argc > 1) && !strcmp("-x931", argv[1]))
- {
- Saltlen = -2;
- argc--;
- argv++;
- }
-
- if (argc == 1)
- in = stdin;
- else
- in = fopen(argv[1], "r");
-
- if (argc < 2)
- out = stdout;
- else
- out = fopen(argv[2], "w");
-
- if (!in)
- {
- fprintf(stderr, "FATAL input initialization error\n");
- goto end;
- }
-
- if (!out)
- {
- fprintf(stderr, "FATAL output initialization error\n");
- goto end;
- }
-
- if (!rsa_test(out, in, Saltlen))
- {
- fprintf(stderr, "FATAL RSAVTEST file processing error\n");
- goto end;
- }
- else
- ret = 0;
-
- end:
-
- if (ret)
- do_print_errors();
-
- if (in && (in != stdin))
- fclose(in);
- if (out && (out != stdout))
- fclose(out);
-
- return ret;
-
- }
-
-#define RSA_TEST_MAXLINELEN 10240
-
-int rsa_test(FILE *out, FILE *in, int Saltlen)
- {
- char *linebuf, *olinebuf, *p, *q;
- char *keyword, *value;
- const EVP_MD *dgst = NULL;
- BIGNUM *n = NULL, *e = NULL;
- unsigned char *Msg = NULL, *S = NULL;
- long Msglen, Slen;
- int ret = 0;
- int lnum = 0;
-
- olinebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
- linebuf = OPENSSL_malloc(RSA_TEST_MAXLINELEN);
-
- if (!linebuf || !olinebuf)
- goto error;
-
- while (fgets(olinebuf, RSA_TEST_MAXLINELEN, in))
- {
- lnum++;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
-
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no = or starts with [ (for [foo = bar] line) just copy */
- if (!p || *keyword=='[')
- {
- if (fputs(olinebuf, out) < 0)
- goto error;
- continue;
- }
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
-
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- if (!strcmp(keyword, "n"))
- {
- if (!do_hex2bn(&n,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "e"))
- {
- if (!do_hex2bn(&e,value))
- goto parse_error;
- }
- else if (!strcmp(keyword, "SHAAlg"))
- {
- if (!strcmp(value, "SHA1"))
- dgst = EVP_sha1();
- else if (!strcmp(value, "SHA224"))
- dgst = EVP_sha224();
- else if (!strcmp(value, "SHA256"))
- dgst = EVP_sha256();
- else if (!strcmp(value, "SHA384"))
- dgst = EVP_sha384();
- else if (!strcmp(value, "SHA512"))
- dgst = EVP_sha512();
- else
- {
- fprintf(stderr,
- "FATAL: unsupported algorithm \"%s\"\n",
- value);
- goto parse_error;
- }
- }
- else if (!strcmp(keyword, "Msg"))
- {
- if (Msg)
- goto parse_error;
- if (strlen(value) & 1)
- *(--value) = '0';
- Msg = hex2bin_m(value, &Msglen);
- if (!Msg)
- goto parse_error;
- }
- else if (!strcmp(keyword, "S"))
- {
- if (S)
- goto parse_error;
- if (strlen(value) & 1)
- *(--value) = '0';
- S = hex2bin_m(value, &Slen);
- if (!S)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Result"))
- continue;
- else
- goto parse_error;
-
- fputs(olinebuf, out);
-
- if (n && e && Msg && S && dgst)
- {
- if (!rsa_printver(out, n, e, dgst,
- Msg, Msglen, S, Slen, Saltlen))
- goto error;
- OPENSSL_free(Msg);
- Msg = NULL;
- OPENSSL_free(S);
- S = NULL;
- }
-
- }
-
-
- ret = 1;
-
-
- error:
-
- if (olinebuf)
- OPENSSL_free(olinebuf);
- if (linebuf)
- OPENSSL_free(linebuf);
- if (n)
- BN_free(n);
- if (e)
- BN_free(e);
-
- return ret;
-
- parse_error:
-
- fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
-
- goto error;
-
- }
-
-static int rsa_printver(FILE *out,
- BIGNUM *n, BIGNUM *e,
- const EVP_MD *dgst,
- unsigned char *Msg, long Msglen,
- unsigned char *S, long Slen, int Saltlen)
- {
- int ret = 0, r;
- /* Setup RSA and EVP_PKEY structures */
- RSA *rsa_pubkey = NULL;
- EVP_PKEY pk;
- EVP_MD_CTX ctx;
- unsigned char *buf = NULL;
- rsa_pubkey = FIPS_rsa_new();
- if (!rsa_pubkey)
- goto error;
- rsa_pubkey->n = BN_dup(n);
- rsa_pubkey->e = BN_dup(e);
- if (!rsa_pubkey->n || !rsa_pubkey->e)
- goto error;
- pk.type = EVP_PKEY_RSA;
- pk.pkey.rsa = rsa_pubkey;
-
- EVP_MD_CTX_init(&ctx);
-
- if (Saltlen >= 0)
- {
- M_EVP_MD_CTX_set_flags(&ctx,
- EVP_MD_CTX_FLAG_PAD_PSS | (Saltlen << 16));
- }
- else if (Saltlen == -2)
- M_EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_PAD_X931);
- if (!EVP_VerifyInit_ex(&ctx, dgst, NULL))
- goto error;
- if (!EVP_VerifyUpdate(&ctx, Msg, Msglen))
- goto error;
-
- r = EVP_VerifyFinal(&ctx, S, Slen, &pk);
-
-
- EVP_MD_CTX_cleanup(&ctx);
-
- if (r < 0)
- goto error;
- ERR_clear_error();
-
- if (r == 0)
- fputs("Result = F\n", out);
- else
- fputs("Result = P\n", out);
-
- ret = 1;
-
- error:
- if (rsa_pubkey)
- FIPS_rsa_free(rsa_pubkey);
- if (buf)
- OPENSSL_free(buf);
-
- return ret;
- }
-#endif
diff --git a/crypto/openssl/fips/sha/Makefile b/crypto/openssl/fips/sha/Makefile
deleted file mode 100644
index 0f8cca9..0000000
--- a/crypto/openssl/fips/sha/Makefile
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# OpenSSL/fips/sha/Makefile
-#
-
-DIR= sha
-TOP= ../..
-CC= cc
-INCLUDES=
-CFLAG=-g
-INSTALL_PREFIX=
-OPENSSLDIR= /usr/local/ssl
-INSTALLTOP=/usr/local/ssl
-MAKEDEPPROG= makedepend
-MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
-MAKEFILE= Makefile
-AR= ar r
-EXE_EXT=
-
-ASFLAGS= $(INCLUDES) $(ASFLAG)
-AFLAGS= $(ASFLAGS)
-
-CFLAGS= $(INCLUDES) $(CFLAG)
-
-GENERAL=Makefile
-TEST= fips_shatest.c
-APPS=
-EXE= fips_standalone_sha1$(EXE_EXT)
-
-LIB=$(TOP)/libcrypto.a
-LIBSRC=fips_sha1_selftest.c
-LIBOBJ=fips_sha1_selftest.o
-
-SRC= $(LIBSRC) fips_standalone_sha1.c
-
-EXHEADER=
-HEADER=
-
-ALL= $(GENERAL) $(SRC) $(HEADER)
-
-top:
- (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all)
-
-all: ../fips_standalone_sha1$(EXE_EXT) lib
-
-lib: $(LIBOBJ)
- @echo $(LIBOBJ) > lib
-
-../fips_standalone_sha1$(EXE_EXT): fips_standalone_sha1.o
- if [ -z "$(HOSTCC)" ] ; then \
- FIPS_SHA_ASM=""; for i in $(SHA1_ASM_OBJ) sha1dgst.o ; do FIPS_SHA_ASM="$$FIPS_SHA_ASM ../../crypto/sha/$$i" ; done; \
- $(CC) -o $@ $(CFLAGS) fips_standalone_sha1.o $$FIPS_SHA_ASM ; \
- else \
- $(HOSTCC) $(HOSTCFLAGS) -o $ $@ -I../../include -I../../crypto fips_standalone_sha1.c ../../crypto/sha/sha1dgst.c ; \
- fi
-
-files:
- $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
-
-links:
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
- @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
-
-install:
- @headerlist="$(EXHEADER)"; for i in $$headerlist; \
- do \
- (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
- chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
- done
-
-tags:
- ctags $(SRC)
-
-tests:
-
-Q=../testvectors/sha/req
-A=../testvectors/sha/rsp
-
-VECTORS = SHA1LongMsg \
- SHA1Monte \
- SHA1ShortMsg \
- SHA224LongMsg \
- SHA224Monte \
- SHA224ShortMsg \
- SHA256LongMsg \
- SHA256Monte \
- SHA256ShortMsg \
- SHA384LongMsg \
- SHA384Monte \
- SHA384ShortMsg \
- SHA512LongMsg \
- SHA512Monte \
- SHA512ShortMsg
-
-fips_test:
- -rm -rf $(A)
- mkdir $(A)
- for file in $(VECTORS); do \
- if [ -f $(Q)/$$file.req ]; then \
- $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_shatest $(Q)/$$file.req $(A)/$$file.rsp; \
- fi; \
- done
-
-lint:
- lint -DLINT $(INCLUDES) $(SRC)>fluff
-
-depend:
- $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
-
-dclean:
- $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
- mv -f Makefile.new $(MAKEFILE)
-
-clean:
- rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff $(EXE)
-
-# DO NOT DELETE THIS LINE -- make depend depends on it.
-
-fips_sha1_selftest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_sha1_selftest.o: ../../include/openssl/crypto.h
-fips_sha1_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
-fips_sha1_selftest.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
-fips_sha1_selftest.o: ../../include/openssl/lhash.h
-fips_sha1_selftest.o: ../../include/openssl/obj_mac.h
-fips_sha1_selftest.o: ../../include/openssl/objects.h
-fips_sha1_selftest.o: ../../include/openssl/opensslconf.h
-fips_sha1_selftest.o: ../../include/openssl/opensslv.h
-fips_sha1_selftest.o: ../../include/openssl/ossl_typ.h
-fips_sha1_selftest.o: ../../include/openssl/safestack.h
-fips_sha1_selftest.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
-fips_sha1_selftest.o: ../../include/openssl/symhacks.h fips_sha1_selftest.c
-fips_shatest.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-fips_shatest.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
-fips_shatest.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
-fips_shatest.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
-fips_shatest.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
-fips_shatest.o: ../../include/openssl/err.h ../../include/openssl/evp.h
-fips_shatest.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
-fips_shatest.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
-fips_shatest.o: ../../include/openssl/opensslconf.h
-fips_shatest.o: ../../include/openssl/opensslv.h
-fips_shatest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h
-fips_shatest.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
-fips_shatest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
-fips_shatest.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
-fips_shatest.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_shatest.c
-fips_standalone_sha1.o: ../../include/openssl/asn1.h
-fips_standalone_sha1.o: ../../include/openssl/bio.h
-fips_standalone_sha1.o: ../../include/openssl/crypto.h
-fips_standalone_sha1.o: ../../include/openssl/e_os2.h
-fips_standalone_sha1.o: ../../include/openssl/evp.h
-fips_standalone_sha1.o: ../../include/openssl/fips.h
-fips_standalone_sha1.o: ../../include/openssl/hmac.h
-fips_standalone_sha1.o: ../../include/openssl/obj_mac.h
-fips_standalone_sha1.o: ../../include/openssl/objects.h
-fips_standalone_sha1.o: ../../include/openssl/opensslconf.h
-fips_standalone_sha1.o: ../../include/openssl/opensslv.h
-fips_standalone_sha1.o: ../../include/openssl/ossl_typ.h
-fips_standalone_sha1.o: ../../include/openssl/safestack.h
-fips_standalone_sha1.o: ../../include/openssl/sha.h
-fips_standalone_sha1.o: ../../include/openssl/stack.h
-fips_standalone_sha1.o: ../../include/openssl/symhacks.h fips_standalone_sha1.c
diff --git a/crypto/openssl/fips/sha/fips_sha1_selftest.c b/crypto/openssl/fips/sha/fips_sha1_selftest.c
deleted file mode 100644
index 4c0d463..0000000
--- a/crypto/openssl/fips/sha/fips_sha1_selftest.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <string.h>
-#include <openssl/err.h>
-#include <openssl/fips.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-
-#ifdef OPENSSL_FIPS
-static char test[][60]=
- {
- "",
- "abc",
- "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
- };
-
-static const unsigned char ret[][SHA_DIGEST_LENGTH]=
- {
- { 0xda,0x39,0xa3,0xee,0x5e,0x6b,0x4b,0x0d,0x32,0x55,
- 0xbf,0xef,0x95,0x60,0x18,0x90,0xaf,0xd8,0x07,0x09 },
- { 0xa9,0x99,0x3e,0x36,0x47,0x06,0x81,0x6a,0xba,0x3e,
- 0x25,0x71,0x78,0x50,0xc2,0x6c,0x9c,0xd0,0xd8,0x9d },
- { 0x84,0x98,0x3e,0x44,0x1c,0x3b,0xd2,0x6e,0xba,0xae,
- 0x4a,0xa1,0xf9,0x51,0x29,0xe5,0xe5,0x46,0x70,0xf1 },
- };
-
-void FIPS_corrupt_sha1()
- {
- test[2][0]++;
- }
-
-int FIPS_selftest_sha1()
- {
- size_t n;
-
- for(n=0 ; n<sizeof(test)/sizeof(test[0]) ; ++n)
- {
- unsigned char md[SHA_DIGEST_LENGTH];
-
- EVP_Digest(test[n],strlen(test[n]),md, NULL, EVP_sha1(), NULL);
- if(memcmp(md,ret[n],sizeof md))
- {
- FIPSerr(FIPS_F_FIPS_SELFTEST_SHA1,FIPS_R_SELFTEST_FAILED);
- return 0;
- }
- }
- return 1;
- }
-
-#endif
diff --git a/crypto/openssl/fips/sha/fips_shatest.c b/crypto/openssl/fips/sha/fips_shatest.c
deleted file mode 100644
index ae5ecdd..0000000
--- a/crypto/openssl/fips/sha/fips_shatest.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/* fips_shatest.c */
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2005.
- */
-/* ====================================================================
- * Copyright (c) 2005 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).
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <openssl/bio.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/x509v3.h>
-
-#ifndef OPENSSL_FIPS
-
-int main(int argc, char *argv[])
-{
- printf("No FIPS SHAXXX support\n");
- return(0);
-}
-
-#else
-
-#include "fips_utl.h"
-
-static int dgst_test(FILE *out, FILE *in);
-static int print_dgst(const EVP_MD *md, FILE *out,
- unsigned char *Msg, int Msglen);
-static int print_monte(const EVP_MD *md, FILE *out,
- unsigned char *Seed, int SeedLen);
-
-int main(int argc, char **argv)
- {
- FILE *in = NULL, *out = NULL;
-
- int ret = 1;
-
- if(!FIPS_mode_set(1))
- {
- do_print_errors();
- goto end;
- }
-
- if (argc == 1)
- in = stdin;
- else
- in = fopen(argv[1], "r");
-
- if (argc < 2)
- out = stdout;
- else
- out = fopen(argv[2], "w");
-
- if (!in)
- {
- fprintf(stderr, "FATAL input initialization error\n");
- goto end;
- }
-
- if (!out)
- {
- fprintf(stderr, "FATAL output initialization error\n");
- goto end;
- }
-
- if (!dgst_test(out, in))
- {
- fprintf(stderr, "FATAL digest file processing error\n");
- goto end;
- }
- else
- ret = 0;
-
- end:
-
- if (ret)
- do_print_errors();
-
- if (in && (in != stdin))
- fclose(in);
- if (out && (out != stdout))
- fclose(out);
-
- return ret;
-
- }
-
-#define SHA_TEST_MAX_BITS 102400
-#define SHA_TEST_MAXLINELEN (((SHA_TEST_MAX_BITS >> 3) * 2) + 100)
-
-int dgst_test(FILE *out, FILE *in)
- {
- const EVP_MD *md = NULL;
- char *linebuf, *olinebuf, *p, *q;
- char *keyword, *value;
- unsigned char *Msg = NULL, *Seed = NULL;
- long MsgLen = -1, Len = -1, SeedLen = -1;
- int ret = 0;
- int lnum = 0;
-
- olinebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN);
- linebuf = OPENSSL_malloc(SHA_TEST_MAXLINELEN);
-
- if (!linebuf || !olinebuf)
- goto error;
-
-
- while (fgets(olinebuf, SHA_TEST_MAXLINELEN, in))
- {
- lnum++;
- strcpy(linebuf, olinebuf);
- keyword = linebuf;
- /* Skip leading space */
- while (isspace((unsigned char)*keyword))
- keyword++;
-
- /* Look for = sign */
- p = strchr(linebuf, '=');
-
- /* If no = or starts with [ (for [L=20] line) just copy */
- if (!p)
- {
- fputs(olinebuf, out);
- continue;
- }
-
- q = p - 1;
-
- /* Remove trailing space */
- while (isspace((unsigned char)*q))
- *q-- = 0;
-
- *p = 0;
- value = p + 1;
-
- /* Remove leading space from value */
- while (isspace((unsigned char)*value))
- value++;
-
- /* Remove trailing space from value */
- p = value + strlen(value) - 1;
- while (*p == '\n' || isspace((unsigned char)*p))
- *p-- = 0;
-
- if (!strcmp(keyword,"[L") && *p==']')
- {
- switch (atoi(value))
- {
- case 20: md=EVP_sha1(); break;
- case 28: md=EVP_sha224(); break;
- case 32: md=EVP_sha256(); break;
- case 48: md=EVP_sha384(); break;
- case 64: md=EVP_sha512(); break;
- default: goto parse_error;
- }
- }
- else if (!strcmp(keyword, "Len"))
- {
- if (Len != -1)
- goto parse_error;
- Len = atoi(value);
- if (Len < 0)
- goto parse_error;
- /* Only handle multiples of 8 bits */
- if (Len & 0x7)
- goto parse_error;
- if (Len > SHA_TEST_MAX_BITS)
- goto parse_error;
- MsgLen = Len >> 3;
- }
-
- else if (!strcmp(keyword, "Msg"))
- {
- long tmplen;
- if (strlen(value) & 1)
- *(--value) = '0';
- if (Msg)
- goto parse_error;
- Msg = hex2bin_m(value, &tmplen);
- if (!Msg)
- goto parse_error;
- }
- else if (!strcmp(keyword, "Seed"))
- {
- if (strlen(value) & 1)
- *(--value) = '0';
- if (Seed)
- goto parse_error;
- Seed = hex2bin_m(value, &SeedLen);
- if (!Seed)
- goto parse_error;
- }
- else if (!strcmp(keyword, "MD"))
- continue;
- else
- goto parse_error;
-
- fputs(olinebuf, out);
-
- if (md && Msg && (MsgLen >= 0))
- {
- if (!print_dgst(md, out, Msg, MsgLen))
- goto error;
- OPENSSL_free(Msg);
- Msg = NULL;
- MsgLen = -1;
- Len = -1;
- }
- else if (md && Seed && (SeedLen > 0))
- {
- if (!print_monte(md, out, Seed, SeedLen))
- goto error;
- OPENSSL_free(Seed);
- Seed = NULL;
- SeedLen = -1;
- }
-
-
- }
-
-
- ret = 1;
-
-
- error:
-
- if (olinebuf)
- OPENSSL_free(olinebuf);
- if (linebuf)
- OPENSSL_free(linebuf);
- if (Msg)
- OPENSSL_free(Msg);
- if (Seed)
- OPENSSL_free(Seed);
-
- return ret;
-
- parse_error:
-
- fprintf(stderr, "FATAL parse error processing line %d\n", lnum);
-
- goto error;
-
- }
-
-static int print_dgst(const EVP_MD *emd, FILE *out,
- unsigned char *Msg, int Msglen)
- {
- int i, mdlen;
- unsigned char md[EVP_MAX_MD_SIZE];
- if (!EVP_Digest(Msg, Msglen, md, (unsigned int *)&mdlen, emd, NULL))
- {
- fputs("Error calculating HASH\n", stderr);
- return 0;
- }
- fputs("MD = ", out);
- for (i = 0; i < mdlen; i++)
- fprintf(out, "%02x", md[i]);
- fputs("\n", out);
- return 1;
- }
-
-static int print_monte(const EVP_MD *md, FILE *out,
- unsigned char *Seed, int SeedLen)
- {
- unsigned int i, j, k;
- int ret = 0;
- EVP_MD_CTX ctx;
- unsigned char *m1, *m2, *m3, *p;
- unsigned int mlen, m1len, m2len, m3len;
-
- EVP_MD_CTX_init(&ctx);
-
- if (SeedLen > EVP_MAX_MD_SIZE)
- mlen = SeedLen;
- else
- mlen = EVP_MAX_MD_SIZE;
-
- m1 = OPENSSL_malloc(mlen);
- m2 = OPENSSL_malloc(mlen);
- m3 = OPENSSL_malloc(mlen);
-
- if (!m1 || !m2 || !m3)
- goto mc_error;
-
- m1len = m2len = m3len = SeedLen;
- memcpy(m1, Seed, SeedLen);
- memcpy(m2, Seed, SeedLen);
- memcpy(m3, Seed, SeedLen);
-
- fputs("\n", out);
-
- for (j = 0; j < 100; j++)
- {
- for (i = 0; i < 1000; i++)
- {
- EVP_DigestInit_ex(&ctx, md, NULL);
- EVP_DigestUpdate(&ctx, m1, m1len);
- EVP_DigestUpdate(&ctx, m2, m2len);
- EVP_DigestUpdate(&ctx, m3, m3len);
- p = m1;
- m1 = m2;
- m1len = m2len;
- m2 = m3;
- m2len = m3len;
- m3 = p;
- EVP_DigestFinal_ex(&ctx, m3, &m3len);
- }
- fprintf(out, "COUNT = %d\n", j);
- fputs("MD = ", out);
- for (k = 0; k < m3len; k++)
- fprintf(out, "%02x", m3[k]);
- fputs("\n\n", out);
- memcpy(m1, m3, m3len);
- memcpy(m2, m3, m3len);
- m1len = m2len = m3len;
- }
-
- ret = 1;
-
- mc_error:
- if (m1)
- OPENSSL_free(m1);
- if (m2)
- OPENSSL_free(m2);
- if (m3)
- OPENSSL_free(m3);
-
- EVP_MD_CTX_cleanup(&ctx);
-
- return ret;
- }
-
-#endif
diff --git a/crypto/openssl/fips/sha/fips_standalone_sha1.c b/crypto/openssl/fips/sha/fips_standalone_sha1.c
deleted file mode 100644
index eec65dc..0000000
--- a/crypto/openssl/fips/sha/fips_standalone_sha1.c
+++ /dev/null
@@ -1,173 +0,0 @@
-/* ====================================================================
- * Copyright (c) 2003 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.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <openssl/opensslconf.h>
-#include <openssl/sha.h>
-#include <openssl/hmac.h>
-
-#ifndef FIPSCANISTER_O
-int FIPS_selftest_failed() { return 0; }
-void FIPS_selftest_check() {}
-void OPENSSL_cleanse(void *p,size_t len) {}
-#endif
-
-#ifdef OPENSSL_FIPS
-
-static void hmac_init(SHA_CTX *md_ctx,SHA_CTX *o_ctx,
- const char *key)
- {
- size_t len=strlen(key);
- int i;
- unsigned char keymd[HMAC_MAX_MD_CBLOCK];
- unsigned char pad[HMAC_MAX_MD_CBLOCK];
-
- if (len > SHA_CBLOCK)
- {
- SHA1_Init(md_ctx);
- SHA1_Update(md_ctx,key,len);
- SHA1_Final(keymd,md_ctx);
- len=20;
- }
- else
- memcpy(keymd,key,len);
- memset(&keymd[len],'\0',HMAC_MAX_MD_CBLOCK-len);
-
- for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++)
- pad[i]=0x36^keymd[i];
- SHA1_Init(md_ctx);
- SHA1_Update(md_ctx,pad,SHA_CBLOCK);
-
- for(i=0 ; i < HMAC_MAX_MD_CBLOCK ; i++)
- pad[i]=0x5c^keymd[i];
- SHA1_Init(o_ctx);
- SHA1_Update(o_ctx,pad,SHA_CBLOCK);
- }
-
-static void hmac_final(unsigned char *md,SHA_CTX *md_ctx,SHA_CTX *o_ctx)
- {
- unsigned char buf[20];
-
- SHA1_Final(buf,md_ctx);
- SHA1_Update(o_ctx,buf,sizeof buf);
- SHA1_Final(md,o_ctx);
- }
-
-#endif
-
-int main(int argc,char **argv)
- {
-#ifdef OPENSSL_FIPS
- static char key[]="etaonrishdlcupfm";
- int n,binary=0;
-
- if(argc < 2)
- {
- fprintf(stderr,"%s [<file>]+\n",argv[0]);
- exit(1);
- }
-
- n=1;
- if (!strcmp(argv[n],"-binary"))
- {
- n++;
- binary=1; /* emit binary fingerprint... */
- }
-
- for(; n < argc ; ++n)
- {
- FILE *f=fopen(argv[n],"rb");
- SHA_CTX md_ctx,o_ctx;
- unsigned char md[20];
- int i;
-
- if(!f)
- {
- perror(argv[n]);
- exit(2);
- }
-
- hmac_init(&md_ctx,&o_ctx,key);
- for( ; ; )
- {
- char buf[1024];
- size_t l=fread(buf,1,sizeof buf,f);
-
- if(l == 0)
- {
- if(ferror(f))
- {
- perror(argv[n]);
- exit(3);
- }
- else
- break;
- }
- SHA1_Update(&md_ctx,buf,l);
- }
- hmac_final(md,&md_ctx,&o_ctx);
-
- if (binary)
- {
- fwrite(md,20,1,stdout);
- break; /* ... for single(!) file */
- }
-
- printf("HMAC-SHA1(%s)= ",argv[n]);
- for(i=0 ; i < 20 ; ++i)
- printf("%02x",md[i]);
- printf("\n");
- }
-#endif
- return 0;
- }
-
-
diff --git a/gnu/lib/libstdc++/Makefile b/gnu/lib/libstdc++/Makefile
index df64a50..1005b5d 100644
--- a/gnu/lib/libstdc++/Makefile
+++ b/gnu/lib/libstdc++/Makefile
@@ -626,9 +626,5 @@ CLEANFILES+= ${VERSION_MAP}
.include <bsd.lib.mk>
-.if ${MK_STAGING} == "yes"
-CXXFLAGS+= -I${STAGE_OBJTOP}${CXXINCLUDEDIR}/backward
-.endif
-
# Filter out libc++-specific flags, and -std= flags above c++98 or gnu++98.
CXXFLAGS:= ${CXXFLAGS:N-stdlib=libc++:N-std=c++[01][13x]:N-std=gnu++[01][13x]}
diff --git a/gnu/usr.bin/sort/Makefile b/gnu/usr.bin/sort/Makefile
deleted file mode 100644
index bf193bc..0000000
--- a/gnu/usr.bin/sort/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-# $FreeBSD$
-
-SORTDIR= ${.CURDIR}/../../../contrib/gnu-sort
-.PATH: ${SORTDIR}/lib ${SORTDIR}/src ${SORTDIR}/man
-
-.include <bsd.own.mk>
-
-.if ${MK_GNU_SORT} == "yes"
-PROG= sort
-.else
-PROG= gnusort
-
-CLEANFILES+= gnusort.1
-gnusort.1: sort.1
- cp ${.ALLSRC} ${.TARGET}
-.endif
-
-SRCS= sort.c \
- __fpending.c \
- argmatch.c \
- closeout.c \
- dup-safer.c \
- error.c \
- exitfail.c \
- fopen-safer.c \
- hard-locale.c \
- human.c \
- long-options.c \
- memcoll.c \
- physmem.c \
- posixver.c \
- quote.c \
- quotearg.c \
- strnlen.c \
- umaxtostr.c \
- version-etc.c \
- xalloc-die.c \
- xmalloc.c \
- xmemcoll.c \
- xstrtoul.c \
- xstrtoumax.c
-
-CFLAGS+=-DHAVE_CONFIG_H -DHAVE_LANGINFO_H=1 -DHAVE_NL_LANGINFO=1 \
- -I${.CURDIR} -I${SORTDIR}/lib
-
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/sort/Makefile.depend b/gnu/usr.bin/sort/Makefile.depend
deleted file mode 100644
index a839545..0000000
--- a/gnu/usr.bin/sort/Makefile.depend
+++ /dev/null
@@ -1,19 +0,0 @@
-# Autogenerated - do NOT edit!
-
-DEP_RELDIR := ${_PARSEDIR:S,${SRCTOP}/,,}
-
-DEP_MACHINE := ${.PARSEFILE:E}
-
-DIRDEPS = \
- gnu/lib/libgcc \
- include \
- include/xlocale \
- lib/${CSU_DIR} \
- lib/libc \
-
-
-.include <dirdeps.mk>
-
-.if ${DEP_RELDIR} == ${_DEP_RELDIR}
-# local dependencies - needed for -jN in clean tree
-.endif
diff --git a/gnu/usr.bin/sort/alloca.h b/gnu/usr.bin/sort/alloca.h
deleted file mode 100644
index 59a1309..0000000
--- a/gnu/usr.bin/sort/alloca.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-extern void *alloca(size_t size);
diff --git a/gnu/usr.bin/sort/config.h b/gnu/usr.bin/sort/config.h
deleted file mode 100644
index 601b368..0000000
--- a/gnu/usr.bin/sort/config.h
+++ /dev/null
@@ -1,1519 +0,0 @@
-/* $FreeBSD$ */
-/* config.h. Generated by configure. */
-/* config.hin. Generated from configure.ac by autoheader. */
-
-/* Define if you have the Andrew File System. */
-/* #undef AFS */
-
-/* Define to the function xargmatch calls on failures. */
-#define ARGMATCH_DIE usage (1)
-
-/* Define to the declaration of the xargmatch failure function. */
-#define ARGMATCH_DIE_DECL extern void usage ()
-
-/* Define to 1 if the `closedir' function returns void instead of `int'. */
-/* #undef CLOSEDIR_VOID */
-
-/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
- systems. This function is required for `alloca.c' support on those systems.
- */
-/* #undef CRAY_STACKSEG_END */
-
-/* Define to 1 if using `alloca.c'. */
-/* #undef C_ALLOCA */
-
-/* Define to 1 if using `getloadavg.c'. */
-/* #undef C_GETLOADAVG */
-
-/* Define the default level of POSIX conformance. The value is of the form
- YYYYMM, specifying the year and month the standard was adopted. If not
- defined here, it defaults to the value of _POSIX2_VERSION in <unistd.h>.
- Define to 199209 to default to POSIX 1003.2-1992, which makes standard
- programs like `head', `tail', and `sort' accept obsolete options like `+10'
- and `-10'. Define to 200112 to default to POSIX 1003.1-2001, which makes
- these standard programs treat leading-`+' operands as file names and
- require modern usages like `-n 10' instead of `-10'. Whether defined here
- or not, the default can be overridden at run time via the _POSIX2_VERSION
- environment variable. */
-/* #undef DEFAULT_POSIX2_VERSION */
-
-/* Define to 1 for DGUX with <sys/dg_sys_info.h>. */
-/* #undef DGUX */
-
-/* the name of the file descriptor member of DIR */
-/* #undef DIR_FD_MEMBER_NAME */
-
-#ifdef DIR_FD_MEMBER_NAME
-# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
-#else
-# define DIR_TO_FD(Dir_p) -1
-#endif
-
-
-
-/* Define if there is a member named d_ino in the struct describing directory
- headers. */
-#define D_INO_IN_DIRENT 1
-
-/* Define to 1 if translation of program messages to the user's native
- language is requested. */
-/* #undef ENABLE_NLS */
-
-/* Define on systems for which file names may have a so-called `drive letter'
- prefix, define this to compute the length of that prefix, including the
- colon. */
-#define FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0
-
-/* Define if the backslash character may also serve as a file name component
- separator. */
-#define FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0
-
-#if FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
-# define FILESYSTEM_PREFIX_LEN(Filename) \
- ((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)
-#else
-# define FILESYSTEM_PREFIX_LEN(Filename) 0
-#endif
-
-/* Define to the type of elements in the array set by `getgroups'. Usually
- this is either `int' or `gid_t'. */
-#define GETGROUPS_T gid_t
-
-/* Define to 1 if the `getloadavg' function needs to be run setuid or setgid.
- */
-/* #undef GETLOADAVG_PRIVILEGED */
-
-/* Define if gettimeofday clobbers localtime's static buffer. */
-/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME_BUFFER */
-
-/* The concatenation of the strings `GNU ', and PACKAGE. */
-#define GNU_PACKAGE "GNU coreutils"
-
-/* Define if your system defines TIOCGWINSZ in sys/ioctl.h. */
-/* #undef GWINSZ_IN_SYS_IOCTL */
-
-/* Define if your system defines TIOCGWINSZ in sys/pty.h. */
-/* #undef GWINSZ_IN_SYS_PTY */
-
-/* Define to 1 if you have the `acl' function. */
-/* #undef HAVE_ACL */
-
-/* Define to 1 if you have the `alarm' function. */
-#define HAVE_ALARM 1
-
-/* Define to 1 if you have `alloca', as a function or macro. */
-#define HAVE_ALLOCA 1
-
-/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
- */
-/* #undef HAVE_ALLOCA_H */
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#define HAVE_ARPA_INET_H 1
-
-/* Define to 1 if you have the `atexit' function. */
-#define HAVE_ATEXIT 1
-
-/* Define to 1 if you have the <bp-sym.h> header file. */
-/* #undef HAVE_BP_SYM_H */
-
-/* Define to 1 if you have the `btowc' function. */
-#define HAVE_BTOWC 1
-
-/* Define to 1 if your system has a working `chown' function. */
-#define HAVE_CHOWN 1
-
-/* Define to 1 if you have the `chroot' function. */
-#define HAVE_CHROOT 1
-
-/* Define to 1 if you have the `chsize' function. */
-/* #undef HAVE_CHSIZE */
-
-/* Define to 1 if you have the `clock_gettime' function. */
-#define HAVE_CLOCK_GETTIME 1
-
-/* Define to 1 if you have the `clock_settime' function. */
-#define HAVE_CLOCK_SETTIME 1
-
-/* FIXME */
-/* #undef HAVE_C_LINE */
-
-/* Define if the GNU dcgettext() function is already present or preinstalled.
- */
-/* #undef HAVE_DCGETTEXT */
-
-/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_CLEARERR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `dirfd', and to 0 if you don't.
- */
-#define HAVE_DECL_DIRFD 1
-
-/* Define to 1 if you have the declaration of `euidaccess', and to 0 if you
- don't. */
-#define HAVE_DECL_EUIDACCESS 0
-
-/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
- don't. */
-#define HAVE_DECL_FEOF_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FERROR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FFLUSH_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FGETS_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FPUTC_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FPUTS_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FREAD_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `free', and to 0 if you don't.
- */
-#define HAVE_DECL_FREE 1
-
-/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_FWRITE_UNLOCKED 0
-
-/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_GETCHAR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `getcwd', and to 0 if you don't.
- */
-#define HAVE_DECL_GETCWD 1
-
-/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
- don't. */
-#define HAVE_DECL_GETC_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
- */
-#define HAVE_DECL_GETENV 1
-
-/* Define to 1 if you have the declaration of `geteuid', and to 0 if you
- don't. */
-#define HAVE_DECL_GETEUID 1
-
-/* Define to 1 if you have the declaration of `getgrgid', and to 0 if you
- don't. */
-#define HAVE_DECL_GETGRGID 1
-
-/* Define to 1 if you have the declaration of `getlogin', and to 0 if you
- don't. */
-#define HAVE_DECL_GETLOGIN 1
-
-/* Define to 1 if you have the declaration of `getpwuid', and to 0 if you
- don't. */
-#define HAVE_DECL_GETPWUID 1
-
-/* Define to 1 if you have the declaration of `getuid', and to 0 if you don't.
- */
-#define HAVE_DECL_GETUID 1
-
-/* Define to 1 if you have the declaration of `getutent', and to 0 if you
- don't. */
-#define HAVE_DECL_GETUTENT 0
-
-/* Define to 1 if you have the declaration of `lseek', and to 0 if you don't.
- */
-#define HAVE_DECL_LSEEK 1
-
-/* Define to 1 if you have the declaration of `malloc', and to 0 if you don't.
- */
-#define HAVE_DECL_MALLOC 1
-
-/* Define to 1 if you have the declaration of `memchr', and to 0 if you don't.
- */
-#define HAVE_DECL_MEMCHR 1
-
-/* Define to 1 if you have the declaration of `memrchr', and to 0 if you
- don't. */
-#define HAVE_DECL_MEMRCHR 0
-
-/* Define to 1 if you have the declaration of `nanosleep', and to 0 if you
- don't. */
-#define HAVE_DECL_NANOSLEEP 1
-
-/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if
- you don't. */
-#define HAVE_DECL_PUTCHAR_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you
- don't. */
-#define HAVE_DECL_PUTC_UNLOCKED 1
-
-/* Define to 1 if you have the declaration of `realloc', and to 0 if you
- don't. */
-#define HAVE_DECL_REALLOC 1
-
-/* Define to 1 if you have the declaration of `stpcpy', and to 0 if you don't.
- */
-#define HAVE_DECL_STPCPY 1
-
-/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
- don't. */
-#define HAVE_DECL_STRERROR_R 1
-
-/* Define to 1 if you have the declaration of `strndup', and to 0 if you
- don't. */
-#define HAVE_DECL_STRNDUP 0
-
-/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
- don't. */
-#define HAVE_DECL_STRNLEN 0
-
-/* Define to 1 if you have the declaration of `strsignal', and to 0 if you
- don't. */
-#define HAVE_DECL_STRSIGNAL 1
-
-/* Define to 1 if you have the declaration of `strstr', and to 0 if you don't.
- */
-#define HAVE_DECL_STRSTR 1
-
-/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you
- don't. */
-#define HAVE_DECL_STRTOIMAX 1
-
-/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
- don't. */
-/* #undef HAVE_DECL_STRTOLL */
-
-/* Define to 1 if you have the declaration of `strtoul', and to 0 if you
- don't. */
-#define HAVE_DECL_STRTOUL 1
-
-/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
- don't. */
-#define HAVE_DECL_STRTOULL 1
-
-/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you
- don't. */
-#define HAVE_DECL_STRTOUMAX 1
-
-/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
- don't. */
-#define HAVE_DECL_SYS_SIGLIST 1
-
-/* Define to 1 if you have the declaration of `ttyname', and to 0 if you
- don't. */
-#define HAVE_DECL_TTYNAME 1
-
-/* Define to 1 if you have the declaration of wcwidth(), and to 0 otherwise.
- */
-#define HAVE_DECL_WCWIDTH 1
-
-/* Define to 1 if you have the declaration of `_sys_siglist', and to 0 if you
- don't. */
-#define HAVE_DECL__SYS_SIGLIST 0
-
-/* Define to 1 if you have the declaration of `__fpending', and to 0 if you
- don't. */
-#define HAVE_DECL___FPENDING 0
-
-/* Define to 1 if you have the declaration of `__sys_siglist', and to 0 if you
- don't. */
-#define HAVE_DECL___SYS_SIGLIST 0
-
-/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
- */
-#define HAVE_DIRENT_H 1
-
-/* Define to 1 if you have the `dirfd' function. */
-/* #undef HAVE_DIRFD */
-
-/* Define to 1 if you have the `dup2' function. */
-#define HAVE_DUP2 1
-
-/* Define to 1 if you have the <dustat.h> header file. */
-/* #undef HAVE_DUSTAT_H */
-
-/* Define to 1 if you have the `endgrent' function. */
-#define HAVE_ENDGRENT 1
-
-/* Define to 1 if you have the `endpwent' function. */
-#define HAVE_ENDPWENT 1
-
-/* Define to 1 if you have the <errno.h> header file. */
-#define HAVE_ERRNO_H 1
-
-/* Define to 1 if you have the `euidaccess' function. */
-/* #undef HAVE_EUIDACCESS */
-
-/* Define to 1 if you have the `fchdir' function. */
-#define HAVE_FCHDIR 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `fdatasync' function. */
-/* #undef HAVE_FDATASYNC */
-
-/* Define to 1 if you have the `fesetround' function. */
-/* #undef HAVE_FESETROUND */
-
-/* Define to 1 if you have the <float.h> header file. */
-#define HAVE_FLOAT_H 1
-
-/* Define to 1 if you have the `floor' function. */
-#define HAVE_FLOOR 1
-
-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
-#define HAVE_FSEEKO 1
-
-/* Define to 1 if you have the <fs_info.h> header file. */
-/* #undef HAVE_FS_INFO_H */
-
-/* Define to 1 if you have the `fs_stat_dev' function. */
-/* #undef HAVE_FS_STAT_DEV */
-
-/* Define to 1 if you have the `ftruncate' function. */
-#define HAVE_FTRUNCATE 1
-
-/* Define if struct statfs has the f_fstypename member. */
-#define HAVE_F_FSTYPENAME_IN_STATFS 1
-
-/* Define to 1 if you have the `getcwd' function. */
-#define HAVE_GETCWD 1
-
-/* Define if getcwd (NULL, 0) allocates memory for result. */
-#define HAVE_GETCWD_NULL 1
-
-/* Define to 1 if you have the `getdelim' function. */
-/* #undef HAVE_GETDELIM */
-
-/* Define to 1 if your system has a working `getgroups' function. */
-#define HAVE_GETGROUPS 1
-
-/* Define to 1 if you have the `gethostbyaddr' function. */
-#define HAVE_GETHOSTBYADDR 1
-
-/* Define to 1 if you have the `gethostbyname' function. */
-#define HAVE_GETHOSTBYNAME 1
-
-/* Define to 1 if you have the `gethostid' function. */
-#define HAVE_GETHOSTID 1
-
-/* Define to 1 if you have the `gethostname' function. */
-#define HAVE_GETHOSTNAME 1
-
-/* Define to 1 if you have the `gethrtime' function. */
-/* #undef HAVE_GETHRTIME */
-
-/* Define to 1 if you have the `getloadavg' function. */
-#define HAVE_GETLOADAVG 1
-
-/* Define to 1 if you have the `getmntent' function. */
-/* #undef HAVE_GETMNTENT */
-
-/* Define to 1 if you have the `getmntinfo' function. */
-#define HAVE_GETMNTINFO 1
-
-/* Define to 1 if you have the `getpagesize' function. */
-#define HAVE_GETPAGESIZE 1
-
-/* Define to 1 if you have the `getpass' function. */
-#define HAVE_GETPASS 1
-
-/* Define to 1 if you have the `getspnam' function. */
-/* #undef HAVE_GETSPNAM */
-
-/* Define to 1 if you have the `getsysinfo' function. */
-/* #undef HAVE_GETSYSINFO */
-
-/* Define if the GNU gettext() function is already present or preinstalled. */
-/* #undef HAVE_GETTEXT */
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#define HAVE_GETTIMEOFDAY 1
-
-/* Define to 1 if you have the `getusershell' function. */
-#define HAVE_GETUSERSHELL 1
-
-/* Define to 1 if you have the <grp.h> header file. */
-#define HAVE_GRP_H 1
-
-/* Define to 1 if you have the `hasmntopt' function. */
-/* #undef HAVE_HASMNTOPT */
-
-/* Define to 1 if you have the <hurd.h> header file. */
-/* #undef HAVE_HURD_H */
-
-/* Define if you have the iconv() function. */
-/* #undef HAVE_ICONV */
-
-/* Define to 1 if you have the `inet_ntoa' function. */
-#define HAVE_INET_NTOA 1
-
-/* Define to 1 if you have the `initgroups' function. */
-#define HAVE_INITGROUPS 1
-
-/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
-#define HAVE_INTMAX_T 1
-
-/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */
-#define HAVE_INTTYPES_H 1
-
-/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
- declares uintmax_t. */
-#define HAVE_INTTYPES_H_WITH_UINTMAX 1
-
-/* Define to 1 if you have the `isascii' function. */
-#define HAVE_ISASCII 1
-
-/* Define to 1 if you have the `iswcntrl' function. */
-#define HAVE_ISWCNTRL 1
-
-/* Define to 1 if you have the `iswprint' function. */
-#define HAVE_ISWPRINT 1
-
-/* Define to 1 if you have the `iswspace' function. */
-#define HAVE_ISWSPACE 1
-
-/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
-#define HAVE_LANGINFO_CODESET 1
-
-/* Define to 1 if you have the `lchown' function. */
-#define HAVE_LCHOWN 1
-
-/* Define to 1 if you have the `dgc' library (-ldgc). */
-/* #undef HAVE_LIBDGC */
-
-/* Define to 1 if you have the `kstat' library (-lkstat). */
-/* #undef HAVE_LIBKSTAT */
-
-/* Define to 1 if you have the `ldgc' library (-lldgc). */
-/* #undef HAVE_LIBLDGC */
-
-/* Define to 1 if you have the `os' library (-los). */
-/* #undef HAVE_LIBOS */
-
-/* Define to 1 if you have the `ypsec' library (-lypsec). */
-/* #undef HAVE_LIBYPSEC */
-
-/* Define to 1 if you have the <limits.h> header file. */
-#define HAVE_LIMITS_H 1
-
-/* Define to 1 if you have the `listmntent' function. */
-/* #undef HAVE_LISTMNTENT */
-
-/* Define to 1 if you have the `localeconv' function. */
-#define HAVE_LOCALECONV 1
-
-/* Define to 1 if you have the <locale.h> header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define if you have the 'long double' type. */
-#define HAVE_LONG_DOUBLE 1
-
-/* Define to 1 if you support file names longer than 14 characters. */
-#define HAVE_LONG_FILE_NAMES 1
-
-/* Define if you have the 'long long' type. */
-#define HAVE_LONG_LONG 1
-
-/* Define to 1 if `lstat' has the bug that it succeeds when given the
- zero-length file name argument. */
-/* #undef HAVE_LSTAT_EMPTY_STRING_BUG */
-
-/* Define to 1 if you have the <machine/hal_sysinfo.h> header file. */
-/* #undef HAVE_MACHINE_HAL_SYSINFO_H */
-
-/* Define to 1 if you have the <mach/mach.h> header file. */
-/* #undef HAVE_MACH_MACH_H */
-
-/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
- to 0 otherwise. */
-#define HAVE_MALLOC 1
-
-/* Define to 1 if you have the `mblen' function. */
-#define HAVE_MBLEN 1
-
-/* Define to 1 if you have the `mbrlen' function. */
-#define HAVE_MBRLEN 1
-
-/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
-#define HAVE_MBRTOWC 1
-
-/* Define to 1 if you have the `mbsinit' function. */
-#define HAVE_MBSINIT 1
-
-/* Define to 1 if you have the `mbsrtowcs' function. */
-#define HAVE_MBSRTOWCS 1
-
-/* Define to 1 if <wchar.h> declares mbstate_t. */
-#define HAVE_MBSTATE_T 1
-
-/* Define to 1 if you have the `memchr' function. */
-#define HAVE_MEMCHR 1
-
-/* Define to 1 if you have the `memcpy' function. */
-#define HAVE_MEMCPY 1
-
-/* Define to 1 if you have the `memmove' function. */
-#define HAVE_MEMMOVE 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `mempcpy' function. */
-/* #undef HAVE_MEMPCPY */
-
-/* Define to 1 if you have the `memrchr' function. */
-/* #undef HAVE_MEMRCHR */
-
-/* Define to 1 if you have the `memset' function. */
-#define HAVE_MEMSET 1
-
-/* Define to 1 if you have the `mkfifo' function. */
-#define HAVE_MKFIFO 1
-
-/* Define to 1 if you have the `mkstemp' function. */
-#define HAVE_MKSTEMP 1
-
-/* Define to 1 if you have the <mntent.h> header file. */
-/* #undef HAVE_MNTENT_H */
-
-/* Define to 1 if you have the <mnttab.h> header file. */
-/* #undef HAVE_MNTTAB_H */
-
-/* Define to 1 if you have the `modf' function. */
-#define HAVE_MODF 1
-
-/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
-/* #undef HAVE_NDIR_H */
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#define HAVE_NETINET_IN_H 1
-
-/* Define to 1 if you have the `next_dev' function. */
-/* #undef HAVE_NEXT_DEV */
-
-/* Define to 1 if you have the <nfs/nfs_clnt.h> header file. */
-/* #undef HAVE_NFS_NFS_CLNT_H */
-
-/* Define to 1 if you have the <nfs/vfs.h> header file. */
-/* #undef HAVE_NFS_VFS_H */
-
-/* Define to 1 if you have the <nlist.h> header file. */
-/* #undef HAVE_NLIST_H */
-
-/* Define to 1 if libc includes obstacks. */
-/* #undef HAVE_OBSTACK */
-
-/* Define to 1 if you have the <OS.h> header file. */
-/* #undef HAVE_OS_H */
-
-/* Define to 1 if you have the `pathconf' function. */
-#define HAVE_PATHCONF 1
-
-/* Define to 1 if you have the <paths.h> header file. */
-#define HAVE_PATHS_H 1
-
-/* Define if your system has the /proc/uptime special file. */
-/* #undef HAVE_PROC_UPTIME */
-
-/* Define to 1 if you have the `pstat_getdynamic' function. */
-/* #undef HAVE_PSTAT_GETDYNAMIC */
-
-/* Define to 1 if you have the `pstat_getstatic' function. */
-/* #undef HAVE_PSTAT_GETSTATIC */
-
-/* Define to 1 if the system has the type `ptrdiff_t'. */
-#define HAVE_PTRDIFF_T 1
-
-/* Define to 1 if you have the <pwd.h> header file. */
-#define HAVE_PWD_H 1
-
-/* Define to 1 if you have the `raise' function. */
-#define HAVE_RAISE 1
-
-/* Define to 1 if you have the `readlink' function. */
-#define HAVE_READLINK 1
-
-/* Define to 1 if your system has a GNU libc compatible `realloc' function,
- and to 0 otherwise. */
-#define HAVE_REALLOC 1
-
-/* Define to 1 if you have the `realpath' function. */
-#define HAVE_REALPATH 1
-
-/* Define to 1 if you have the `resolvepath' function. */
-/* #undef HAVE_RESOLVEPATH */
-
-/* Define to 1 if you have the `rint' function. */
-#define HAVE_RINT 1
-
-/* Define to 1 if you have the `rmdir' function. */
-#define HAVE_RMDIR 1
-
-/* Define to 1 if you have the `rpmatch' function. */
-/* #undef HAVE_RPMATCH */
-
-/* Define to 1 if you have run the test for working tzset. */
-#define HAVE_RUN_TZSET_TEST 1
-
-/* Define to 1 if you have the `sethostname' function. */
-#define HAVE_SETHOSTNAME 1
-
-/* Define to 1 if you have the `setlocale' function. */
-#define HAVE_SETLOCALE 1
-
-/* Define to 1 if you have the `setregid' function. */
-#define HAVE_SETREGID 1
-
-/* Define to 1 if you have the `setreuid' function. */
-#define HAVE_SETREUID 1
-
-/* Define to 1 if you have the <shadow.h> header file. */
-/* #undef HAVE_SHADOW_H */
-
-/* Define to 1 if you have the `sig2str' function. */
-/* #undef HAVE_SIG2STR */
-
-/* Define to 1 if you have the `snprintf' function. */
-#define HAVE_SNPRINTF 1
-
-/* Define to 1 if you have the `sqrt' function. */
-/* #undef HAVE_SQRT */
-
-/* Define to 1 if you have the `statvfs' function. */
-#define HAVE_STATVFS 1
-
-/* Define to 1 if `stat' has the bug that it succeeds when given the
- zero-length file name argument. */
-/* #undef HAVE_STAT_EMPTY_STRING_BUG */
-
-/* Define to 1 if stdbool.h conforms to C99. */
-#define HAVE_STDBOOL_H 1
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#define HAVE_STDDEF_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
- uintmax_t. */
-#define HAVE_STDINT_H_WITH_UINTMAX 1
-
-/* Define to 1 if you have the <stdio_ext.h> header file. */
-/* #undef HAVE_STDIO_EXT_H */
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the `stpcpy' function. */
-#define HAVE_STPCPY 1
-
-/* Define to 1 if you have the `strcasecmp' function. */
-#define HAVE_STRCASECMP 1
-
-/* Define to 1 if you have the `strchr' function. */
-#define HAVE_STRCHR 1
-
-/* Define to 1 if you have the `strcoll' function and it is properly defined.
- */
-#define HAVE_STRCOLL 1
-
-/* Define to 1 if you have the `strcspn' function. */
-#define HAVE_STRCSPN 1
-
-/* Define to 1 if you have the `strdup' function. */
-#define HAVE_STRDUP 1
-
-/* Define to 1 if you have the `strerror' function. */
-#define HAVE_STRERROR 1
-
-/* Define to 1 if you have the `strerror_r' function. */
-#define HAVE_STRERROR_R 1
-
-/* Define to 1 if you have the `strftime' function. */
-#define HAVE_STRFTIME 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strncasecmp' function. */
-#define HAVE_STRNCASECMP 1
-
-/* Define to 1 if you have the `strndup' function. */
-#define HAVE_STRNDUP 1
-
-/* Define to 1 if you have the `strpbrk' function. */
-#define HAVE_STRPBRK 1
-
-/* Define to 1 if you have the `strrchr' function. */
-#define HAVE_STRRCHR 1
-
-/* Define to 1 if you have the `strstr' function. */
-#define HAVE_STRSTR 1
-
-/* Define to 1 if you have the `strtoimax' function. */
-#define HAVE_STRTOIMAX 1
-
-/* Define to 1 if you have the `strtol' function. */
-#define HAVE_STRTOL 1
-
-/* Define to 1 if you have the `strtoll' function. */
-#define HAVE_STRTOLL 1
-
-/* Define to 1 if you have the `strtoul' function. */
-#define HAVE_STRTOUL 1
-
-/* Define to 1 if you have the `strtoull' function. */
-#define HAVE_STRTOULL 1
-
-/* Define to 1 if you have the `strtoumax' function. */
-#define HAVE_STRTOUMAX 1
-
-/* Define if there is a member named d_type in the struct describing directory
- headers. */
-#define HAVE_STRUCT_DIRENT_D_TYPE 1
-
-/* Define to 1 if `f_fstypename' is member of `struct fsstat'. */
-/* #undef HAVE_STRUCT_FSSTAT_F_FSTYPENAME */
-
-/* Define to 1 if `n_un.n_name' is member of `struct nlist'. */
-/* #undef HAVE_STRUCT_NLIST_N_UN_N_NAME */
-
-/* Define to 1 if `sp_pwdp' is member of `struct spwd'. */
-/* #undef HAVE_STRUCT_SPWD_SP_PWDP */
-
-/* Define to 1 if `f_basetype' is member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_BASETYPE */
-
-/* Define to 1 if `f_fsid.__val' is member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_FSID___VAL */
-
-/* Define to 1 if `f_fstypename' is member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_FSTYPENAME */
-
-/* Define to 1 if `f_namelen' is member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_NAMELEN */
-
-/* Define to 1 if `f_namemax' is member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_NAMEMAX */
-
-/* Define to 1 if `f_type' is member of `struct statfs'. */
-/* #undef HAVE_STRUCT_STATFS_F_TYPE */
-
-/* Define to 1 if `f_basetype' is member of `struct statvfs'. */
-/* #undef HAVE_STRUCT_STATVFS_F_BASETYPE */
-
-/* Define to 1 if `f_fsid.__val' is member of `struct statvfs'. */
-/* #undef HAVE_STRUCT_STATVFS_F_FSID___VAL */
-
-/* Define to 1 if `f_namelen' is member of `struct statvfs'. */
-/* #undef HAVE_STRUCT_STATVFS_F_NAMELEN */
-
-/* Define to 1 if `f_namemax' is member of `struct statvfs'. */
-#define HAVE_STRUCT_STATVFS_F_NAMEMAX 1
-
-/* Define to 1 if `f_type' is member of `struct statvfs'. */
-/* #undef HAVE_STRUCT_STATVFS_F_TYPE */
-
-/* Define to 1 if `st_author' is member of `struct stat'. */
-/* #undef HAVE_STRUCT_STAT_ST_AUTHOR */
-
-/* Define to 1 if `st_blksize' is member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
-
-/* Define to 1 if `st_blocks' is member of `struct stat'. */
-#define HAVE_STRUCT_STAT_ST_BLOCKS 1
-
-/* Define if struct timespec is declared in <time.h>. */
-#define HAVE_STRUCT_TIMESPEC 1
-
-/* Define to 1 if `tm_zone' is member of `struct tm'. */
-#define HAVE_STRUCT_TM_TM_ZONE 1
-
-/* Define if struct utimbuf is declared -- usually in <utime.h>. Some systems
- have utime.h but don't declare the struct anywhere. */
-#define HAVE_STRUCT_UTIMBUF 1
-
-/* Define to 1 if `ut_exit' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_EXIT */
-
-/* Define to 1 if `ut_exit.e_exit' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_E_EXIT */
-
-/* Define to 1 if `ut_exit.e_termination' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_E_TERMINATION */
-
-/* Define to 1 if `ut_exit.ut_exit' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_UT_EXIT */
-
-/* Define to 1 if `ut_exit.ut_termination' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_EXIT_UT_TERMINATION */
-
-/* Define to 1 if `ut_id' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_ID */
-
-/* Define to 1 if `ut_name' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_NAME */
-
-/* Define to 1 if `ut_pid' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_PID */
-
-/* Define to 1 if `ut_type' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_TYPE */
-
-/* Define to 1 if `ut_user' is member of `struct utmpx'. */
-/* #undef HAVE_STRUCT_UTMPX_UT_USER */
-
-/* Define to 1 if `ut_exit' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_EXIT */
-
-/* Define to 1 if `ut_exit.e_exit' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_EXIT_E_EXIT */
-
-/* Define to 1 if `ut_exit.e_termination' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_EXIT_E_TERMINATION */
-
-/* Define to 1 if `ut_exit.ut_exit' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_EXIT_UT_EXIT */
-
-/* Define to 1 if `ut_exit.ut_termination' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_EXIT_UT_TERMINATION */
-
-/* Define to 1 if `ut_id' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_ID */
-
-/* Define to 1 if `ut_name' is member of `struct utmp'. */
-#define HAVE_STRUCT_UTMP_UT_NAME 1
-
-/* Define to 1 if `ut_pid' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_PID */
-
-/* Define to 1 if `ut_type' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_TYPE */
-
-/* Define to 1 if `ut_user' is member of `struct utmp'. */
-/* #undef HAVE_STRUCT_UTMP_UT_USER */
-
-/* Define to 1 if you have the `strverscmp' function. */
-/* #undef HAVE_STRVERSCMP */
-
-/* Define to 1 if your `struct stat' has `st_blocks'. Deprecated, use
- `HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
-#define HAVE_ST_BLOCKS 1
-
-/* Define if struct stat has an st_dm_mode member. */
-/* #undef HAVE_ST_DM_MODE */
-
-/* Define to 1 if you have the `sysctl' function. */
-#define HAVE_SYSCTL 1
-
-/* Define to 1 if you have the `sysinfo' function. */
-/* #undef HAVE_SYSINFO */
-
-/* FIXME */
-#define HAVE_SYSLOG 1
-
-/* Define to 1 if you have the <syslog.h> header file. */
-#define HAVE_SYSLOG_H 1
-
-/* Define to 1 if you have the `sysmp' function. */
-/* #undef HAVE_SYSMP */
-
-/* Define to 1 if you have the <sys/acl.h> header file. */
-#define HAVE_SYS_ACL_H 1
-
-/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_DIR_H */
-
-/* Define to 1 if you have the <sys/filsys.h> header file. */
-/* #undef HAVE_SYS_FILSYS_H */
-
-/* Define to 1 if you have the <sys/fstyp.h> header file. */
-/* #undef HAVE_SYS_FSTYP_H */
-
-/* Define to 1 if you have the <sys/fs/s5param.h> header file. */
-/* #undef HAVE_SYS_FS_S5PARAM_H */
-
-/* Define to 1 if you have the <sys/fs_types.h> header file. */
-/* #undef HAVE_SYS_FS_TYPES_H */
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#define HAVE_SYS_IOCTL_H 1
-
-/* Define to 1 if you have the <sys/mntent.h> header file. */
-/* #undef HAVE_SYS_MNTENT_H */
-
-/* Define to 1 if you have the <sys/mount.h> header file. */
-#define HAVE_SYS_MOUNT_H 1
-
-/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
- */
-/* #undef HAVE_SYS_NDIR_H */
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/pstat.h> header file. */
-/* #undef HAVE_SYS_PSTAT_H */
-
-/* Define to 1 if you have the <sys/resource.h> header file. */
-#define HAVE_SYS_RESOURCE_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define to 1 if you have the <sys/statfs.h> header file. */
-/* #undef HAVE_SYS_STATFS_H */
-
-/* Define to 1 if you have the <sys/statvfs.h> header file. */
-#define HAVE_SYS_STATVFS_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/sysctl.h> header file. */
-#define HAVE_SYS_SYSCTL_H 1
-
-/* Define to 1 if you have the <sys/sysinfo.h> header file. */
-/* #undef HAVE_SYS_SYSINFO_H */
-
-/* Define to 1 if you have the <sys/sysmacros.h> header file. */
-/* #undef HAVE_SYS_SYSMACROS_H */
-
-/* Define to 1 if you have the <sys/sysmp.h> header file. */
-/* #undef HAVE_SYS_SYSMP_H */
-
-/* Define to 1 if you have the <sys/systemcfg.h> header file. */
-/* #undef HAVE_SYS_SYSTEMCFG_H */
-
-/* Define to 1 if you have the <sys/systeminfo.h> header file. */
-/* #undef HAVE_SYS_SYSTEMINFO_H */
-
-/* Define to 1 if you have the <sys/table.h> header file. */
-/* #undef HAVE_SYS_TABLE_H */
-
-/* Define to 1 if you have the <sys/timeb.h> header file. */
-#define HAVE_SYS_TIMEB_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#define HAVE_SYS_TIME_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <sys/ucred.h> header file. */
-/* #undef HAVE_SYS_UCRED_H */
-
-/* Define to 1 if you have the <sys/vfs.h> header file. */
-/* #undef HAVE_SYS_VFS_H */
-
-/* Define to 1 if you have the <sys/wait.h> header file. */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to 1 if you have the `table' function. */
-/* #undef HAVE_TABLE */
-
-/* Define to 1 if you have the <termios.h> header file. */
-#define HAVE_TERMIOS_H 1
-
-/* Define if struct tm has the tm_gmtoff member. */
-#define HAVE_TM_GMTOFF 1
-
-/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
- `HAVE_STRUCT_TM_TM_ZONE' instead. */
-#define HAVE_TM_ZONE 1
-
-/* Define to 1 if you don't have `tm_zone' but do have the external array
- `tzname'. */
-/* #undef HAVE_TZNAME */
-
-/* Define to 1 if you have the `tzset' function. */
-#define HAVE_TZSET 1
-
-/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
-#define HAVE_UINTMAX_T 1
-
-/* Define to 1 if you have the `uname' function. */
-#define HAVE_UNAME 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Define if you have the 'unsigned long long' type. */
-#define HAVE_UNSIGNED_LONG_LONG 1
-
-/* Define if utimes accepts a null argument */
-/* #undef HAVE_UTIMES_NULL */
-
-/* Define to 1 if you have the <utime.h> header file. */
-#define HAVE_UTIME_H 1
-
-/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
-#define HAVE_UTIME_NULL 1
-
-/* Define to 1 if you have the `utmpname' function. */
-/* #undef HAVE_UTMPNAME */
-
-/* Define to 1 if you have the `utmpxname' function. */
-/* #undef HAVE_UTMPXNAME */
-
-/* FIXME */
-/* #undef HAVE_UTMPX_H */
-
-/* Define to 1 if you have the <utmp.h> header file. */
-#define HAVE_UTMP_H 1
-
-/* FIXME */
-#define HAVE_UT_HOST 1
-
-/* Define to 1 if you have the <values.h> header file. */
-/* #undef HAVE_VALUES_H */
-
-/* Define to 1 if you have the `vasnprintf' function. */
-/* #undef HAVE_VASNPRINTF */
-
-/* Define to 1 if you have the `vasprintf' function. */
-#define HAVE_VASPRINTF 1
-
-/* Define to 1 if you have the <wchar.h> header file. */
-#define HAVE_WCHAR_H 1
-
-/* Define if you have the 'wchar_t' type. */
-#define HAVE_WCHAR_T 1
-
-/* Define to 1 if you have the `wcrtomb' function. */
-#define HAVE_WCRTOMB 1
-
-/* Define to 1 if you have the `wcslen' function. */
-#define HAVE_WCSLEN 1
-
-/* Define to 1 if you have the <wctype.h> header file. */
-#define HAVE_WCTYPE_H 1
-
-/* Define to 1 if you have the `wcwidth' function. */
-#define HAVE_WCWIDTH 1
-
-/* Define if you have the 'wint_t' type. */
-#define HAVE_WINT_T 1
-
-/* Define to 1 if you have the `wmempcpy' function. */
-/* #undef HAVE_WMEMPCPY */
-
-/* Define if readdir is found to work properly in some unusual cases. */
-#define HAVE_WORKING_READDIR 1
-
-/* Define if utimes works properly. */
-#define HAVE_WORKING_UTIMES 1
-
-/* Define to 1 if the system has the type `_Bool'. */
-#define HAVE__BOOL 1
-
-/* Define to 1 if you have the external variable, _system_configuration with a
- member named physmem. */
-/* #undef HAVE__SYSTEM_CONFIGURATION */
-
-/* Define to 1 if you have the `__fpending' function. */
-/* #undef HAVE___FPENDING */
-
-/* Define to 1 if you have the `__secure_getenv' function. */
-/* #undef HAVE___SECURE_GETENV */
-
-/* The host operating system. */
-#define HOST_OPERATING_SYSTEM "FreeBSD"
-
-/* Define as const if the declaration of iconv() needs const. */
-/* #undef ICONV_CONST */
-
-#if FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
-# define ISSLASH(C) ((C) == '/' || (C) == '\\')
-#else
-# define ISSLASH(C) ((C) == '/')
-#endif
-
-/* Define if `link(2)' dereferences symbolic links. */
-#define LINK_FOLLOWS_SYMLINKS 1
-
-/* FIXME */
-#define LOCALTIME_CACHE 1
-
-/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
- slash. */
-/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in <mkdev.h>.
- */
-/* #undef MAJOR_IN_MKDEV */
-
-/* Define to 1 if `major', `minor', and `makedev' are declared in
- <sysmacros.h>. */
-/* #undef MAJOR_IN_SYSMACROS */
-
-/* Define if there is no specific function for reading the list of mounted
- filesystems. fread will be used to read /etc/mnttab. (SVR2) */
-/* #undef MOUNTED_FREAD */
-
-/* Define if (like SVR2) there is no specific function for reading the list of
- mounted filesystems, and your system has these header files: <sys/fstyp.h>
- and <sys/statfs.h>. (SVR3) */
-/* #undef MOUNTED_FREAD_FSTYP */
-
-/* Define if there are functions named next_dev and fs_stat_dev for reading
- the list of mounted filesystems. (BeOS) */
-/* #undef MOUNTED_FS_STAT_DEV */
-
-/* Define if there is a function named getfsstat for reading the list of
- mounted filesystems. (DEC Alpha running OSF/1) */
-/* #undef MOUNTED_GETFSSTAT */
-
-/* Define if there is a function named getmnt for reading the list of mounted
- filesystems. (Ultrix) */
-/* #undef MOUNTED_GETMNT */
-
-/* Define if there is a function named getmntent for reading the list of
- mounted filesystems, and that function takes a single argument. (4.3BSD,
- SunOS, HP-UX, Dynix, Irix) */
-/* #undef MOUNTED_GETMNTENT1 */
-
-/* Define if there is a function named getmntent for reading the list of
- mounted filesystems, and that function takes two arguments. (SVR4) */
-/* #undef MOUNTED_GETMNTENT2 */
-
-/* Define if there is a function named getmntinfo for reading the list of
- mounted filesystems. (4.4BSD, Darwin) */
-#define MOUNTED_GETMNTINFO 1
-
-/* Define if there is a function named listmntent that can be used to list all
- mounted filesystems. (UNICOS) */
-/* #undef MOUNTED_LISTMNTENT */
-
-/* Define if there is a function named mntctl that can be used to read the
- list of mounted filesystems, and there is a system header file that
- declares `struct vmount.' (AIX) */
-/* #undef MOUNTED_VMOUNT */
-
-/* Define to 1 if assertions should be disabled. */
-/* #undef NDEBUG */
-
-/* FIXME */
-/* #undef NICE_PRIORITY */
-
-/* Define to 1 if your `struct nlist' has an `n_un' member. Obsolete, depend
- on `HAVE_STRUCT_NLIST_N_UN_N_NAME */
-/* #undef NLIST_NAME_UNION */
-
-/* Name of package */
-#define PACKAGE "coreutils"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "bug-coreutils@gnu.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "GNU coreutils"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "GNU coreutils 5.3.0-20040812-FreeBSD"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "coreutils"
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "5.3.0-20040812-FreeBSD"
-
-/* the number of pending output bytes on stream `fp' */
-#define PENDING_OUTPUT_N_BYTES fp->_p - fp->_bf._base
-
-/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
-/* #undef PRI_MACROS_BROKEN */
-
-/* Define to 1 if the C compiler supports function prototypes. */
-#define PROTOTYPES 1
-
-/* Define if rename does not work for source paths with a trailing slash, like
- the one from SunOS 4.1.1_U1. */
-/* #undef RENAME_TRAILING_SLASH_BUG */
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#define RETSIGTYPE void
-
-/* the value to which errno is set when rmdir fails on a nonempty directory */
-#define RMDIR_ERRNO_NOT_EMPTY 66
-
-/* Define to 1 if the `setvbuf' function takes the buffering type as its
- second argument and the buffer pointer as the third, as on System V before
- release 3. */
-/* #undef SETVBUF_REVERSED */
-
-/* If using the C implementation of alloca, define if you know the
- direction of stack growth for your system; otherwise it will be
- automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-/* #undef STACK_DIRECTION */
-
-/* Define if the block counts reported by statfs may be truncated to 2GB and
- the correct values may be stored in the f_spare array. (SunOS 4.1.2, 4.1.3,
- and 4.1.3_U1 are reported to have this problem. SunOS 4.1.1 seems not to be
- affected.) */
-/* #undef STATFS_TRUNCATES_BLOCK_COUNTS */
-
-/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
-/* #undef STAT_MACROS_BROKEN */
-
-/* Define if there is no specific function for reading filesystems usage
- information and you have the <sys/filsys.h> header file. (SVR2) */
-/* #undef STAT_READ_FILSYS */
-
-/* Define if statfs takes 2 args and struct statfs has a field named f_bsize.
- (4.3BSD, SunOS 4, HP-UX, AIX PS/2) */
-/* #undef STAT_STATFS2_BSIZE */
-
-/* Define if statfs takes 2 args and struct statfs has a field named f_fsize.
- (4.4BSD, NetBSD) */
-/* #undef STAT_STATFS2_FSIZE */
-
-/* Define if statfs takes 2 args and the second argument has type struct
- fs_data. (Ultrix) */
-/* #undef STAT_STATFS2_FS_DATA */
-
-/* Define if statfs takes 3 args. (DEC Alpha running OSF/1) */
-/* #undef STAT_STATFS3_OSF1 */
-
-/* Define if statfs takes 4 args. (SVR3, Dynix, Irix, Dolphin) */
-/* #undef STAT_STATFS4 */
-
-/* Define if there is a function named statvfs. (SVR4) */
-#define STAT_STATVFS 1
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if strerror_r returns char *. */
-/* #undef STRERROR_R_CHAR_P */
-
-/* Define to be the nanoseconds member of struct stat's st_mtim, if it exists.
- */
-/* #undef ST_MTIM_NSEC */
-
-/* Define to 1 on System V Release 4. */
-/* #undef SVR4 */
-
-/* FIXME */
-/* #undef TERMIOS_NEEDS_XOPEN_SOURCE */
-
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define to 1 if your <sys/time.h> declares `struct tm'. */
-/* #undef TM_IN_SYS_TIME */
-
-/* Define if tzset clobbers localtime's static buffer. */
-/* #undef TZSET_CLOBBERS_LOCALTIME_BUFFER */
-
-/* Define to 1 for Encore UMAX. */
-/* #undef UMAX */
-
-/* Define to 1 for Encore UMAX 4.3 that has <inq_status/cpustats.h> instead of
- <sys/cpustats.h>. */
-/* #undef UMAX4_3 */
-
-/* Version number of package */
-#define VERSION "5.3.0-20040812-FreeBSD"
-
-/* Define if sys/ptem.h is required for struct winsize. */
-/* #undef WINSIZE_IN_PTEM */
-
-/* Define to 1 if your processor stores words with the most significant byte
- first (like Motorola and SPARC, unlike Intel and VAX). */
-/* #undef WORDS_BIGENDIAN */
-
-/* Define to 1 if on AIX 3.
- System headers sometimes define this.
- We just want to avoid a redefinition error message. */
-#ifndef _ALL_SOURCE
-/* # undef _ALL_SOURCE */
-#endif
-
-/* Number of bits in a file offset, on hosts where this is settable. */
-/* #undef _FILE_OFFSET_BITS */
-
-/* Enable GNU extensions on systems that have them. */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
-#endif
-
-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
-/* #undef _LARGEFILE_SOURCE */
-
-/* Define for large files, on AIX-style hosts. */
-/* #undef _LARGE_FILES */
-
-/* Define to 1 if on MINIX. */
-/* #undef _MINIX */
-
-/* Define to 2 if the system does not provide POSIX.1 features except with
- this defined. */
-/* #undef _POSIX_1_SOURCE */
-
-/* Define to 1 if you need to in order for `stat' and other things to work. */
-/* #undef _POSIX_SOURCE */
-
-/* Enable extensions on Solaris. */
-#ifndef __EXTENSIONS__
-# define __EXTENSIONS__ 1
-#endif
-
-/* Define like PROTOTYPES; this can be used by system headers. */
-#define __PROTOTYPES 1
-
-/* Define to rpl_chown if the replacement function should be used. */
-/* #undef chown */
-
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
-/* Define to a replacement function name for fnmatch(). */
-/* #undef fnmatch */
-
-/* Define to rpl_free if the replacement function should be used. */
-/* #undef free */
-
-/* Define to rpl_getcwd if the wrapper function should be used. */
-/* #undef getcwd */
-
-/* Define as rpl_getgroups if getgroups doesn't work right. */
-/* #undef getgroups */
-
-/* Define to a replacement function name for getline(). */
-/* #undef getline */
-
-/* Define to rpl_gettimeofday if the replacement function should be used. */
-/* #undef gettimeofday */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef gid_t */
-
-/* Define to rpl_gmtime if the replacement function should be used. */
-/* #undef gmtime */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to `unsigned long int' if <sys/types.h> does not define. */
-/* #undef ino_t */
-
-/* Define to long or long long if <stdint.h> and <inttypes.h> don't define. */
-/* #undef intmax_t */
-
-/* Define to rpl_localtime if the replacement function should be used. */
-/* #undef localtime */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#define major_t unsigned int
-
-/* Define to rpl_malloc if the replacement function should be used. */
-/* #undef malloc */
-
-/* Define to a type if <wchar.h> does not define. */
-/* #undef mbstate_t */
-
-/* Define to rpl_memcmp if the replacement function should be used. */
-/* #undef memcmp */
-
-/* Define to `unsigned int' if <sys/types.h> does not define. */
-#define minor_t unsigned int
-
-/* Define to rpl_mkdir if the replacement function should be used. */
-/* #undef mkdir */
-
-/* Define to rpl_mkstemp if the replacement function should be used. */
-/* #undef mkstemp */
-
-/* Define to rpl_mktime if the replacement function should be used. */
-/* #undef mktime */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef mode_t */
-
-/* Define to the name of the strftime replacement function. */
-#define my_strftime nstrftime
-
-/* Define to rpl_nanosleep if the replacement function should be used. */
-/* #undef nanosleep */
-
-/* Define to `long' if <sys/types.h> does not define. */
-/* #undef off_t */
-
-/* Define to `int' if <sys/types.h> does not define. */
-/* #undef pid_t */
-
-/* Define to rpl_putenv if the replacement function should be used. */
-/* #undef putenv */
-
-/* Define to rpl_realloc if the replacement function should be used. */
-/* #undef realloc */
-
-/* Define to rpl_rename if the replacement function should be used. */
-/* #undef rename */
-
-/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
- supported. Do not define if restrict is supported directly. */
-#define restrict __restrict
-
-/* Define to empty if the C compiler doesn't support this keyword. */
-/* #undef signed */
-
-/* Define to `unsigned' if <sys/types.h> does not define. */
-/* #undef size_t */
-
-/* Define as a signed type of the same size as size_t. */
-/* #undef ssize_t */
-
-/* Define to rpl_strnlen if the replacement function should be used. */
-#define strnlen rpl_strnlen
-
-/* Define to rpl_strtod if the replacement function should be used. */
-/* #undef strtod */
-
-/* Define to rpl_tzset if the wrapper function should be used. */
-/* #undef tzset */
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-/* #undef uid_t */
-
-/* Define to unsigned long or unsigned long long if <stdint.h> and
- <inttypes.h> don't define. */
-/* #undef uintmax_t */
-
-/* Define to `size_t' if <sys/types.h> does not define. */
-/* #undef uintptr_t */
-
-/* Define to rpl_utime if the replacement function should be used. */
-/* #undef utime */
-
-/* Define to empty if the keyword `volatile' does not work. Warning: valid
- code using `volatile' can become incorrect without. Disable with care. */
-/* #undef volatile */
diff --git a/gnu/usr.bin/sort/localedir.h b/gnu/usr.bin/sort/localedir.h
deleted file mode 100644
index f119a5f..0000000
--- a/gnu/usr.bin/sort/localedir.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-#define LOCALEDIR ""
diff --git a/gnu/usr.bin/sort/unlocked-io.h b/gnu/usr.bin/sort/unlocked-io.h
deleted file mode 100644
index 3c7a476..0000000
--- a/gnu/usr.bin/sort/unlocked-io.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* $FreeBSD$ */
-/* Dummy file for trimmed down sort */
diff --git a/lib/libc/arm/Symbol.map b/lib/libc/arm/Symbol.map
index 48f6747..b786afd 100644
--- a/lib/libc/arm/Symbol.map
+++ b/lib/libc/arm/Symbol.map
@@ -37,6 +37,10 @@ FBSD_1.3 {
__flt_rounds;
};
+FBSD_1.3 {
+ __flt_rounds;
+};
+
FBSDprivate_1.0 {
/* PSEUDO syscalls */
__sys_getlogin;
diff --git a/sys/contrib/pf/net/if_pflog.c b/sys/contrib/pf/net/if_pflog.c
deleted file mode 100644
index 349930b..0000000
--- a/sys/contrib/pf/net/if_pflog.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/* $OpenBSD: if_pflog.c,v 1.26 2007/10/18 21:58:18 mpf Exp $ */
-/*
- * The authors of this code are John Ioannidis (ji@tla.org),
- * Angelos D. Keromytis (kermit@csd.uch.gr) and
- * Niels Provos (provos@physnet.uni-hamburg.de).
- *
- * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
- * in November 1995.
- *
- * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
- * by Angelos D. Keromytis.
- *
- * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
- * and Niels Provos.
- *
- * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
- * and Niels Provos.
- * Copyright (c) 2001, Angelos D. Keromytis, Niels Provos.
- *
- * Permission to use, copy, and modify this software with or without fee
- * is hereby granted, provided that this entire notice is included in
- * all copies of any software which is or includes a copy or
- * modification of this software.
- * You may use this code under the GNU public license if you so wish. Please
- * contribute changes back to the authors under this freer than GPL license
- * so that we may further the use of strong encryption without limitations to
- * all.
- *
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
- * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
- * PURPOSE.
- */
-
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_bpf.h"
-#include "opt_pf.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#ifdef DEV_BPF
-#define NBPFILTER DEV_BPF
-#else
-#define NBPFILTER 0
-#endif
-
-#ifdef DEV_PFLOG
-#define NPFLOG DEV_PFLOG
-#else
-#define NPFLOG 0
-#endif
-
-#else /* ! __FreeBSD__ */
-#include "bpfilter.h"
-#include "pflog.h"
-#endif /* __FreeBSD__ */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/proc.h>
-#include <sys/socket.h>
-#ifdef __FreeBSD__
-#include <sys/kernel.h>
-#include <sys/limits.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/sockio.h>
-#else
-#include <sys/ioctl.h>
-#endif
-
-#include <net/if.h>
-#ifdef __FreeBSD__
-#include <net/if_clone.h>
-#endif
-#include <net/if_types.h>
-#include <net/route.h>
-#include <net/bpf.h>
-
-#if defined(INET) || defined(INET6)
-#include <netinet/in.h>
-#endif
-#ifdef INET
-#include <netinet/in_var.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#endif
-
-#ifdef INET6
-#include <netinet6/in6_var.h>
-#include <netinet6/nd6.h>
-#endif /* INET6 */
-
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-
-#ifdef __FreeBSD__
-#ifdef INET
-#include <machine/in_cksum.h>
-#endif /* INET */
-#endif /* __FreeBSD__ */
-
-#define PFLOGMTU (32768 + MHLEN + MLEN)
-
-#ifdef PFLOGDEBUG
-#define DPRINTF(x) do { if (pflogdebug) printf x ; } while (0)
-#else
-#define DPRINTF(x)
-#endif
-
-void pflogattach(int);
-int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
-#ifdef __FreeBSD__
- struct route *);
-#else
- struct rtentry *);
-#endif
-int pflogioctl(struct ifnet *, u_long, caddr_t);
-void pflogstart(struct ifnet *);
-#ifdef __FreeBSD__
-static int pflog_clone_create(struct if_clone *, int, caddr_t);
-static void pflog_clone_destroy(struct ifnet *);
-#else
-int pflog_clone_create(struct if_clone *, int);
-int pflog_clone_destroy(struct ifnet *);
-#endif
-
-LIST_HEAD(, pflog_softc) pflogif_list;
-#ifdef __FreeBSD__
-IFC_SIMPLE_DECLARE(pflog, 1);
-#else
-struct if_clone pflog_cloner =
- IF_CLONE_INITIALIZER("pflog", pflog_clone_create, pflog_clone_destroy);
-#endif
-
-struct ifnet *pflogifs[PFLOGIFS_MAX]; /* for fast access */
-
-void
-pflogattach(int npflog)
-{
- int i;
- LIST_INIT(&pflogif_list);
- for (i = 0; i < PFLOGIFS_MAX; i++)
- pflogifs[i] = NULL;
- if_clone_attach(&pflog_cloner);
-}
-
-#ifdef __FreeBSD__
-static int
-pflog_clone_create(struct if_clone *ifc, int unit, caddr_t param)
-#else
-int
-pflog_clone_create(struct if_clone *ifc, int unit)
-#endif
-{
- struct ifnet *ifp;
- struct pflog_softc *pflogif;
- int s;
-
- if (unit >= PFLOGIFS_MAX)
- return (EINVAL);
-
- if ((pflogif = malloc(sizeof(*pflogif),
- M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL)
- return (ENOMEM);
-
- pflogif->sc_unit = unit;
-#ifdef __FreeBSD__
- ifp = pflogif->sc_ifp = if_alloc(IFT_PFLOG);
- if (ifp == NULL) {
- free(pflogif, M_DEVBUF);
- return (ENOSPC);
- }
- if_initname(ifp, ifc->ifc_name, unit);
-#else
- ifp = &pflogif->sc_if;
- snprintf(ifp->if_xname, sizeof ifp->if_xname, "pflog%d", unit);
-#endif
- ifp->if_softc = pflogif;
- ifp->if_mtu = PFLOGMTU;
- ifp->if_ioctl = pflogioctl;
- ifp->if_output = pflogoutput;
- ifp->if_start = pflogstart;
-#ifndef __FreeBSD__
- ifp->if_type = IFT_PFLOG;
-#endif
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_hdrlen = PFLOG_HDRLEN;
- if_attach(ifp);
-#ifndef __FreeBSD__
- if_alloc_sadl(ifp);
-#endif
-
-#if NBPFILTER > 0
-#ifdef __FreeBSD__
- bpfattach(ifp, DLT_PFLOG, PFLOG_HDRLEN);
-#else
- bpfattach(&pflogif->sc_if.if_bpf, ifp, DLT_PFLOG, PFLOG_HDRLEN);
-#endif
-#endif
-
- s = splnet();
-#ifdef __FreeBSD__
- /* XXX: Why pf(4) lock?! Better add a pflog lock?! */
- PF_LOCK();
-#endif
- LIST_INSERT_HEAD(&pflogif_list, pflogif, sc_list);
- pflogifs[unit] = ifp;
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (0);
-}
-
-#ifdef __FreeBSD__
-static void
-pflog_clone_destroy(struct ifnet *ifp)
-#else
-int
-pflog_clone_destroy(struct ifnet *ifp)
-#endif
-{
- struct pflog_softc *pflogif = ifp->if_softc;
- int s;
-
- s = splnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- pflogifs[pflogif->sc_unit] = NULL;
- LIST_REMOVE(pflogif, sc_list);
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
-#if NBPFILTER > 0
- bpfdetach(ifp);
-#endif
- if_detach(ifp);
-#ifdef __FreeBSD__
- if_free(ifp);
-#endif
- free(pflogif, M_DEVBUF);
-#ifndef __FreeBSD__
- return (0);
-#endif
-}
-
-/*
- * Start output on the pflog interface.
- */
-void
-pflogstart(struct ifnet *ifp)
-{
- struct mbuf *m;
-#ifndef __FreeBSD__
- int s;
-#endif
-
- for (;;) {
-#ifdef __FreeBSD__
- IF_LOCK(&ifp->if_snd);
- _IF_DROP(&ifp->if_snd);
- _IF_DEQUEUE(&ifp->if_snd, m);
- IF_UNLOCK(&ifp->if_snd);
-#else
- s = splnet();
- IF_DROP(&ifp->if_snd);
- IF_DEQUEUE(&ifp->if_snd, m);
- splx(s);
-#endif
-
- if (m == NULL)
- return;
- else
- m_freem(m);
- }
-}
-
-int
-pflogoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
-#ifdef __FreeBSD__
- struct route *rt)
-#else
- struct rtentry *rt)
-#endif
-{
- m_freem(m);
- return (0);
-}
-
-/* ARGSUSED */
-int
-pflogioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
- switch (cmd) {
- case SIOCSIFFLAGS:
-#ifdef __FreeBSD__
- if (ifp->if_flags & IFF_UP)
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- else
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-#else
- if (ifp->if_flags & IFF_UP)
- ifp->if_flags |= IFF_RUNNING;
- else
- ifp->if_flags &= ~IFF_RUNNING;
-#endif
- break;
- default:
- return (ENOTTY);
- }
-
- return (0);
-}
-
-int
-pflog_packet(struct pfi_kif *kif, struct mbuf *m, sa_family_t af, u_int8_t dir,
- u_int8_t reason, struct pf_rule *rm, struct pf_rule *am,
- struct pf_ruleset *ruleset, struct pf_pdesc *pd)
-{
-#if NBPFILTER > 0
- struct ifnet *ifn;
- struct pfloghdr hdr;
-
- if (kif == NULL || m == NULL || rm == NULL || pd == NULL)
- return ( 1);
-
- if ((ifn = pflogifs[rm->logif]) == NULL || !ifn->if_bpf)
- return (0);
-
- bzero(&hdr, sizeof(hdr));
- hdr.length = PFLOG_REAL_HDRLEN;
- hdr.af = af;
- hdr.action = rm->action;
- hdr.reason = reason;
- memcpy(hdr.ifname, kif->pfik_name, sizeof(hdr.ifname));
-
- if (am == NULL) {
- hdr.rulenr = htonl(rm->nr);
- hdr.subrulenr = 1;
- } else {
- hdr.rulenr = htonl(am->nr);
- hdr.subrulenr = htonl(rm->nr);
- if (ruleset != NULL && ruleset->anchor != NULL)
- strlcpy(hdr.ruleset, ruleset->anchor->name,
- sizeof(hdr.ruleset));
- }
- if (rm->log & PF_LOG_SOCKET_LOOKUP && !pd->lookup.done)
-#ifdef __FreeBSD__
- /*
- * XXX: This should not happen as we force an early lookup
- * via debug.pfugidhack
- */
- ; /* empty */
-#else
- pd->lookup.done = pf_socket_lookup(dir, pd);
-#endif
- if (pd->lookup.done > 0) {
- hdr.uid = pd->lookup.uid;
- hdr.pid = pd->lookup.pid;
- } else {
- hdr.uid = UID_MAX;
- hdr.pid = NO_PID;
- }
- hdr.rule_uid = rm->cuid;
- hdr.rule_pid = rm->cpid;
- hdr.dir = dir;
-
-#ifdef INET
- if (af == AF_INET && dir == PF_OUT) {
- struct ip *ip;
-
- ip = mtod(m, struct ip *);
- ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
- }
-#endif /* INET */
-
- ifn->if_opackets++;
- ifn->if_obytes += m->m_pkthdr.len;
-#ifdef __FreeBSD__
- BPF_MTAP2(ifn, &hdr, PFLOG_HDRLEN, m);
-#else
- bpf_mtap_hdr(ifn->if_bpf, (char *)&hdr, PFLOG_HDRLEN, m,
- BPF_DIRECTION_OUT);
-#endif
-#endif
-
- return (0);
-}
-
-#ifdef __FreeBSD__
-static int
-pflog_modevent(module_t mod, int type, void *data)
-{
- int error = 0;
-
- switch (type) {
- case MOD_LOAD:
- pflogattach(1);
- PF_LOCK();
- pflog_packet_ptr = pflog_packet;
- PF_UNLOCK();
- break;
- case MOD_UNLOAD:
- PF_LOCK();
- pflog_packet_ptr = NULL;
- PF_UNLOCK();
- if_clone_detach(&pflog_cloner);
- break;
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-static moduledata_t pflog_mod = { "pflog", pflog_modevent, 0 };
-
-#define PFLOG_MODVER 1
-
-DECLARE_MODULE(pflog, pflog_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
-MODULE_VERSION(pflog, PFLOG_MODVER);
-MODULE_DEPEND(pflog, pf, PF_MODVER, PF_MODVER, PF_MODVER);
-#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/if_pflog.h b/sys/contrib/pf/net/if_pflog.h
deleted file mode 100644
index 5f48f6c..0000000
--- a/sys/contrib/pf/net/if_pflog.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* $OpenBSD: if_pflog.h,v 1.13 2006/10/23 12:46:09 henning Exp $ */
-/*
- * Copyright 2001 Niels Provos <provos@citi.umich.edu>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
- */
-
-#ifndef _NET_IF_PFLOG_H_
-#define _NET_IF_PFLOG_H_
-
-#define PFLOGIFS_MAX 16
-
-struct pflog_softc {
-#ifdef __FreeBSD__
- struct ifnet *sc_ifp; /* the interface pointer */
-#else
- struct ifnet sc_if; /* the interface */
-#endif
- int sc_unit;
- LIST_ENTRY(pflog_softc) sc_list;
-};
-
-#define PFLOG_RULESET_NAME_SIZE 16
-
-struct pfloghdr {
- u_int8_t length;
- sa_family_t af;
- u_int8_t action;
- u_int8_t reason;
- char ifname[IFNAMSIZ];
- char ruleset[PFLOG_RULESET_NAME_SIZE];
- u_int32_t rulenr;
- u_int32_t subrulenr;
- uid_t uid;
- pid_t pid;
- uid_t rule_uid;
- pid_t rule_pid;
- u_int8_t dir;
- u_int8_t pad[3];
-};
-
-#define PFLOG_HDRLEN sizeof(struct pfloghdr)
-/* minus pad, also used as a signature */
-#define PFLOG_REAL_HDRLEN offsetof(struct pfloghdr, pad)
-
-/* XXX remove later when old format logs are no longer needed */
-struct old_pfloghdr {
- u_int32_t af;
- char ifname[IFNAMSIZ];
- short rnr;
- u_short reason;
- u_short action;
- u_short dir;
-};
-#define OLD_PFLOG_HDRLEN sizeof(struct old_pfloghdr)
-
-#ifdef _KERNEL
-#ifdef __FreeBSD__
-struct pf_rule;
-struct pf_ruleset;
-struct pfi_kif;
-struct pf_pdesc;
-
-#if 0
-typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
- u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
- struct pf_ruleset *, struct pf_pdesc *);
-extern pflog_packet_t *pflog_packet_ptr;
-#endif
-#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) do { \
- if (pflog_packet_ptr != NULL) \
- pflog_packet_ptr(i,a,b,c,d,e,f,g,h); \
-} while (0)
-#else /* ! __FreeBSD__ */
-#if NPFLOG > 0
-#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) pflog_packet(i,a,b,c,d,e,f,g,h)
-#else
-#define PFLOG_PACKET(i,x,a,b,c,d,e,f,g,h) ((void)0)
-#endif /* NPFLOG > 0 */
-#endif
-#endif /* _KERNEL */
-#endif /* _NET_IF_PFLOG_H_ */
diff --git a/sys/contrib/pf/net/if_pflow.h b/sys/contrib/pf/net/if_pflow.h
deleted file mode 100644
index 35ccbeb..0000000
--- a/sys/contrib/pf/net/if_pflow.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/* $OpenBSD: if_pflow.h,v 1.5 2009/02/27 11:09:36 gollo Exp $ */
-
-/*
- * Copyright (c) 2008 Henning Brauer <henning@openbsd.org>
- * Copyright (c) 2008 Joerg Goltermann <jg@osn.de>
- *
- * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _NET_IF_PFLOW_H_
-#define _NET_IF_PFLOW_H_
-
-#define PFLOW_ID_LEN sizeof(u_int64_t)
-
-#define PFLOW_MAXFLOWS 30
-#define PFLOW_VERSION 5
-#define PFLOW_ENGINE_TYPE 42
-#define PFLOW_ENGINE_ID 42
-#define PFLOW_MAXBYTES 0xffffffff
-#define PFLOW_TIMEOUT 30
-
-struct pflow_flow {
- u_int32_t src_ip;
- u_int32_t dest_ip;
- u_int32_t nexthop_ip;
- u_int16_t if_index_in;
- u_int16_t if_index_out;
- u_int32_t flow_packets;
- u_int32_t flow_octets;
- u_int32_t flow_start;
- u_int32_t flow_finish;
- u_int16_t src_port;
- u_int16_t dest_port;
- u_int8_t pad1;
- u_int8_t tcp_flags;
- u_int8_t protocol;
- u_int8_t tos;
- u_int16_t src_as;
- u_int16_t dest_as;
- u_int8_t src_mask;
- u_int8_t dest_mask;
- u_int16_t pad2;
-} __packed;
-
-#ifdef _KERNEL
-
-extern int pflow_ok;
-
-struct pflow_softc {
- struct ifnet sc_if;
- struct ifnet *sc_pflow_ifp;
-
- unsigned int sc_count;
- unsigned int sc_maxcount;
- u_int64_t sc_gcounter;
- struct ip_moptions sc_imo;
-#ifdef __FreeBSD__
- struct callout sc_tmo;
-#else
- struct timeout sc_tmo;
-#endif
- struct in_addr sc_sender_ip;
- u_int16_t sc_sender_port;
- struct in_addr sc_receiver_ip;
- u_int16_t sc_receiver_port;
- struct mbuf *sc_mbuf; /* current cumulative mbuf */
- SLIST_ENTRY(pflow_softc) sc_next;
-};
-
-extern struct pflow_softc *pflowif;
-
-#endif /* _KERNEL */
-
-struct pflow_header {
- u_int16_t version;
- u_int16_t count;
- u_int32_t uptime_ms;
- u_int32_t time_sec;
- u_int32_t time_nanosec;
- u_int32_t flow_sequence;
- u_int8_t engine_type;
- u_int8_t engine_id;
- u_int8_t reserved1;
- u_int8_t reserved2;
-} __packed;
-
-#define PFLOW_HDRLEN sizeof(struct pflow_header)
-
-struct pflowstats {
- u_int64_t pflow_flows;
- u_int64_t pflow_packets;
- u_int64_t pflow_onomem;
- u_int64_t pflow_oerrors;
-};
-
-/*
- * Configuration structure for SIOCSETPFLOW SIOCGETPFLOW
- */
-struct pflowreq {
- struct in_addr sender_ip;
- struct in_addr receiver_ip;
- u_int16_t receiver_port;
- u_int16_t addrmask;
-#define PFLOW_MASK_SRCIP 0x01
-#define PFLOW_MASK_DSTIP 0x02
-#define PFLOW_MASK_DSTPRT 0x04
-};
-
-#ifdef _KERNEL
-int export_pflow(struct pf_state *);
-int pflow_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-#endif /* _KERNEL */
-
-#endif /* _NET_IF_PFLOW_H_ */
diff --git a/sys/contrib/pf/net/if_pfsync.c b/sys/contrib/pf/net/if_pfsync.c
deleted file mode 100644
index 7da6c2e..0000000
--- a/sys/contrib/pf/net/if_pfsync.c
+++ /dev/null
@@ -1,3474 +0,0 @@
-/* $OpenBSD: if_pfsync.c,v 1.110 2009/02/24 05:39:19 dlg Exp $ */
-
-/*
- * Copyright (c) 2002 Michael Shalayeff
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 HIS RELATIVES 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 MIND, 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.
- */
-
-/*
- * Copyright (c) 2009 David Gwynne <dlg@openbsd.org>
- *
- * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
- */
-
-/*
- * Revisions picked from OpenBSD after revision 1.110 import:
- * 1.118, 1.124, 1.148, 1.149, 1.151, 1.171 - fixes to bulk updates
- * 1.120, 1.175 - use monotonic time_uptime
- * 1.122 - reduce number of updates for non-TCP sessions
- * 1.128 - cleanups
- * 1.146 - bzero() mbuf before sparsely filling it with data
- * 1.170 - SIOCSIFMTU checks
- * 1.126, 1.142 - deferred packets processing
- * 1.173 - correct expire time processing
- */
-
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_pf.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define NBPFILTER 1
-#endif /* __FreeBSD__ */
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#ifdef __FreeBSD__
-#include <sys/bus.h>
-#include <sys/interrupt.h>
-#include <sys/priv.h>
-#endif
-#include <sys/proc.h>
-#include <sys/systm.h>
-#include <sys/time.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#ifdef __FreeBSD__
-#include <sys/endian.h>
-#include <sys/malloc.h>
-#include <sys/module.h>
-#include <sys/sockio.h>
-#include <sys/taskqueue.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <sys/protosw.h>
-#else
-#include <sys/ioctl.h>
-#include <sys/timeout.h>
-#endif
-#include <sys/sysctl.h>
-#ifndef __FreeBSD__
-#include <sys/pool.h>
-#endif
-
-#include <net/if.h>
-#ifdef __FreeBSD__
-#include <net/if_clone.h>
-#endif
-#include <net/if_types.h>
-#include <net/route.h>
-#include <net/bpf.h>
-#include <net/netisr.h>
-#ifdef __FreeBSD__
-#include <net/vnet.h>
-#endif
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <netinet/tcp.h>
-#include <netinet/tcp_seq.h>
-
-#ifdef INET
-#include <netinet/in_systm.h>
-#include <netinet/in_var.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#endif
-
-#ifdef INET6
-#include <netinet6/nd6.h>
-#endif /* INET6 */
-
-#ifdef __FreeBSD__
-#include <netinet/ip_carp.h>
-#else
-#include "carp.h"
-#if NCARP > 0
-#include <netinet/ip_carp.h>
-#endif
-#endif
-
-#include <net/pfvar.h>
-#include <net/if_pfsync.h>
-
-#ifndef __FreeBSD__
-#include "bpfilter.h"
-#include "pfsync.h"
-#endif
-
-#define PFSYNC_MINPKT ( \
- sizeof(struct ip) + \
- sizeof(struct pfsync_header) + \
- sizeof(struct pfsync_subheader) + \
- sizeof(struct pfsync_eof))
-
-struct pfsync_pkt {
- struct ip *ip;
- struct in_addr src;
- u_int8_t flags;
-};
-
-int pfsync_input_hmac(struct mbuf *, int);
-
-int pfsync_upd_tcp(struct pf_state *, struct pfsync_state_peer *,
- struct pfsync_state_peer *);
-
-int pfsync_in_clr(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_ins(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_iack(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_upd(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_upd_c(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_ureq(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_del(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_del_c(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_bus(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_tdb(struct pfsync_pkt *, struct mbuf *, int, int);
-int pfsync_in_eof(struct pfsync_pkt *, struct mbuf *, int, int);
-
-int pfsync_in_error(struct pfsync_pkt *, struct mbuf *, int, int);
-
-int (*pfsync_acts[])(struct pfsync_pkt *, struct mbuf *, int, int) = {
- pfsync_in_clr, /* PFSYNC_ACT_CLR */
- pfsync_in_ins, /* PFSYNC_ACT_INS */
- pfsync_in_iack, /* PFSYNC_ACT_INS_ACK */
- pfsync_in_upd, /* PFSYNC_ACT_UPD */
- pfsync_in_upd_c, /* PFSYNC_ACT_UPD_C */
- pfsync_in_ureq, /* PFSYNC_ACT_UPD_REQ */
- pfsync_in_del, /* PFSYNC_ACT_DEL */
- pfsync_in_del_c, /* PFSYNC_ACT_DEL_C */
- pfsync_in_error, /* PFSYNC_ACT_INS_F */
- pfsync_in_error, /* PFSYNC_ACT_DEL_F */
- pfsync_in_bus, /* PFSYNC_ACT_BUS */
- pfsync_in_tdb, /* PFSYNC_ACT_TDB */
- pfsync_in_eof /* PFSYNC_ACT_EOF */
-};
-
-struct pfsync_q {
- int (*write)(struct pf_state *, struct mbuf *, int);
- size_t len;
- u_int8_t action;
-};
-
-/* we have one of these for every PFSYNC_S_ */
-int pfsync_out_state(struct pf_state *, struct mbuf *, int);
-int pfsync_out_iack(struct pf_state *, struct mbuf *, int);
-int pfsync_out_upd_c(struct pf_state *, struct mbuf *, int);
-int pfsync_out_del(struct pf_state *, struct mbuf *, int);
-
-struct pfsync_q pfsync_qs[] = {
- { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_INS },
- { pfsync_out_iack, sizeof(struct pfsync_ins_ack), PFSYNC_ACT_INS_ACK },
- { pfsync_out_state, sizeof(struct pfsync_state), PFSYNC_ACT_UPD },
- { pfsync_out_upd_c, sizeof(struct pfsync_upd_c), PFSYNC_ACT_UPD_C },
- { pfsync_out_del, sizeof(struct pfsync_del_c), PFSYNC_ACT_DEL_C }
-};
-
-void pfsync_q_ins(struct pf_state *, int);
-void pfsync_q_del(struct pf_state *);
-
-struct pfsync_upd_req_item {
- TAILQ_ENTRY(pfsync_upd_req_item) ur_entry;
- struct pfsync_upd_req ur_msg;
-};
-TAILQ_HEAD(pfsync_upd_reqs, pfsync_upd_req_item);
-
-struct pfsync_deferral {
- TAILQ_ENTRY(pfsync_deferral) pd_entry;
- struct pf_state *pd_st;
- struct mbuf *pd_m;
-#ifdef __FreeBSD__
- struct callout pd_tmo;
-#else
- struct timeout pd_tmo;
-#endif
-};
-TAILQ_HEAD(pfsync_deferrals, pfsync_deferral);
-
-#define PFSYNC_PLSIZE MAX(sizeof(struct pfsync_upd_req_item), \
- sizeof(struct pfsync_deferral))
-
-#ifdef notyet
-int pfsync_out_tdb(struct tdb *, struct mbuf *, int);
-#endif
-
-struct pfsync_softc {
-#ifdef __FreeBSD__
- struct ifnet *sc_ifp;
-#else
- struct ifnet sc_if;
-#endif
- struct ifnet *sc_sync_if;
-
-#ifdef __FreeBSD__
- uma_zone_t sc_pool;
-#else
- struct pool sc_pool;
-#endif
-
- struct ip_moptions sc_imo;
-
- struct in_addr sc_sync_peer;
- u_int8_t sc_maxupdates;
-#ifdef __FreeBSD__
- int pfsync_sync_ok;
-#endif
-
- struct ip sc_template;
-
- struct pf_state_queue sc_qs[PFSYNC_S_COUNT];
- size_t sc_len;
-
- struct pfsync_upd_reqs sc_upd_req_list;
-
- int sc_defer;
- struct pfsync_deferrals sc_deferrals;
- u_int sc_deferred;
-
- void *sc_plus;
- size_t sc_pluslen;
-
- u_int32_t sc_ureq_sent;
- int sc_bulk_tries;
-#ifdef __FreeBSD__
- struct callout sc_bulkfail_tmo;
-#else
- struct timeout sc_bulkfail_tmo;
-#endif
-
- u_int32_t sc_ureq_received;
- struct pf_state *sc_bulk_next;
- struct pf_state *sc_bulk_last;
-#ifdef __FreeBSD__
- struct callout sc_bulk_tmo;
-#else
- struct timeout sc_bulk_tmo;
-#endif
-
- TAILQ_HEAD(, tdb) sc_tdb_q;
-
-#ifdef __FreeBSD__
- struct callout sc_tmo;
-#else
- struct timeout sc_tmo;
-#endif
-};
-
-#ifdef __FreeBSD__
-static MALLOC_DEFINE(M_PFSYNC, "pfsync", "pfsync data");
-static VNET_DEFINE(struct pfsync_softc *, pfsyncif) = NULL;
-#define V_pfsyncif VNET(pfsyncif)
-static VNET_DEFINE(void *, pfsync_swi_cookie) = NULL;
-#define V_pfsync_swi_cookie VNET(pfsync_swi_cookie)
-static VNET_DEFINE(struct pfsyncstats, pfsyncstats);
-#define V_pfsyncstats VNET(pfsyncstats)
-static VNET_DEFINE(int, pfsync_carp_adj) = CARP_MAXSKEW;
-#define V_pfsync_carp_adj VNET(pfsync_carp_adj)
-
-static void pfsyncintr(void *);
-static int pfsync_multicast_setup(struct pfsync_softc *);
-static void pfsync_multicast_cleanup(struct pfsync_softc *);
-static int pfsync_init(void);
-static void pfsync_uninit(void);
-static void pfsync_sendout1(int);
-
-#define schednetisr(NETISR_PFSYNC) swi_sched(V_pfsync_swi_cookie, 0)
-
-SYSCTL_NODE(_net, OID_AUTO, pfsync, CTLFLAG_RW, 0, "PFSYNC");
-SYSCTL_VNET_STRUCT(_net_pfsync, OID_AUTO, stats, CTLFLAG_RW,
- &VNET_NAME(pfsyncstats), pfsyncstats,
- "PFSYNC statistics (struct pfsyncstats, net/if_pfsync.h)");
-SYSCTL_INT(_net_pfsync, OID_AUTO, carp_demotion_factor, CTLFLAG_RW,
- &VNET_NAME(pfsync_carp_adj), 0, "pfsync's CARP demotion factor adjustment");
-#else
-struct pfsync_softc *pfsyncif = NULL;
-struct pfsyncstats pfsyncstats;
-#define V_pfsyncstats pfsyncstats
-#endif
-
-void pfsyncattach(int);
-#ifdef __FreeBSD__
-int pfsync_clone_create(struct if_clone *, int, caddr_t);
-void pfsync_clone_destroy(struct ifnet *);
-#else
-int pfsync_clone_create(struct if_clone *, int);
-int pfsync_clone_destroy(struct ifnet *);
-#endif
-int pfsync_alloc_scrub_memory(struct pfsync_state_peer *,
- struct pf_state_peer *);
-void pfsync_update_net_tdb(struct pfsync_tdb *);
-int pfsyncoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
-#ifdef __FreeBSD__
- struct route *);
-#else
- struct rtentry *);
-#endif
-int pfsyncioctl(struct ifnet *, u_long, caddr_t);
-void pfsyncstart(struct ifnet *);
-
-struct mbuf *pfsync_if_dequeue(struct ifnet *);
-
-void pfsync_deferred(struct pf_state *, int);
-void pfsync_undefer(struct pfsync_deferral *, int);
-void pfsync_defer_tmo(void *);
-
-void pfsync_request_update(u_int32_t, u_int64_t);
-void pfsync_update_state_req(struct pf_state *);
-
-void pfsync_drop(struct pfsync_softc *);
-void pfsync_sendout(void);
-void pfsync_send_plus(void *, size_t);
-void pfsync_timeout(void *);
-void pfsync_tdb_timeout(void *);
-
-void pfsync_bulk_start(void);
-void pfsync_bulk_status(u_int8_t);
-void pfsync_bulk_update(void *);
-void pfsync_bulk_fail(void *);
-
-#ifdef __FreeBSD__
-/* XXX: ugly */
-#define betoh64 (unsigned long long)be64toh
-#define timeout_del callout_stop
-#endif
-
-#define PFSYNC_MAX_BULKTRIES 12
-#ifndef __FreeBSD__
-int pfsync_sync_ok;
-#endif
-
-#ifdef __FreeBSD__
-VNET_DEFINE(struct ifc_simple_data, pfsync_cloner_data);
-VNET_DEFINE(struct if_clone, pfsync_cloner);
-#define V_pfsync_cloner_data VNET(pfsync_cloner_data)
-#define V_pfsync_cloner VNET(pfsync_cloner)
-IFC_SIMPLE_DECLARE(pfsync, 1);
-#else
-struct if_clone pfsync_cloner =
- IF_CLONE_INITIALIZER("pfsync", pfsync_clone_create, pfsync_clone_destroy);
-#endif
-
-void
-pfsyncattach(int npfsync)
-{
- if_clone_attach(&pfsync_cloner);
-}
-int
-#ifdef __FreeBSD__
-pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
-#else
-pfsync_clone_create(struct if_clone *ifc, int unit)
-#endif
-{
- struct pfsync_softc *sc;
- struct ifnet *ifp;
- int q;
-
- if (unit != 0)
- return (EINVAL);
-
-#ifdef __FreeBSD__
- sc = malloc(sizeof(struct pfsync_softc), M_PFSYNC, M_WAITOK | M_ZERO);
- sc->pfsync_sync_ok = 1;
-#else
- pfsync_sync_ok = 1;
- sc = malloc(sizeof(*pfsyncif), M_DEVBUF, M_NOWAIT | M_ZERO);
-#endif
-
- for (q = 0; q < PFSYNC_S_COUNT; q++)
- TAILQ_INIT(&sc->sc_qs[q]);
-
-#ifdef __FreeBSD__
- sc->sc_pool = uma_zcreate("pfsync", PFSYNC_PLSIZE, NULL, NULL, NULL,
- NULL, UMA_ALIGN_PTR, 0);
-#else
- pool_init(&sc->sc_pool, PFSYNC_PLSIZE, 0, 0, 0, "pfsync", NULL);
-#endif
- TAILQ_INIT(&sc->sc_upd_req_list);
- TAILQ_INIT(&sc->sc_deferrals);
- sc->sc_deferred = 0;
-
- TAILQ_INIT(&sc->sc_tdb_q);
-
- sc->sc_len = PFSYNC_MINPKT;
- sc->sc_maxupdates = 128;
-
-#ifndef __FreeBSD__
- sc->sc_imo.imo_membership = (struct in_multi **)malloc(
- (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_IPMOPTS,
- M_WAITOK | M_ZERO);
- sc->sc_imo.imo_max_memberships = IP_MIN_MEMBERSHIPS;
-#endif
-
-#ifdef __FreeBSD__
- ifp = sc->sc_ifp = if_alloc(IFT_PFSYNC);
- if (ifp == NULL) {
- uma_zdestroy(sc->sc_pool);
- free(sc, M_PFSYNC);
- return (ENOSPC);
- }
- if_initname(ifp, ifc->ifc_name, unit);
-#else
- ifp = &sc->sc_if;
- snprintf(ifp->if_xname, sizeof ifp->if_xname, "pfsync%d", unit);
-#endif
- ifp->if_softc = sc;
- ifp->if_ioctl = pfsyncioctl;
- ifp->if_output = pfsyncoutput;
- ifp->if_start = pfsyncstart;
- ifp->if_type = IFT_PFSYNC;
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_hdrlen = sizeof(struct pfsync_header);
- ifp->if_mtu = ETHERMTU;
-#ifdef __FreeBSD__
- callout_init(&sc->sc_tmo, CALLOUT_MPSAFE);
- callout_init_mtx(&sc->sc_bulk_tmo, &pf_task_mtx, 0);
- callout_init(&sc->sc_bulkfail_tmo, CALLOUT_MPSAFE);
-#else
- timeout_set(&sc->sc_tmo, pfsync_timeout, sc);
- timeout_set(&sc->sc_bulk_tmo, pfsync_bulk_update, sc);
- timeout_set(&sc->sc_bulkfail_tmo, pfsync_bulk_fail, sc);
-#endif
-
- if_attach(ifp);
-#ifndef __FreeBSD__
- if_alloc_sadl(ifp);
-
-#if NCARP > 0
- if_addgroup(ifp, "carp");
-#endif
-#endif
-
-#if NBPFILTER > 0
-#ifdef __FreeBSD__
- bpfattach(ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
-#else
- bpfattach(&sc->sc_if.if_bpf, ifp, DLT_PFSYNC, PFSYNC_HDRLEN);
-#endif
-#endif
-
-#ifdef __FreeBSD__
- V_pfsyncif = sc;
-#else
- pfsyncif = sc;
-#endif
-
- return (0);
-}
-
-#ifdef __FreeBSD__
-void
-#else
-int
-#endif
-pfsync_clone_destroy(struct ifnet *ifp)
-{
- struct pfsync_softc *sc = ifp->if_softc;
-
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- timeout_del(&sc->sc_bulkfail_tmo);
- timeout_del(&sc->sc_bulk_tmo);
- timeout_del(&sc->sc_tmo);
-#ifdef __FreeBSD__
- PF_UNLOCK();
- if (!sc->pfsync_sync_ok && carp_demote_adj_p)
- (*carp_demote_adj_p)(-V_pfsync_carp_adj, "pfsync destroy");
-#else
-#if NCARP > 0
- if (!pfsync_sync_ok)
- carp_group_demote_adj(&sc->sc_if, -1);
-#endif
-#endif
-#if NBPFILTER > 0
- bpfdetach(ifp);
-#endif
- if_detach(ifp);
-
- pfsync_drop(sc);
-
- while (sc->sc_deferred > 0)
- pfsync_undefer(TAILQ_FIRST(&sc->sc_deferrals), 0);
-
-#ifdef __FreeBSD__
- UMA_DESTROY(sc->sc_pool);
-#else
- pool_destroy(&sc->sc_pool);
-#endif
-#ifdef __FreeBSD__
- if_free(ifp);
- if (sc->sc_imo.imo_membership)
- pfsync_multicast_cleanup(sc);
- free(sc, M_PFSYNC);
-#else
- free(sc->sc_imo.imo_membership, M_IPMOPTS);
- free(sc, M_DEVBUF);
-#endif
-
-#ifdef __FreeBSD__
- V_pfsyncif = NULL;
-#else
- pfsyncif = NULL;
-#endif
-
-#ifndef __FreeBSD__
- return (0);
-#endif
-}
-
-struct mbuf *
-pfsync_if_dequeue(struct ifnet *ifp)
-{
- struct mbuf *m;
-#ifndef __FreeBSD__
- int s;
-#endif
-
-#ifdef __FreeBSD__
- IF_LOCK(&ifp->if_snd);
- _IF_DROP(&ifp->if_snd);
- _IF_DEQUEUE(&ifp->if_snd, m);
- IF_UNLOCK(&ifp->if_snd);
-#else
- s = splnet();
- IF_DEQUEUE(&ifp->if_snd, m);
- splx(s);
-#endif
-
- return (m);
-}
-
-/*
- * Start output on the pfsync interface.
- */
-void
-pfsyncstart(struct ifnet *ifp)
-{
- struct mbuf *m;
-
- while ((m = pfsync_if_dequeue(ifp)) != NULL) {
-#ifndef __FreeBSD__
- IF_DROP(&ifp->if_snd);
-#endif
- m_freem(m);
- }
-}
-
-int
-pfsync_alloc_scrub_memory(struct pfsync_state_peer *s,
- struct pf_state_peer *d)
-{
- if (s->scrub.scrub_flag && d->scrub == NULL) {
-#ifdef __FreeBSD__
- d->scrub = pool_get(&V_pf_state_scrub_pl, PR_NOWAIT | PR_ZERO);
-#else
- d->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT | PR_ZERO);
-#endif
- if (d->scrub == NULL)
- return (ENOMEM);
- }
-
- return (0);
-}
-
-#ifndef __FreeBSD__
-void
-pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
-{
- bzero(sp, sizeof(struct pfsync_state));
-
- /* copy from state key */
- sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
- sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
- sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
- sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
- sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
- sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
- sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
- sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
- sp->proto = st->key[PF_SK_WIRE]->proto;
- sp->af = st->key[PF_SK_WIRE]->af;
-
- /* copy from state */
- strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
- bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
- sp->creation = htonl(time_uptime - st->creation);
- sp->expire = pf_state_expires(st);
- if (sp->expire <= time_second)
- sp->expire = htonl(0);
- else
- sp->expire = htonl(sp->expire - time_second);
-
- sp->direction = st->direction;
- sp->log = st->log;
- sp->timeout = st->timeout;
- sp->state_flags = st->state_flags;
- if (st->src_node)
- sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
- if (st->nat_src_node)
- sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
-
- bcopy(&st->id, &sp->id, sizeof(sp->id));
- sp->creatorid = st->creatorid;
- pf_state_peer_hton(&st->src, &sp->src);
- pf_state_peer_hton(&st->dst, &sp->dst);
-
- if (st->rule.ptr == NULL)
- sp->rule = htonl(-1);
- else
- sp->rule = htonl(st->rule.ptr->nr);
- if (st->anchor.ptr == NULL)
- sp->anchor = htonl(-1);
- else
- sp->anchor = htonl(st->anchor.ptr->nr);
- if (st->nat_rule.ptr == NULL)
- sp->nat_rule = htonl(-1);
- else
- sp->nat_rule = htonl(st->nat_rule.ptr->nr);
-
- pf_state_counter_hton(st->packets[0], sp->packets[0]);
- pf_state_counter_hton(st->packets[1], sp->packets[1]);
- pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
- pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
-
-}
-#endif
-
-int
-pfsync_state_import(struct pfsync_state *sp, u_int8_t flags)
-{
- struct pf_state *st = NULL;
- struct pf_state_key *skw = NULL, *sks = NULL;
- struct pf_rule *r = NULL;
- struct pfi_kif *kif;
- int pool_flags;
- int error;
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-
- if (sp->creatorid == 0 && V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (sp->creatorid == 0 && pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pfsync_state_import: invalid creator id:"
- " %08x\n", ntohl(sp->creatorid));
- return (EINVAL);
- }
-
- if ((kif = pfi_kif_get(sp->ifname)) == NULL) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync_state_import: "
- "unknown interface: %s\n", sp->ifname);
- if (flags & PFSYNC_SI_IOCTL)
- return (EINVAL);
- return (0); /* skip this state */
- }
-
- /*
- * If the ruleset checksums match or the state is coming from the ioctl,
- * it's safe to associate the state with the rule of that number.
- */
- if (sp->rule != htonl(-1) && sp->anchor == htonl(-1) &&
- (flags & (PFSYNC_SI_IOCTL | PFSYNC_SI_CKSUM)) && ntohl(sp->rule) <
- pf_main_ruleset.rules[PF_RULESET_FILTER].active.rcount)
- r = pf_main_ruleset.rules[
- PF_RULESET_FILTER].active.ptr_array[ntohl(sp->rule)];
- else
-#ifdef __FreeBSD__
- r = &V_pf_default_rule;
-#else
- r = &pf_default_rule;
-#endif
-
- if ((r->max_states && r->states_cur >= r->max_states))
- goto cleanup;
-
-#ifdef __FreeBSD__
- if (flags & PFSYNC_SI_IOCTL)
- pool_flags = PR_WAITOK | PR_ZERO;
- else
- pool_flags = PR_NOWAIT | PR_ZERO;
-
- if ((st = pool_get(&V_pf_state_pl, pool_flags)) == NULL)
- goto cleanup;
-#else
- if (flags & PFSYNC_SI_IOCTL)
- pool_flags = PR_WAITOK | PR_LIMITFAIL | PR_ZERO;
- else
- pool_flags = PR_LIMITFAIL | PR_ZERO;
-
- if ((st = pool_get(&pf_state_pl, pool_flags)) == NULL)
- goto cleanup;
-#endif
-
- if ((skw = pf_alloc_state_key(pool_flags)) == NULL)
- goto cleanup;
-
- if (PF_ANEQ(&sp->key[PF_SK_WIRE].addr[0],
- &sp->key[PF_SK_STACK].addr[0], sp->af) ||
- PF_ANEQ(&sp->key[PF_SK_WIRE].addr[1],
- &sp->key[PF_SK_STACK].addr[1], sp->af) ||
- sp->key[PF_SK_WIRE].port[0] != sp->key[PF_SK_STACK].port[0] ||
- sp->key[PF_SK_WIRE].port[1] != sp->key[PF_SK_STACK].port[1]) {
- if ((sks = pf_alloc_state_key(pool_flags)) == NULL)
- goto cleanup;
- } else
- sks = skw;
-
- /* allocate memory for scrub info */
- if (pfsync_alloc_scrub_memory(&sp->src, &st->src) ||
- pfsync_alloc_scrub_memory(&sp->dst, &st->dst))
- goto cleanup;
-
- /* copy to state key(s) */
- skw->addr[0] = sp->key[PF_SK_WIRE].addr[0];
- skw->addr[1] = sp->key[PF_SK_WIRE].addr[1];
- skw->port[0] = sp->key[PF_SK_WIRE].port[0];
- skw->port[1] = sp->key[PF_SK_WIRE].port[1];
- skw->proto = sp->proto;
- skw->af = sp->af;
- if (sks != skw) {
- sks->addr[0] = sp->key[PF_SK_STACK].addr[0];
- sks->addr[1] = sp->key[PF_SK_STACK].addr[1];
- sks->port[0] = sp->key[PF_SK_STACK].port[0];
- sks->port[1] = sp->key[PF_SK_STACK].port[1];
- sks->proto = sp->proto;
- sks->af = sp->af;
- }
-
- /* copy to state */
- bcopy(&sp->rt_addr, &st->rt_addr, sizeof(st->rt_addr));
- st->creation = time_uptime - ntohl(sp->creation);
- st->expire = time_second;
- if (sp->expire) {
- uint32_t timeout;
-
- timeout = r->timeout[sp->timeout];
- if (!timeout)
-#ifdef __FreeBSD__
- timeout = V_pf_default_rule.timeout[sp->timeout];
-#else
- timeout = pf_default_rule.timeout[sp->timeout];
-#endif
-
- /* sp->expire may have been adaptively scaled by export. */
- st->expire -= timeout - ntohl(sp->expire);
- }
-
- st->direction = sp->direction;
- st->log = sp->log;
- st->timeout = sp->timeout;
- st->state_flags = sp->state_flags;
-
- bcopy(sp->id, &st->id, sizeof(st->id));
- st->creatorid = sp->creatorid;
- pf_state_peer_ntoh(&sp->src, &st->src);
- pf_state_peer_ntoh(&sp->dst, &st->dst);
-
- st->rule.ptr = r;
- st->nat_rule.ptr = NULL;
- st->anchor.ptr = NULL;
- st->rt_kif = NULL;
-
- st->pfsync_time = time_uptime;
- st->sync_state = PFSYNC_S_NONE;
-
- /* XXX when we have nat_rule/anchors, use STATE_INC_COUNTERS */
- r->states_cur++;
- r->states_tot++;
-
- if (!ISSET(flags, PFSYNC_SI_IOCTL))
- SET(st->state_flags, PFSTATE_NOSYNC);
-
- if ((error = pf_state_insert(kif, skw, sks, st)) != 0) {
- /* XXX when we have nat_rule/anchors, use STATE_DEC_COUNTERS */
- r->states_cur--;
- goto cleanup_state;
- }
-
- if (!ISSET(flags, PFSYNC_SI_IOCTL)) {
- CLR(st->state_flags, PFSTATE_NOSYNC);
- if (ISSET(st->state_flags, PFSTATE_ACK)) {
- pfsync_q_ins(st, PFSYNC_S_IACK);
- schednetisr(NETISR_PFSYNC);
- }
- }
- CLR(st->state_flags, PFSTATE_ACK);
-
- return (0);
-
-cleanup:
- error = ENOMEM;
- if (skw == sks)
- sks = NULL;
-#ifdef __FreeBSD__
- if (skw != NULL)
- pool_put(&V_pf_state_key_pl, skw);
- if (sks != NULL)
- pool_put(&V_pf_state_key_pl, sks);
-#else
- if (skw != NULL)
- pool_put(&pf_state_key_pl, skw);
- if (sks != NULL)
- pool_put(&pf_state_key_pl, sks);
-#endif
-
-cleanup_state: /* pf_state_insert frees the state keys */
- if (st) {
-#ifdef __FreeBSD__
- if (st->dst.scrub)
- pool_put(&V_pf_state_scrub_pl, st->dst.scrub);
- if (st->src.scrub)
- pool_put(&V_pf_state_scrub_pl, st->src.scrub);
- pool_put(&V_pf_state_pl, st);
-#else
- if (st->dst.scrub)
- pool_put(&pf_state_scrub_pl, st->dst.scrub);
- if (st->src.scrub)
- pool_put(&pf_state_scrub_pl, st->src.scrub);
- pool_put(&pf_state_pl, st);
-#endif
- }
- return (error);
-}
-
-void
-#ifdef __FreeBSD__
-pfsync_input(struct mbuf *m, __unused int off)
-#else
-pfsync_input(struct mbuf *m, ...)
-#endif
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- struct pfsync_pkt pkt;
- struct ip *ip = mtod(m, struct ip *);
- struct pfsync_header *ph;
- struct pfsync_subheader subh;
-
- int offset;
- int rv;
-
- V_pfsyncstats.pfsyncs_ipackets++;
-
- /* verify that we have a sync interface configured */
-#ifdef __FreeBSD__
- if (!sc || !sc->sc_sync_if || !V_pf_status.running)
-#else
- if (!sc || !sc->sc_sync_if || !pf_status.running)
-#endif
- goto done;
-
- /* verify that the packet came in on the right interface */
- if (sc->sc_sync_if != m->m_pkthdr.rcvif) {
- V_pfsyncstats.pfsyncs_badif++;
- goto done;
- }
-
-#ifdef __FreeBSD__
- sc->sc_ifp->if_ipackets++;
- sc->sc_ifp->if_ibytes += m->m_pkthdr.len;
-#else
- sc->sc_if.if_ipackets++;
- sc->sc_if.if_ibytes += m->m_pkthdr.len;
-#endif
- /* verify that the IP TTL is 255. */
- if (ip->ip_ttl != PFSYNC_DFLTTL) {
- V_pfsyncstats.pfsyncs_badttl++;
- goto done;
- }
-
- offset = ip->ip_hl << 2;
- if (m->m_pkthdr.len < offset + sizeof(*ph)) {
- V_pfsyncstats.pfsyncs_hdrops++;
- goto done;
- }
-
- if (offset + sizeof(*ph) > m->m_len) {
- if (m_pullup(m, offset + sizeof(*ph)) == NULL) {
- V_pfsyncstats.pfsyncs_hdrops++;
- return;
- }
- ip = mtod(m, struct ip *);
- }
- ph = (struct pfsync_header *)((char *)ip + offset);
-
- /* verify the version */
- if (ph->version != PFSYNC_VERSION) {
- V_pfsyncstats.pfsyncs_badver++;
- goto done;
- }
-
-#if 0
- if (pfsync_input_hmac(m, offset) != 0) {
- /* XXX stats */
- goto done;
- }
-#endif
-
- /* Cheaper to grab this now than having to mess with mbufs later */
- pkt.ip = ip;
- pkt.src = ip->ip_src;
- pkt.flags = 0;
-
-#ifdef __FreeBSD__
- if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
-#else
- if (!bcmp(&ph->pfcksum, &pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
-#endif
- pkt.flags |= PFSYNC_SI_CKSUM;
-
- offset += sizeof(*ph);
- for (;;) {
- m_copydata(m, offset, sizeof(subh), (caddr_t)&subh);
- offset += sizeof(subh);
-
- if (subh.action >= PFSYNC_ACT_MAX) {
- V_pfsyncstats.pfsyncs_badact++;
- goto done;
- }
-
- rv = (*pfsync_acts[subh.action])(&pkt, m, offset,
- ntohs(subh.count));
- if (rv == -1)
- return;
-
- offset += rv;
- }
-
-done:
- m_freem(m);
-}
-
-int
-pfsync_in_clr(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct pfsync_clr *clr;
- struct mbuf *mp;
- int len = sizeof(*clr) * count;
- int i, offp;
-
- struct pf_state *st, *nexts;
- struct pf_state_key *sk, *nextsk;
- struct pf_state_item *si;
- u_int32_t creatorid;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- clr = (struct pfsync_clr *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- creatorid = clr[i].creatorid;
-
- if (clr[i].ifname[0] == '\0') {
-#ifdef __FreeBSD__
- for (st = RB_MIN(pf_state_tree_id, &V_tree_id);
- st; st = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, st);
-#else
- for (st = RB_MIN(pf_state_tree_id, &tree_id);
- st; st = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &tree_id, st);
-#endif
- if (st->creatorid == creatorid) {
- SET(st->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(st);
- }
- }
- } else {
- if (pfi_kif_get(clr[i].ifname) == NULL)
- continue;
-
- /* XXX correct? */
-#ifdef __FreeBSD__
- for (sk = RB_MIN(pf_state_tree, &V_pf_statetbl);
-#else
- for (sk = RB_MIN(pf_state_tree, &pf_statetbl);
-#endif
- sk; sk = nextsk) {
- nextsk = RB_NEXT(pf_state_tree,
-#ifdef __FreeBSD__
- &V_pf_statetbl, sk);
-#else
- &pf_statetbl, sk);
-#endif
- TAILQ_FOREACH(si, &sk->states, entry) {
- if (si->s->creatorid == creatorid) {
- SET(si->s->state_flags,
- PFSTATE_NOSYNC);
- pf_unlink_state(si->s);
- }
- }
- }
- }
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (len);
-}
-
-int
-pfsync_in_ins(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct mbuf *mp;
- struct pfsync_state *sa, *sp;
- int len = sizeof(*sp) * count;
- int i, offp;
-
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- sa = (struct pfsync_state *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- sp = &sa[i];
-
- /* check for invalid values */
- if (sp->timeout >= PFTM_MAX ||
- sp->src.state > PF_TCPS_PROXY_DST ||
- sp->dst.state > PF_TCPS_PROXY_DST ||
- sp->direction > PF_OUT ||
- (sp->af != AF_INET && sp->af != AF_INET6)) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pfsync_input: PFSYNC5_ACT_INS: "
- "invalid value\n");
- }
- V_pfsyncstats.pfsyncs_badval++;
- continue;
- }
-
- if (pfsync_state_import(sp, pkt->flags) == ENOMEM) {
- /* drop out, but process the rest of the actions */
- break;
- }
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (len);
-}
-
-int
-pfsync_in_iack(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct pfsync_ins_ack *ia, *iaa;
- struct pf_state_cmp id_key;
- struct pf_state *st;
-
- struct mbuf *mp;
- int len = count * sizeof(*ia);
- int offp, i;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- iaa = (struct pfsync_ins_ack *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- ia = &iaa[i];
-
- bcopy(&ia->id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = ia->creatorid;
-
- st = pf_find_state_byid(&id_key);
- if (st == NULL)
- continue;
-
- if (ISSET(st->state_flags, PFSTATE_ACK))
- pfsync_deferred(st, 0);
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
- /*
- * XXX this is not yet implemented, but we know the size of the
- * message so we can skip it.
- */
-
- return (count * sizeof(struct pfsync_ins_ack));
-}
-
-int
-pfsync_upd_tcp(struct pf_state *st, struct pfsync_state_peer *src,
- struct pfsync_state_peer *dst)
-{
- int sfail = 0;
-
- /*
- * The state should never go backwards except
- * for syn-proxy states. Neither should the
- * sequence window slide backwards.
- */
- if (st->src.state > src->state &&
- (st->src.state < PF_TCPS_PROXY_SRC ||
- src->state >= PF_TCPS_PROXY_SRC))
- sfail = 1;
- else if (SEQ_GT(st->src.seqlo, ntohl(src->seqlo)))
- sfail = 3;
- else if (st->dst.state > dst->state) {
- /* There might still be useful
- * information about the src state here,
- * so import that part of the update,
- * then "fail" so we send the updated
- * state back to the peer who is missing
- * our what we know. */
- pf_state_peer_ntoh(src, &st->src);
- /* XXX do anything with timeouts? */
- sfail = 7;
- } else if (st->dst.state >= TCPS_SYN_SENT &&
- SEQ_GT(st->dst.seqlo, ntohl(dst->seqlo)))
- sfail = 4;
-
- return (sfail);
-}
-
-int
-pfsync_in_upd(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct pfsync_state *sa, *sp;
- struct pf_state_cmp id_key;
- struct pf_state_key *sk;
- struct pf_state *st;
- int sfail;
-
- struct mbuf *mp;
- int len = count * sizeof(*sp);
- int offp, i;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- sa = (struct pfsync_state *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- sp = &sa[i];
-
- /* check for invalid values */
- if (sp->timeout >= PFTM_MAX ||
- sp->src.state > PF_TCPS_PROXY_DST ||
- sp->dst.state > PF_TCPS_PROXY_DST) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pfsync_input: PFSYNC_ACT_UPD: "
- "invalid value\n");
- }
- V_pfsyncstats.pfsyncs_badval++;
- continue;
- }
-
- bcopy(sp->id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = sp->creatorid;
-
- st = pf_find_state_byid(&id_key);
- if (st == NULL) {
- /* insert the update */
- if (pfsync_state_import(sp, 0))
- V_pfsyncstats.pfsyncs_badstate++;
- continue;
- }
-
- if (ISSET(st->state_flags, PFSTATE_ACK))
- pfsync_deferred(st, 1);
-
- sk = st->key[PF_SK_WIRE]; /* XXX right one? */
- sfail = 0;
- if (sk->proto == IPPROTO_TCP)
- sfail = pfsync_upd_tcp(st, &sp->src, &sp->dst);
- else {
- /*
- * Non-TCP protocol state machine always go
- * forwards
- */
- if (st->src.state > sp->src.state)
- sfail = 5;
- else if (st->dst.state > sp->dst.state)
- sfail = 6;
- }
-
- if (sfail) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pfsync: %s stale update (%d)"
- " id: %016llx creatorid: %08x\n",
- (sfail < 7 ? "ignoring" : "partial"),
- sfail, betoh64(st->id),
- ntohl(st->creatorid));
- }
- V_pfsyncstats.pfsyncs_stale++;
-
- pfsync_update_state(st);
- schednetisr(NETISR_PFSYNC);
- continue;
- }
- pfsync_alloc_scrub_memory(&sp->dst, &st->dst);
- pf_state_peer_ntoh(&sp->src, &st->src);
- pf_state_peer_ntoh(&sp->dst, &st->dst);
- st->expire = time_second;
- st->timeout = sp->timeout;
- st->pfsync_time = time_uptime;
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (len);
-}
-
-int
-pfsync_in_upd_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct pfsync_upd_c *ua, *up;
- struct pf_state_key *sk;
- struct pf_state_cmp id_key;
- struct pf_state *st;
-
- int len = count * sizeof(*up);
- int sfail;
-
- struct mbuf *mp;
- int offp, i;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- ua = (struct pfsync_upd_c *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- up = &ua[i];
-
- /* check for invalid values */
- if (up->timeout >= PFTM_MAX ||
- up->src.state > PF_TCPS_PROXY_DST ||
- up->dst.state > PF_TCPS_PROXY_DST) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pfsync_input: "
- "PFSYNC_ACT_UPD_C: "
- "invalid value\n");
- }
- V_pfsyncstats.pfsyncs_badval++;
- continue;
- }
-
- bcopy(&up->id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = up->creatorid;
-
- st = pf_find_state_byid(&id_key);
- if (st == NULL) {
- /* We don't have this state. Ask for it. */
- pfsync_request_update(id_key.creatorid, id_key.id);
- continue;
- }
-
- if (ISSET(st->state_flags, PFSTATE_ACK))
- pfsync_deferred(st, 1);
-
- sk = st->key[PF_SK_WIRE]; /* XXX right one? */
- sfail = 0;
- if (sk->proto == IPPROTO_TCP)
- sfail = pfsync_upd_tcp(st, &up->src, &up->dst);
- else {
- /*
- * Non-TCP protocol state machine always go forwards
- */
- if (st->src.state > up->src.state)
- sfail = 5;
- else if (st->dst.state > up->dst.state)
- sfail = 6;
- }
-
- if (sfail) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pfsync: ignoring stale update "
- "(%d) id: %016llx "
- "creatorid: %08x\n", sfail,
- betoh64(st->id),
- ntohl(st->creatorid));
- }
- V_pfsyncstats.pfsyncs_stale++;
-
- pfsync_update_state(st);
- schednetisr(NETISR_PFSYNC);
- continue;
- }
- pfsync_alloc_scrub_memory(&up->dst, &st->dst);
- pf_state_peer_ntoh(&up->src, &st->src);
- pf_state_peer_ntoh(&up->dst, &st->dst);
- st->expire = time_second;
- st->timeout = up->timeout;
- st->pfsync_time = time_uptime;
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (len);
-}
-
-int
-pfsync_in_ureq(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct pfsync_upd_req *ur, *ura;
- struct mbuf *mp;
- int len = count * sizeof(*ur);
- int i, offp;
-
- struct pf_state_cmp id_key;
- struct pf_state *st;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- ura = (struct pfsync_upd_req *)(mp->m_data + offp);
-
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- ur = &ura[i];
-
- bcopy(&ur->id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = ur->creatorid;
-
- if (id_key.id == 0 && id_key.creatorid == 0)
- pfsync_bulk_start();
- else {
- st = pf_find_state_byid(&id_key);
- if (st == NULL) {
- V_pfsyncstats.pfsyncs_badstate++;
- continue;
- }
- if (ISSET(st->state_flags, PFSTATE_NOSYNC))
- continue;
-
- pfsync_update_state_req(st);
- }
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
-
- return (len);
-}
-
-int
-pfsync_in_del(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct mbuf *mp;
- struct pfsync_state *sa, *sp;
- struct pf_state_cmp id_key;
- struct pf_state *st;
- int len = count * sizeof(*sp);
- int offp, i;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- sa = (struct pfsync_state *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- sp = &sa[i];
-
- bcopy(sp->id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = sp->creatorid;
-
- st = pf_find_state_byid(&id_key);
- if (st == NULL) {
- V_pfsyncstats.pfsyncs_badstate++;
- continue;
- }
- SET(st->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(st);
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (len);
-}
-
-int
-pfsync_in_del_c(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- struct mbuf *mp;
- struct pfsync_del_c *sa, *sp;
- struct pf_state_cmp id_key;
- struct pf_state *st;
- int len = count * sizeof(*sp);
- int offp, i;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- sa = (struct pfsync_del_c *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++) {
- sp = &sa[i];
-
- bcopy(&sp->id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = sp->creatorid;
-
- st = pf_find_state_byid(&id_key);
- if (st == NULL) {
- V_pfsyncstats.pfsyncs_badstate++;
- continue;
- }
-
- SET(st->state_flags, PFSTATE_NOSYNC);
- pf_unlink_state(st);
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- return (len);
-}
-
-int
-pfsync_in_bus(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- struct pfsync_bus *bus;
- struct mbuf *mp;
- int len = count * sizeof(*bus);
- int offp;
-
- /* If we're not waiting for a bulk update, who cares. */
- if (sc->sc_ureq_sent == 0)
- return (len);
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- bus = (struct pfsync_bus *)(mp->m_data + offp);
-
- switch (bus->status) {
- case PFSYNC_BUS_START:
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_bulkfail_tmo, 4 * hz +
- V_pf_pool_limits[PF_LIMIT_STATES].limit /
- ((sc->sc_ifp->if_mtu - PFSYNC_MINPKT) /
- sizeof(struct pfsync_state)),
- pfsync_bulk_fail, V_pfsyncif);
-#else
- timeout_add(&sc->sc_bulkfail_tmo, 4 * hz +
- pf_pool_limits[PF_LIMIT_STATES].limit /
- ((sc->sc_if.if_mtu - PFSYNC_MINPKT) /
- sizeof(struct pfsync_state)));
-#endif
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync: received bulk update start\n");
- break;
-
- case PFSYNC_BUS_END:
- if (time_uptime - ntohl(bus->endtime) >=
- sc->sc_ureq_sent) {
- /* that's it, we're happy */
- sc->sc_ureq_sent = 0;
- sc->sc_bulk_tries = 0;
- timeout_del(&sc->sc_bulkfail_tmo);
-#ifdef __FreeBSD__
- if (!sc->pfsync_sync_ok && carp_demote_adj_p)
- (*carp_demote_adj_p)(-V_pfsync_carp_adj,
- "pfsync bulk done");
- sc->pfsync_sync_ok = 1;
-#else
-#if NCARP > 0
- if (!pfsync_sync_ok)
- carp_group_demote_adj(&sc->sc_if, -1);
-#endif
- pfsync_sync_ok = 1;
-#endif
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync: received valid "
- "bulk update end\n");
- } else {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync: received invalid "
- "bulk update end: bad timestamp\n");
- }
- break;
- }
-
- return (len);
-}
-
-int
-pfsync_in_tdb(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- int len = count * sizeof(struct pfsync_tdb);
-
-#if defined(IPSEC)
- struct pfsync_tdb *tp;
- struct mbuf *mp;
- int offp;
- int i;
- int s;
-
- mp = m_pulldown(m, offset, len, &offp);
- if (mp == NULL) {
- V_pfsyncstats.pfsyncs_badlen++;
- return (-1);
- }
- tp = (struct pfsync_tdb *)(mp->m_data + offp);
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < count; i++)
- pfsync_update_net_tdb(&tp[i]);
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-#endif
-
- return (len);
-}
-
-#if defined(IPSEC)
-/* Update an in-kernel tdb. Silently fail if no tdb is found. */
-void
-pfsync_update_net_tdb(struct pfsync_tdb *pt)
-{
- struct tdb *tdb;
- int s;
-
- /* check for invalid values */
- if (ntohl(pt->spi) <= SPI_RESERVED_MAX ||
- (pt->dst.sa.sa_family != AF_INET &&
- pt->dst.sa.sa_family != AF_INET6))
- goto bad;
-
- s = spltdb();
- tdb = gettdb(pt->spi, &pt->dst, pt->sproto);
- if (tdb) {
- pt->rpl = ntohl(pt->rpl);
- pt->cur_bytes = betoh64(pt->cur_bytes);
-
- /* Neither replay nor byte counter should ever decrease. */
- if (pt->rpl < tdb->tdb_rpl ||
- pt->cur_bytes < tdb->tdb_cur_bytes) {
- splx(s);
- goto bad;
- }
-
- tdb->tdb_rpl = pt->rpl;
- tdb->tdb_cur_bytes = pt->cur_bytes;
- }
- splx(s);
- return;
-
-bad:
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync_insert: PFSYNC_ACT_TDB_UPD: "
- "invalid value\n");
- V_pfsyncstats.pfsyncs_badstate++;
- return;
-}
-#endif
-
-
-int
-pfsync_in_eof(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- /* check if we are at the right place in the packet */
- if (offset != m->m_pkthdr.len - sizeof(struct pfsync_eof))
- V_pfsyncstats.pfsyncs_badact++;
-
- /* we're done. free and let the caller return */
- m_freem(m);
- return (-1);
-}
-
-int
-pfsync_in_error(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
-{
- V_pfsyncstats.pfsyncs_badact++;
-
- m_freem(m);
- return (-1);
-}
-
-int
-pfsyncoutput(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
-#ifdef __FreeBSD__
- struct route *rt)
-#else
- struct rtentry *rt)
-#endif
-{
- m_freem(m);
- return (0);
-}
-
-/* ARGSUSED */
-int
-pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
-{
-#ifndef __FreeBSD__
- struct proc *p = curproc;
-#endif
- struct pfsync_softc *sc = ifp->if_softc;
- struct ifreq *ifr = (struct ifreq *)data;
- struct ip_moptions *imo = &sc->sc_imo;
- struct pfsyncreq pfsyncr;
- struct ifnet *sifp;
- struct ip *ip;
- int s, error;
-
- switch (cmd) {
-#if 0
- case SIOCSIFADDR:
- case SIOCAIFADDR:
- case SIOCSIFDSTADDR:
-#endif
- case SIOCSIFFLAGS:
-#ifdef __FreeBSD__
- if (ifp->if_flags & IFF_UP)
- ifp->if_drv_flags |= IFF_DRV_RUNNING;
- else
- ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
-#else
- if (ifp->if_flags & IFF_UP)
- ifp->if_flags |= IFF_RUNNING;
- else
- ifp->if_flags &= ~IFF_RUNNING;
-#endif
- break;
- case SIOCSIFMTU:
- if (!sc->sc_sync_if ||
- ifr->ifr_mtu <= PFSYNC_MINPKT ||
- ifr->ifr_mtu > sc->sc_sync_if->if_mtu)
- return (EINVAL);
- if (ifr->ifr_mtu < ifp->if_mtu) {
- s = splnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- pfsync_sendout();
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
- }
- ifp->if_mtu = ifr->ifr_mtu;
- break;
- case SIOCGETPFSYNC:
- bzero(&pfsyncr, sizeof(pfsyncr));
- if (sc->sc_sync_if) {
- strlcpy(pfsyncr.pfsyncr_syncdev,
- sc->sc_sync_if->if_xname, IFNAMSIZ);
- }
- pfsyncr.pfsyncr_syncpeer = sc->sc_sync_peer;
- pfsyncr.pfsyncr_maxupdates = sc->sc_maxupdates;
- pfsyncr.pfsyncr_defer = sc->sc_defer;
- return (copyout(&pfsyncr, ifr->ifr_data, sizeof(pfsyncr)));
-
- case SIOCSETPFSYNC:
-#ifdef __FreeBSD__
- if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0)
-#else
- if ((error = suser(p, p->p_acflag)) != 0)
-#endif
- return (error);
- if ((error = copyin(ifr->ifr_data, &pfsyncr, sizeof(pfsyncr))))
- return (error);
-
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
-#ifdef __FreeBSD__
- sc->sc_sync_peer.s_addr = htonl(INADDR_PFSYNC_GROUP);
-#else
- sc->sc_sync_peer.s_addr = INADDR_PFSYNC_GROUP;
-#endif
- else
- sc->sc_sync_peer.s_addr =
- pfsyncr.pfsyncr_syncpeer.s_addr;
-
- if (pfsyncr.pfsyncr_maxupdates > 255)
-#ifdef __FreeBSD__
- {
- PF_UNLOCK();
-#endif
- return (EINVAL);
-#ifdef __FreeBSD__
- }
-#endif
- sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
- sc->sc_defer = pfsyncr.pfsyncr_defer;
-
- if (pfsyncr.pfsyncr_syncdev[0] == 0) {
- sc->sc_sync_if = NULL;
-#ifdef __FreeBSD__
- PF_UNLOCK();
- if (imo->imo_membership)
- pfsync_multicast_cleanup(sc);
-#else
- if (imo->imo_num_memberships > 0) {
- in_delmulti(imo->imo_membership[
- --imo->imo_num_memberships]);
- imo->imo_multicast_ifp = NULL;
- }
-#endif
- break;
- }
-
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- if ((sifp = ifunit(pfsyncr.pfsyncr_syncdev)) == NULL)
- return (EINVAL);
-
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- s = splnet();
-#ifdef __FreeBSD__
- if (sifp->if_mtu < sc->sc_ifp->if_mtu ||
-#else
- if (sifp->if_mtu < sc->sc_if.if_mtu ||
-#endif
- (sc->sc_sync_if != NULL &&
- sifp->if_mtu < sc->sc_sync_if->if_mtu) ||
- sifp->if_mtu < MCLBYTES - sizeof(struct ip))
- pfsync_sendout();
- sc->sc_sync_if = sifp;
-
-#ifdef __FreeBSD__
- if (imo->imo_membership) {
- PF_UNLOCK();
- pfsync_multicast_cleanup(sc);
- PF_LOCK();
- }
-#else
- if (imo->imo_num_memberships > 0) {
- in_delmulti(imo->imo_membership[--imo->imo_num_memberships]);
- imo->imo_multicast_ifp = NULL;
- }
-#endif
-
-#ifdef __FreeBSD__
- if (sc->sc_sync_if &&
- sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
- PF_UNLOCK();
- error = pfsync_multicast_setup(sc);
- if (error)
- return (error);
- PF_LOCK();
- }
-#else
- if (sc->sc_sync_if &&
- sc->sc_sync_peer.s_addr == INADDR_PFSYNC_GROUP) {
- struct in_addr addr;
-
- if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
- sc->sc_sync_if = NULL;
- splx(s);
- return (EADDRNOTAVAIL);
- }
-
- addr.s_addr = INADDR_PFSYNC_GROUP;
-
- if ((imo->imo_membership[0] =
- in_addmulti(&addr, sc->sc_sync_if)) == NULL) {
- sc->sc_sync_if = NULL;
- splx(s);
- return (ENOBUFS);
- }
- imo->imo_num_memberships++;
- imo->imo_multicast_ifp = sc->sc_sync_if;
- imo->imo_multicast_ttl = PFSYNC_DFLTTL;
- imo->imo_multicast_loop = 0;
- }
-#endif /* !__FreeBSD__ */
-
- ip = &sc->sc_template;
- bzero(ip, sizeof(*ip));
- ip->ip_v = IPVERSION;
- ip->ip_hl = sizeof(sc->sc_template) >> 2;
- ip->ip_tos = IPTOS_LOWDELAY;
- /* len and id are set later */
-#ifdef __FreeBSD__
- ip->ip_off = IP_DF;
-#else
- ip->ip_off = htons(IP_DF);
-#endif
- ip->ip_ttl = PFSYNC_DFLTTL;
- ip->ip_p = IPPROTO_PFSYNC;
- ip->ip_src.s_addr = INADDR_ANY;
- ip->ip_dst.s_addr = sc->sc_sync_peer.s_addr;
-
- if (sc->sc_sync_if) {
- /* Request a full state table update. */
- sc->sc_ureq_sent = time_uptime;
-#ifdef __FreeBSD__
- if (sc->pfsync_sync_ok && carp_demote_adj_p)
- (*carp_demote_adj_p)(V_pfsync_carp_adj,
- "pfsync bulk start");
- sc->pfsync_sync_ok = 0;
-#else
-#if NCARP > 0
- if (pfsync_sync_ok)
- carp_group_demote_adj(&sc->sc_if, 1);
-#endif
- pfsync_sync_ok = 0;
-#endif
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync: requesting bulk update\n");
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
- pfsync_bulk_fail, V_pfsyncif);
-#else
- timeout_add_sec(&sc->sc_bulkfail_tmo, 5);
-#endif
- pfsync_request_update(0, 0);
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
- break;
-
- default:
- return (ENOTTY);
- }
-
- return (0);
-}
-
-int
-pfsync_out_state(struct pf_state *st, struct mbuf *m, int offset)
-{
- struct pfsync_state *sp = (struct pfsync_state *)(m->m_data + offset);
-
- pfsync_state_export(sp, st);
-
- return (sizeof(*sp));
-}
-
-int
-pfsync_out_iack(struct pf_state *st, struct mbuf *m, int offset)
-{
- struct pfsync_ins_ack *iack =
- (struct pfsync_ins_ack *)(m->m_data + offset);
-
- iack->id = st->id;
- iack->creatorid = st->creatorid;
-
- return (sizeof(*iack));
-}
-
-int
-pfsync_out_upd_c(struct pf_state *st, struct mbuf *m, int offset)
-{
- struct pfsync_upd_c *up = (struct pfsync_upd_c *)(m->m_data + offset);
-
- bzero(up, sizeof(*up));
- up->id = st->id;
- pf_state_peer_hton(&st->src, &up->src);
- pf_state_peer_hton(&st->dst, &up->dst);
- up->creatorid = st->creatorid;
- up->timeout = st->timeout;
-
- return (sizeof(*up));
-}
-
-int
-pfsync_out_del(struct pf_state *st, struct mbuf *m, int offset)
-{
- struct pfsync_del_c *dp = (struct pfsync_del_c *)(m->m_data + offset);
-
- dp->id = st->id;
- dp->creatorid = st->creatorid;
-
- SET(st->state_flags, PFSTATE_NOSYNC);
-
- return (sizeof(*dp));
-}
-
-void
-pfsync_drop(struct pfsync_softc *sc)
-{
- struct pf_state *st;
- struct pfsync_upd_req_item *ur;
-#ifdef notyet
- struct tdb *t;
-#endif
- int q;
-
- for (q = 0; q < PFSYNC_S_COUNT; q++) {
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
- continue;
-
- TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) {
-#ifdef PFSYNC_DEBUG
-#ifdef __FreeBSD__
- KASSERT(st->sync_state == q,
- ("%s: st->sync_state == q",
- __FUNCTION__));
-#else
- KASSERT(st->sync_state == q);
-#endif
-#endif
- st->sync_state = PFSYNC_S_NONE;
- }
- TAILQ_INIT(&sc->sc_qs[q]);
- }
-
- while ((ur = TAILQ_FIRST(&sc->sc_upd_req_list)) != NULL) {
- TAILQ_REMOVE(&sc->sc_upd_req_list, ur, ur_entry);
- pool_put(&sc->sc_pool, ur);
- }
-
- sc->sc_plus = NULL;
-
-#ifdef notyet
- if (!TAILQ_EMPTY(&sc->sc_tdb_q)) {
- TAILQ_FOREACH(t, &sc->sc_tdb_q, tdb_sync_entry)
- CLR(t->tdb_flags, TDBF_PFSYNC);
-
- TAILQ_INIT(&sc->sc_tdb_q);
- }
-#endif
-
- sc->sc_len = PFSYNC_MINPKT;
-}
-
-#ifdef __FreeBSD__
-void pfsync_sendout()
-{
- pfsync_sendout1(1);
-}
-
-static void
-pfsync_sendout1(int schedswi)
-{
- struct pfsync_softc *sc = V_pfsyncif;
-#else
-void
-pfsync_sendout(void)
-{
- struct pfsync_softc *sc = pfsyncif;
-#endif
-#if NBPFILTER > 0
-#ifdef __FreeBSD__
- struct ifnet *ifp = sc->sc_ifp;
-#else
- struct ifnet *ifp = &sc->sc_if;
-#endif
-#endif
- struct mbuf *m;
- struct ip *ip;
- struct pfsync_header *ph;
- struct pfsync_subheader *subh;
- struct pf_state *st;
- struct pfsync_upd_req_item *ur;
-#ifdef notyet
- struct tdb *t;
-#endif
- int offset;
- int q, count = 0;
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_NET);
-#endif
-
- if (sc == NULL || sc->sc_len == PFSYNC_MINPKT)
- return;
-
-#if NBPFILTER > 0
- if (ifp->if_bpf == NULL && sc->sc_sync_if == NULL) {
-#else
- if (sc->sc_sync_if == NULL) {
-#endif
- pfsync_drop(sc);
- return;
- }
-
-#ifdef __FreeBSD__
- m = m_get2(M_NOWAIT, MT_DATA, M_PKTHDR, max_linkhdr + sc->sc_len);
- if (m == NULL) {
- sc->sc_ifp->if_oerrors++;
- V_pfsyncstats.pfsyncs_onomem++;
- return;
- }
-#else
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL) {
- sc->sc_if.if_oerrors++;
- pfsyncstats.pfsyncs_onomem++;
- pfsync_drop(sc);
- return;
- }
-
- if (max_linkhdr + sc->sc_len > MHLEN) {
- MCLGETI(m, M_DONTWAIT, NULL, max_linkhdr + sc->sc_len);
- if (!ISSET(m->m_flags, M_EXT)) {
- m_free(m);
- sc->sc_if.if_oerrors++;
- pfsyncstats.pfsyncs_onomem++;
- pfsync_drop(sc);
- return;
- }
- }
-#endif
- m->m_data += max_linkhdr;
- m->m_len = m->m_pkthdr.len = sc->sc_len;
-
- /* build the ip header */
- ip = (struct ip *)m->m_data;
- bcopy(&sc->sc_template, ip, sizeof(*ip));
- offset = sizeof(*ip);
-
-#ifdef __FreeBSD__
- ip->ip_len = m->m_pkthdr.len;
-#else
- ip->ip_len = htons(m->m_pkthdr.len);
-#endif
- ip->ip_id = htons(ip_randomid());
-
- /* build the pfsync header */
- ph = (struct pfsync_header *)(m->m_data + offset);
- bzero(ph, sizeof(*ph));
- offset += sizeof(*ph);
-
- ph->version = PFSYNC_VERSION;
- ph->len = htons(sc->sc_len - sizeof(*ip));
-#ifdef __FreeBSD__
- bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
-#else
- bcopy(pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
-#endif
-
- /* walk the queues */
- for (q = 0; q < PFSYNC_S_COUNT; q++) {
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
- continue;
-
- subh = (struct pfsync_subheader *)(m->m_data + offset);
- offset += sizeof(*subh);
-
- count = 0;
- TAILQ_FOREACH(st, &sc->sc_qs[q], sync_list) {
-#ifdef PFSYNC_DEBUG
-#ifdef __FreeBSD__
- KASSERT(st->sync_state == q,
- ("%s: st->sync_state == q",
- __FUNCTION__));
-#else
- KASSERT(st->sync_state == q);
-#endif
-#endif
-
- offset += pfsync_qs[q].write(st, m, offset);
- st->sync_state = PFSYNC_S_NONE;
- count++;
- }
- TAILQ_INIT(&sc->sc_qs[q]);
-
- bzero(subh, sizeof(*subh));
- subh->action = pfsync_qs[q].action;
- subh->count = htons(count);
- }
-
- if (!TAILQ_EMPTY(&sc->sc_upd_req_list)) {
- subh = (struct pfsync_subheader *)(m->m_data + offset);
- offset += sizeof(*subh);
-
- count = 0;
- while ((ur = TAILQ_FIRST(&sc->sc_upd_req_list)) != NULL) {
- TAILQ_REMOVE(&sc->sc_upd_req_list, ur, ur_entry);
-
- bcopy(&ur->ur_msg, m->m_data + offset,
- sizeof(ur->ur_msg));
- offset += sizeof(ur->ur_msg);
-
- pool_put(&sc->sc_pool, ur);
-
- count++;
- }
-
- bzero(subh, sizeof(*subh));
- subh->action = PFSYNC_ACT_UPD_REQ;
- subh->count = htons(count);
- }
-
- /* has someone built a custom region for us to add? */
- if (sc->sc_plus != NULL) {
- bcopy(sc->sc_plus, m->m_data + offset, sc->sc_pluslen);
- offset += sc->sc_pluslen;
-
- sc->sc_plus = NULL;
- }
-
-#ifdef notyet
- if (!TAILQ_EMPTY(&sc->sc_tdb_q)) {
- subh = (struct pfsync_subheader *)(m->m_data + offset);
- offset += sizeof(*subh);
-
- count = 0;
- TAILQ_FOREACH(t, &sc->sc_tdb_q, tdb_sync_entry) {
- offset += pfsync_out_tdb(t, m, offset);
- CLR(t->tdb_flags, TDBF_PFSYNC);
-
- count++;
- }
- TAILQ_INIT(&sc->sc_tdb_q);
-
- bzero(subh, sizeof(*subh));
- subh->action = PFSYNC_ACT_TDB;
- subh->count = htons(count);
- }
-#endif
-
- subh = (struct pfsync_subheader *)(m->m_data + offset);
- offset += sizeof(*subh);
-
- bzero(subh, sizeof(*subh));
- subh->action = PFSYNC_ACT_EOF;
- subh->count = htons(1);
-
- /* XXX write checksum in EOF here */
-
- /* we're done, let's put it on the wire */
-#if NBPFILTER > 0
- if (ifp->if_bpf) {
- m->m_data += sizeof(*ip);
- m->m_len = m->m_pkthdr.len = sc->sc_len - sizeof(*ip);
-#ifdef __FreeBSD__
- BPF_MTAP(ifp, m);
-#else
- bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
-#endif
- m->m_data -= sizeof(*ip);
- m->m_len = m->m_pkthdr.len = sc->sc_len;
- }
-
- if (sc->sc_sync_if == NULL) {
- sc->sc_len = PFSYNC_MINPKT;
- m_freem(m);
- return;
- }
-#endif
-
-#ifdef __FreeBSD__
- sc->sc_ifp->if_opackets++;
- sc->sc_ifp->if_obytes += m->m_pkthdr.len;
- sc->sc_len = PFSYNC_MINPKT;
-
- if (!_IF_QFULL(&sc->sc_ifp->if_snd))
- _IF_ENQUEUE(&sc->sc_ifp->if_snd, m);
- else {
- m_freem(m);
- sc->sc_ifp->if_snd.ifq_drops++;
- }
- if (schedswi)
- swi_sched(V_pfsync_swi_cookie, 0);
-#else
- sc->sc_if.if_opackets++;
- sc->sc_if.if_obytes += m->m_pkthdr.len;
-
- if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL) == 0)
- pfsyncstats.pfsyncs_opackets++;
- else
- pfsyncstats.pfsyncs_oerrors++;
-
- /* start again */
- sc->sc_len = PFSYNC_MINPKT;
-#endif
-}
-
-void
-pfsync_insert_state(struct pf_state *st)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- if (ISSET(st->rule.ptr->rule_flag, PFRULE_NOSYNC) ||
- st->key[PF_SK_WIRE]->proto == IPPROTO_PFSYNC) {
- SET(st->state_flags, PFSTATE_NOSYNC);
- return;
- }
-
- if (sc == NULL || ISSET(st->state_flags, PFSTATE_NOSYNC))
- return;
-
-#ifdef PFSYNC_DEBUG
-#ifdef __FreeBSD__
- KASSERT(st->sync_state == PFSYNC_S_NONE,
- ("%s: st->sync_state == PFSYNC_S_NONE", __FUNCTION__));
-#else
- KASSERT(st->sync_state == PFSYNC_S_NONE);
-#endif
-#endif
-
- if (sc->sc_len == PFSYNC_MINPKT)
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout,
- V_pfsyncif);
-#else
- timeout_add_sec(&sc->sc_tmo, 1);
-#endif
-
- pfsync_q_ins(st, PFSYNC_S_INS);
-
- st->sync_updates = 0;
-}
-
-int defer = 10;
-
-int
-pfsync_defer(struct pf_state *st, struct mbuf *m)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- struct pfsync_deferral *pd;
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- if (!sc->sc_defer || m->m_flags & (M_BCAST|M_MCAST))
- return (0);
-
- if (sc->sc_deferred >= 128)
- pfsync_undefer(TAILQ_FIRST(&sc->sc_deferrals), 0);
-
- pd = pool_get(&sc->sc_pool, M_NOWAIT);
- if (pd == NULL)
- return (0);
- sc->sc_deferred++;
-
-#ifdef __FreeBSD__
- m->m_flags |= M_SKIP_FIREWALL;
-#else
- m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
-#endif
- SET(st->state_flags, PFSTATE_ACK);
-
- pd->pd_st = st;
- pd->pd_m = m;
-
- TAILQ_INSERT_TAIL(&sc->sc_deferrals, pd, pd_entry);
-#ifdef __FreeBSD__
- callout_init(&pd->pd_tmo, CALLOUT_MPSAFE);
- callout_reset(&pd->pd_tmo, defer, pfsync_defer_tmo,
- pd);
-#else
- timeout_set(&pd->pd_tmo, pfsync_defer_tmo, pd);
- timeout_add(&pd->pd_tmo, defer);
-#endif
-
- swi_sched(V_pfsync_swi_cookie, 0);
-
- return (1);
-}
-
-void
-pfsync_undefer(struct pfsync_deferral *pd, int drop)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- int s;
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- TAILQ_REMOVE(&sc->sc_deferrals, pd, pd_entry);
- sc->sc_deferred--;
-
- CLR(pd->pd_st->state_flags, PFSTATE_ACK);
- timeout_del(&pd->pd_tmo); /* bah */
- if (drop)
- m_freem(pd->pd_m);
- else {
- s = splnet();
-#ifdef __FreeBSD__
- /* XXX: use pf_defered?! */
- PF_UNLOCK();
-#endif
- ip_output(pd->pd_m, (void *)NULL, (void *)NULL, 0,
- (void *)NULL, (void *)NULL);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- splx(s);
- }
-
- pool_put(&sc->sc_pool, pd);
-}
-
-void
-pfsync_defer_tmo(void *arg)
-{
-#if defined(__FreeBSD__) && defined(VIMAGE)
- struct pfsync_deferral *pd = arg;
-#endif
- int s;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- CURVNET_SET(pd->pd_m->m_pkthdr.rcvif->if_vnet); /* XXX */
- PF_LOCK();
-#endif
- pfsync_undefer(arg, 0);
-#ifdef __FreeBSD__
- PF_UNLOCK();
- CURVNET_RESTORE();
-#endif
- splx(s);
-}
-
-void
-pfsync_deferred(struct pf_state *st, int drop)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- struct pfsync_deferral *pd;
-
- TAILQ_FOREACH(pd, &sc->sc_deferrals, pd_entry) {
- if (pd->pd_st == st) {
- pfsync_undefer(pd, drop);
- return;
- }
- }
-
- panic("pfsync_send_deferred: unable to find deferred state");
-}
-
-u_int pfsync_upds = 0;
-
-void
-pfsync_update_state(struct pf_state *st)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- int sync = 0;
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- if (sc == NULL)
- return;
-
- if (ISSET(st->state_flags, PFSTATE_ACK))
- pfsync_deferred(st, 0);
- if (ISSET(st->state_flags, PFSTATE_NOSYNC)) {
- if (st->sync_state != PFSYNC_S_NONE)
- pfsync_q_del(st);
- return;
- }
-
- if (sc->sc_len == PFSYNC_MINPKT)
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout,
- V_pfsyncif);
-#else
- timeout_add_sec(&sc->sc_tmo, 1);
-#endif
-
- switch (st->sync_state) {
- case PFSYNC_S_UPD_C:
- case PFSYNC_S_UPD:
- case PFSYNC_S_INS:
- /* we're already handling it */
-
- if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) {
- st->sync_updates++;
- if (st->sync_updates >= sc->sc_maxupdates)
- sync = 1;
- }
- break;
-
- case PFSYNC_S_IACK:
- pfsync_q_del(st);
- case PFSYNC_S_NONE:
- pfsync_q_ins(st, PFSYNC_S_UPD_C);
- st->sync_updates = 0;
- break;
-
- default:
- panic("pfsync_update_state: unexpected sync state %d",
- st->sync_state);
- }
-
- if (sync || (time_uptime - st->pfsync_time) < 2) {
- pfsync_upds++;
- schednetisr(NETISR_PFSYNC);
- }
-}
-
-void
-pfsync_request_update(u_int32_t creatorid, u_int64_t id)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- struct pfsync_upd_req_item *item;
- size_t nlen = sizeof(struct pfsync_upd_req);
- int s;
-
- PF_LOCK_ASSERT();
-
- /*
- * this code does nothing to prevent multiple update requests for the
- * same state being generated.
- */
-
- item = pool_get(&sc->sc_pool, PR_NOWAIT);
- if (item == NULL) {
- /* XXX stats */
- return;
- }
-
- item->ur_msg.id = id;
- item->ur_msg.creatorid = creatorid;
-
- if (TAILQ_EMPTY(&sc->sc_upd_req_list))
- nlen += sizeof(struct pfsync_subheader);
-
-#ifdef __FreeBSD__
- if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
-#else
- if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
-#endif
- s = splnet();
- pfsync_sendout();
- splx(s);
-
- nlen = sizeof(struct pfsync_subheader) +
- sizeof(struct pfsync_upd_req);
- }
-
- TAILQ_INSERT_TAIL(&sc->sc_upd_req_list, item, ur_entry);
- sc->sc_len += nlen;
-
- schednetisr(NETISR_PFSYNC);
-}
-
-void
-pfsync_update_state_req(struct pf_state *st)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
- PF_LOCK_ASSERT();
-
- if (sc == NULL)
- panic("pfsync_update_state_req: nonexistant instance");
-
- if (ISSET(st->state_flags, PFSTATE_NOSYNC)) {
- if (st->sync_state != PFSYNC_S_NONE)
- pfsync_q_del(st);
- return;
- }
-
- switch (st->sync_state) {
- case PFSYNC_S_UPD_C:
- case PFSYNC_S_IACK:
- pfsync_q_del(st);
- case PFSYNC_S_NONE:
- pfsync_q_ins(st, PFSYNC_S_UPD);
- schednetisr(NETISR_PFSYNC);
- return;
-
- case PFSYNC_S_INS:
- case PFSYNC_S_UPD:
- case PFSYNC_S_DEL:
- /* we're already handling it */
- return;
-
- default:
- panic("pfsync_update_state_req: unexpected sync state %d",
- st->sync_state);
- }
-}
-
-void
-pfsync_delete_state(struct pf_state *st)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- if (sc == NULL)
- return;
-
- if (ISSET(st->state_flags, PFSTATE_ACK))
- pfsync_deferred(st, 1);
- if (ISSET(st->state_flags, PFSTATE_NOSYNC)) {
- if (st->sync_state != PFSYNC_S_NONE)
- pfsync_q_del(st);
- return;
- }
-
- if (sc->sc_len == PFSYNC_MINPKT)
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_tmo, 1 * hz, pfsync_timeout,
- V_pfsyncif);
-#else
- timeout_add_sec(&sc->sc_tmo, 1);
-#endif
-
- switch (st->sync_state) {
- case PFSYNC_S_INS:
- /* we never got to tell the world so just forget about it */
- pfsync_q_del(st);
- return;
-
- case PFSYNC_S_UPD_C:
- case PFSYNC_S_UPD:
- case PFSYNC_S_IACK:
- pfsync_q_del(st);
- /* FALLTHROUGH to putting it on the del list */
-
- case PFSYNC_S_NONE:
- pfsync_q_ins(st, PFSYNC_S_DEL);
- return;
-
- default:
- panic("pfsync_delete_state: unexpected sync state %d",
- st->sync_state);
- }
-}
-
-void
-pfsync_clear_states(u_int32_t creatorid, const char *ifname)
-{
- struct {
- struct pfsync_subheader subh;
- struct pfsync_clr clr;
- } __packed r;
-
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- if (sc == NULL)
- return;
-
- bzero(&r, sizeof(r));
-
- r.subh.action = PFSYNC_ACT_CLR;
- r.subh.count = htons(1);
-
- strlcpy(r.clr.ifname, ifname, sizeof(r.clr.ifname));
- r.clr.creatorid = creatorid;
-
- pfsync_send_plus(&r, sizeof(r));
-}
-
-void
-pfsync_q_ins(struct pf_state *st, int q)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- size_t nlen = pfsync_qs[q].len;
- int s;
-
- PF_LOCK_ASSERT();
-
-#ifdef __FreeBSD__
- KASSERT(st->sync_state == PFSYNC_S_NONE,
- ("%s: st->sync_state == PFSYNC_S_NONE", __FUNCTION__));
-#else
- KASSERT(st->sync_state == PFSYNC_S_NONE);
-#endif
-
-#if 1 || defined(PFSYNC_DEBUG)
- if (sc->sc_len < PFSYNC_MINPKT)
-#ifdef __FreeBSD__
- panic("pfsync pkt len is too low %zu", sc->sc_len);
-#else
- panic("pfsync pkt len is too low %d", sc->sc_len);
-#endif
-#endif
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
- nlen += sizeof(struct pfsync_subheader);
-
-#ifdef __FreeBSD__
- if (sc->sc_len + nlen > sc->sc_ifp->if_mtu) {
-#else
- if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
-#endif
- s = splnet();
- pfsync_sendout();
- splx(s);
-
- nlen = sizeof(struct pfsync_subheader) + pfsync_qs[q].len;
- }
-
- sc->sc_len += nlen;
- TAILQ_INSERT_TAIL(&sc->sc_qs[q], st, sync_list);
- st->sync_state = q;
-}
-
-void
-pfsync_q_del(struct pf_state *st)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- int q = st->sync_state;
-
-#ifdef __FreeBSD__
- KASSERT(st->sync_state != PFSYNC_S_NONE,
- ("%s: st->sync_state != PFSYNC_S_NONE", __FUNCTION__));
-#else
- KASSERT(st->sync_state != PFSYNC_S_NONE);
-#endif
-
- sc->sc_len -= pfsync_qs[q].len;
- TAILQ_REMOVE(&sc->sc_qs[q], st, sync_list);
- st->sync_state = PFSYNC_S_NONE;
-
- if (TAILQ_EMPTY(&sc->sc_qs[q]))
- sc->sc_len -= sizeof(struct pfsync_subheader);
-}
-
-#ifdef notyet
-void
-pfsync_update_tdb(struct tdb *t, int output)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- size_t nlen = sizeof(struct pfsync_tdb);
- int s;
-
- if (sc == NULL)
- return;
-
- if (!ISSET(t->tdb_flags, TDBF_PFSYNC)) {
- if (TAILQ_EMPTY(&sc->sc_tdb_q))
- nlen += sizeof(struct pfsync_subheader);
-
- if (sc->sc_len + nlen > sc->sc_if.if_mtu) {
- s = splnet();
- PF_LOCK();
- pfsync_sendout();
- PF_UNLOCK();
- splx(s);
-
- nlen = sizeof(struct pfsync_subheader) +
- sizeof(struct pfsync_tdb);
- }
-
- sc->sc_len += nlen;
- TAILQ_INSERT_TAIL(&sc->sc_tdb_q, t, tdb_sync_entry);
- SET(t->tdb_flags, TDBF_PFSYNC);
- t->tdb_updates = 0;
- } else {
- if (++t->tdb_updates >= sc->sc_maxupdates)
- schednetisr(NETISR_PFSYNC);
- }
-
- if (output)
- SET(t->tdb_flags, TDBF_PFSYNC_RPL);
- else
- CLR(t->tdb_flags, TDBF_PFSYNC_RPL);
-}
-
-void
-pfsync_delete_tdb(struct tdb *t)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
- if (sc == NULL || !ISSET(t->tdb_flags, TDBF_PFSYNC))
- return;
-
- sc->sc_len -= sizeof(struct pfsync_tdb);
- TAILQ_REMOVE(&sc->sc_tdb_q, t, tdb_sync_entry);
- CLR(t->tdb_flags, TDBF_PFSYNC);
-
- if (TAILQ_EMPTY(&sc->sc_tdb_q))
- sc->sc_len -= sizeof(struct pfsync_subheader);
-}
-
-int
-pfsync_out_tdb(struct tdb *t, struct mbuf *m, int offset)
-{
- struct pfsync_tdb *ut = (struct pfsync_tdb *)(m->m_data + offset);
-
- bzero(ut, sizeof(*ut));
- ut->spi = t->tdb_spi;
- bcopy(&t->tdb_dst, &ut->dst, sizeof(ut->dst));
- /*
- * When a failover happens, the master's rpl is probably above
- * what we see here (we may be up to a second late), so
- * increase it a bit for outbound tdbs to manage most such
- * situations.
- *
- * For now, just add an offset that is likely to be larger
- * than the number of packets we can see in one second. The RFC
- * just says the next packet must have a higher seq value.
- *
- * XXX What is a good algorithm for this? We could use
- * a rate-determined increase, but to know it, we would have
- * to extend struct tdb.
- * XXX pt->rpl can wrap over MAXINT, but if so the real tdb
- * will soon be replaced anyway. For now, just don't handle
- * this edge case.
- */
-#define RPL_INCR 16384
- ut->rpl = htonl(t->tdb_rpl + (ISSET(t->tdb_flags, TDBF_PFSYNC_RPL) ?
- RPL_INCR : 0));
- ut->cur_bytes = htobe64(t->tdb_cur_bytes);
- ut->sproto = t->tdb_sproto;
-
- return (sizeof(*ut));
-}
-#endif
-
-void
-pfsync_bulk_start(void)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync: received bulk update request\n");
-
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
- if (TAILQ_EMPTY(&V_state_list))
-#else
- if (TAILQ_EMPTY(&state_list))
-#endif
- pfsync_bulk_status(PFSYNC_BUS_END);
- else {
- sc->sc_ureq_received = time_uptime;
- if (sc->sc_bulk_next == NULL)
-#ifdef __FreeBSD__
- sc->sc_bulk_next = TAILQ_FIRST(&V_state_list);
-#else
- sc->sc_bulk_next = TAILQ_FIRST(&state_list);
-#endif
- sc->sc_bulk_last = sc->sc_bulk_next;
-
- pfsync_bulk_status(PFSYNC_BUS_START);
- callout_reset(&sc->sc_bulk_tmo, 1, pfsync_bulk_update, sc);
- }
-}
-
-void
-pfsync_bulk_update(void *arg)
-{
- struct pfsync_softc *sc = arg;
- struct pf_state *st = sc->sc_bulk_next;
- int i = 0;
- int s;
-
- PF_LOCK_ASSERT();
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- CURVNET_SET(sc->sc_ifp->if_vnet);
-#endif
- for (;;) {
- if (st->sync_state == PFSYNC_S_NONE &&
- st->timeout < PFTM_MAX &&
- st->pfsync_time <= sc->sc_ureq_received) {
- pfsync_update_state_req(st);
- i++;
- }
-
- st = TAILQ_NEXT(st, entry_list);
- if (st == NULL)
-#ifdef __FreeBSD__
- st = TAILQ_FIRST(&V_state_list);
-#else
- st = TAILQ_FIRST(&state_list);
-#endif
-
- if (st == sc->sc_bulk_last) {
- /* we're done */
- sc->sc_bulk_next = NULL;
- sc->sc_bulk_last = NULL;
- pfsync_bulk_status(PFSYNC_BUS_END);
- break;
- }
-
-#ifdef __FreeBSD__
- if (i > 1 && (sc->sc_ifp->if_mtu - sc->sc_len) <
-#else
- if (i > 1 && (sc->sc_if.if_mtu - sc->sc_len) <
-#endif
- sizeof(struct pfsync_state)) {
- /* we've filled a packet */
- sc->sc_bulk_next = st;
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_bulk_tmo, 1,
- pfsync_bulk_update, sc);
-#else
- timeout_add(&sc->sc_bulk_tmo, 1);
-#endif
- break;
- }
- }
-
-#ifdef __FreeBSD__
- CURVNET_RESTORE();
-#endif
- splx(s);
-}
-
-void
-pfsync_bulk_status(u_int8_t status)
-{
- struct {
- struct pfsync_subheader subh;
- struct pfsync_bus bus;
- } __packed r;
-
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
- PF_LOCK_ASSERT();
-
- bzero(&r, sizeof(r));
-
- r.subh.action = PFSYNC_ACT_BUS;
- r.subh.count = htons(1);
-
-#ifdef __FreeBSD__
- r.bus.creatorid = V_pf_status.hostid;
-#else
- r.bus.creatorid = pf_status.hostid;
-#endif
- r.bus.endtime = htonl(time_uptime - sc->sc_ureq_received);
- r.bus.status = status;
-
- pfsync_send_plus(&r, sizeof(r));
-}
-
-void
-pfsync_bulk_fail(void *arg)
-{
- struct pfsync_softc *sc = arg;
-
-#ifdef __FreeBSD__
- CURVNET_SET(sc->sc_ifp->if_vnet);
-#endif
-
- if (sc->sc_bulk_tries++ < PFSYNC_MAX_BULKTRIES) {
- /* Try again */
-#ifdef __FreeBSD__
- callout_reset(&sc->sc_bulkfail_tmo, 5 * hz,
- pfsync_bulk_fail, V_pfsyncif);
-#else
- timeout_add_sec(&sc->sc_bulkfail_tmo, 5);
-#endif
- PF_LOCK();
- pfsync_request_update(0, 0);
- PF_UNLOCK();
- } else {
- /* Pretend like the transfer was ok */
- sc->sc_ureq_sent = 0;
- sc->sc_bulk_tries = 0;
-#ifdef __FreeBSD__
- if (!sc->pfsync_sync_ok && carp_demote_adj_p)
- (*carp_demote_adj_p)(-V_pfsync_carp_adj,
- "pfsync bulk fail");
- sc->pfsync_sync_ok = 1;
-#else
-#if NCARP > 0
- if (!pfsync_sync_ok)
- carp_group_demote_adj(&sc->sc_if, -1);
-#endif
- pfsync_sync_ok = 1;
-#endif
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("pfsync: failed to receive bulk update\n");
- }
-
-#ifdef __FreeBSD__
- CURVNET_RESTORE();
-#endif
-}
-
-void
-pfsync_send_plus(void *plus, size_t pluslen)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
- int s;
-
- PF_LOCK_ASSERT();
-
-#ifdef __FreeBSD__
- if (sc->sc_len + pluslen > sc->sc_ifp->if_mtu) {
-#else
- if (sc->sc_len + pluslen > sc->sc_if.if_mtu) {
-#endif
- s = splnet();
- pfsync_sendout();
- splx(s);
- }
-
- sc->sc_plus = plus;
- sc->sc_len += (sc->sc_pluslen = pluslen);
-
- s = splnet();
- pfsync_sendout();
- splx(s);
-}
-
-int
-pfsync_up(void)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
-#ifdef __FreeBSD__
- if (sc == NULL || !ISSET(sc->sc_ifp->if_flags, IFF_DRV_RUNNING))
-#else
- if (sc == NULL || !ISSET(sc->sc_if.if_flags, IFF_RUNNING))
-#endif
- return (0);
-
- return (1);
-}
-
-int
-pfsync_state_in_use(struct pf_state *st)
-{
-#ifdef __FreeBSD__
- struct pfsync_softc *sc = V_pfsyncif;
-#else
- struct pfsync_softc *sc = pfsyncif;
-#endif
-
- if (sc == NULL)
- return (0);
-
- if (st->sync_state != PFSYNC_S_NONE ||
- st == sc->sc_bulk_next ||
- st == sc->sc_bulk_last)
- return (1);
-
- return (0);
-}
-
-u_int pfsync_ints;
-u_int pfsync_tmos;
-
-void
-pfsync_timeout(void *arg)
-{
-#if defined(__FreeBSD__) && defined(VIMAGE)
- struct pfsync_softc *sc = arg;
-#endif
- int s;
-
-#ifdef __FreeBSD__
- CURVNET_SET(sc->sc_ifp->if_vnet);
-#endif
-
- pfsync_tmos++;
-
- s = splnet();
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- pfsync_sendout();
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- splx(s);
-
-#ifdef __FreeBSD__
- CURVNET_RESTORE();
-#endif
-}
-
-/* this is a softnet/netisr handler */
-void
-#ifdef __FreeBSD__
-pfsyncintr(void *arg)
-{
- struct pfsync_softc *sc = arg;
- struct mbuf *m, *n;
-
- CURVNET_SET(sc->sc_ifp->if_vnet);
- pfsync_ints++;
-
- PF_LOCK();
- if (sc->sc_len > PFSYNC_MINPKT)
- pfsync_sendout1(0);
- _IF_DEQUEUE_ALL(&sc->sc_ifp->if_snd, m);
- PF_UNLOCK();
-
- for (; m != NULL; m = n) {
-
- n = m->m_nextpkt;
- m->m_nextpkt = NULL;
- if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, NULL)
- == 0)
- V_pfsyncstats.pfsyncs_opackets++;
- else
- V_pfsyncstats.pfsyncs_oerrors++;
- }
- CURVNET_RESTORE();
-}
-#else
-pfsyncintr(void)
-{
- int s;
-
- pfsync_ints++;
-
- s = splnet();
- pfsync_sendout();
- splx(s);
-}
-#endif
-
-int
-pfsync_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
- size_t newlen)
-{
-
-#ifdef notyet
- /* All sysctl names at this level are terminal. */
- if (namelen != 1)
- return (ENOTDIR);
-
- switch (name[0]) {
- case PFSYNCCTL_STATS:
- if (newp != NULL)
- return (EPERM);
- return (sysctl_struct(oldp, oldlenp, newp, newlen,
- &V_pfsyncstats, sizeof(V_pfsyncstats)));
- }
-#endif
- return (ENOPROTOOPT);
-}
-
-#ifdef __FreeBSD__
-static int
-pfsync_multicast_setup(struct pfsync_softc *sc)
-{
- struct ip_moptions *imo = &sc->sc_imo;
- int error;
-
- if (!(sc->sc_sync_if->if_flags & IFF_MULTICAST)) {
- sc->sc_sync_if = NULL;
- return (EADDRNOTAVAIL);
- }
-
- imo->imo_membership = (struct in_multi **)malloc(
- (sizeof(struct in_multi *) * IP_MIN_MEMBERSHIPS), M_PFSYNC,
- M_WAITOK | M_ZERO);
- imo->imo_max_memberships = IP_MIN_MEMBERSHIPS;
- imo->imo_multicast_vif = -1;
-
- if ((error = in_joingroup(sc->sc_sync_if, &sc->sc_sync_peer, NULL,
- &imo->imo_membership[0])) != 0) {
- free(imo->imo_membership, M_PFSYNC);
- return (error);
- }
- imo->imo_num_memberships++;
- imo->imo_multicast_ifp = sc->sc_sync_if;
- imo->imo_multicast_ttl = PFSYNC_DFLTTL;
- imo->imo_multicast_loop = 0;
-
- return (0);
-}
-
-static void
-pfsync_multicast_cleanup(struct pfsync_softc *sc)
-{
- struct ip_moptions *imo = &sc->sc_imo;
-
- in_leavegroup(imo->imo_membership[0], NULL);
- free(imo->imo_membership, M_PFSYNC);
- imo->imo_membership = NULL;
- imo->imo_multicast_ifp = NULL;
-}
-
-#ifdef INET
-extern struct domain inetdomain;
-static struct protosw in_pfsync_protosw = {
- .pr_type = SOCK_RAW,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_PFSYNC,
- .pr_flags = PR_ATOMIC|PR_ADDR,
- .pr_input = pfsync_input,
- .pr_output = (pr_output_t *)rip_output,
- .pr_ctloutput = rip_ctloutput,
- .pr_usrreqs = &rip_usrreqs
-};
-#endif
-
-static int
-pfsync_init()
-{
- VNET_ITERATOR_DECL(vnet_iter);
- int error = 0;
-
- VNET_LIST_RLOCK();
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET(vnet_iter);
- V_pfsync_cloner = pfsync_cloner;
- V_pfsync_cloner_data = pfsync_cloner_data;
- V_pfsync_cloner.ifc_data = &V_pfsync_cloner_data;
- if_clone_attach(&V_pfsync_cloner);
- error = swi_add(NULL, "pfsync", pfsyncintr, V_pfsyncif,
- SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie);
- CURVNET_RESTORE();
- if (error)
- goto fail_locked;
- }
- VNET_LIST_RUNLOCK();
-#ifdef INET
- error = pf_proto_register(PF_INET, &in_pfsync_protosw);
- if (error)
- goto fail;
- error = ipproto_register(IPPROTO_PFSYNC);
- if (error) {
- pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
- goto fail;
- }
-#endif
- PF_LOCK();
- pfsync_state_import_ptr = pfsync_state_import;
- pfsync_up_ptr = pfsync_up;
- pfsync_insert_state_ptr = pfsync_insert_state;
- pfsync_update_state_ptr = pfsync_update_state;
- pfsync_delete_state_ptr = pfsync_delete_state;
- pfsync_clear_states_ptr = pfsync_clear_states;
- pfsync_state_in_use_ptr = pfsync_state_in_use;
- pfsync_defer_ptr = pfsync_defer;
- PF_UNLOCK();
-
- return (0);
-
-fail:
- VNET_LIST_RLOCK();
-fail_locked:
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET(vnet_iter);
- if (V_pfsync_swi_cookie) {
- swi_remove(V_pfsync_swi_cookie);
- if_clone_detach(&V_pfsync_cloner);
- }
- CURVNET_RESTORE();
- }
- VNET_LIST_RUNLOCK();
-
- return (error);
-}
-
-static void
-pfsync_uninit()
-{
- VNET_ITERATOR_DECL(vnet_iter);
-
- PF_LOCK();
- pfsync_state_import_ptr = NULL;
- pfsync_up_ptr = NULL;
- pfsync_insert_state_ptr = NULL;
- pfsync_update_state_ptr = NULL;
- pfsync_delete_state_ptr = NULL;
- pfsync_clear_states_ptr = NULL;
- pfsync_state_in_use_ptr = NULL;
- pfsync_defer_ptr = NULL;
- PF_UNLOCK();
-
- ipproto_unregister(IPPROTO_PFSYNC);
- pf_proto_unregister(PF_INET, IPPROTO_PFSYNC, SOCK_RAW);
- VNET_LIST_RLOCK();
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET(vnet_iter);
- swi_remove(V_pfsync_swi_cookie);
- if_clone_detach(&V_pfsync_cloner);
- CURVNET_RESTORE();
- }
- VNET_LIST_RUNLOCK();
-}
-
-static int
-pfsync_modevent(module_t mod, int type, void *data)
-{
- int error = 0;
-
- switch (type) {
- case MOD_LOAD:
- error = pfsync_init();
- break;
- case MOD_QUIESCE:
- /*
- * Module should not be unloaded due to race conditions.
- */
- error = EPERM;
- break;
- case MOD_UNLOAD:
- pfsync_uninit();
- break;
- default:
- error = EINVAL;
- break;
- }
-
- return (error);
-}
-
-static moduledata_t pfsync_mod = {
- "pfsync",
- pfsync_modevent,
- 0
-};
-
-#define PFSYNC_MODVER 1
-
-DECLARE_MODULE(pfsync, pfsync_mod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
-MODULE_VERSION(pfsync, PFSYNC_MODVER);
-MODULE_DEPEND(pfsync, pf, PF_MODVER, PF_MODVER, PF_MODVER);
-#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/if_pfsync.h b/sys/contrib/pf/net/if_pfsync.h
deleted file mode 100644
index 3f34038..0000000
--- a/sys/contrib/pf/net/if_pfsync.h
+++ /dev/null
@@ -1,324 +0,0 @@
-/* $OpenBSD: if_pfsync.h,v 1.35 2008/06/29 08:42:15 mcbride Exp $ */
-
-/*
- * Copyright (c) 2001 Michael Shalayeff
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 HIS RELATIVES 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 MIND, 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.
- */
-
-/*
- * Copyright (c) 2008 David Gwynne <dlg@openbsd.org>
- *
- * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
- */
-
-#ifndef _NET_IF_PFSYNC_H_
-#define _NET_IF_PFSYNC_H_
-
-#define PFSYNC_VERSION 5
-#define PFSYNC_DFLTTL 255
-
-#define PFSYNC_ACT_CLR 0 /* clear all states */
-#define PFSYNC_ACT_INS 1 /* insert state */
-#define PFSYNC_ACT_INS_ACK 2 /* ack of insterted state */
-#define PFSYNC_ACT_UPD 3 /* update state */
-#define PFSYNC_ACT_UPD_C 4 /* "compressed" update state */
-#define PFSYNC_ACT_UPD_REQ 5 /* request "uncompressed" state */
-#define PFSYNC_ACT_DEL 6 /* delete state */
-#define PFSYNC_ACT_DEL_C 7 /* "compressed" delete state */
-#define PFSYNC_ACT_INS_F 8 /* insert fragment */
-#define PFSYNC_ACT_DEL_F 9 /* delete fragments */
-#define PFSYNC_ACT_BUS 10 /* bulk update status */
-#define PFSYNC_ACT_TDB 11 /* TDB replay counter update */
-#define PFSYNC_ACT_EOF 12 /* end of frame */
-#define PFSYNC_ACT_MAX 13
-
-#define PFSYNC_ACTIONS "CLR ST", \
- "INS ST", \
- "INS ST ACK", \
- "UPD ST", \
- "UPD ST COMP", \
- "UPD ST REQ", \
- "DEL ST", \
- "DEL ST COMP", \
- "INS FR", \
- "DEL FR", \
- "BULK UPD STAT", \
- "TDB UPD", \
- "EOF"
-
-#define PFSYNC_HMAC_LEN 20
-
-/*
- * A pfsync frame is built from a header followed by several sections which
- * are all prefixed with their own subheaders. Frames must be terminated with
- * an EOF subheader.
- *
- * | ... |
- * | IP header |
- * +============================+
- * | pfsync_header |
- * +----------------------------+
- * | pfsync_subheader |
- * +----------------------------+
- * | first action fields |
- * | ... |
- * +----------------------------+
- * | pfsync_subheader |
- * +----------------------------+
- * | second action fields |
- * | ... |
- * +----------------------------+
- * | EOF pfsync_subheader |
- * +----------------------------+
- * | HMAC |
- * +============================+
- */
-
-/*
- * Frame header
- */
-
-struct pfsync_header {
- u_int8_t version;
- u_int8_t _pad;
- u_int16_t len;
- u_int8_t pfcksum[PF_MD5_DIGEST_LENGTH];
-} __packed;
-
-/*
- * Frame region subheader
- */
-
-struct pfsync_subheader {
- u_int8_t action;
- u_int8_t _pad;
- u_int16_t count;
-} __packed;
-
-/*
- * CLR
- */
-
-struct pfsync_clr {
- char ifname[IFNAMSIZ];
- u_int32_t creatorid;
-} __packed;
-
-/*
- * INS, UPD, DEL
- */
-
-/* these use struct pfsync_state in pfvar.h */
-
-/*
- * INS_ACK
- */
-
-struct pfsync_ins_ack {
- u_int64_t id;
- u_int32_t creatorid;
-} __packed;
-
-/*
- * UPD_C
- */
-
-struct pfsync_upd_c {
- u_int64_t id;
- struct pfsync_state_peer src;
- struct pfsync_state_peer dst;
- u_int32_t creatorid;
- u_int32_t expire;
- u_int8_t timeout;
- u_int8_t _pad[3];
-} __packed;
-
-/*
- * UPD_REQ
- */
-
-struct pfsync_upd_req {
- u_int64_t id;
- u_int32_t creatorid;
-} __packed;
-
-/*
- * DEL_C
- */
-
-struct pfsync_del_c {
- u_int64_t id;
- u_int32_t creatorid;
-} __packed;
-
-/*
- * INS_F, DEL_F
- */
-
-/* not implemented (yet) */
-
-/*
- * BUS
- */
-
-struct pfsync_bus {
- u_int32_t creatorid;
- u_int32_t endtime;
- u_int8_t status;
-#define PFSYNC_BUS_START 1
-#define PFSYNC_BUS_END 2
- u_int8_t _pad[3];
-} __packed;
-
-/*
- * TDB
- */
-
-struct pfsync_tdb {
- u_int32_t spi;
- union sockaddr_union dst;
- u_int32_t rpl;
- u_int64_t cur_bytes;
- u_int8_t sproto;
- u_int8_t updates;
- u_int8_t _pad[2];
-} __packed;
-
-/*
- * EOF
- */
-
-struct pfsync_eof {
- u_int8_t hmac[PFSYNC_HMAC_LEN];
-} __packed;
-
-#define PFSYNC_HDRLEN sizeof(struct pfsync_header)
-
-
-
-/*
- * Names for PFSYNC sysctl objects
- */
-#define PFSYNCCTL_STATS 1 /* PFSYNC stats */
-#define PFSYNCCTL_MAXID 2
-
-#define PFSYNCCTL_NAMES { \
- { 0, 0 }, \
- { "stats", CTLTYPE_STRUCT }, \
-}
-
-struct pfsyncstats {
- u_int64_t pfsyncs_ipackets; /* total input packets, IPv4 */
- u_int64_t pfsyncs_ipackets6; /* total input packets, IPv6 */
- u_int64_t pfsyncs_badif; /* not the right interface */
- u_int64_t pfsyncs_badttl; /* TTL is not PFSYNC_DFLTTL */
- u_int64_t pfsyncs_hdrops; /* packets shorter than hdr */
- u_int64_t pfsyncs_badver; /* bad (incl unsupp) version */
- u_int64_t pfsyncs_badact; /* bad action */
- u_int64_t pfsyncs_badlen; /* data length does not match */
- u_int64_t pfsyncs_badauth; /* bad authentication */
- u_int64_t pfsyncs_stale; /* stale state */
- u_int64_t pfsyncs_badval; /* bad values */
- u_int64_t pfsyncs_badstate; /* insert/lookup failed */
-
- u_int64_t pfsyncs_opackets; /* total output packets, IPv4 */
- u_int64_t pfsyncs_opackets6; /* total output packets, IPv6 */
- u_int64_t pfsyncs_onomem; /* no memory for an mbuf */
- u_int64_t pfsyncs_oerrors; /* ip output error */
-};
-
-/*
- * Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
- */
-struct pfsyncreq {
- char pfsyncr_syncdev[IFNAMSIZ];
- struct in_addr pfsyncr_syncpeer;
- int pfsyncr_maxupdates;
- int pfsyncr_defer;
-};
-
-#ifdef __FreeBSD__
-#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
-#define SIOCGETPFSYNC _IOWR('i', 248, struct ifreq)
-#endif
-
-#ifdef _KERNEL
-
-/*
- * this shows where a pf state is with respect to the syncing.
- */
-#define PFSYNC_S_INS 0x00
-#define PFSYNC_S_IACK 0x01
-#define PFSYNC_S_UPD 0x02
-#define PFSYNC_S_UPD_C 0x03
-#define PFSYNC_S_DEL 0x04
-#define PFSYNC_S_COUNT 0x05
-
-#define PFSYNC_S_DEFER 0xfe
-#define PFSYNC_S_NONE 0xff
-
-#ifdef __FreeBSD__
-void pfsync_input(struct mbuf *, __unused int);
-#else
-void pfsync_input(struct mbuf *, ...);
-#endif
-int pfsync_sysctl(int *, u_int, void *, size_t *,
- void *, size_t);
-
-#define PFSYNC_SI_IOCTL 0x01
-#define PFSYNC_SI_CKSUM 0x02
-#define PFSYNC_SI_ACK 0x04
-int pfsync_state_import(struct pfsync_state *, u_int8_t);
-#ifndef __FreeBSD__
-void pfsync_state_export(struct pfsync_state *,
- struct pf_state *);
-#endif
-
-void pfsync_insert_state(struct pf_state *);
-void pfsync_update_state(struct pf_state *);
-void pfsync_delete_state(struct pf_state *);
-void pfsync_clear_states(u_int32_t, const char *);
-
-#ifdef notyet
-void pfsync_update_tdb(struct tdb *, int);
-void pfsync_delete_tdb(struct tdb *);
-#endif
-
-int pfsync_defer(struct pf_state *, struct mbuf *);
-
-int pfsync_up(void);
-int pfsync_state_in_use(struct pf_state *);
-#endif
-
-#endif /* _NET_IF_PFSYNC_H_ */
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c
deleted file mode 100644
index ac51282..0000000
--- a/sys/contrib/pf/net/pf.c
+++ /dev/null
@@ -1,7620 +0,0 @@
-/* $OpenBSD: pf.c,v 1.634 2009/02/27 12:37:45 henning Exp $ */
-
-/*
- * Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002 - 2008 Henning Brauer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- * Effort sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- *
- */
-
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#ifdef __FreeBSD__
-#include "opt_bpf.h"
-#include "opt_pf.h"
-
-#define NPFSYNC 1
-
-#ifdef DEV_PFLOW
-#define NPFLOW DEV_PFLOW
-#else
-#define NPFLOW 0
-#endif
-
-#else
-#include "bpfilter.h"
-#include "pflog.h"
-#include "pfsync.h"
-#include "pflow.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/filio.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/time.h>
-#ifdef __FreeBSD__
-#include <sys/random.h>
-#include <sys/sysctl.h>
-#include <sys/endian.h>
-#define betoh64 be64toh
-#else
-#include <sys/pool.h>
-#endif
-#include <sys/proc.h>
-#ifdef __FreeBSD__
-#include <sys/kthread.h>
-#include <sys/lock.h>
-#include <sys/sx.h>
-#else
-#include <sys/rwlock.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/md5.h>
-#else
-#include <crypto/md5.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/bpf.h>
-#include <net/route.h>
-#ifdef __FreeBSD__
-#ifdef RADIX_MPATH
-#include <net/radix_mpath.h>
-#endif
-#else
-#include <net/radix_mpath.h>
-#endif
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcp_seq.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/in_pcb.h>
-#include <netinet/tcp_timer.h>
-#include <netinet/tcp_var.h>
-#include <netinet/udp_var.h>
-#include <netinet/icmp_var.h>
-#include <netinet/if_ether.h>
-#ifdef __FreeBSD__
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h> /* XXX: only for DIR_IN/DIR_OUT */
-#endif
-
-#ifndef __FreeBSD__
-#include <dev/rndvar.h>
-#endif
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#include <net/if_pflow.h>
-#include <net/if_pfsync.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#include <netinet/in_pcb.h>
-#include <netinet/icmp6.h>
-#include <netinet6/nd6.h>
-#ifdef __FreeBSD__
-#include <netinet6/ip6_var.h>
-#include <netinet6/in6_pcb.h>
-#endif
-#endif /* INET6 */
-
-#ifdef __FreeBSD__
-#include <machine/in_cksum.h>
-#include <sys/limits.h>
-#include <sys/ucred.h>
-#include <security/mac/mac_framework.h>
-
-extern int ip_optcopy(struct ip *, struct ip *);
-#endif
-
-#ifdef __FreeBSD__
-#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
-#else
-#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
-#endif
-
-/*
- * Global variables
- */
-
-/* state tables */
-#ifdef __FreeBSD__
-VNET_DEFINE(struct pf_state_tree, pf_statetbl);
-
-VNET_DEFINE(struct pf_altqqueue, pf_altqs[2]);
-VNET_DEFINE(struct pf_palist, pf_pabuf);
-VNET_DEFINE(struct pf_altqqueue *, pf_altqs_active);
-VNET_DEFINE(struct pf_altqqueue *, pf_altqs_inactive);
-VNET_DEFINE(struct pf_status, pf_status);
-
-VNET_DEFINE(u_int32_t, ticket_altqs_active);
-VNET_DEFINE(u_int32_t, ticket_altqs_inactive);
-VNET_DEFINE(int, altqs_inactive_open);
-VNET_DEFINE(u_int32_t, ticket_pabuf);
-
-VNET_DEFINE(MD5_CTX, pf_tcp_secret_ctx);
-#define V_pf_tcp_secret_ctx VNET(pf_tcp_secret_ctx)
-VNET_DEFINE(u_char, pf_tcp_secret[16]);
-#define V_pf_tcp_secret VNET(pf_tcp_secret)
-VNET_DEFINE(int, pf_tcp_secret_init);
-#define V_pf_tcp_secret_init VNET(pf_tcp_secret_init)
-VNET_DEFINE(int, pf_tcp_iss_off);
-#define V_pf_tcp_iss_off VNET(pf_tcp_iss_off)
-
-struct pf_anchor_stackframe {
- struct pf_ruleset *rs;
- struct pf_rule *r;
- struct pf_anchor_node *parent;
- struct pf_anchor *child;
-};
-VNET_DEFINE(struct pf_anchor_stackframe, pf_anchor_stack[64]);
-#define V_pf_anchor_stack VNET(pf_anchor_stack)
-
-VNET_DEFINE(uma_zone_t, pf_src_tree_pl);
-VNET_DEFINE(uma_zone_t, pf_rule_pl);
-VNET_DEFINE(uma_zone_t, pf_pooladdr_pl);
-VNET_DEFINE(uma_zone_t, pf_state_pl);
-VNET_DEFINE(uma_zone_t, pf_state_key_pl);
-VNET_DEFINE(uma_zone_t, pf_state_item_pl);
-VNET_DEFINE(uma_zone_t, pf_altq_pl);
-#else
-struct pf_state_tree pf_statetbl;
-
-struct pf_altqqueue pf_altqs[2];
-struct pf_palist pf_pabuf;
-struct pf_altqqueue *pf_altqs_active;
-struct pf_altqqueue *pf_altqs_inactive;
-struct pf_status pf_status;
-
-u_int32_t ticket_altqs_active;
-u_int32_t ticket_altqs_inactive;
-int altqs_inactive_open;
-u_int32_t ticket_pabuf;
-
-MD5_CTX pf_tcp_secret_ctx;
-u_char pf_tcp_secret[16];
-int pf_tcp_secret_init;
-int pf_tcp_iss_off;
-
-struct pf_anchor_stackframe {
- struct pf_ruleset *rs;
- struct pf_rule *r;
- struct pf_anchor_node *parent;
- struct pf_anchor *child;
-} pf_anchor_stack[64];
-
-struct pool pf_src_tree_pl, pf_rule_pl, pf_pooladdr_pl;
-struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl;
-struct pool pf_altq_pl;
-#endif
-
-void pf_init_threshold(struct pf_threshold *, u_int32_t,
- u_int32_t);
-void pf_add_threshold(struct pf_threshold *);
-int pf_check_threshold(struct pf_threshold *);
-
-void pf_change_ap(struct pf_addr *, u_int16_t *,
- u_int16_t *, u_int16_t *, struct pf_addr *,
- u_int16_t, u_int8_t, sa_family_t);
-int pf_modulate_sack(struct mbuf *, int, struct pf_pdesc *,
- struct tcphdr *, struct pf_state_peer *);
-#ifdef INET6
-void pf_change_a6(struct pf_addr *, u_int16_t *,
- struct pf_addr *, u_int8_t);
-#endif /* INET6 */
-void pf_change_icmp(struct pf_addr *, u_int16_t *,
- struct pf_addr *, struct pf_addr *, u_int16_t,
- u_int16_t *, u_int16_t *, u_int16_t *,
- u_int16_t *, u_int8_t, sa_family_t);
-#ifdef __FreeBSD__
-void pf_send_tcp(struct mbuf *,
- const struct pf_rule *, sa_family_t,
-#else
-void pf_send_tcp(const struct pf_rule *, sa_family_t,
-#endif
- const struct pf_addr *, const struct pf_addr *,
- u_int16_t, u_int16_t, u_int32_t, u_int32_t,
- u_int8_t, u_int16_t, u_int16_t, u_int8_t, int,
- u_int16_t, struct ether_header *, struct ifnet *);
-static void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
- sa_family_t, struct pf_rule *);
-void pf_detach_state(struct pf_state *);
-void pf_state_key_detach(struct pf_state *, int);
-u_int32_t pf_tcp_iss(struct pf_pdesc *);
-int pf_test_rule(struct pf_rule **, struct pf_state **,
- int, struct pfi_kif *, struct mbuf *, int,
- void *, struct pf_pdesc *, struct pf_rule **,
-#ifdef __FreeBSD__
- struct pf_ruleset **, struct ifqueue *,
- struct inpcb *);
-#else
- struct pf_ruleset **, struct ifqueue *);
-#endif
-static __inline int pf_create_state(struct pf_rule *, struct pf_rule *,
- struct pf_rule *, struct pf_pdesc *,
- struct pf_src_node *, struct pf_state_key *,
- struct pf_state_key *, struct pf_state_key *,
- struct pf_state_key *, struct mbuf *, int,
- u_int16_t, u_int16_t, int *, struct pfi_kif *,
- struct pf_state **, int, u_int16_t, u_int16_t,
- int);
-int pf_test_fragment(struct pf_rule **, int,
- struct pfi_kif *, struct mbuf *, void *,
- struct pf_pdesc *, struct pf_rule **,
- struct pf_ruleset **);
-int pf_tcp_track_full(struct pf_state_peer *,
- struct pf_state_peer *, struct pf_state **,
- struct pfi_kif *, struct mbuf *, int,
- struct pf_pdesc *, u_short *, int *);
-int pf_tcp_track_sloppy(struct pf_state_peer *,
- struct pf_state_peer *, struct pf_state **,
- struct pf_pdesc *, u_short *);
-int pf_test_state_tcp(struct pf_state **, int,
- struct pfi_kif *, struct mbuf *, int,
- void *, struct pf_pdesc *, u_short *);
-int pf_test_state_udp(struct pf_state **, int,
- struct pfi_kif *, struct mbuf *, int,
- void *, struct pf_pdesc *);
-int pf_test_state_icmp(struct pf_state **, int,
- struct pfi_kif *, struct mbuf *, int,
- void *, struct pf_pdesc *, u_short *);
-int pf_test_state_other(struct pf_state **, int,
- struct pfi_kif *, struct mbuf *, struct pf_pdesc *);
-void pf_route(struct mbuf **, struct pf_rule *, int,
- struct ifnet *, struct pf_state *,
- struct pf_pdesc *);
-void pf_route6(struct mbuf **, struct pf_rule *, int,
- struct ifnet *, struct pf_state *,
- struct pf_pdesc *);
-#ifndef __FreeBSD__
-int pf_socket_lookup(int, struct pf_pdesc *);
-#endif
-u_int8_t pf_get_wscale(struct mbuf *, int, u_int16_t,
- sa_family_t);
-u_int16_t pf_get_mss(struct mbuf *, int, u_int16_t,
- sa_family_t);
-u_int16_t pf_calc_mss(struct pf_addr *, sa_family_t,
- int, u_int16_t);
-void pf_set_rt_ifp(struct pf_state *,
- struct pf_addr *);
-int pf_check_proto_cksum(struct mbuf *, int, int,
- u_int8_t, sa_family_t);
-#ifndef __FreeBSD__
-struct pf_divert *pf_get_divert(struct mbuf *);
-#endif
-void pf_print_state_parts(struct pf_state *,
- struct pf_state_key *, struct pf_state_key *);
-int pf_addr_wrap_neq(struct pf_addr_wrap *,
- struct pf_addr_wrap *);
-int pf_compare_state_keys(struct pf_state_key *,
- struct pf_state_key *, struct pfi_kif *, u_int);
-#ifdef __FreeBSD__
-struct pf_state *pf_find_state(struct pfi_kif *,
- struct pf_state_key_cmp *, u_int, struct mbuf *,
- struct pf_mtag *);
-#else
-struct pf_state *pf_find_state(struct pfi_kif *,
- struct pf_state_key_cmp *, u_int, struct mbuf *);
-#endif
-int pf_src_connlimit(struct pf_state **);
-int pf_check_congestion(struct ifqueue *);
-
-#ifdef __FreeBSD__
-int in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len);
-
-VNET_DECLARE(int, pf_end_threads);
-
-VNET_DEFINE(struct pf_pool_limit, pf_pool_limits[PF_LIMIT_MAX]);
-#else
-extern struct pool pfr_ktable_pl;
-extern struct pool pfr_kentry_pl;
-
-struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX] = {
- { &pf_state_pl, PFSTATE_HIWAT },
- { &pf_src_tree_pl, PFSNODE_HIWAT },
- { &pf_frent_pl, PFFRAG_FRENT_HIWAT },
- { &pfr_ktable_pl, PFR_KTABLE_HIWAT },
- { &pfr_kentry_pl, PFR_KENTRY_HIWAT }
-};
-#endif
-
-#ifdef __FreeBSD__
-#define PPACKET_LOOPED() \
- (pd->pf_mtag->flags & PF_PACKET_LOOPED)
-
-#define PACKET_LOOPED() \
- (pd.pf_mtag->flags & PF_PACKET_LOOPED)
-
-#define STATE_LOOKUP(i, k, d, s, m, pt) \
- do { \
- s = pf_find_state(i, k, d, m, pt); \
- if (s == NULL || (s)->timeout == PFTM_PURGE) \
- return (PF_DROP); \
- if (PPACKET_LOOPED()) \
- return (PF_PASS); \
- if (d == PF_OUT && \
- (((s)->rule.ptr->rt == PF_ROUTETO && \
- (s)->rule.ptr->direction == PF_OUT) || \
- ((s)->rule.ptr->rt == PF_REPLYTO && \
- (s)->rule.ptr->direction == PF_IN)) && \
- (s)->rt_kif != NULL && \
- (s)->rt_kif != i) \
- return (PF_PASS); \
- } while (0)
-#else
-#define STATE_LOOKUP(i, k, d, s, m) \
- do { \
- s = pf_find_state(i, k, d, m); \
- if (s == NULL || (s)->timeout == PFTM_PURGE) \
- return (PF_DROP); \
- if (d == PF_OUT && \
- (((s)->rule.ptr->rt == PF_ROUTETO && \
- (s)->rule.ptr->direction == PF_OUT) || \
- ((s)->rule.ptr->rt == PF_REPLYTO && \
- (s)->rule.ptr->direction == PF_IN)) && \
- (s)->rt_kif != NULL && \
- (s)->rt_kif != i) \
- return (PF_PASS); \
- } while (0)
-#endif
-
-#ifdef __FreeBSD__
-#define BOUND_IFACE(r, k) \
- ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : V_pfi_all
-#else
-#define BOUND_IFACE(r, k) \
- ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : pfi_all
-#endif
-
-#define STATE_INC_COUNTERS(s) \
- do { \
- s->rule.ptr->states_cur++; \
- s->rule.ptr->states_tot++; \
- if (s->anchor.ptr != NULL) { \
- s->anchor.ptr->states_cur++; \
- s->anchor.ptr->states_tot++; \
- } \
- if (s->nat_rule.ptr != NULL) { \
- s->nat_rule.ptr->states_cur++; \
- s->nat_rule.ptr->states_tot++; \
- } \
- } while (0)
-
-#define STATE_DEC_COUNTERS(s) \
- do { \
- if (s->nat_rule.ptr != NULL) \
- s->nat_rule.ptr->states_cur--; \
- if (s->anchor.ptr != NULL) \
- s->anchor.ptr->states_cur--; \
- s->rule.ptr->states_cur--; \
- } while (0)
-
-static __inline int pf_src_compare(struct pf_src_node *, struct pf_src_node *);
-static __inline int pf_state_compare_key(struct pf_state_key *,
- struct pf_state_key *);
-static __inline int pf_state_compare_id(struct pf_state *,
- struct pf_state *);
-
-#ifdef __FreeBSD__
-VNET_DEFINE(struct pf_src_tree, tree_src_tracking);
-
-VNET_DEFINE(struct pf_state_tree_id, tree_id);
-VNET_DEFINE(struct pf_state_queue, state_list);
-#else
-struct pf_src_tree tree_src_tracking;
-
-struct pf_state_tree_id tree_id;
-struct pf_state_queue state_list;
-#endif
-
-RB_GENERATE(pf_src_tree, pf_src_node, entry, pf_src_compare);
-RB_GENERATE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
-RB_GENERATE(pf_state_tree_id, pf_state,
- entry_id, pf_state_compare_id);
-
-static __inline int
-pf_src_compare(struct pf_src_node *a, struct pf_src_node *b)
-{
- int diff;
-
- if (a->rule.ptr > b->rule.ptr)
- return (1);
- if (a->rule.ptr < b->rule.ptr)
- return (-1);
- if ((diff = a->af - b->af) != 0)
- return (diff);
- switch (a->af) {
-#ifdef INET
- case AF_INET:
- if (a->addr.addr32[0] > b->addr.addr32[0])
- return (1);
- if (a->addr.addr32[0] < b->addr.addr32[0])
- return (-1);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (a->addr.addr32[3] > b->addr.addr32[3])
- return (1);
- if (a->addr.addr32[3] < b->addr.addr32[3])
- return (-1);
- if (a->addr.addr32[2] > b->addr.addr32[2])
- return (1);
- if (a->addr.addr32[2] < b->addr.addr32[2])
- return (-1);
- if (a->addr.addr32[1] > b->addr.addr32[1])
- return (1);
- if (a->addr.addr32[1] < b->addr.addr32[1])
- return (-1);
- if (a->addr.addr32[0] > b->addr.addr32[0])
- return (1);
- if (a->addr.addr32[0] < b->addr.addr32[0])
- return (-1);
- break;
-#endif /* INET6 */
- }
- return (0);
-}
-
-#ifdef INET6
-void
-pf_addrcpy(struct pf_addr *dst, struct pf_addr *src, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET:
- dst->addr32[0] = src->addr32[0];
- break;
-#endif /* INET */
- case AF_INET6:
- dst->addr32[0] = src->addr32[0];
- dst->addr32[1] = src->addr32[1];
- dst->addr32[2] = src->addr32[2];
- dst->addr32[3] = src->addr32[3];
- break;
- }
-}
-#endif /* INET6 */
-
-void
-pf_init_threshold(struct pf_threshold *threshold,
- u_int32_t limit, u_int32_t seconds)
-{
- threshold->limit = limit * PF_THRESHOLD_MULT;
- threshold->seconds = seconds;
- threshold->count = 0;
- threshold->last = time_second;
-}
-
-void
-pf_add_threshold(struct pf_threshold *threshold)
-{
- u_int32_t t = time_second, diff = t - threshold->last;
-
- if (diff >= threshold->seconds)
- threshold->count = 0;
- else
- threshold->count -= threshold->count * diff /
- threshold->seconds;
- threshold->count += PF_THRESHOLD_MULT;
- threshold->last = t;
-}
-
-int
-pf_check_threshold(struct pf_threshold *threshold)
-{
- return (threshold->count > threshold->limit);
-}
-
-int
-pf_src_connlimit(struct pf_state **state)
-{
- int bad = 0;
-
- (*state)->src_node->conn++;
- (*state)->src.tcp_est = 1;
- pf_add_threshold(&(*state)->src_node->conn_rate);
-
- if ((*state)->rule.ptr->max_src_conn &&
- (*state)->rule.ptr->max_src_conn <
- (*state)->src_node->conn) {
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_SRCCONN]++;
-#else
- pf_status.lcounters[LCNT_SRCCONN]++;
-#endif
- bad++;
- }
-
- if ((*state)->rule.ptr->max_src_conn_rate.limit &&
- pf_check_threshold(&(*state)->src_node->conn_rate)) {
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_SRCCONNRATE]++;
-#else
- pf_status.lcounters[LCNT_SRCCONNRATE]++;
-#endif
- bad++;
- }
-
- if (!bad)
- return (0);
-
- if ((*state)->rule.ptr->overload_tbl) {
- struct pfr_addr p;
- u_int32_t killed = 0;
-
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- pf_status.lcounters[LCNT_OVERLOAD_TABLE]++;
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf_src_connlimit: blocking address ");
- pf_print_host(&(*state)->src_node->addr, 0,
- (*state)->key[PF_SK_WIRE]->af);
- }
-
- bzero(&p, sizeof(p));
- p.pfra_af = (*state)->key[PF_SK_WIRE]->af;
- switch ((*state)->key[PF_SK_WIRE]->af) {
-#ifdef INET
- case AF_INET:
- p.pfra_net = 32;
- p.pfra_ip4addr = (*state)->src_node->addr.v4;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- p.pfra_net = 128;
- p.pfra_ip6addr = (*state)->src_node->addr.v6;
- break;
-#endif /* INET6 */
- }
-
- pfr_insert_kentry((*state)->rule.ptr->overload_tbl,
- &p, time_second);
-
- /* kill existing states if that's required. */
- if ((*state)->rule.ptr->flush) {
- struct pf_state_key *sk;
- struct pf_state *st;
-
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
- RB_FOREACH(st, pf_state_tree_id, &V_tree_id) {
-#else
- pf_status.lcounters[LCNT_OVERLOAD_FLUSH]++;
- RB_FOREACH(st, pf_state_tree_id, &tree_id) {
-#endif
- sk = st->key[PF_SK_WIRE];
- /*
- * Kill states from this source. (Only those
- * from the same rule if PF_FLUSH_GLOBAL is not
- * set)
- */
- if (sk->af ==
- (*state)->key[PF_SK_WIRE]->af &&
- (((*state)->direction == PF_OUT &&
- PF_AEQ(&(*state)->src_node->addr,
- &sk->addr[1], sk->af)) ||
- ((*state)->direction == PF_IN &&
- PF_AEQ(&(*state)->src_node->addr,
- &sk->addr[0], sk->af))) &&
- ((*state)->rule.ptr->flush &
- PF_FLUSH_GLOBAL ||
- (*state)->rule.ptr == st->rule.ptr)) {
- st->timeout = PFTM_PURGE;
- st->src.state = st->dst.state =
- TCPS_CLOSED;
- killed++;
- }
- }
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf(", %u states killed", killed);
- }
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC)
-#else
- if (pf_status.debug >= PF_DEBUG_MISC)
-#endif
- printf("\n");
- }
-
- /* kill this state */
- (*state)->timeout = PFTM_PURGE;
- (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
- return (1);
-}
-
-int
-pf_insert_src_node(struct pf_src_node **sn, struct pf_rule *rule,
- struct pf_addr *src, sa_family_t af)
-{
- struct pf_src_node k;
-
- if (*sn == NULL) {
- k.af = af;
- PF_ACPY(&k.addr, src, af);
- if (rule->rule_flag & PFRULE_RULESRCTRACK ||
- rule->rpool.opts & PF_POOL_STICKYADDR)
- k.rule.ptr = rule;
- else
- k.rule.ptr = NULL;
-#ifdef __FreeBSD__
- V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
- *sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
-#else
- pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
- *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
-#endif
- }
- if (*sn == NULL) {
- if (!rule->max_src_nodes ||
- rule->src_nodes < rule->max_src_nodes)
-#ifdef __FreeBSD__
- (*sn) = pool_get(&V_pf_src_tree_pl, PR_NOWAIT | PR_ZERO);
-#else
- (*sn) = pool_get(&pf_src_tree_pl, PR_NOWAIT | PR_ZERO);
-#endif
- else
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_SRCNODES]++;
-#else
- pf_status.lcounters[LCNT_SRCNODES]++;
-#endif
- if ((*sn) == NULL)
- return (-1);
-
- pf_init_threshold(&(*sn)->conn_rate,
- rule->max_src_conn_rate.limit,
- rule->max_src_conn_rate.seconds);
-
- (*sn)->af = af;
- if (rule->rule_flag & PFRULE_RULESRCTRACK ||
- rule->rpool.opts & PF_POOL_STICKYADDR)
- (*sn)->rule.ptr = rule;
- else
- (*sn)->rule.ptr = NULL;
- PF_ACPY(&(*sn)->addr, src, af);
- if (RB_INSERT(pf_src_tree,
-#ifdef __FreeBSD__
- &V_tree_src_tracking, *sn) != NULL) {
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- &tree_src_tracking, *sn) != NULL) {
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: src_tree insert failed: ");
- pf_print_host(&(*sn)->addr, 0, af);
- printf("\n");
- }
-#ifdef __FreeBSD__
- pool_put(&V_pf_src_tree_pl, *sn);
-#else
- pool_put(&pf_src_tree_pl, *sn);
-#endif
- return (-1);
- }
- (*sn)->creation = time_second;
- (*sn)->ruletype = rule->action;
- if ((*sn)->rule.ptr != NULL)
- (*sn)->rule.ptr->src_nodes++;
-#ifdef __FreeBSD__
- V_pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
- V_pf_status.src_nodes++;
-#else
- pf_status.scounters[SCNT_SRC_NODE_INSERT]++;
- pf_status.src_nodes++;
-#endif
- } else {
- if (rule->max_src_states &&
- (*sn)->states >= rule->max_src_states) {
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_SRCSTATES]++;
-#else
- pf_status.lcounters[LCNT_SRCSTATES]++;
-#endif
- return (-1);
- }
- }
- return (0);
-}
-
-/* state table stuff */
-
-static __inline int
-pf_state_compare_key(struct pf_state_key *a, struct pf_state_key *b)
-{
- int diff;
-
- if ((diff = a->proto - b->proto) != 0)
- return (diff);
- if ((diff = a->af - b->af) != 0)
- return (diff);
- switch (a->af) {
-#ifdef INET
- case AF_INET:
- if (a->addr[0].addr32[0] > b->addr[0].addr32[0])
- return (1);
- if (a->addr[0].addr32[0] < b->addr[0].addr32[0])
- return (-1);
- if (a->addr[1].addr32[0] > b->addr[1].addr32[0])
- return (1);
- if (a->addr[1].addr32[0] < b->addr[1].addr32[0])
- return (-1);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (a->addr[0].addr32[3] > b->addr[0].addr32[3])
- return (1);
- if (a->addr[0].addr32[3] < b->addr[0].addr32[3])
- return (-1);
- if (a->addr[1].addr32[3] > b->addr[1].addr32[3])
- return (1);
- if (a->addr[1].addr32[3] < b->addr[1].addr32[3])
- return (-1);
- if (a->addr[0].addr32[2] > b->addr[0].addr32[2])
- return (1);
- if (a->addr[0].addr32[2] < b->addr[0].addr32[2])
- return (-1);
- if (a->addr[1].addr32[2] > b->addr[1].addr32[2])
- return (1);
- if (a->addr[1].addr32[2] < b->addr[1].addr32[2])
- return (-1);
- if (a->addr[0].addr32[1] > b->addr[0].addr32[1])
- return (1);
- if (a->addr[0].addr32[1] < b->addr[0].addr32[1])
- return (-1);
- if (a->addr[1].addr32[1] > b->addr[1].addr32[1])
- return (1);
- if (a->addr[1].addr32[1] < b->addr[1].addr32[1])
- return (-1);
- if (a->addr[0].addr32[0] > b->addr[0].addr32[0])
- return (1);
- if (a->addr[0].addr32[0] < b->addr[0].addr32[0])
- return (-1);
- if (a->addr[1].addr32[0] > b->addr[1].addr32[0])
- return (1);
- if (a->addr[1].addr32[0] < b->addr[1].addr32[0])
- return (-1);
- break;
-#endif /* INET6 */
- }
-
- if ((diff = a->port[0] - b->port[0]) != 0)
- return (diff);
- if ((diff = a->port[1] - b->port[1]) != 0)
- return (diff);
-
- return (0);
-}
-
-static __inline int
-pf_state_compare_id(struct pf_state *a, struct pf_state *b)
-{
- if (a->id > b->id)
- return (1);
- if (a->id < b->id)
- return (-1);
- if (a->creatorid > b->creatorid)
- return (1);
- if (a->creatorid < b->creatorid)
- return (-1);
-
- return (0);
-}
-
-int
-pf_state_key_attach(struct pf_state_key *sk, struct pf_state *s, int idx)
-{
- struct pf_state_item *si;
- struct pf_state_key *cur;
- struct pf_state *olds = NULL;
-
-#ifdef __FreeBSD__
- KASSERT(s->key[idx] == NULL, ("%s: key is null!", __FUNCTION__));
-#else
- KASSERT(s->key[idx] == NULL); /* XXX handle this? */
-#endif
-
-#ifdef __FreeBSD__
- if ((cur = RB_INSERT(pf_state_tree, &V_pf_statetbl, sk)) != NULL) {
-#else
- if ((cur = RB_INSERT(pf_state_tree, &pf_statetbl, sk)) != NULL) {
-#endif
- /* key exists. check for same kif, if none, add to key */
- TAILQ_FOREACH(si, &cur->states, entry)
- if (si->s->kif == s->kif &&
- si->s->direction == s->direction) {
- if (sk->proto == IPPROTO_TCP &&
- si->s->src.state >= TCPS_FIN_WAIT_2 &&
- si->s->dst.state >= TCPS_FIN_WAIT_2) {
- si->s->src.state = si->s->dst.state =
- TCPS_CLOSED;
- /* unlink late or sks can go away */
- olds = si->s;
- } else {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: %s key attach "
- "failed on %s: ",
- (idx == PF_SK_WIRE) ?
- "wire" : "stack",
- s->kif->pfik_name);
- pf_print_state_parts(s,
- (idx == PF_SK_WIRE) ?
- sk : NULL,
- (idx == PF_SK_STACK) ?
- sk : NULL);
- printf(", existing: ");
- pf_print_state_parts(si->s,
- (idx == PF_SK_WIRE) ?
- sk : NULL,
- (idx == PF_SK_STACK) ?
- sk : NULL);
- printf("\n");
- }
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_key_pl, sk);
-#else
- pool_put(&pf_state_key_pl, sk);
-#endif
- return (-1); /* collision! */
- }
- }
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_key_pl, sk);
-#else
- pool_put(&pf_state_key_pl, sk);
-#endif
- s->key[idx] = cur;
- } else
- s->key[idx] = sk;
-
-#ifdef __FreeBSD__
- if ((si = pool_get(&V_pf_state_item_pl, PR_NOWAIT)) == NULL) {
-#else
- if ((si = pool_get(&pf_state_item_pl, PR_NOWAIT)) == NULL) {
-#endif
- pf_state_key_detach(s, idx);
- return (-1);
- }
- si->s = s;
-
- /* list is sorted, if-bound states before floating */
-#ifdef __FreeBSD__
- if (s->kif == V_pfi_all)
-#else
- if (s->kif == pfi_all)
-#endif
- TAILQ_INSERT_TAIL(&s->key[idx]->states, si, entry);
- else
- TAILQ_INSERT_HEAD(&s->key[idx]->states, si, entry);
-
- if (olds)
- pf_unlink_state(olds);
-
- return (0);
-}
-
-void
-pf_detach_state(struct pf_state *s)
-{
- if (s->key[PF_SK_WIRE] == s->key[PF_SK_STACK])
- s->key[PF_SK_WIRE] = NULL;
-
- if (s->key[PF_SK_STACK] != NULL)
- pf_state_key_detach(s, PF_SK_STACK);
-
- if (s->key[PF_SK_WIRE] != NULL)
- pf_state_key_detach(s, PF_SK_WIRE);
-}
-
-void
-pf_state_key_detach(struct pf_state *s, int idx)
-{
- struct pf_state_item *si;
-
- si = TAILQ_FIRST(&s->key[idx]->states);
- while (si && si->s != s)
- si = TAILQ_NEXT(si, entry);
-
- if (si) {
- TAILQ_REMOVE(&s->key[idx]->states, si, entry);
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_item_pl, si);
-#else
- pool_put(&pf_state_item_pl, si);
-#endif
- }
-
- if (TAILQ_EMPTY(&s->key[idx]->states)) {
-#ifdef __FreeBSD__
- RB_REMOVE(pf_state_tree, &V_pf_statetbl, s->key[idx]);
-#else
- RB_REMOVE(pf_state_tree, &pf_statetbl, s->key[idx]);
-#endif
- if (s->key[idx]->reverse)
- s->key[idx]->reverse->reverse = NULL;
-#ifdef __FreeBSD__
- /* XXX: implement this */
-#else
- if (s->key[idx]->inp)
- s->key[idx]->inp->inp_pf_sk = NULL;
-#endif
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_key_pl, s->key[idx]);
-#else
- pool_put(&pf_state_key_pl, s->key[idx]);
-#endif
- }
- s->key[idx] = NULL;
-}
-
-struct pf_state_key *
-pf_alloc_state_key(int pool_flags)
-{
- struct pf_state_key *sk;
-
-#ifdef __FreeBSD__
- if ((sk = pool_get(&V_pf_state_key_pl, pool_flags)) == NULL)
-#else
- if ((sk = pool_get(&pf_state_key_pl, pool_flags)) == NULL)
-#endif
- return (NULL);
- TAILQ_INIT(&sk->states);
-
- return (sk);
-}
-
-int
-pf_state_key_setup(struct pf_pdesc *pd, struct pf_rule *nr,
- struct pf_state_key **skw, struct pf_state_key **sks,
- struct pf_state_key **skp, struct pf_state_key **nkp,
- struct pf_addr *saddr, struct pf_addr *daddr,
- u_int16_t sport, u_int16_t dport)
-{
-#ifdef __FreeBSD__
- KASSERT((*skp == NULL && *nkp == NULL),
- ("%s: skp == NULL && nkp == NULL", __FUNCTION__));
-#else
- KASSERT((*skp == NULL && *nkp == NULL));
-#endif
-
- if ((*skp = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL)
- return (ENOMEM);
-
- PF_ACPY(&(*skp)->addr[pd->sidx], saddr, pd->af);
- PF_ACPY(&(*skp)->addr[pd->didx], daddr, pd->af);
- (*skp)->port[pd->sidx] = sport;
- (*skp)->port[pd->didx] = dport;
- (*skp)->proto = pd->proto;
- (*skp)->af = pd->af;
-
- if (nr != NULL) {
- if ((*nkp = pf_alloc_state_key(PR_NOWAIT | PR_ZERO)) == NULL)
- return (ENOMEM); /* caller must handle cleanup */
-
- /* XXX maybe just bcopy and TAILQ_INIT(&(*nkp)->states) */
- PF_ACPY(&(*nkp)->addr[0], &(*skp)->addr[0], pd->af);
- PF_ACPY(&(*nkp)->addr[1], &(*skp)->addr[1], pd->af);
- (*nkp)->port[0] = (*skp)->port[0];
- (*nkp)->port[1] = (*skp)->port[1];
- (*nkp)->proto = pd->proto;
- (*nkp)->af = pd->af;
- } else
- *nkp = *skp;
-
- if (pd->dir == PF_IN) {
- *skw = *skp;
- *sks = *nkp;
- } else {
- *sks = *skp;
- *skw = *nkp;
- }
- return (0);
-}
-
-
-int
-pf_state_insert(struct pfi_kif *kif, struct pf_state_key *skw,
- struct pf_state_key *sks, struct pf_state *s)
-{
-#ifndef __FreeBSD__
- splassert(IPL_SOFTNET);
-#endif
-
- s->kif = kif;
-
- if (skw == sks) {
- if (pf_state_key_attach(skw, s, PF_SK_WIRE))
- return (-1);
- s->key[PF_SK_STACK] = s->key[PF_SK_WIRE];
- } else {
- if (pf_state_key_attach(skw, s, PF_SK_WIRE)) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_key_pl, sks);
-#else
- pool_put(&pf_state_key_pl, sks);
-#endif
- return (-1);
- }
- if (pf_state_key_attach(sks, s, PF_SK_STACK)) {
- pf_state_key_detach(s, PF_SK_WIRE);
- return (-1);
- }
- }
-
- if (s->id == 0 && s->creatorid == 0) {
-#ifdef __FreeBSD__
- s->id = htobe64(V_pf_status.stateid++);
- s->creatorid = V_pf_status.hostid;
-#else
- s->id = htobe64(pf_status.stateid++);
- s->creatorid = pf_status.hostid;
-#endif
- }
-#ifdef __FreeBSD__
- if (RB_INSERT(pf_state_tree_id, &V_tree_id, s) != NULL) {
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (RB_INSERT(pf_state_tree_id, &tree_id, s) != NULL) {
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: state insert failed: "
- "id: %016llx creatorid: %08x",
-#ifdef __FreeBSD__
- (unsigned long long)betoh64(s->id), ntohl(s->creatorid));
-#else
- betoh64(s->id), ntohl(s->creatorid));
-#endif
- printf("\n");
- }
- pf_detach_state(s);
- return (-1);
- }
-#ifdef __FreeBSD__
- TAILQ_INSERT_TAIL(&V_state_list, s, entry_list);
- V_pf_status.fcounters[FCNT_STATE_INSERT]++;
- V_pf_status.states++;
-#else
- TAILQ_INSERT_TAIL(&state_list, s, entry_list);
- pf_status.fcounters[FCNT_STATE_INSERT]++;
- pf_status.states++;
-#endif
- pfi_kif_ref(kif, PFI_KIF_REF_STATE);
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_insert_state_ptr != NULL)
- pfsync_insert_state_ptr(s);
-#else
- pfsync_insert_state(s);
-#endif
-#endif
- return (0);
-}
-
-struct pf_state *
-pf_find_state_byid(struct pf_state_cmp *key)
-{
-#ifdef __FreeBSD__
- V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
-
- return (RB_FIND(pf_state_tree_id, &V_tree_id, (struct pf_state *)key));
-#else
- pf_status.fcounters[FCNT_STATE_SEARCH]++;
-
- return (RB_FIND(pf_state_tree_id, &tree_id, (struct pf_state *)key));
-#endif
-}
-
-/* XXX debug function, intended to be removed one day */
-int
-pf_compare_state_keys(struct pf_state_key *a, struct pf_state_key *b,
- struct pfi_kif *kif, u_int dir)
-{
- /* a (from hdr) and b (new) must be exact opposites of each other */
- if (a->af == b->af && a->proto == b->proto &&
- PF_AEQ(&a->addr[0], &b->addr[1], a->af) &&
- PF_AEQ(&a->addr[1], &b->addr[0], a->af) &&
- a->port[0] == b->port[1] &&
- a->port[1] == b->port[0])
- return (0);
- else {
- /* mismatch. must not happen. */
- printf("pf: state key linking mismatch! dir=%s, "
- "if=%s, stored af=%u, a0: ",
- dir == PF_OUT ? "OUT" : "IN", kif->pfik_name, a->af);
- pf_print_host(&a->addr[0], a->port[0], a->af);
- printf(", a1: ");
- pf_print_host(&a->addr[1], a->port[1], a->af);
- printf(", proto=%u", a->proto);
- printf(", found af=%u, a0: ", b->af);
- pf_print_host(&b->addr[0], b->port[0], b->af);
- printf(", a1: ");
- pf_print_host(&b->addr[1], b->port[1], b->af);
- printf(", proto=%u", b->proto);
- printf(".\n");
- return (-1);
- }
-}
-
-struct pf_state *
-#ifdef __FreeBSD__
-pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir,
- struct mbuf *m, struct pf_mtag *pftag)
-#else
-pf_find_state(struct pfi_kif *kif, struct pf_state_key_cmp *key, u_int dir,
- struct mbuf *m)
-#endif
-{
- struct pf_state_key *sk;
- struct pf_state_item *si;
-
-#ifdef __FreeBSD__
- V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
-#else
- pf_status.fcounters[FCNT_STATE_SEARCH]++;
-#endif
-
-#ifdef __FreeBSD__
- if (dir == PF_OUT && pftag->statekey &&
- ((struct pf_state_key *)pftag->statekey)->reverse)
- sk = ((struct pf_state_key *)pftag->statekey)->reverse;
- else {
-#ifdef __FreeBSD__
- if ((sk = RB_FIND(pf_state_tree, &V_pf_statetbl,
-#else
- if ((sk = RB_FIND(pf_state_tree, &pf_statetbl,
-#endif
- (struct pf_state_key *)key)) == NULL)
- return (NULL);
- if (dir == PF_OUT && pftag->statekey &&
- pf_compare_state_keys(pftag->statekey, sk,
- kif, dir) == 0) {
- ((struct pf_state_key *)
- pftag->statekey)->reverse = sk;
- sk->reverse = pftag->statekey;
- }
- }
-#else
- if (dir == PF_OUT && m->m_pkthdr.pf.statekey &&
- ((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse)
- sk = ((struct pf_state_key *)m->m_pkthdr.pf.statekey)->reverse;
- else {
-#ifdef __FreeBSD__
- if ((sk = RB_FIND(pf_state_tree, &V_pf_statetbl,
-#else
- if ((sk = RB_FIND(pf_state_tree, &pf_statetbl,
-#endif
- (struct pf_state_key *)key)) == NULL)
- return (NULL);
- if (dir == PF_OUT && m->m_pkthdr.pf.statekey &&
- pf_compare_state_keys(m->m_pkthdr.pf.statekey, sk,
- kif, dir) == 0) {
- ((struct pf_state_key *)
- m->m_pkthdr.pf.statekey)->reverse = sk;
- sk->reverse = m->m_pkthdr.pf.statekey;
- }
- }
-#endif
-
- if (dir == PF_OUT)
-#ifdef __FreeBSD__
- pftag->statekey = NULL;
-#else
- m->m_pkthdr.pf.statekey = NULL;
-#endif
-
- /* list is sorted, if-bound states before floating ones */
- TAILQ_FOREACH(si, &sk->states, entry)
-#ifdef __FreeBSD__
- if ((si->s->kif == V_pfi_all || si->s->kif == kif) &&
-#else
- if ((si->s->kif == pfi_all || si->s->kif == kif) &&
-#endif
- sk == (dir == PF_IN ? si->s->key[PF_SK_WIRE] :
- si->s->key[PF_SK_STACK]))
- return (si->s);
-
- return (NULL);
-}
-
-struct pf_state *
-pf_find_state_all(struct pf_state_key_cmp *key, u_int dir, int *more)
-{
- struct pf_state_key *sk;
- struct pf_state_item *si, *ret = NULL;
-
-#ifdef __FreeBSD__
- V_pf_status.fcounters[FCNT_STATE_SEARCH]++;
-#else
- pf_status.fcounters[FCNT_STATE_SEARCH]++;
-#endif
-
-#ifdef __FreeBSD__
- sk = RB_FIND(pf_state_tree, &V_pf_statetbl, (struct pf_state_key *)key);
-#else
- sk = RB_FIND(pf_state_tree, &pf_statetbl, (struct pf_state_key *)key);
-#endif
- if (sk != NULL) {
- TAILQ_FOREACH(si, &sk->states, entry)
- if (dir == PF_INOUT ||
- (sk == (dir == PF_IN ? si->s->key[PF_SK_WIRE] :
- si->s->key[PF_SK_STACK]))) {
- if (more == NULL)
- return (si->s);
-
- if (ret)
- (*more)++;
- else
- ret = si;
- }
- }
- return (ret ? ret->s : NULL);
-}
-
-/* END state table stuff */
-
-
-void
-pf_purge_thread(void *v)
-{
- int nloops = 0, s;
-#ifdef __FreeBSD__
- int locked;
-#endif
-
- CURVNET_SET((struct vnet *)v);
-
- for (;;) {
- tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
-
-#ifdef __FreeBSD__
- sx_slock(&V_pf_consistency_lock);
- PF_LOCK();
- locked = 0;
-
- if (V_pf_end_threads) {
- PF_UNLOCK();
- sx_sunlock(&V_pf_consistency_lock);
- sx_xlock(&V_pf_consistency_lock);
- PF_LOCK();
-
- pf_purge_expired_states(V_pf_status.states, 1);
- pf_purge_expired_fragments();
- pf_purge_expired_src_nodes(1);
- V_pf_end_threads++;
-
- sx_xunlock(&V_pf_consistency_lock);
- PF_UNLOCK();
- wakeup(pf_purge_thread);
- kproc_exit(0);
- }
-#endif
- s = splsoftnet();
-
- /* process a fraction of the state table every second */
-#ifdef __FreeBSD__
- if (!pf_purge_expired_states(1 + (V_pf_status.states /
- V_pf_default_rule.timeout[PFTM_INTERVAL]), 0)) {
- PF_UNLOCK();
- sx_sunlock(&V_pf_consistency_lock);
- sx_xlock(&V_pf_consistency_lock);
- PF_LOCK();
- locked = 1;
-
- pf_purge_expired_states(1 + (V_pf_status.states /
- V_pf_default_rule.timeout[PFTM_INTERVAL]), 1);
- }
-#else
- pf_purge_expired_states(1 + (pf_status.states
- / pf_default_rule.timeout[PFTM_INTERVAL]));
-#endif
-
- /* purge other expired types every PFTM_INTERVAL seconds */
-#ifdef __FreeBSD__
- if (++nloops >= V_pf_default_rule.timeout[PFTM_INTERVAL]) {
-#else
- if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) {
-#endif
- pf_purge_expired_fragments();
- pf_purge_expired_src_nodes(0);
- nloops = 0;
- }
-
- splx(s);
-#ifdef __FreeBSD__
- PF_UNLOCK();
- if (locked)
- sx_xunlock(&V_pf_consistency_lock);
- else
- sx_sunlock(&V_pf_consistency_lock);
-#endif
- }
- CURVNET_RESTORE();
-}
-
-u_int32_t
-pf_state_expires(const struct pf_state *state)
-{
- u_int32_t timeout;
- u_int32_t start;
- u_int32_t end;
- u_int32_t states;
-
- /* handle all PFTM_* > PFTM_MAX here */
- if (state->timeout == PFTM_PURGE)
- return (time_second);
- if (state->timeout == PFTM_UNTIL_PACKET)
- return (0);
-#ifdef __FreeBSD__
- KASSERT(state->timeout != PFTM_UNLINKED,
- ("pf_state_expires: timeout == PFTM_UNLINKED"));
- KASSERT((state->timeout < PFTM_MAX),
- ("pf_state_expires: timeout > PFTM_MAX"));
-#else
- KASSERT(state->timeout != PFTM_UNLINKED);
- KASSERT(state->timeout < PFTM_MAX);
-#endif
- timeout = state->rule.ptr->timeout[state->timeout];
- if (!timeout)
-#ifdef __FreeBSD__
- timeout = V_pf_default_rule.timeout[state->timeout];
-#else
- timeout = pf_default_rule.timeout[state->timeout];
-#endif
- start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
- if (start) {
- end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
- states = state->rule.ptr->states_cur;
- } else {
-#ifdef __FreeBSD__
- start = V_pf_default_rule.timeout[PFTM_ADAPTIVE_START];
- end = V_pf_default_rule.timeout[PFTM_ADAPTIVE_END];
- states = V_pf_status.states;
-#else
- start = pf_default_rule.timeout[PFTM_ADAPTIVE_START];
- end = pf_default_rule.timeout[PFTM_ADAPTIVE_END];
- states = pf_status.states;
-#endif
- }
- if (end && states > start && start < end) {
- if (states < end)
- return (state->expire + timeout * (end - states) /
- (end - start));
- else
- return (time_second);
- }
- return (state->expire + timeout);
-}
-
-#ifdef __FreeBSD__
-int
-pf_purge_expired_src_nodes(int waslocked)
-#else
-void
-pf_purge_expired_src_nodes(int waslocked)
-#endif
-{
- struct pf_src_node *cur, *next;
- int locked = waslocked;
-
-#ifdef __FreeBSD__
- for (cur = RB_MIN(pf_src_tree, &V_tree_src_tracking); cur; cur = next) {
- next = RB_NEXT(pf_src_tree, &V_tree_src_tracking, cur);
-#else
- for (cur = RB_MIN(pf_src_tree, &tree_src_tracking); cur; cur = next) {
- next = RB_NEXT(pf_src_tree, &tree_src_tracking, cur);
-#endif
-
- if (cur->states <= 0 && cur->expire <= time_second) {
- if (! locked) {
-#ifdef __FreeBSD__
- if (!sx_try_upgrade(&V_pf_consistency_lock))
- return (0);
-#else
- rw_enter_write(&pf_consistency_lock);
-#endif
- next = RB_NEXT(pf_src_tree,
-#ifdef __FreeBSD__
- &V_tree_src_tracking, cur);
-#else
- &tree_src_tracking, cur);
-#endif
- locked = 1;
- }
- if (cur->rule.ptr != NULL) {
- cur->rule.ptr->src_nodes--;
- if (cur->rule.ptr->states_cur <= 0 &&
- cur->rule.ptr->max_src_nodes <= 0)
- pf_rm_rule(NULL, cur->rule.ptr);
- }
-#ifdef __FreeBSD__
- RB_REMOVE(pf_src_tree, &V_tree_src_tracking, cur);
- V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
- V_pf_status.src_nodes--;
- pool_put(&V_pf_src_tree_pl, cur);
-#else
- RB_REMOVE(pf_src_tree, &tree_src_tracking, cur);
- pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
- pf_status.src_nodes--;
- pool_put(&pf_src_tree_pl, cur);
-#endif
- }
- }
-
- if (locked && !waslocked)
-#ifdef __FreeBSD__
- {
- sx_downgrade(&V_pf_consistency_lock);
- }
- return (1);
-#else
- rw_exit_write(&pf_consistency_lock);
-#endif
-}
-
-void
-pf_src_tree_remove_state(struct pf_state *s)
-{
- u_int32_t timeout;
-
- if (s->src_node != NULL) {
- if (s->src.tcp_est)
- --s->src_node->conn;
- if (--s->src_node->states <= 0) {
- timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
- if (!timeout)
- timeout =
-#ifdef __FreeBSD__
- V_pf_default_rule.timeout[PFTM_SRC_NODE];
-#else
- pf_default_rule.timeout[PFTM_SRC_NODE];
-#endif
- s->src_node->expire = time_second + timeout;
- }
- }
- if (s->nat_src_node != s->src_node && s->nat_src_node != NULL) {
- if (--s->nat_src_node->states <= 0) {
- timeout = s->rule.ptr->timeout[PFTM_SRC_NODE];
- if (!timeout)
- timeout =
-#ifdef __FreeBSD__
- V_pf_default_rule.timeout[PFTM_SRC_NODE];
-#else
- pf_default_rule.timeout[PFTM_SRC_NODE];
-#endif
- s->nat_src_node->expire = time_second + timeout;
- }
- }
- s->src_node = s->nat_src_node = NULL;
-}
-
-/* callers should be at splsoftnet */
-void
-pf_unlink_state(struct pf_state *cur)
-{
-#ifdef __FreeBSD__
- if (cur->local_flags & PFSTATE_EXPIRING)
- return;
- cur->local_flags |= PFSTATE_EXPIRING;
-#else
- splassert(IPL_SOFTNET);
-#endif
-
- if (cur->src.state == PF_TCPS_PROXY_DST) {
- /* XXX wire key the right one? */
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
-#else
- pf_send_tcp(cur->rule.ptr, cur->key[PF_SK_WIRE]->af,
-#endif
- &cur->key[PF_SK_WIRE]->addr[1],
- &cur->key[PF_SK_WIRE]->addr[0],
- cur->key[PF_SK_WIRE]->port[1],
- cur->key[PF_SK_WIRE]->port[0],
- cur->src.seqhi, cur->src.seqlo + 1,
- TH_RST|TH_ACK, 0, 0, 0, 1, cur->tag, NULL, NULL);
- }
-#ifdef __FreeBSD__
- RB_REMOVE(pf_state_tree_id, &V_tree_id, cur);
-#else
- RB_REMOVE(pf_state_tree_id, &tree_id, cur);
-#endif
-#if NPFLOW > 0
- if (cur->state_flags & PFSTATE_PFLOW)
-#ifdef __FreeBSD__
- if (export_pflow_ptr != NULL)
- export_pflow_ptr(cur);
-#else
- export_pflow(cur);
-#endif
-#endif
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_delete_state_ptr != NULL)
- pfsync_delete_state_ptr(cur);
-#else
- pfsync_delete_state(cur);
-#endif
-#endif
- cur->timeout = PFTM_UNLINKED;
- pf_src_tree_remove_state(cur);
- pf_detach_state(cur);
-}
-
-/* callers should be at splsoftnet and hold the
- * write_lock on pf_consistency_lock */
-void
-pf_free_state(struct pf_state *cur)
-{
-#ifndef __FreeBSD__
- splassert(IPL_SOFTNET);
-#endif
-
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_state_in_use_ptr != NULL &&
- pfsync_state_in_use_ptr(cur))
-#else
- if (pfsync_state_in_use(cur))
-#endif
- return;
-#endif
-#ifdef __FreeBSD__
- KASSERT(cur->timeout == PFTM_UNLINKED,
- ("pf_free_state: cur->timeout != PFTM_UNLINKED"));
-#else
- KASSERT(cur->timeout == PFTM_UNLINKED);
-#endif
- if (--cur->rule.ptr->states_cur <= 0 &&
- cur->rule.ptr->src_nodes <= 0)
- pf_rm_rule(NULL, cur->rule.ptr);
- if (cur->nat_rule.ptr != NULL)
- if (--cur->nat_rule.ptr->states_cur <= 0 &&
- cur->nat_rule.ptr->src_nodes <= 0)
- pf_rm_rule(NULL, cur->nat_rule.ptr);
- if (cur->anchor.ptr != NULL)
- if (--cur->anchor.ptr->states_cur <= 0)
- pf_rm_rule(NULL, cur->anchor.ptr);
- pf_normalize_tcp_cleanup(cur);
- pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE);
-#ifdef __FreeBSD__
- TAILQ_REMOVE(&V_state_list, cur, entry_list);
-#else
- TAILQ_REMOVE(&state_list, cur, entry_list);
-#endif
- if (cur->tag)
- pf_tag_unref(cur->tag);
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_pl, cur);
- V_pf_status.fcounters[FCNT_STATE_REMOVALS]++;
- V_pf_status.states--;
-#else
- pool_put(&pf_state_pl, cur);
- pf_status.fcounters[FCNT_STATE_REMOVALS]++;
- pf_status.states--;
-#endif
-}
-
-#ifdef __FreeBSD__
-int
-pf_purge_expired_states(u_int32_t maxcheck, int waslocked)
-#else
-void
-pf_purge_expired_states(u_int32_t maxcheck)
-#endif
-{
- static struct pf_state *cur = NULL;
- struct pf_state *next;
-#ifdef __FreeBSD__
- int locked = waslocked;
-#else
- int locked = 0;
-#endif
-
- while (maxcheck--) {
- /* wrap to start of list when we hit the end */
- if (cur == NULL) {
-#ifdef __FreeBSD__
- cur = TAILQ_FIRST(&V_state_list);
-#else
- cur = TAILQ_FIRST(&state_list);
-#endif
- if (cur == NULL)
- break; /* list empty */
- }
-
- /* get next state, as cur may get deleted */
- next = TAILQ_NEXT(cur, entry_list);
-
- if (cur->timeout == PFTM_UNLINKED) {
- /* free unlinked state */
- if (! locked) {
-#ifdef __FreeBSD__
- if (!sx_try_upgrade(&V_pf_consistency_lock))
- return (0);
-#else
- rw_enter_write(&pf_consistency_lock);
-#endif
- locked = 1;
- }
- pf_free_state(cur);
- } else if (pf_state_expires(cur) <= time_second) {
- /* unlink and free expired state */
- pf_unlink_state(cur);
- if (! locked) {
-#ifdef __FreeBSD__
- if (!sx_try_upgrade(&V_pf_consistency_lock))
- return (0);
-#else
- rw_enter_write(&pf_consistency_lock);
-#endif
- locked = 1;
- }
- pf_free_state(cur);
- }
- cur = next;
- }
-
-#ifdef __FreeBSD__
- if (!waslocked && locked)
- sx_downgrade(&V_pf_consistency_lock);
-
- return (1);
-#else
- if (locked)
- rw_exit_write(&pf_consistency_lock);
-#endif
-}
-
-int
-pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
-{
- if (aw->type != PF_ADDR_TABLE)
- return (0);
- if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
- return (1);
- return (0);
-}
-
-void
-pf_tbladdr_remove(struct pf_addr_wrap *aw)
-{
- if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL)
- return;
- pfr_detach_table(aw->p.tbl);
- aw->p.tbl = NULL;
-}
-
-void
-pf_tbladdr_copyout(struct pf_addr_wrap *aw)
-{
- struct pfr_ktable *kt = aw->p.tbl;
-
- if (aw->type != PF_ADDR_TABLE || kt == NULL)
- return;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- aw->p.tbl = NULL;
- aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ?
- kt->pfrkt_cnt : -1;
-}
-
-void
-pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET: {
- u_int32_t a = ntohl(addr->addr32[0]);
- printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
- (a>>8)&255, a&255);
- if (p) {
- p = ntohs(p);
- printf(":%u", p);
- }
- break;
- }
-#endif /* INET */
-#ifdef INET6
- case AF_INET6: {
- u_int16_t b;
- u_int8_t i, curstart, curend, maxstart, maxend;
- curstart = curend = maxstart = maxend = 255;
- for (i = 0; i < 8; i++) {
- if (!addr->addr16[i]) {
- if (curstart == 255)
- curstart = i;
- curend = i;
- } else {
- if ((curend - curstart) >
- (maxend - maxstart)) {
- maxstart = curstart;
- maxend = curend;
- }
- curstart = curend = 255;
- }
- }
- if ((curend - curstart) >
- (maxend - maxstart)) {
- maxstart = curstart;
- maxend = curend;
- }
- for (i = 0; i < 8; i++) {
- if (i >= maxstart && i <= maxend) {
- if (i == 0)
- printf(":");
- if (i == maxend)
- printf(":");
- } else {
- b = ntohs(addr->addr16[i]);
- printf("%x", b);
- if (i < 7)
- printf(":");
- }
- }
- if (p) {
- p = ntohs(p);
- printf("[%u]", p);
- }
- break;
- }
-#endif /* INET6 */
- }
-}
-
-void
-pf_print_state(struct pf_state *s)
-{
- pf_print_state_parts(s, NULL, NULL);
-}
-
-void
-pf_print_state_parts(struct pf_state *s,
- struct pf_state_key *skwp, struct pf_state_key *sksp)
-{
- struct pf_state_key *skw, *sks;
- u_int8_t proto, dir;
-
- /* Do our best to fill these, but they're skipped if NULL */
- skw = skwp ? skwp : (s ? s->key[PF_SK_WIRE] : NULL);
- sks = sksp ? sksp : (s ? s->key[PF_SK_STACK] : NULL);
- proto = skw ? skw->proto : (sks ? sks->proto : 0);
- dir = s ? s->direction : 0;
-
- switch (proto) {
- case IPPROTO_IPV4:
- printf("IPv4");
- break;
- case IPPROTO_IPV6:
- printf("IPv6");
- break;
- case IPPROTO_TCP:
- printf("TCP");
- break;
- case IPPROTO_UDP:
- printf("UDP");
- break;
- case IPPROTO_ICMP:
- printf("ICMP");
- break;
- case IPPROTO_ICMPV6:
- printf("ICMPv6");
- break;
- default:
- printf("%u", skw->proto);
- break;
- }
- switch (dir) {
- case PF_IN:
- printf(" in");
- break;
- case PF_OUT:
- printf(" out");
- break;
- }
- if (skw) {
- printf(" wire: ");
- pf_print_host(&skw->addr[0], skw->port[0], skw->af);
- printf(" ");
- pf_print_host(&skw->addr[1], skw->port[1], skw->af);
- }
- if (sks) {
- printf(" stack: ");
- if (sks != skw) {
- pf_print_host(&sks->addr[0], sks->port[0], sks->af);
- printf(" ");
- pf_print_host(&sks->addr[1], sks->port[1], sks->af);
- } else
- printf("-");
- }
- if (s) {
- if (proto == IPPROTO_TCP) {
- printf(" [lo=%u high=%u win=%u modulator=%u",
- s->src.seqlo, s->src.seqhi,
- s->src.max_win, s->src.seqdiff);
- if (s->src.wscale && s->dst.wscale)
- printf(" wscale=%u",
- s->src.wscale & PF_WSCALE_MASK);
- printf("]");
- printf(" [lo=%u high=%u win=%u modulator=%u",
- s->dst.seqlo, s->dst.seqhi,
- s->dst.max_win, s->dst.seqdiff);
- if (s->src.wscale && s->dst.wscale)
- printf(" wscale=%u",
- s->dst.wscale & PF_WSCALE_MASK);
- printf("]");
- }
- printf(" %u:%u", s->src.state, s->dst.state);
- }
-}
-
-void
-pf_print_flags(u_int8_t f)
-{
- if (f)
- printf(" ");
- if (f & TH_FIN)
- printf("F");
- if (f & TH_SYN)
- printf("S");
- if (f & TH_RST)
- printf("R");
- if (f & TH_PUSH)
- printf("P");
- if (f & TH_ACK)
- printf("A");
- if (f & TH_URG)
- printf("U");
- if (f & TH_ECE)
- printf("E");
- if (f & TH_CWR)
- printf("W");
-}
-
-#define PF_SET_SKIP_STEPS(i) \
- do { \
- while (head[i] != cur) { \
- head[i]->skip[i].ptr = cur; \
- head[i] = TAILQ_NEXT(head[i], entries); \
- } \
- } while (0)
-
-void
-pf_calc_skip_steps(struct pf_rulequeue *rules)
-{
- struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT];
- int i;
-
- cur = TAILQ_FIRST(rules);
- prev = cur;
- for (i = 0; i < PF_SKIP_COUNT; ++i)
- head[i] = cur;
- while (cur != NULL) {
-
- if (cur->kif != prev->kif || cur->ifnot != prev->ifnot)
- PF_SET_SKIP_STEPS(PF_SKIP_IFP);
- if (cur->direction != prev->direction)
- PF_SET_SKIP_STEPS(PF_SKIP_DIR);
- if (cur->af != prev->af)
- PF_SET_SKIP_STEPS(PF_SKIP_AF);
- if (cur->proto != prev->proto)
- PF_SET_SKIP_STEPS(PF_SKIP_PROTO);
- if (cur->src.neg != prev->src.neg ||
- pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr))
- PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR);
- if (cur->src.port[0] != prev->src.port[0] ||
- cur->src.port[1] != prev->src.port[1] ||
- cur->src.port_op != prev->src.port_op)
- PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT);
- if (cur->dst.neg != prev->dst.neg ||
- pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr))
- PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR);
- if (cur->dst.port[0] != prev->dst.port[0] ||
- cur->dst.port[1] != prev->dst.port[1] ||
- cur->dst.port_op != prev->dst.port_op)
- PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT);
-
- prev = cur;
- cur = TAILQ_NEXT(cur, entries);
- }
- for (i = 0; i < PF_SKIP_COUNT; ++i)
- PF_SET_SKIP_STEPS(i);
-}
-
-int
-pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2)
-{
- if (aw1->type != aw2->type)
- return (1);
- switch (aw1->type) {
- case PF_ADDR_ADDRMASK:
- case PF_ADDR_RANGE:
- if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0))
- return (1);
- if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0))
- return (1);
- return (0);
- case PF_ADDR_DYNIFTL:
- return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt);
- case PF_ADDR_NOROUTE:
- case PF_ADDR_URPFFAILED:
- return (0);
- case PF_ADDR_TABLE:
- return (aw1->p.tbl != aw2->p.tbl);
- case PF_ADDR_RTLABEL:
- return (aw1->v.rtlabel != aw2->v.rtlabel);
- default:
- printf("invalid address type: %d\n", aw1->type);
- return (1);
- }
-}
-
-u_int16_t
-pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp)
-{
- u_int32_t l;
-
- if (udp && !cksum)
- return (0x0000);
- l = cksum + old - new;
- l = (l >> 16) + (l & 65535);
- l = l & 65535;
- if (udp && !l)
- return (0xFFFF);
- return (l);
-}
-
-void
-pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc,
- struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af)
-{
- struct pf_addr ao;
- u_int16_t po = *p;
-
- PF_ACPY(&ao, a, af);
- PF_ACPY(a, an, af);
-
- *p = pn;
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
- ao.addr16[0], an->addr16[0], 0),
- ao.addr16[1], an->addr16[1], 0);
- *p = pn;
- *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
- ao.addr16[0], an->addr16[0], u),
- ao.addr16[1], an->addr16[1], u),
- po, pn, u);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc,
- ao.addr16[0], an->addr16[0], u),
- ao.addr16[1], an->addr16[1], u),
- ao.addr16[2], an->addr16[2], u),
- ao.addr16[3], an->addr16[3], u),
- ao.addr16[4], an->addr16[4], u),
- ao.addr16[5], an->addr16[5], u),
- ao.addr16[6], an->addr16[6], u),
- ao.addr16[7], an->addr16[7], u),
- po, pn, u);
- break;
-#endif /* INET6 */
- }
-}
-
-
-/* Changes a u_int32_t. Uses a void * so there are no align restrictions */
-void
-pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u)
-{
- u_int32_t ao;
-
- memcpy(&ao, a, sizeof(ao));
- memcpy(a, &an, sizeof(u_int32_t));
- *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u),
- ao % 65536, an % 65536, u);
-}
-
-#ifdef INET6
-void
-pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u)
-{
- struct pf_addr ao;
-
- PF_ACPY(&ao, a, AF_INET6);
- PF_ACPY(a, an, AF_INET6);
-
- *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(*c,
- ao.addr16[0], an->addr16[0], u),
- ao.addr16[1], an->addr16[1], u),
- ao.addr16[2], an->addr16[2], u),
- ao.addr16[3], an->addr16[3], u),
- ao.addr16[4], an->addr16[4], u),
- ao.addr16[5], an->addr16[5], u),
- ao.addr16[6], an->addr16[6], u),
- ao.addr16[7], an->addr16[7], u);
-}
-#endif /* INET6 */
-
-void
-pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa,
- struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c,
- u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af)
-{
- struct pf_addr oia, ooa;
-
- PF_ACPY(&oia, ia, af);
- if (oa)
- PF_ACPY(&ooa, oa, af);
-
- /* Change inner protocol port, fix inner protocol checksum. */
- if (ip != NULL) {
- u_int16_t oip = *ip;
- u_int32_t opc;
-
- if (pc != NULL)
- opc = *pc;
- *ip = np;
- if (pc != NULL)
- *pc = pf_cksum_fixup(*pc, oip, *ip, u);
- *ic = pf_cksum_fixup(*ic, oip, *ip, 0);
- if (pc != NULL)
- *ic = pf_cksum_fixup(*ic, opc, *pc, 0);
- }
- /* Change inner ip address, fix inner ip and icmp checksums. */
- PF_ACPY(ia, na, af);
- switch (af) {
-#ifdef INET
- case AF_INET: {
- u_int32_t oh2c = *h2c;
-
- *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c,
- oia.addr16[0], ia->addr16[0], 0),
- oia.addr16[1], ia->addr16[1], 0);
- *ic = pf_cksum_fixup(pf_cksum_fixup(*ic,
- oia.addr16[0], ia->addr16[0], 0),
- oia.addr16[1], ia->addr16[1], 0);
- *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0);
- break;
- }
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(*ic,
- oia.addr16[0], ia->addr16[0], u),
- oia.addr16[1], ia->addr16[1], u),
- oia.addr16[2], ia->addr16[2], u),
- oia.addr16[3], ia->addr16[3], u),
- oia.addr16[4], ia->addr16[4], u),
- oia.addr16[5], ia->addr16[5], u),
- oia.addr16[6], ia->addr16[6], u),
- oia.addr16[7], ia->addr16[7], u);
- break;
-#endif /* INET6 */
- }
- /* Outer ip address, fix outer ip or icmpv6 checksum, if necessary. */
- if (oa) {
- PF_ACPY(oa, na, af);
- switch (af) {
-#ifdef INET
- case AF_INET:
- *hc = pf_cksum_fixup(pf_cksum_fixup(*hc,
- ooa.addr16[0], oa->addr16[0], 0),
- ooa.addr16[1], oa->addr16[1], 0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(
- pf_cksum_fixup(pf_cksum_fixup(*ic,
- ooa.addr16[0], oa->addr16[0], u),
- ooa.addr16[1], oa->addr16[1], u),
- ooa.addr16[2], oa->addr16[2], u),
- ooa.addr16[3], oa->addr16[3], u),
- ooa.addr16[4], oa->addr16[4], u),
- ooa.addr16[5], oa->addr16[5], u),
- ooa.addr16[6], oa->addr16[6], u),
- ooa.addr16[7], oa->addr16[7], u);
- break;
-#endif /* INET6 */
- }
- }
-}
-
-
-/*
- * Need to modulate the sequence numbers in the TCP SACK option
- * (credits to Krzysztof Pfaff for report and patch)
- */
-int
-pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd,
- struct tcphdr *th, struct pf_state_peer *dst)
-{
- int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen;
-#ifdef __FreeBSD__
- u_int8_t opts[TCP_MAXOLEN], *opt = opts;
-#else
- u_int8_t opts[MAX_TCPOPTLEN], *opt = opts;
-#endif
- int copyback = 0, i, olen;
- struct sackblk sack;
-
-#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2)
- if (hlen < TCPOLEN_SACKLEN ||
- !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af))
- return 0;
-
- while (hlen >= TCPOLEN_SACKLEN) {
- olen = opt[1];
- switch (*opt) {
- case TCPOPT_EOL: /* FALLTHROUGH */
- case TCPOPT_NOP:
- opt++;
- hlen--;
- break;
- case TCPOPT_SACK:
- if (olen > hlen)
- olen = hlen;
- if (olen >= TCPOLEN_SACKLEN) {
- for (i = 2; i + TCPOLEN_SACK <= olen;
- i += TCPOLEN_SACK) {
- memcpy(&sack, &opt[i], sizeof(sack));
- pf_change_a(&sack.start, &th->th_sum,
- htonl(ntohl(sack.start) -
- dst->seqdiff), 0);
- pf_change_a(&sack.end, &th->th_sum,
- htonl(ntohl(sack.end) -
- dst->seqdiff), 0);
- memcpy(&opt[i], &sack, sizeof(sack));
- }
- copyback = 1;
- }
- /* FALLTHROUGH */
- default:
- if (olen < 2)
- olen = 2;
- hlen -= olen;
- opt += olen;
- }
- }
-
- if (copyback)
-#ifdef __FreeBSD__
- m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts);
-#else
- m_copyback(m, off + sizeof(*th), thoptlen, opts);
-#endif
- return (copyback);
-}
-
-void
-#ifdef __FreeBSD__
-pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af,
-#else
-pf_send_tcp(const struct pf_rule *r, sa_family_t af,
-#endif
- const struct pf_addr *saddr, const struct pf_addr *daddr,
- u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack,
- u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag,
- u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp)
-{
- struct mbuf *m;
- int len, tlen;
-#ifdef INET
- struct ip *h;
-#endif /* INET */
-#ifdef INET6
- struct ip6_hdr *h6;
-#endif /* INET6 */
- struct tcphdr *th;
- char *opt;
-#ifdef __FreeBSD__
- struct pf_mtag *pf_mtag;
-
- KASSERT(
-#ifdef INET
- af == AF_INET
-#else
- 0
-#endif
- ||
-#ifdef INET6
- af == AF_INET6
-#else
- 0
-#endif
- , ("Unsupported AF %d", af));
- len = 0;
- th = NULL;
-#ifdef INET
- h = NULL;
-#endif
-#ifdef INET6
- h6 = NULL;
-#endif
-#endif /* __FreeBSD__ */
-
- /* maximum segment size tcp option */
- tlen = sizeof(struct tcphdr);
- if (mss)
- tlen += 4;
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- len = sizeof(struct ip) + tlen;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- len = sizeof(struct ip6_hdr) + tlen;
- break;
-#endif /* INET6 */
- }
-
- /* create outgoing mbuf */
- m = m_gethdr(M_DONTWAIT, MT_HEADER);
- if (m == NULL)
- return;
-#ifdef __FreeBSD__
-#ifdef MAC
- mac_netinet_firewall_send(m);
-#endif
- if ((pf_mtag = pf_get_mtag(m)) == NULL) {
- m_freem(m);
- return;
- }
-#endif
- if (tag)
-#ifdef __FreeBSD__
- m->m_flags |= M_SKIP_FIREWALL;
- pf_mtag->tag = rtag;
-#else
- m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
- m->m_pkthdr.pf.tag = rtag;
-#endif
-
- if (r != NULL && r->rtableid >= 0)
-#ifdef __FreeBSD__
- {
- M_SETFIB(m, r->rtableid);
- pf_mtag->rtableid = r->rtableid;
-#else
- m->m_pkthdr.pf.rtableid = r->rtableid;
-#endif
-#ifdef __FreeBSD__
- }
-#endif
-
-#ifdef ALTQ
- if (r != NULL && r->qid) {
-#ifdef __FreeBSD__
- pf_mtag->qid = r->qid;
-
- /* add hints for ecn */
- pf_mtag->hdr = mtod(m, struct ip *);
-#else
- m->m_pkthdr.pf.qid = r->qid;
- /* add hints for ecn */
- m->m_pkthdr.pf.hdr = mtod(m, struct ip *);
-#endif
- }
-#endif /* ALTQ */
- m->m_data += max_linkhdr;
- m->m_pkthdr.len = m->m_len = len;
- m->m_pkthdr.rcvif = NULL;
- bzero(m->m_data, len);
- switch (af) {
-#ifdef INET
- case AF_INET:
- h = mtod(m, struct ip *);
-
- /* IP header fields included in the TCP checksum */
- h->ip_p = IPPROTO_TCP;
- h->ip_len = htons(tlen);
- h->ip_src.s_addr = saddr->v4.s_addr;
- h->ip_dst.s_addr = daddr->v4.s_addr;
-
- th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip));
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- h6 = mtod(m, struct ip6_hdr *);
-
- /* IP header fields included in the TCP checksum */
- h6->ip6_nxt = IPPROTO_TCP;
- h6->ip6_plen = htons(tlen);
- memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr));
- memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr));
-
- th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr));
- break;
-#endif /* INET6 */
- }
-
- /* TCP header */
- th->th_sport = sport;
- th->th_dport = dport;
- th->th_seq = htonl(seq);
- th->th_ack = htonl(ack);
- th->th_off = tlen >> 2;
- th->th_flags = flags;
- th->th_win = htons(win);
-
- if (mss) {
- opt = (char *)(th + 1);
- opt[0] = TCPOPT_MAXSEG;
- opt[1] = 4;
- HTONS(mss);
- bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2);
- }
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- /* TCP checksum */
- th->th_sum = in_cksum(m, len);
-
- /* Finish the IP header */
- h->ip_v = 4;
- h->ip_hl = sizeof(*h) >> 2;
- h->ip_tos = IPTOS_LOWDELAY;
-#ifdef __FreeBSD__
- h->ip_off = V_path_mtu_discovery ? IP_DF : 0;
- h->ip_len = len;
- h->ip_ttl = ttl ? ttl : V_ip_defttl;
-#else
- h->ip_len = htons(len);
- h->ip_off = htons(ip_mtudisc ? IP_DF : 0);
- h->ip_ttl = ttl ? ttl : ip_defttl;
-#endif
- h->ip_sum = 0;
- if (eh == NULL) {
-#ifdef __FreeBSD__
- PF_UNLOCK();
- ip_output(m, (void *)NULL, (void *)NULL, 0,
- (void *)NULL, (void *)NULL);
- PF_LOCK();
-#else /* ! __FreeBSD__ */
- ip_output(m, (void *)NULL, (void *)NULL, 0,
- (void *)NULL, (void *)NULL);
-#endif
- } else {
- struct route ro;
- struct rtentry rt;
- struct ether_header *e = (void *)ro.ro_dst.sa_data;
-
- if (ifp == NULL) {
- m_freem(m);
- return;
- }
- rt.rt_ifp = ifp;
- ro.ro_rt = &rt;
- ro.ro_dst.sa_len = sizeof(ro.ro_dst);
- ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT;
- bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN);
- bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN);
- e->ether_type = eh->ether_type;
-#ifdef __FreeBSD__
- PF_UNLOCK();
- /* XXX_IMPORT: later */
- ip_output(m, (void *)NULL, &ro, 0,
- (void *)NULL, (void *)NULL);
- PF_LOCK();
-#else /* ! __FreeBSD__ */
- ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER,
- (void *)NULL, (void *)NULL);
-#endif
- }
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- /* TCP checksum */
- th->th_sum = in6_cksum(m, IPPROTO_TCP,
- sizeof(struct ip6_hdr), tlen);
-
- h6->ip6_vfc |= IPV6_VERSION;
- h6->ip6_hlim = IPV6_DEFHLIM;
-
-#ifdef __FreeBSD__
- PF_UNLOCK();
- ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
- PF_LOCK();
-#else
- ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
-#endif
- break;
-#endif /* INET6 */
- }
-}
-
-static void
-pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af,
- struct pf_rule *r)
-{
- struct mbuf *m0;
-#ifdef __FreeBSD__
-#ifdef INET
- struct ip *ip;
-#endif
- struct pf_mtag *pf_mtag;
-#endif
-
-#ifdef __FreeBSD__
- m0 = m_copypacket(m, M_DONTWAIT);
- if (m0 == NULL)
- return;
-#else
- if ((m0 = m_copy(m, 0, M_COPYALL)) == NULL)
- return;
-#endif
-
-#ifdef __FreeBSD__
- if ((pf_mtag = pf_get_mtag(m0)) == NULL)
- return;
- /* XXX: revisit */
- m0->m_flags |= M_SKIP_FIREWALL;
-#else
- m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
-#endif
-
- if (r->rtableid >= 0)
-#ifdef __FreeBSD__
- {
- M_SETFIB(m0, r->rtableid);
- pf_mtag->rtableid = r->rtableid;
-#else
- m0->m_pkthdr.pf.rtableid = r->rtableid;
-#endif
-#ifdef __FreeBSD__
- }
-#endif
-
-#ifdef ALTQ
- if (r->qid) {
-#ifdef __FreeBSD__
- pf_mtag->qid = r->qid;
- /* add hints for ecn */
- pf_mtag->hdr = mtod(m0, struct ip *);
-#else
- m0->m_pkthdr.pf.qid = r->qid;
- /* add hints for ecn */
- m0->m_pkthdr.pf.hdr = mtod(m0, struct ip *);
-#endif
- }
-#endif /* ALTQ */
-
- switch (af) {
-#ifdef INET
- case AF_INET:
-#ifdef __FreeBSD__
- /* icmp_error() expects host byte ordering */
- ip = mtod(m0, struct ip *);
- NTOHS(ip->ip_len);
- NTOHS(ip->ip_off);
- PF_UNLOCK();
- icmp_error(m0, type, code, 0, 0);
- PF_LOCK();
-#else
- icmp_error(m0, type, code, 0, 0);
-#endif
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- icmp6_error(m0, type, code, 0);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- break;
-#endif /* INET6 */
- }
-}
-
-/*
- * Return 1 if the addresses a and b match (with mask m), otherwise return 0.
- * If n is 0, they match if they are equal. If n is != 0, they match if they
- * are different.
- */
-int
-pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m,
- struct pf_addr *b, sa_family_t af)
-{
- int match = 0;
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- if ((a->addr32[0] & m->addr32[0]) ==
- (b->addr32[0] & m->addr32[0]))
- match++;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (((a->addr32[0] & m->addr32[0]) ==
- (b->addr32[0] & m->addr32[0])) &&
- ((a->addr32[1] & m->addr32[1]) ==
- (b->addr32[1] & m->addr32[1])) &&
- ((a->addr32[2] & m->addr32[2]) ==
- (b->addr32[2] & m->addr32[2])) &&
- ((a->addr32[3] & m->addr32[3]) ==
- (b->addr32[3] & m->addr32[3])))
- match++;
- break;
-#endif /* INET6 */
- }
- if (match) {
- if (n)
- return (0);
- else
- return (1);
- } else {
- if (n)
- return (1);
- else
- return (0);
- }
-}
-
-/*
- * Return 1 if b <= a <= e, otherwise return 0.
- */
-int
-pf_match_addr_range(struct pf_addr *b, struct pf_addr *e,
- struct pf_addr *a, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET:
- if ((a->addr32[0] < b->addr32[0]) ||
- (a->addr32[0] > e->addr32[0]))
- return (0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6: {
- int i;
-
- /* check a >= b */
- for (i = 0; i < 4; ++i)
- if (a->addr32[i] > b->addr32[i])
- break;
- else if (a->addr32[i] < b->addr32[i])
- return (0);
- /* check a <= e */
- for (i = 0; i < 4; ++i)
- if (a->addr32[i] < e->addr32[i])
- break;
- else if (a->addr32[i] > e->addr32[i])
- return (0);
- break;
- }
-#endif /* INET6 */
- }
- return (1);
-}
-
-int
-pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p)
-{
- switch (op) {
- case PF_OP_IRG:
- return ((p > a1) && (p < a2));
- case PF_OP_XRG:
- return ((p < a1) || (p > a2));
- case PF_OP_RRG:
- return ((p >= a1) && (p <= a2));
- case PF_OP_EQ:
- return (p == a1);
- case PF_OP_NE:
- return (p != a1);
- case PF_OP_LT:
- return (p < a1);
- case PF_OP_LE:
- return (p <= a1);
- case PF_OP_GT:
- return (p > a1);
- case PF_OP_GE:
- return (p >= a1);
- }
- return (0); /* never reached */
-}
-
-int
-pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
-{
- NTOHS(a1);
- NTOHS(a2);
- NTOHS(p);
- return (pf_match(op, a1, a2, p));
-}
-
-int
-pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u)
-{
- if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
- return (0);
- return (pf_match(op, a1, a2, u));
-}
-
-int
-pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
-{
- if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE)
- return (0);
- return (pf_match(op, a1, a2, g));
-}
-
-int
-#ifdef __FreeBSD__
-pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag,
- struct pf_mtag *pf_mtag)
-#else
-pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag)
-#endif
-{
- if (*tag == -1)
-#ifdef __FreeBSD__
- *tag = pf_mtag->tag;
-#else
- *tag = m->m_pkthdr.pf.tag;
-#endif
-
- return ((!r->match_tag_not && r->match_tag == *tag) ||
- (r->match_tag_not && r->match_tag != *tag));
-}
-
-int
-#ifdef __FreeBSD__
-pf_tag_packet(struct mbuf *m, int tag, int rtableid,
- struct pf_mtag *pf_mtag)
-#else
-pf_tag_packet(struct mbuf *m, int tag, int rtableid)
-#endif
-{
- if (tag <= 0 && rtableid < 0)
- return (0);
-
- if (tag > 0)
-#ifdef __FreeBSD__
- pf_mtag->tag = tag;
-#else
- m->m_pkthdr.pf.tag = tag;
-#endif
- if (rtableid >= 0)
-#ifdef __FreeBSD__
- {
- M_SETFIB(m, rtableid);
- }
-#else
- m->m_pkthdr.pf.rtableid = rtableid;
-#endif
-
- return (0);
-}
-
-void
-pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n,
- struct pf_rule **r, struct pf_rule **a, int *match)
-{
- struct pf_anchor_stackframe *f;
-
- (*r)->anchor->match = 0;
- if (match)
- *match = 0;
-#ifdef __FreeBSD__
- if (*depth >= sizeof(V_pf_anchor_stack) /
- sizeof(V_pf_anchor_stack[0])) {
-#else
- if (*depth >= sizeof(pf_anchor_stack) /
- sizeof(pf_anchor_stack[0])) {
-#endif
- printf("pf_step_into_anchor: stack overflow\n");
- *r = TAILQ_NEXT(*r, entries);
- return;
- } else if (*depth == 0 && a != NULL)
- *a = *r;
-#ifdef __FreeBSD__
- f = V_pf_anchor_stack + (*depth)++;
-#else
- f = pf_anchor_stack + (*depth)++;
-#endif
- f->rs = *rs;
- f->r = *r;
- if ((*r)->anchor_wildcard) {
- f->parent = &(*r)->anchor->children;
- if ((f->child = RB_MIN(pf_anchor_node, f->parent)) ==
- NULL) {
- *r = NULL;
- return;
- }
- *rs = &f->child->ruleset;
- } else {
- f->parent = NULL;
- f->child = NULL;
- *rs = &(*r)->anchor->ruleset;
- }
- *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
-}
-
-int
-pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n,
- struct pf_rule **r, struct pf_rule **a, int *match)
-{
- struct pf_anchor_stackframe *f;
- int quick = 0;
-
- do {
- if (*depth <= 0)
- break;
-#ifdef __FreeBSD__
- f = V_pf_anchor_stack + *depth - 1;
-#else
- f = pf_anchor_stack + *depth - 1;
-#endif
- if (f->parent != NULL && f->child != NULL) {
- if (f->child->match ||
- (match != NULL && *match)) {
- f->r->anchor->match = 1;
- *match = 0;
- }
- f->child = RB_NEXT(pf_anchor_node, f->parent, f->child);
- if (f->child != NULL) {
- *rs = &f->child->ruleset;
- *r = TAILQ_FIRST((*rs)->rules[n].active.ptr);
- if (*r == NULL)
- continue;
- else
- break;
- }
- }
- (*depth)--;
- if (*depth == 0 && a != NULL)
- *a = NULL;
- *rs = f->rs;
- if (f->r->anchor->match || (match != NULL && *match))
- quick = f->r->quick;
- *r = TAILQ_NEXT(f->r, entries);
- } while (*r == NULL);
-
- return (quick);
-}
-
-#ifdef INET6
-void
-pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr,
- struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET:
- naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
- ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
- break;
-#endif /* INET */
- case AF_INET6:
- naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) |
- ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]);
- naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) |
- ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]);
- naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) |
- ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]);
- naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) |
- ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]);
- break;
- }
-}
-
-void
-pf_addr_inc(struct pf_addr *addr, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET:
- addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1);
- break;
-#endif /* INET */
- case AF_INET6:
- if (addr->addr32[3] == 0xffffffff) {
- addr->addr32[3] = 0;
- if (addr->addr32[2] == 0xffffffff) {
- addr->addr32[2] = 0;
- if (addr->addr32[1] == 0xffffffff) {
- addr->addr32[1] = 0;
- addr->addr32[0] =
- htonl(ntohl(addr->addr32[0]) + 1);
- } else
- addr->addr32[1] =
- htonl(ntohl(addr->addr32[1]) + 1);
- } else
- addr->addr32[2] =
- htonl(ntohl(addr->addr32[2]) + 1);
- } else
- addr->addr32[3] =
- htonl(ntohl(addr->addr32[3]) + 1);
- break;
- }
-}
-#endif /* INET6 */
-
-int
-#ifdef __FreeBSD__
-pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg)
-#else
-pf_socket_lookup(int direction, struct pf_pdesc *pd)
-#endif
-{
- struct pf_addr *saddr, *daddr;
- u_int16_t sport, dport;
-#ifdef __FreeBSD__
- struct inpcbinfo *pi;
-#else
- struct inpcbtable *tb;
-#endif
- struct inpcb *inp;
-
- if (pd == NULL)
- return (-1);
- pd->lookup.uid = UID_MAX;
- pd->lookup.gid = GID_MAX;
- pd->lookup.pid = NO_PID;
-
-#ifdef __FreeBSD__
- if (inp_arg != NULL) {
- INP_LOCK_ASSERT(inp_arg);
- pd->lookup.uid = inp_arg->inp_cred->cr_uid;
- pd->lookup.gid = inp_arg->inp_cred->cr_groups[0];
- return (1);
- }
-#endif
-
- switch (pd->proto) {
- case IPPROTO_TCP:
- if (pd->hdr.tcp == NULL)
- return (-1);
- sport = pd->hdr.tcp->th_sport;
- dport = pd->hdr.tcp->th_dport;
-#ifdef __FreeBSD__
- pi = &V_tcbinfo;
-#else
- tb = &tcbtable;
-#endif
- break;
- case IPPROTO_UDP:
- if (pd->hdr.udp == NULL)
- return (-1);
- sport = pd->hdr.udp->uh_sport;
- dport = pd->hdr.udp->uh_dport;
-#ifdef __FreeBSD__
- pi = &V_udbinfo;
-#else
- tb = &udbtable;
-#endif
- break;
- default:
- return (-1);
- }
- if (direction == PF_IN) {
- saddr = pd->src;
- daddr = pd->dst;
- } else {
- u_int16_t p;
-
- p = sport;
- sport = dport;
- dport = p;
- saddr = pd->dst;
- daddr = pd->src;
- }
- switch (pd->af) {
-#ifdef INET
- case AF_INET:
-#ifdef __FreeBSD__
- /*
- * XXXRW: would be nice if we had an mbuf here so that we
- * could use in_pcblookup_mbuf().
- */
- inp = in_pcblookup(pi, saddr->v4, sport, daddr->v4,
- dport, INPLOOKUP_RLOCKPCB, NULL);
- if (inp == NULL) {
- inp = in_pcblookup(pi, saddr->v4, sport,
- daddr->v4, dport, INPLOOKUP_WILDCARD |
- INPLOOKUP_RLOCKPCB, NULL);
- if (inp == NULL)
- return (-1);
- }
-#else
- inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport);
- if (inp == NULL) {
- inp = in_pcblookup_listen(tb, daddr->v4, dport, 0,
- NULL);
- if (inp == NULL)
- return (-1);
- }
-#endif
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
-#ifdef __FreeBSD__
- /*
- * XXXRW: would be nice if we had an mbuf here so that we
- * could use in6_pcblookup_mbuf().
- */
- inp = in6_pcblookup(pi, &saddr->v6, sport,
- &daddr->v6, dport, INPLOOKUP_RLOCKPCB, NULL);
- if (inp == NULL) {
- inp = in6_pcblookup(pi, &saddr->v6, sport,
- &daddr->v6, dport, INPLOOKUP_WILDCARD |
- INPLOOKUP_RLOCKPCB, NULL);
- if (inp == NULL)
- return (-1);
- }
-#else
- inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6,
- dport);
- if (inp == NULL) {
- inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0,
- NULL);
- if (inp == NULL)
- return (-1);
- }
-#endif
- break;
-#endif /* INET6 */
-
- default:
- return (-1);
- }
-#ifdef __FreeBSD__
- INP_RLOCK_ASSERT(inp);
- pd->lookup.uid = inp->inp_cred->cr_uid;
- pd->lookup.gid = inp->inp_cred->cr_groups[0];
- INP_RUNLOCK(inp);
-#else
- pd->lookup.uid = inp->inp_socket->so_euid;
- pd->lookup.gid = inp->inp_socket->so_egid;
- pd->lookup.pid = inp->inp_socket->so_cpid;
-#endif
- return (1);
-}
-
-u_int8_t
-pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
-{
- int hlen;
- u_int8_t hdr[60];
- u_int8_t *opt, optlen;
- u_int8_t wscale = 0;
-
- hlen = th_off << 2; /* hlen <= sizeof(hdr) */
- if (hlen <= sizeof(struct tcphdr))
- return (0);
- if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
- return (0);
- opt = hdr + sizeof(struct tcphdr);
- hlen -= sizeof(struct tcphdr);
- while (hlen >= 3) {
- switch (*opt) {
- case TCPOPT_EOL:
- case TCPOPT_NOP:
- ++opt;
- --hlen;
- break;
- case TCPOPT_WINDOW:
- wscale = opt[2];
- if (wscale > TCP_MAX_WINSHIFT)
- wscale = TCP_MAX_WINSHIFT;
- wscale |= PF_WSCALE_FLAG;
- /* FALLTHROUGH */
- default:
- optlen = opt[1];
- if (optlen < 2)
- optlen = 2;
- hlen -= optlen;
- opt += optlen;
- break;
- }
- }
- return (wscale);
-}
-
-u_int16_t
-pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af)
-{
- int hlen;
- u_int8_t hdr[60];
- u_int8_t *opt, optlen;
-#ifdef __FreeBSD__
- u_int16_t mss = V_tcp_mssdflt;
-#else
- u_int16_t mss = tcp_mssdflt;
-#endif
-
- hlen = th_off << 2; /* hlen <= sizeof(hdr) */
- if (hlen <= sizeof(struct tcphdr))
- return (0);
- if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af))
- return (0);
- opt = hdr + sizeof(struct tcphdr);
- hlen -= sizeof(struct tcphdr);
- while (hlen >= TCPOLEN_MAXSEG) {
- switch (*opt) {
- case TCPOPT_EOL:
- case TCPOPT_NOP:
- ++opt;
- --hlen;
- break;
- case TCPOPT_MAXSEG:
- bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2);
- NTOHS(mss);
- /* FALLTHROUGH */
- default:
- optlen = opt[1];
- if (optlen < 2)
- optlen = 2;
- hlen -= optlen;
- opt += optlen;
- break;
- }
- }
- return (mss);
-}
-
-u_int16_t
-pf_calc_mss(struct pf_addr *addr, sa_family_t af, int rtableid, u_int16_t offer)
-{
-#ifdef INET
- struct sockaddr_in *dst;
- struct route ro;
-#endif /* INET */
-#ifdef INET6
- struct sockaddr_in6 *dst6;
- struct route_in6 ro6;
-#endif /* INET6 */
- struct rtentry *rt = NULL;
-#ifdef __FreeBSD__
- int hlen = 0;
- u_int16_t mss = V_tcp_mssdflt;
-#else
- int hlen;
- u_int16_t mss = tcp_mssdflt;
-#endif
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- hlen = sizeof(struct ip);
- bzero(&ro, sizeof(ro));
- dst = (struct sockaddr_in *)&ro.ro_dst;
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr = addr->v4;
-#ifdef __FreeBSD__
- in_rtalloc_ign(&ro, 0, rtableid);
-#else /* ! __FreeBSD__ */
- rtalloc_noclone(&ro, NO_CLONING);
-#endif
- rt = ro.ro_rt;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- hlen = sizeof(struct ip6_hdr);
- bzero(&ro6, sizeof(ro6));
- dst6 = (struct sockaddr_in6 *)&ro6.ro_dst;
- dst6->sin6_family = AF_INET6;
- dst6->sin6_len = sizeof(*dst6);
- dst6->sin6_addr = addr->v6;
-#ifdef __FreeBSD__
- in6_rtalloc_ign(&ro6, 0, rtableid);
-#else /* ! __FreeBSD__ */
- rtalloc_noclone((struct route *)&ro6, NO_CLONING);
-#endif
- rt = ro6.ro_rt;
- break;
-#endif /* INET6 */
- }
-
- if (rt && rt->rt_ifp) {
- mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr);
-#ifdef __FreeBSD__
- mss = max(V_tcp_mssdflt, mss);
-#else
- mss = max(tcp_mssdflt, mss);
-#endif
- RTFREE(rt);
- }
- mss = min(mss, offer);
- mss = max(mss, 64); /* sanity - at least max opt space */
- return (mss);
-}
-
-void
-pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr)
-{
- struct pf_rule *r = s->rule.ptr;
- struct pf_src_node *sn = NULL;
-
- s->rt_kif = NULL;
- if (!r->rt || r->rt == PF_FASTROUTE)
- return;
- switch (s->key[PF_SK_WIRE]->af) {
-#ifdef INET
- case AF_INET:
- pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn);
- s->rt_kif = r->rpool.cur->kif;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn);
- s->rt_kif = r->rpool.cur->kif;
- break;
-#endif /* INET6 */
- }
-}
-
-u_int32_t
-pf_tcp_iss(struct pf_pdesc *pd)
-{
- MD5_CTX ctx;
- u_int32_t digest[4];
-
-#ifdef __FreeBSD__
- if (V_pf_tcp_secret_init == 0) {
- read_random(&V_pf_tcp_secret, sizeof(V_pf_tcp_secret));
- MD5Init(&V_pf_tcp_secret_ctx);
- MD5Update(&V_pf_tcp_secret_ctx, V_pf_tcp_secret,
- sizeof(V_pf_tcp_secret));
- V_pf_tcp_secret_init = 1;
- }
-
- ctx = V_pf_tcp_secret_ctx;
-#else
- if (pf_tcp_secret_init == 0) {
- arc4random_buf(pf_tcp_secret, sizeof(pf_tcp_secret));
- MD5Init(&pf_tcp_secret_ctx);
- MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret,
- sizeof(pf_tcp_secret));
- pf_tcp_secret_init = 1;
- }
-
- ctx = pf_tcp_secret_ctx;
-#endif
-
- MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short));
- MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short));
- if (pd->af == AF_INET6) {
- MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr));
- MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr));
- } else {
- MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr));
- MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr));
- }
- MD5Final((u_char *)digest, &ctx);
-#ifdef __FreeBSD__
- V_pf_tcp_iss_off += 4096;
-#define ISN_RANDOM_INCREMENT (4096 - 1)
- return (digest[0] + (arc4random() & ISN_RANDOM_INCREMENT) +
- V_pf_tcp_iss_off);
-#undef ISN_RANDOM_INCREMENT
-#else
- pf_tcp_iss_off += 4096;
- return (digest[0] + tcp_iss + pf_tcp_iss_off);
-#endif
-}
-
-int
-pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction,
- struct pfi_kif *kif, struct mbuf *m, int off, void *h,
- struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm,
-#ifdef __FreeBSD__
- struct ifqueue *ifq, struct inpcb *inp)
-#else
- struct ifqueue *ifq)
-#endif
-{
- struct pf_rule *nr = NULL;
- struct pf_addr *saddr = pd->src, *daddr = pd->dst;
- sa_family_t af = pd->af;
- struct pf_rule *r, *a = NULL;
- struct pf_ruleset *ruleset = NULL;
- struct pf_src_node *nsn = NULL;
- struct tcphdr *th = pd->hdr.tcp;
- struct pf_state_key *skw = NULL, *sks = NULL;
- struct pf_state_key *sk = NULL, *nk = NULL;
- u_short reason;
- int rewrite = 0, hdrlen = 0;
- int tag = -1, rtableid = -1;
- int asd = 0;
- int match = 0;
- int state_icmp = 0;
-#ifdef __FreeBSD__
- u_int16_t sport = 0, dport = 0;
- u_int16_t bproto_sum = 0, bip_sum = 0;
-#else
- u_int16_t sport, dport;
- u_int16_t bproto_sum = 0, bip_sum;
-#endif
- u_int8_t icmptype = 0, icmpcode = 0;
-
-
- if (direction == PF_IN && pf_check_congestion(ifq)) {
- REASON_SET(&reason, PFRES_CONGEST);
- return (PF_DROP);
- }
-
-#ifdef __FreeBSD__
- if (inp != NULL)
- pd->lookup.done = pf_socket_lookup(direction, pd, inp);
- else if (V_debug_pfugidhack) {
- PF_UNLOCK();
- DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n"));
- pd->lookup.done = pf_socket_lookup(direction, pd, inp);
- PF_LOCK();
- }
-#endif
-
- switch (pd->proto) {
- case IPPROTO_TCP:
- sport = th->th_sport;
- dport = th->th_dport;
- hdrlen = sizeof(*th);
- break;
- case IPPROTO_UDP:
- sport = pd->hdr.udp->uh_sport;
- dport = pd->hdr.udp->uh_dport;
- hdrlen = sizeof(*pd->hdr.udp);
- break;
-#ifdef INET
- case IPPROTO_ICMP:
- if (pd->af != AF_INET)
- break;
- sport = dport = pd->hdr.icmp->icmp_id;
- hdrlen = sizeof(*pd->hdr.icmp);
- icmptype = pd->hdr.icmp->icmp_type;
- icmpcode = pd->hdr.icmp->icmp_code;
-
- if (icmptype == ICMP_UNREACH ||
- icmptype == ICMP_SOURCEQUENCH ||
- icmptype == ICMP_REDIRECT ||
- icmptype == ICMP_TIMXCEED ||
- icmptype == ICMP_PARAMPROB)
- state_icmp++;
- break;
-#endif /* INET */
-#ifdef INET6
- case IPPROTO_ICMPV6:
- if (af != AF_INET6)
- break;
- sport = dport = pd->hdr.icmp6->icmp6_id;
- hdrlen = sizeof(*pd->hdr.icmp6);
- icmptype = pd->hdr.icmp6->icmp6_type;
- icmpcode = pd->hdr.icmp6->icmp6_code;
-
- if (icmptype == ICMP6_DST_UNREACH ||
- icmptype == ICMP6_PACKET_TOO_BIG ||
- icmptype == ICMP6_TIME_EXCEEDED ||
- icmptype == ICMP6_PARAM_PROB)
- state_icmp++;
- break;
-#endif /* INET6 */
- default:
- sport = dport = hdrlen = 0;
- break;
- }
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
-
- /* check packet for BINAT/NAT/RDR */
- if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn,
- &skw, &sks, &sk, &nk, saddr, daddr, sport, dport)) != NULL) {
- if (nk == NULL || sk == NULL) {
- REASON_SET(&reason, PFRES_MEMORY);
- goto cleanup;
- }
-
- if (pd->ip_sum)
- bip_sum = *pd->ip_sum;
-
- switch (pd->proto) {
- case IPPROTO_TCP:
- bproto_sum = th->th_sum;
- pd->proto_sum = &th->th_sum;
-
- if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) ||
- nk->port[pd->sidx] != sport) {
- pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
- &th->th_sum, &nk->addr[pd->sidx],
- nk->port[pd->sidx], 0, af);
- pd->sport = &th->th_sport;
- sport = th->th_sport;
- }
-
- if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) ||
- nk->port[pd->didx] != dport) {
- pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
- &th->th_sum, &nk->addr[pd->didx],
- nk->port[pd->didx], 0, af);
- dport = th->th_dport;
- pd->dport = &th->th_dport;
- }
- rewrite++;
- break;
- case IPPROTO_UDP:
- bproto_sum = pd->hdr.udp->uh_sum;
- pd->proto_sum = &pd->hdr.udp->uh_sum;
-
- if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) ||
- nk->port[pd->sidx] != sport) {
- pf_change_ap(saddr, &pd->hdr.udp->uh_sport,
- pd->ip_sum, &pd->hdr.udp->uh_sum,
- &nk->addr[pd->sidx],
- nk->port[pd->sidx], 1, af);
- sport = pd->hdr.udp->uh_sport;
- pd->sport = &pd->hdr.udp->uh_sport;
- }
-
- if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) ||
- nk->port[pd->didx] != dport) {
- pf_change_ap(daddr, &pd->hdr.udp->uh_dport,
- pd->ip_sum, &pd->hdr.udp->uh_sum,
- &nk->addr[pd->didx],
- nk->port[pd->didx], 1, af);
- dport = pd->hdr.udp->uh_dport;
- pd->dport = &pd->hdr.udp->uh_dport;
- }
- rewrite++;
- break;
-#ifdef INET
- case IPPROTO_ICMP:
- nk->port[0] = nk->port[1];
- if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET))
- pf_change_a(&saddr->v4.s_addr, pd->ip_sum,
- nk->addr[pd->sidx].v4.s_addr, 0);
-
- if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET))
- pf_change_a(&daddr->v4.s_addr, pd->ip_sum,
- nk->addr[pd->didx].v4.s_addr, 0);
-
- if (nk->port[1] != pd->hdr.icmp->icmp_id) {
- pd->hdr.icmp->icmp_cksum = pf_cksum_fixup(
- pd->hdr.icmp->icmp_cksum, sport,
- nk->port[1], 0);
- pd->hdr.icmp->icmp_id = nk->port[1];
- pd->sport = &pd->hdr.icmp->icmp_id;
- }
- m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
- break;
-#endif /* INET */
-#ifdef INET6
- case IPPROTO_ICMPV6:
- nk->port[0] = nk->port[1];
- if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET6))
- pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
- &nk->addr[pd->sidx], 0);
-
- if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET6))
- pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
- &nk->addr[pd->didx], 0);
- rewrite++;
- break;
-#endif /* INET */
- default:
- switch (af) {
-#ifdef INET
- case AF_INET:
- if (PF_ANEQ(saddr,
- &nk->addr[pd->sidx], AF_INET))
- pf_change_a(&saddr->v4.s_addr,
- pd->ip_sum,
- nk->addr[pd->sidx].v4.s_addr, 0);
-
- if (PF_ANEQ(daddr,
- &nk->addr[pd->didx], AF_INET))
- pf_change_a(&daddr->v4.s_addr,
- pd->ip_sum,
- nk->addr[pd->didx].v4.s_addr, 0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (PF_ANEQ(saddr,
- &nk->addr[pd->sidx], AF_INET6))
- PF_ACPY(saddr, &nk->addr[pd->sidx], af);
-
- if (PF_ANEQ(daddr,
- &nk->addr[pd->didx], AF_INET6))
- PF_ACPY(saddr, &nk->addr[pd->didx], af);
- break;
-#endif /* INET */
- }
- break;
- }
- if (nr->natpass)
- r = NULL;
- pd->nat_rule = nr;
- }
-
- while (r != NULL) {
- r->evaluations++;
- if (pfi_kif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != direction)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != af)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != pd->proto)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, saddr, af,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- /* tcp/udp only. port_op always 0 in other cases */
- else if (r->src.port_op && !pf_match_port(r->src.port_op,
- r->src.port[0], r->src.port[1], sport))
- r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, daddr, af,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- /* tcp/udp only. port_op always 0 in other cases */
- else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
- r->dst.port[0], r->dst.port[1], dport))
- r = r->skip[PF_SKIP_DST_PORT].ptr;
- /* icmp only. type always 0 in other cases */
- else if (r->type && r->type != icmptype + 1)
- r = TAILQ_NEXT(r, entries);
- /* icmp only. type always 0 in other cases */
- else if (r->code && r->code != icmpcode + 1)
- r = TAILQ_NEXT(r, entries);
- else if (r->tos && !(r->tos == pd->tos))
- r = TAILQ_NEXT(r, entries);
- else if (r->rule_flag & PFRULE_FRAGMENT)
- r = TAILQ_NEXT(r, entries);
- else if (pd->proto == IPPROTO_TCP &&
- (r->flagset & th->th_flags) != r->flags)
- r = TAILQ_NEXT(r, entries);
- /* tcp/udp only. uid.op always 0 in other cases */
- else if (r->uid.op && (pd->lookup.done || (pd->lookup.done =
-#ifdef __FreeBSD__
- pf_socket_lookup(direction, pd, inp), 1)) &&
-#else
- pf_socket_lookup(direction, pd), 1)) &&
-#endif
- !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1],
- pd->lookup.uid))
- r = TAILQ_NEXT(r, entries);
- /* tcp/udp only. gid.op always 0 in other cases */
- else if (r->gid.op && (pd->lookup.done || (pd->lookup.done =
-#ifdef __FreeBSD__
- pf_socket_lookup(direction, pd, inp), 1)) &&
-#else
- pf_socket_lookup(direction, pd), 1)) &&
-#endif
- !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1],
- pd->lookup.gid))
- r = TAILQ_NEXT(r, entries);
- else if (r->prob &&
-#ifdef __FreeBSD__
- r->prob <= arc4random())
-#else
- r->prob <= arc4random_uniform(UINT_MAX - 1) + 1)
-#endif
- r = TAILQ_NEXT(r, entries);
-#ifdef __FreeBSD__
- else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
-#else
- else if (r->match_tag && !pf_match_tag(m, r, &tag))
-#endif
- r = TAILQ_NEXT(r, entries);
- else if (r->os_fingerprint != PF_OSFP_ANY &&
- (pd->proto != IPPROTO_TCP || !pf_osfp_match(
- pf_osfp_fingerprint(pd, m, off, th),
- r->os_fingerprint)))
- r = TAILQ_NEXT(r, entries);
- else {
- if (r->tag)
- tag = r->tag;
- if (r->rtableid >= 0)
- rtableid = r->rtableid;
- if (r->anchor == NULL) {
- match = 1;
- *rm = r;
- *am = a;
- *rsm = ruleset;
- if ((*rm)->quick)
- break;
- r = TAILQ_NEXT(r, entries);
- } else
- pf_step_into_anchor(&asd, &ruleset,
- PF_RULESET_FILTER, &r, &a, &match);
- }
- if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
- PF_RULESET_FILTER, &r, &a, &match))
- break;
- }
- r = *rm;
- a = *am;
- ruleset = *rsm;
-
- REASON_SET(&reason, PFRES_MATCH);
-
- if (r->log || (nr != NULL && nr->log)) {
- if (rewrite)
- m_copyback(m, off, hdrlen, pd->hdr.any);
- PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr,
- a, ruleset, pd);
- }
-
- if ((r->action == PF_DROP) &&
- ((r->rule_flag & PFRULE_RETURNRST) ||
- (r->rule_flag & PFRULE_RETURNICMP) ||
- (r->rule_flag & PFRULE_RETURN))) {
- /* undo NAT changes, if they have taken place */
- if (nr != NULL) {
- PF_ACPY(saddr, &sk->addr[pd->sidx], af);
- PF_ACPY(daddr, &sk->addr[pd->didx], af);
- if (pd->sport)
- *pd->sport = sk->port[pd->sidx];
- if (pd->dport)
- *pd->dport = sk->port[pd->didx];
- if (pd->proto_sum)
- *pd->proto_sum = bproto_sum;
- if (pd->ip_sum)
- *pd->ip_sum = bip_sum;
- m_copyback(m, off, hdrlen, pd->hdr.any);
- }
- if (pd->proto == IPPROTO_TCP &&
- ((r->rule_flag & PFRULE_RETURNRST) ||
- (r->rule_flag & PFRULE_RETURN)) &&
- !(th->th_flags & TH_RST)) {
- u_int32_t ack = ntohl(th->th_seq) + pd->p_len;
- int len = 0;
-#ifdef INET
- struct ip *h4;
-#endif
-#ifdef INET6
- struct ip6_hdr *h6;
-#endif
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- h4 = mtod(m, struct ip *);
- len = ntohs(h4->ip_len) - off;
- break;
-#endif
-#ifdef INET6
- case AF_INET6:
- h6 = mtod(m, struct ip6_hdr *);
- len = ntohs(h6->ip6_plen) - (off - sizeof(*h6));
- break;
-#endif
- }
-
- if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af))
- REASON_SET(&reason, PFRES_PROTCKSUM);
- else {
- if (th->th_flags & TH_SYN)
- ack++;
- if (th->th_flags & TH_FIN)
- ack++;
-#ifdef __FreeBSD__
- pf_send_tcp(m, r, af, pd->dst,
-#else
- pf_send_tcp(r, af, pd->dst,
-#endif
- pd->src, th->th_dport, th->th_sport,
- ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0,
- r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp);
- }
- } else if (pd->proto != IPPROTO_ICMP && af == AF_INET &&
- r->return_icmp)
- pf_send_icmp(m, r->return_icmp >> 8,
- r->return_icmp & 255, af, r);
- else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 &&
- r->return_icmp6)
- pf_send_icmp(m, r->return_icmp6 >> 8,
- r->return_icmp6 & 255, af, r);
- }
-
- if (r->action == PF_DROP)
- goto cleanup;
-
-#ifdef __FreeBSD__
- if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag)) {
-#else
- if (pf_tag_packet(m, tag, rtableid)) {
-#endif
- REASON_SET(&reason, PFRES_MEMORY);
- goto cleanup;
- }
-
- if (!state_icmp && (r->keep_state || nr != NULL ||
- (pd->flags & PFDESC_TCP_NORM))) {
- int action;
- action = pf_create_state(r, nr, a, pd, nsn, skw, sks, nk, sk, m,
- off, sport, dport, &rewrite, kif, sm, tag, bproto_sum,
- bip_sum, hdrlen);
- if (action != PF_PASS)
- return (action);
- } else {
-#ifdef __FreeBSD__
- if (sk != NULL)
- pool_put(&V_pf_state_key_pl, sk);
- if (nk != NULL)
- pool_put(&V_pf_state_key_pl, nk);
-#else
- if (sk != NULL)
- pool_put(&pf_state_key_pl, sk);
- if (nk != NULL)
- pool_put(&pf_state_key_pl, nk);
-#endif
- }
-
- /* copy back packet headers if we performed NAT operations */
- if (rewrite)
- m_copyback(m, off, hdrlen, pd->hdr.any);
-
-#if NPFSYNC > 0
- if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) &&
-#ifdef __FreeBSD__
- direction == PF_OUT && pfsync_up_ptr != NULL && pfsync_up_ptr()) {
-#else
- direction == PF_OUT && pfsync_up()) {
-#endif
- /*
- * We want the state created, but we dont
- * want to send this in case a partner
- * firewall has to know about it to allow
- * replies through it.
- */
-#ifdef __FreeBSD__
- if (pfsync_defer_ptr != NULL &&
- pfsync_defer_ptr(*sm, m))
-#else
- if (pfsync_defer(*sm, m))
-#endif
- return (PF_DEFER);
- }
-#endif
-
- return (PF_PASS);
-
-cleanup:
-#ifdef __FreeBSD__
- if (sk != NULL)
- pool_put(&V_pf_state_key_pl, sk);
- if (nk != NULL)
- pool_put(&V_pf_state_key_pl, nk);
-#else
- if (sk != NULL)
- pool_put(&pf_state_key_pl, sk);
- if (nk != NULL)
- pool_put(&pf_state_key_pl, nk);
-#endif
- return (PF_DROP);
-}
-
-static __inline int
-pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a,
- struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *skw,
- struct pf_state_key *sks, struct pf_state_key *nk, struct pf_state_key *sk,
- struct mbuf *m, int off, u_int16_t sport, u_int16_t dport, int *rewrite,
- struct pfi_kif *kif, struct pf_state **sm, int tag, u_int16_t bproto_sum,
- u_int16_t bip_sum, int hdrlen)
-{
- struct pf_state *s = NULL;
- struct pf_src_node *sn = NULL;
- struct tcphdr *th = pd->hdr.tcp;
-#ifdef __FreeBSD__
- u_int16_t mss = V_tcp_mssdflt;
-#else
- u_int16_t mss = tcp_mssdflt;
-#endif
- u_short reason;
-
- /* check maximums */
- if (r->max_states && (r->states_cur >= r->max_states)) {
-#ifdef __FreeBSD__
- V_pf_status.lcounters[LCNT_STATES]++;
-#else
- pf_status.lcounters[LCNT_STATES]++;
-#endif
- REASON_SET(&reason, PFRES_MAXSTATES);
- return (PF_DROP);
- }
- /* src node for filter rule */
- if ((r->rule_flag & PFRULE_SRCTRACK ||
- r->rpool.opts & PF_POOL_STICKYADDR) &&
- pf_insert_src_node(&sn, r, pd->src, pd->af) != 0) {
- REASON_SET(&reason, PFRES_SRCLIMIT);
- goto csfailed;
- }
- /* src node for translation rule */
- if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) &&
- pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af)) {
- REASON_SET(&reason, PFRES_SRCLIMIT);
- goto csfailed;
- }
-#ifdef __FreeBSD__
- s = pool_get(&V_pf_state_pl, PR_NOWAIT | PR_ZERO);
-#else
- s = pool_get(&pf_state_pl, PR_NOWAIT | PR_ZERO);
-#endif
- if (s == NULL) {
- REASON_SET(&reason, PFRES_MEMORY);
- goto csfailed;
- }
- s->rule.ptr = r;
- s->nat_rule.ptr = nr;
- s->anchor.ptr = a;
- STATE_INC_COUNTERS(s);
- if (r->allow_opts)
- s->state_flags |= PFSTATE_ALLOWOPTS;
- if (r->rule_flag & PFRULE_STATESLOPPY)
- s->state_flags |= PFSTATE_SLOPPY;
- if (r->rule_flag & PFRULE_PFLOW)
- s->state_flags |= PFSTATE_PFLOW;
- s->log = r->log & PF_LOG_ALL;
- s->sync_state = PFSYNC_S_NONE;
- if (nr != NULL)
- s->log |= nr->log & PF_LOG_ALL;
- switch (pd->proto) {
- case IPPROTO_TCP:
- s->src.seqlo = ntohl(th->th_seq);
- s->src.seqhi = s->src.seqlo + pd->p_len + 1;
- if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN &&
- r->keep_state == PF_STATE_MODULATE) {
- /* Generate sequence number modulator */
- if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) ==
- 0)
- s->src.seqdiff = 1;
- pf_change_a(&th->th_seq, &th->th_sum,
- htonl(s->src.seqlo + s->src.seqdiff), 0);
- *rewrite = 1;
- } else
- s->src.seqdiff = 0;
- if (th->th_flags & TH_SYN) {
- s->src.seqhi++;
- s->src.wscale = pf_get_wscale(m, off,
- th->th_off, pd->af);
- }
- s->src.max_win = MAX(ntohs(th->th_win), 1);
- if (s->src.wscale & PF_WSCALE_MASK) {
- /* Remove scale factor from initial window */
- int win = s->src.max_win;
- win += 1 << (s->src.wscale & PF_WSCALE_MASK);
- s->src.max_win = (win - 1) >>
- (s->src.wscale & PF_WSCALE_MASK);
- }
- if (th->th_flags & TH_FIN)
- s->src.seqhi++;
- s->dst.seqhi = 1;
- s->dst.max_win = 1;
- s->src.state = TCPS_SYN_SENT;
- s->dst.state = TCPS_CLOSED;
- s->timeout = PFTM_TCP_FIRST_PACKET;
- break;
- case IPPROTO_UDP:
- s->src.state = PFUDPS_SINGLE;
- s->dst.state = PFUDPS_NO_TRAFFIC;
- s->timeout = PFTM_UDP_FIRST_PACKET;
- break;
- case IPPROTO_ICMP:
-#ifdef INET6
- case IPPROTO_ICMPV6:
-#endif
- s->timeout = PFTM_ICMP_FIRST_PACKET;
- break;
- default:
- s->src.state = PFOTHERS_SINGLE;
- s->dst.state = PFOTHERS_NO_TRAFFIC;
- s->timeout = PFTM_OTHER_FIRST_PACKET;
- }
-
- s->creation = time_second;
- s->expire = time_second;
-
- if (sn != NULL) {
- s->src_node = sn;
- s->src_node->states++;
- }
- if (nsn != NULL) {
- /* XXX We only modify one side for now. */
- PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af);
- s->nat_src_node = nsn;
- s->nat_src_node->states++;
- }
- if (pd->proto == IPPROTO_TCP) {
- if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m,
- off, pd, th, &s->src, &s->dst)) {
- REASON_SET(&reason, PFRES_MEMORY);
- pf_src_tree_remove_state(s);
- STATE_DEC_COUNTERS(s);
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_pl, s);
-#else
- pool_put(&pf_state_pl, s);
-#endif
- return (PF_DROP);
- }
- if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub &&
- pf_normalize_tcp_stateful(m, off, pd, &reason, th, s,
- &s->src, &s->dst, rewrite)) {
- /* This really shouldn't happen!!! */
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_normalize_tcp_stateful failed on first pkt"));
- pf_normalize_tcp_cleanup(s);
- pf_src_tree_remove_state(s);
- STATE_DEC_COUNTERS(s);
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_pl, s);
-#else
- pool_put(&pf_state_pl, s);
-#endif
- return (PF_DROP);
- }
- }
- s->direction = pd->dir;
-
- if (sk == NULL && pf_state_key_setup(pd, nr, &skw, &sks, &sk, &nk,
- pd->src, pd->dst, sport, dport))
- goto csfailed;
-
- if (pf_state_insert(BOUND_IFACE(r, kif), skw, sks, s)) {
- if (pd->proto == IPPROTO_TCP)
- pf_normalize_tcp_cleanup(s);
- REASON_SET(&reason, PFRES_STATEINS);
- pf_src_tree_remove_state(s);
- STATE_DEC_COUNTERS(s);
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_pl, s);
-#else
- pool_put(&pf_state_pl, s);
-#endif
- return (PF_DROP);
- } else
- *sm = s;
-
- pf_set_rt_ifp(s, pd->src); /* needs s->state_key set */
- if (tag > 0) {
- pf_tag_ref(tag);
- s->tag = tag;
- }
- if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) ==
- TH_SYN && r->keep_state == PF_STATE_SYNPROXY) {
- s->src.state = PF_TCPS_PROXY_SRC;
- /* undo NAT changes, if they have taken place */
- if (nr != NULL) {
- struct pf_state_key *skt = s->key[PF_SK_WIRE];
- if (pd->dir == PF_OUT)
- skt = s->key[PF_SK_STACK];
- PF_ACPY(pd->src, &skt->addr[pd->sidx], pd->af);
- PF_ACPY(pd->dst, &skt->addr[pd->didx], pd->af);
- if (pd->sport)
- *pd->sport = skt->port[pd->sidx];
- if (pd->dport)
- *pd->dport = skt->port[pd->didx];
- if (pd->proto_sum)
- *pd->proto_sum = bproto_sum;
- if (pd->ip_sum)
- *pd->ip_sum = bip_sum;
- m_copyback(m, off, hdrlen, pd->hdr.any);
- }
- s->src.seqhi = htonl(arc4random());
- /* Find mss option */
- int rtid = M_GETFIB(m);
- mss = pf_get_mss(m, off, th->th_off, pd->af);
- mss = pf_calc_mss(pd->src, pd->af, rtid, mss);
- mss = pf_calc_mss(pd->dst, pd->af, rtid, mss);
- s->src.mss = mss;
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, r, pd->af, pd->dst, pd->src, th->th_dport,
-#else
- pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport,
-#endif
- th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1,
- TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL);
- REASON_SET(&reason, PFRES_SYNPROXY);
- return (PF_SYNPROXY_DROP);
- }
-
- return (PF_PASS);
-
-csfailed:
-#ifdef __FreeBSD__
- if (sk != NULL)
- pool_put(&V_pf_state_key_pl, sk);
- if (nk != NULL)
- pool_put(&V_pf_state_key_pl, nk);
-#else
- if (sk != NULL)
- pool_put(&pf_state_key_pl, sk);
- if (nk != NULL)
- pool_put(&pf_state_key_pl, nk);
-#endif
-
- if (sn != NULL && sn->states == 0 && sn->expire == 0) {
-#ifdef __FreeBSD__
- RB_REMOVE(pf_src_tree, &V_tree_src_tracking, sn);
- V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
- V_pf_status.src_nodes--;
- pool_put(&V_pf_src_tree_pl, sn);
-#else
- RB_REMOVE(pf_src_tree, &tree_src_tracking, sn);
- pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
- pf_status.src_nodes--;
- pool_put(&pf_src_tree_pl, sn);
-#endif
- }
- if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) {
-#ifdef __FreeBSD__
- RB_REMOVE(pf_src_tree, &V_tree_src_tracking, nsn);
- V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
- V_pf_status.src_nodes--;
- pool_put(&V_pf_src_tree_pl, nsn);
-#else
- RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn);
- pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++;
- pf_status.src_nodes--;
- pool_put(&pf_src_tree_pl, nsn);
-#endif
- }
- return (PF_DROP);
-}
-
-int
-pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif,
- struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am,
- struct pf_ruleset **rsm)
-{
- struct pf_rule *r, *a = NULL;
- struct pf_ruleset *ruleset = NULL;
- sa_family_t af = pd->af;
- u_short reason;
- int tag = -1;
- int asd = 0;
- int match = 0;
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr);
- while (r != NULL) {
- r->evaluations++;
- if (pfi_kif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != direction)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != af)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != pd->proto)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- else if (r->tos && !(r->tos == pd->tos))
- r = TAILQ_NEXT(r, entries);
- else if (r->os_fingerprint != PF_OSFP_ANY)
- r = TAILQ_NEXT(r, entries);
- else if (pd->proto == IPPROTO_UDP &&
- (r->src.port_op || r->dst.port_op))
- r = TAILQ_NEXT(r, entries);
- else if (pd->proto == IPPROTO_TCP &&
- (r->src.port_op || r->dst.port_op || r->flagset))
- r = TAILQ_NEXT(r, entries);
- else if ((pd->proto == IPPROTO_ICMP ||
- pd->proto == IPPROTO_ICMPV6) &&
- (r->type || r->code))
- r = TAILQ_NEXT(r, entries);
- else if (r->prob && r->prob <=
- (arc4random() % (UINT_MAX - 1) + 1))
- r = TAILQ_NEXT(r, entries);
-#ifdef __FreeBSD__
- else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
-#else
- else if (r->match_tag && !pf_match_tag(m, r, &tag))
-#endif
- r = TAILQ_NEXT(r, entries);
- else {
- if (r->anchor == NULL) {
- match = 1;
- *rm = r;
- *am = a;
- *rsm = ruleset;
- if ((*rm)->quick)
- break;
- r = TAILQ_NEXT(r, entries);
- } else
- pf_step_into_anchor(&asd, &ruleset,
- PF_RULESET_FILTER, &r, &a, &match);
- }
- if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
- PF_RULESET_FILTER, &r, &a, &match))
- break;
- }
- r = *rm;
- a = *am;
- ruleset = *rsm;
-
- REASON_SET(&reason, PFRES_MATCH);
-
- if (r->log)
- PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset,
- pd);
-
- if (r->action != PF_PASS)
- return (PF_DROP);
-
-#ifdef __FreeBSD__
- if (pf_tag_packet(m, tag, -1, pd->pf_mtag)) {
-#else
- if (pf_tag_packet(m, tag, -1)) {
-#endif
- REASON_SET(&reason, PFRES_MEMORY);
- return (PF_DROP);
- }
-
- return (PF_PASS);
-}
-
-int
-pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst,
- struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off,
- struct pf_pdesc *pd, u_short *reason, int *copyback)
-{
- struct tcphdr *th = pd->hdr.tcp;
- u_int16_t win = ntohs(th->th_win);
- u_int32_t ack, end, seq, orig_seq;
- u_int8_t sws, dws;
- int ackskew;
-
- if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) {
- sws = src->wscale & PF_WSCALE_MASK;
- dws = dst->wscale & PF_WSCALE_MASK;
- } else
- sws = dws = 0;
-
- /*
- * Sequence tracking algorithm from Guido van Rooij's paper:
- * http://www.madison-gurkha.com/publications/tcp_filtering/
- * tcp_filtering.ps
- */
-
- orig_seq = seq = ntohl(th->th_seq);
- if (src->seqlo == 0) {
- /* First packet from this end. Set its state */
-
- if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) &&
- src->scrub == NULL) {
- if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) {
- REASON_SET(reason, PFRES_MEMORY);
- return (PF_DROP);
- }
- }
-
- /* Deferred generation of sequence number modulator */
- if (dst->seqdiff && !src->seqdiff) {
- /* use random iss for the TCP server */
- while ((src->seqdiff = arc4random() - seq) == 0)
- ;
- ack = ntohl(th->th_ack) - dst->seqdiff;
- pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
- src->seqdiff), 0);
- pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
- *copyback = 1;
- } else {
- ack = ntohl(th->th_ack);
- }
-
- end = seq + pd->p_len;
- if (th->th_flags & TH_SYN) {
- end++;
- if (dst->wscale & PF_WSCALE_FLAG) {
- src->wscale = pf_get_wscale(m, off, th->th_off,
- pd->af);
- if (src->wscale & PF_WSCALE_FLAG) {
- /* Remove scale factor from initial
- * window */
- sws = src->wscale & PF_WSCALE_MASK;
- win = ((u_int32_t)win + (1 << sws) - 1)
- >> sws;
- dws = dst->wscale & PF_WSCALE_MASK;
- } else {
- /* fixup other window */
- dst->max_win <<= dst->wscale &
- PF_WSCALE_MASK;
- /* in case of a retrans SYN|ACK */
- dst->wscale = 0;
- }
- }
- }
- if (th->th_flags & TH_FIN)
- end++;
-
- src->seqlo = seq;
- if (src->state < TCPS_SYN_SENT)
- src->state = TCPS_SYN_SENT;
-
- /*
- * May need to slide the window (seqhi may have been set by
- * the crappy stack check or if we picked up the connection
- * after establishment)
- */
- if (src->seqhi == 1 ||
- SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi))
- src->seqhi = end + MAX(1, dst->max_win << dws);
- if (win > src->max_win)
- src->max_win = win;
-
- } else {
- ack = ntohl(th->th_ack) - dst->seqdiff;
- if (src->seqdiff) {
- /* Modulate sequence numbers */
- pf_change_a(&th->th_seq, &th->th_sum, htonl(seq +
- src->seqdiff), 0);
- pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0);
- *copyback = 1;
- }
- end = seq + pd->p_len;
- if (th->th_flags & TH_SYN)
- end++;
- if (th->th_flags & TH_FIN)
- end++;
- }
-
- if ((th->th_flags & TH_ACK) == 0) {
- /* Let it pass through the ack skew check */
- ack = dst->seqlo;
- } else if ((ack == 0 &&
- (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) ||
- /* broken tcp stacks do not set ack */
- (dst->state < TCPS_SYN_SENT)) {
- /*
- * Many stacks (ours included) will set the ACK number in an
- * FIN|ACK if the SYN times out -- no sequence to ACK.
- */
- ack = dst->seqlo;
- }
-
- if (seq == end) {
- /* Ease sequencing restrictions on no data packets */
- seq = src->seqlo;
- end = seq;
- }
-
- ackskew = dst->seqlo - ack;
-
-
- /*
- * Need to demodulate the sequence numbers in any TCP SACK options
- * (Selective ACK). We could optionally validate the SACK values
- * against the current ACK window, either forwards or backwards, but
- * I'm not confident that SACK has been implemented properly
- * everywhere. It wouldn't surprise me if several stacks accidently
- * SACK too far backwards of previously ACKed data. There really aren't
- * any security implications of bad SACKing unless the target stack
- * doesn't validate the option length correctly. Someone trying to
- * spoof into a TCP connection won't bother blindly sending SACK
- * options anyway.
- */
- if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) {
- if (pf_modulate_sack(m, off, pd, th, dst))
- *copyback = 1;
- }
-
-
-#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */
- if (SEQ_GEQ(src->seqhi, end) &&
- /* Last octet inside other's window space */
- SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) &&
- /* Retrans: not more than one window back */
- (ackskew >= -MAXACKWINDOW) &&
- /* Acking not more than one reassembled fragment backwards */
- (ackskew <= (MAXACKWINDOW << sws)) &&
- /* Acking not more than one window forward */
- ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo ||
- (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) ||
- (pd->flags & PFDESC_IP_REAS) == 0)) {
- /* Require an exact/+1 sequence match on resets when possible */
-
- if (dst->scrub || src->scrub) {
- if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
- *state, src, dst, copyback))
- return (PF_DROP);
- }
-
- /* update max window */
- if (src->max_win < win)
- src->max_win = win;
- /* synchronize sequencing */
- if (SEQ_GT(end, src->seqlo))
- src->seqlo = end;
- /* slide the window of what the other end can send */
- if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
- dst->seqhi = ack + MAX((win << sws), 1);
-
-
- /* update states */
- if (th->th_flags & TH_SYN)
- if (src->state < TCPS_SYN_SENT)
- src->state = TCPS_SYN_SENT;
- if (th->th_flags & TH_FIN)
- if (src->state < TCPS_CLOSING)
- src->state = TCPS_CLOSING;
- if (th->th_flags & TH_ACK) {
- if (dst->state == TCPS_SYN_SENT) {
- dst->state = TCPS_ESTABLISHED;
- if (src->state == TCPS_ESTABLISHED &&
- (*state)->src_node != NULL &&
- pf_src_connlimit(state)) {
- REASON_SET(reason, PFRES_SRCLIMIT);
- return (PF_DROP);
- }
- } else if (dst->state == TCPS_CLOSING)
- dst->state = TCPS_FIN_WAIT_2;
- }
- if (th->th_flags & TH_RST)
- src->state = dst->state = TCPS_TIME_WAIT;
-
- /* update expire time */
- (*state)->expire = time_second;
- if (src->state >= TCPS_FIN_WAIT_2 &&
- dst->state >= TCPS_FIN_WAIT_2)
- (*state)->timeout = PFTM_TCP_CLOSED;
- else if (src->state >= TCPS_CLOSING &&
- dst->state >= TCPS_CLOSING)
- (*state)->timeout = PFTM_TCP_FIN_WAIT;
- else if (src->state < TCPS_ESTABLISHED ||
- dst->state < TCPS_ESTABLISHED)
- (*state)->timeout = PFTM_TCP_OPENING;
- else if (src->state >= TCPS_CLOSING ||
- dst->state >= TCPS_CLOSING)
- (*state)->timeout = PFTM_TCP_CLOSING;
- else
- (*state)->timeout = PFTM_TCP_ESTABLISHED;
-
- /* Fall through to PASS packet */
-
- } else if ((dst->state < TCPS_SYN_SENT ||
- dst->state >= TCPS_FIN_WAIT_2 ||
- src->state >= TCPS_FIN_WAIT_2) &&
- SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) &&
- /* Within a window forward of the originating packet */
- SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) {
- /* Within a window backward of the originating packet */
-
- /*
- * This currently handles three situations:
- * 1) Stupid stacks will shotgun SYNs before their peer
- * replies.
- * 2) When PF catches an already established stream (the
- * firewall rebooted, the state table was flushed, routes
- * changed...)
- * 3) Packets get funky immediately after the connection
- * closes (this should catch Solaris spurious ACK|FINs
- * that web servers like to spew after a close)
- *
- * This must be a little more careful than the above code
- * since packet floods will also be caught here. We don't
- * update the TTL here to mitigate the damage of a packet
- * flood and so the same code can handle awkward establishment
- * and a loosened connection close.
- * In the establishment case, a correct peer response will
- * validate the connection, go through the normal state code
- * and keep updating the state TTL.
- */
-
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: loose state match: ");
- pf_print_state(*state);
- pf_print_flags(th->th_flags);
- printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
- "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack,
-#ifdef __FreeBSD__
- pd->p_len, ackskew, (unsigned long long)(*state)->packets[0],
- (unsigned long long)(*state)->packets[1],
-#else
- pd->p_len, ackskew, (*state)->packets[0],
- (*state)->packets[1],
-#endif
- pd->dir == PF_IN ? "in" : "out",
- pd->dir == (*state)->direction ? "fwd" : "rev");
- }
-
- if (dst->scrub || src->scrub) {
- if (pf_normalize_tcp_stateful(m, off, pd, reason, th,
- *state, src, dst, copyback))
- return (PF_DROP);
- }
-
- /* update max window */
- if (src->max_win < win)
- src->max_win = win;
- /* synchronize sequencing */
- if (SEQ_GT(end, src->seqlo))
- src->seqlo = end;
- /* slide the window of what the other end can send */
- if (SEQ_GEQ(ack + (win << sws), dst->seqhi))
- dst->seqhi = ack + MAX((win << sws), 1);
-
- /*
- * Cannot set dst->seqhi here since this could be a shotgunned
- * SYN and not an already established connection.
- */
-
- if (th->th_flags & TH_FIN)
- if (src->state < TCPS_CLOSING)
- src->state = TCPS_CLOSING;
- if (th->th_flags & TH_RST)
- src->state = dst->state = TCPS_TIME_WAIT;
-
- /* Fall through to PASS packet */
-
- } else {
- if ((*state)->dst.state == TCPS_SYN_SENT &&
- (*state)->src.state == TCPS_SYN_SENT) {
- /* Send RST for state mismatches during handshake */
- if (!(th->th_flags & TH_RST))
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
-#else
- pf_send_tcp((*state)->rule.ptr, pd->af,
-#endif
- pd->dst, pd->src, th->th_dport,
- th->th_sport, ntohl(th->th_ack), 0,
- TH_RST, 0, 0,
- (*state)->rule.ptr->return_ttl, 1, 0,
- pd->eh, kif->pfik_ifp);
- src->seqlo = 0;
- src->seqhi = 1;
- src->max_win = 1;
-#ifdef __FreeBSD__
- } else if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- } else if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: BAD state: ");
- pf_print_state(*state);
- pf_print_flags(th->th_flags);
- printf(" seq=%u (%u) ack=%u len=%u ackskew=%d "
- "pkts=%llu:%llu dir=%s,%s\n",
- seq, orig_seq, ack, pd->p_len, ackskew,
-#ifdef __FreeBSD__
- (unsigned long long)(*state)->packets[0],
- (unsigned long long)(*state)->packets[1],
-#else
- (*state)->packets[0], (*state)->packets[1],
-#endif
- pd->dir == PF_IN ? "in" : "out",
- pd->dir == (*state)->direction ? "fwd" : "rev");
- printf("pf: State failure on: %c %c %c %c | %c %c\n",
- SEQ_GEQ(src->seqhi, end) ? ' ' : '1',
- SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ?
- ' ': '2',
- (ackskew >= -MAXACKWINDOW) ? ' ' : '3',
- (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4',
- SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5',
- SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6');
- }
- REASON_SET(reason, PFRES_BADSTATE);
- return (PF_DROP);
- }
-
- return (PF_PASS);
-}
-
-int
-pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst,
- struct pf_state **state, struct pf_pdesc *pd, u_short *reason)
-{
- struct tcphdr *th = pd->hdr.tcp;
-
- if (th->th_flags & TH_SYN)
- if (src->state < TCPS_SYN_SENT)
- src->state = TCPS_SYN_SENT;
- if (th->th_flags & TH_FIN)
- if (src->state < TCPS_CLOSING)
- src->state = TCPS_CLOSING;
- if (th->th_flags & TH_ACK) {
- if (dst->state == TCPS_SYN_SENT) {
- dst->state = TCPS_ESTABLISHED;
- if (src->state == TCPS_ESTABLISHED &&
- (*state)->src_node != NULL &&
- pf_src_connlimit(state)) {
- REASON_SET(reason, PFRES_SRCLIMIT);
- return (PF_DROP);
- }
- } else if (dst->state == TCPS_CLOSING) {
- dst->state = TCPS_FIN_WAIT_2;
- } else if (src->state == TCPS_SYN_SENT &&
- dst->state < TCPS_SYN_SENT) {
- /*
- * Handle a special sloppy case where we only see one
- * half of the connection. If there is a ACK after
- * the initial SYN without ever seeing a packet from
- * the destination, set the connection to established.
- */
- dst->state = src->state = TCPS_ESTABLISHED;
- if ((*state)->src_node != NULL &&
- pf_src_connlimit(state)) {
- REASON_SET(reason, PFRES_SRCLIMIT);
- return (PF_DROP);
- }
- } else if (src->state == TCPS_CLOSING &&
- dst->state == TCPS_ESTABLISHED &&
- dst->seqlo == 0) {
- /*
- * Handle the closing of half connections where we
- * don't see the full bidirectional FIN/ACK+ACK
- * handshake.
- */
- dst->state = TCPS_CLOSING;
- }
- }
- if (th->th_flags & TH_RST)
- src->state = dst->state = TCPS_TIME_WAIT;
-
- /* update expire time */
- (*state)->expire = time_second;
- if (src->state >= TCPS_FIN_WAIT_2 &&
- dst->state >= TCPS_FIN_WAIT_2)
- (*state)->timeout = PFTM_TCP_CLOSED;
- else if (src->state >= TCPS_CLOSING &&
- dst->state >= TCPS_CLOSING)
- (*state)->timeout = PFTM_TCP_FIN_WAIT;
- else if (src->state < TCPS_ESTABLISHED ||
- dst->state < TCPS_ESTABLISHED)
- (*state)->timeout = PFTM_TCP_OPENING;
- else if (src->state >= TCPS_CLOSING ||
- dst->state >= TCPS_CLOSING)
- (*state)->timeout = PFTM_TCP_CLOSING;
- else
- (*state)->timeout = PFTM_TCP_ESTABLISHED;
-
- return (PF_PASS);
-}
-
-int
-pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif,
- struct mbuf *m, int off, void *h, struct pf_pdesc *pd,
- u_short *reason)
-{
- struct pf_state_key_cmp key;
- struct tcphdr *th = pd->hdr.tcp;
- int copyback = 0;
- struct pf_state_peer *src, *dst;
- struct pf_state_key *sk;
-
- key.af = pd->af;
- key.proto = IPPROTO_TCP;
- if (direction == PF_IN) { /* wire side, straight */
- PF_ACPY(&key.addr[0], pd->src, key.af);
- PF_ACPY(&key.addr[1], pd->dst, key.af);
- key.port[0] = th->th_sport;
- key.port[1] = th->th_dport;
- } else { /* stack side, reverse */
- PF_ACPY(&key.addr[1], pd->src, key.af);
- PF_ACPY(&key.addr[0], pd->dst, key.af);
- key.port[1] = th->th_sport;
- key.port[0] = th->th_dport;
- }
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- if (direction == (*state)->direction) {
- src = &(*state)->src;
- dst = &(*state)->dst;
- } else {
- src = &(*state)->dst;
- dst = &(*state)->src;
- }
-
- sk = (*state)->key[pd->didx];
-
- if ((*state)->src.state == PF_TCPS_PROXY_SRC) {
- if (direction != (*state)->direction) {
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_SYNPROXY_DROP);
- }
- if (th->th_flags & TH_SYN) {
- if (ntohl(th->th_seq) != (*state)->src.seqlo) {
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_DROP);
- }
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
-#else
- pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
-#endif
- pd->src, th->th_dport, th->th_sport,
- (*state)->src.seqhi, ntohl(th->th_seq) + 1,
- TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1,
- 0, NULL, NULL);
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_SYNPROXY_DROP);
- } else if (!(th->th_flags & TH_ACK) ||
- (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
- (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_DROP);
- } else if ((*state)->src_node != NULL &&
- pf_src_connlimit(state)) {
- REASON_SET(reason, PFRES_SRCLIMIT);
- return (PF_DROP);
- } else
- (*state)->src.state = PF_TCPS_PROXY_DST;
- }
- if ((*state)->src.state == PF_TCPS_PROXY_DST) {
- if (direction == (*state)->direction) {
- if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) ||
- (ntohl(th->th_ack) != (*state)->src.seqhi + 1) ||
- (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) {
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_DROP);
- }
- (*state)->src.max_win = MAX(ntohs(th->th_win), 1);
- if ((*state)->dst.seqhi == 1)
- (*state)->dst.seqhi = htonl(arc4random());
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
-#else
- pf_send_tcp((*state)->rule.ptr, pd->af,
-#endif
- &sk->addr[pd->sidx], &sk->addr[pd->didx],
- sk->port[pd->sidx], sk->port[pd->didx],
- (*state)->dst.seqhi, 0, TH_SYN, 0,
- (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL);
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_SYNPROXY_DROP);
- } else if (((th->th_flags & (TH_SYN|TH_ACK)) !=
- (TH_SYN|TH_ACK)) ||
- (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) {
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_DROP);
- } else {
- (*state)->dst.max_win = MAX(ntohs(th->th_win), 1);
- (*state)->dst.seqlo = ntohl(th->th_seq);
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst,
-#else
- pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst,
-#endif
- pd->src, th->th_dport, th->th_sport,
- ntohl(th->th_ack), ntohl(th->th_seq) + 1,
- TH_ACK, (*state)->src.max_win, 0, 0, 0,
- (*state)->tag, NULL, NULL);
-#ifdef __FreeBSD__
- pf_send_tcp(NULL, (*state)->rule.ptr, pd->af,
-#else
- pf_send_tcp((*state)->rule.ptr, pd->af,
-#endif
- &sk->addr[pd->sidx], &sk->addr[pd->didx],
- sk->port[pd->sidx], sk->port[pd->didx],
- (*state)->src.seqhi + 1, (*state)->src.seqlo + 1,
- TH_ACK, (*state)->dst.max_win, 0, 0, 1,
- 0, NULL, NULL);
- (*state)->src.seqdiff = (*state)->dst.seqhi -
- (*state)->src.seqlo;
- (*state)->dst.seqdiff = (*state)->src.seqhi -
- (*state)->dst.seqlo;
- (*state)->src.seqhi = (*state)->src.seqlo +
- (*state)->dst.max_win;
- (*state)->dst.seqhi = (*state)->dst.seqlo +
- (*state)->src.max_win;
- (*state)->src.wscale = (*state)->dst.wscale = 0;
- (*state)->src.state = (*state)->dst.state =
- TCPS_ESTABLISHED;
- REASON_SET(reason, PFRES_SYNPROXY);
- return (PF_SYNPROXY_DROP);
- }
- }
-
- if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) &&
- dst->state >= TCPS_FIN_WAIT_2 &&
- src->state >= TCPS_FIN_WAIT_2) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: state reuse ");
- pf_print_state(*state);
- pf_print_flags(th->th_flags);
- printf("\n");
- }
- /* XXX make sure it's the same direction ?? */
- (*state)->src.state = (*state)->dst.state = TCPS_CLOSED;
- pf_unlink_state(*state);
- *state = NULL;
- return (PF_DROP);
- }
-
- if ((*state)->state_flags & PFSTATE_SLOPPY) {
- if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP)
- return (PF_DROP);
- } else {
- if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason,
- &copyback) == PF_DROP)
- return (PF_DROP);
- }
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk = (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) ||
- nk->port[pd->sidx] != th->th_sport)
- pf_change_ap(pd->src, &th->th_sport, pd->ip_sum,
- &th->th_sum, &nk->addr[pd->sidx],
- nk->port[pd->sidx], 0, pd->af);
-
- if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) ||
- nk->port[pd->didx] != th->th_dport)
- pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum,
- &th->th_sum, &nk->addr[pd->didx],
- nk->port[pd->didx], 0, pd->af);
- copyback = 1;
- }
-
- /* Copyback sequence modulation or stateful scrub changes if needed */
- if (copyback)
-#ifdef __FreeBSD__
- m_copyback(m, off, sizeof(*th), (caddr_t)th);
-#else
- m_copyback(m, off, sizeof(*th), th);
-#endif
-
- return (PF_PASS);
-}
-
-int
-pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif,
- struct mbuf *m, int off, void *h, struct pf_pdesc *pd)
-{
- struct pf_state_peer *src, *dst;
- struct pf_state_key_cmp key;
- struct udphdr *uh = pd->hdr.udp;
-
- key.af = pd->af;
- key.proto = IPPROTO_UDP;
- if (direction == PF_IN) { /* wire side, straight */
- PF_ACPY(&key.addr[0], pd->src, key.af);
- PF_ACPY(&key.addr[1], pd->dst, key.af);
- key.port[0] = uh->uh_sport;
- key.port[1] = uh->uh_dport;
- } else { /* stack side, reverse */
- PF_ACPY(&key.addr[1], pd->src, key.af);
- PF_ACPY(&key.addr[0], pd->dst, key.af);
- key.port[1] = uh->uh_sport;
- key.port[0] = uh->uh_dport;
- }
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- if (direction == (*state)->direction) {
- src = &(*state)->src;
- dst = &(*state)->dst;
- } else {
- src = &(*state)->dst;
- dst = &(*state)->src;
- }
-
- /* update states */
- if (src->state < PFUDPS_SINGLE)
- src->state = PFUDPS_SINGLE;
- if (dst->state == PFUDPS_SINGLE)
- dst->state = PFUDPS_MULTIPLE;
-
- /* update expire time */
- (*state)->expire = time_second;
- if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE)
- (*state)->timeout = PFTM_UDP_MULTIPLE;
- else
- (*state)->timeout = PFTM_UDP_SINGLE;
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk = (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) ||
- nk->port[pd->sidx] != uh->uh_sport)
- pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum,
- &uh->uh_sum, &nk->addr[pd->sidx],
- nk->port[pd->sidx], 1, pd->af);
-
- if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) ||
- nk->port[pd->didx] != uh->uh_dport)
- pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum,
- &uh->uh_sum, &nk->addr[pd->didx],
- nk->port[pd->didx], 1, pd->af);
-#ifdef __FreeBSD__
- m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
-#else
- m_copyback(m, off, sizeof(*uh), uh);
-#endif
- }
-
- return (PF_PASS);
-}
-
-int
-pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif,
- struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason)
-{
- struct pf_addr *saddr = pd->src, *daddr = pd->dst;
-#ifdef __FreeBSD__
- u_int16_t icmpid = 0, *icmpsum;
-#else
- u_int16_t icmpid, *icmpsum;
-#endif
- u_int8_t icmptype;
- int state_icmp = 0;
- struct pf_state_key_cmp key;
-
- switch (pd->proto) {
-#ifdef INET
- case IPPROTO_ICMP:
- icmptype = pd->hdr.icmp->icmp_type;
- icmpid = pd->hdr.icmp->icmp_id;
- icmpsum = &pd->hdr.icmp->icmp_cksum;
-
- if (icmptype == ICMP_UNREACH ||
- icmptype == ICMP_SOURCEQUENCH ||
- icmptype == ICMP_REDIRECT ||
- icmptype == ICMP_TIMXCEED ||
- icmptype == ICMP_PARAMPROB)
- state_icmp++;
- break;
-#endif /* INET */
-#ifdef INET6
- case IPPROTO_ICMPV6:
- icmptype = pd->hdr.icmp6->icmp6_type;
- icmpid = pd->hdr.icmp6->icmp6_id;
- icmpsum = &pd->hdr.icmp6->icmp6_cksum;
-
- if (icmptype == ICMP6_DST_UNREACH ||
- icmptype == ICMP6_PACKET_TOO_BIG ||
- icmptype == ICMP6_TIME_EXCEEDED ||
- icmptype == ICMP6_PARAM_PROB)
- state_icmp++;
- break;
-#endif /* INET6 */
- }
-
- if (!state_icmp) {
-
- /*
- * ICMP query/reply message not related to a TCP/UDP packet.
- * Search for an ICMP state.
- */
- key.af = pd->af;
- key.proto = pd->proto;
- key.port[0] = key.port[1] = icmpid;
- if (direction == PF_IN) { /* wire side, straight */
- PF_ACPY(&key.addr[0], pd->src, key.af);
- PF_ACPY(&key.addr[1], pd->dst, key.af);
- } else { /* stack side, reverse */
- PF_ACPY(&key.addr[1], pd->src, key.af);
- PF_ACPY(&key.addr[0], pd->dst, key.af);
- }
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- (*state)->expire = time_second;
- (*state)->timeout = PFTM_ICMP_ERROR_REPLY;
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk = (*state)->key[pd->didx];
-
- switch (pd->af) {
-#ifdef INET
- case AF_INET:
- if (PF_ANEQ(pd->src,
- &nk->addr[pd->sidx], AF_INET))
- pf_change_a(&saddr->v4.s_addr,
- pd->ip_sum,
- nk->addr[pd->sidx].v4.s_addr, 0);
-
- if (PF_ANEQ(pd->dst, &nk->addr[pd->didx],
- AF_INET))
- pf_change_a(&daddr->v4.s_addr,
- pd->ip_sum,
- nk->addr[pd->didx].v4.s_addr, 0);
-
- if (nk->port[0] !=
- pd->hdr.icmp->icmp_id) {
- pd->hdr.icmp->icmp_cksum =
- pf_cksum_fixup(
- pd->hdr.icmp->icmp_cksum, icmpid,
- nk->port[pd->sidx], 0);
- pd->hdr.icmp->icmp_id =
- nk->port[pd->sidx];
- }
-
- m_copyback(m, off, ICMP_MINLEN,
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (PF_ANEQ(pd->src,
- &nk->addr[pd->sidx], AF_INET6))
- pf_change_a6(saddr,
- &pd->hdr.icmp6->icmp6_cksum,
- &nk->addr[pd->sidx], 0);
-
- if (PF_ANEQ(pd->dst,
- &nk->addr[pd->didx], AF_INET6))
- pf_change_a6(daddr,
- &pd->hdr.icmp6->icmp6_cksum,
- &nk->addr[pd->didx], 0);
-
- m_copyback(m, off,
- sizeof(struct icmp6_hdr),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp6);
- break;
-#endif /* INET6 */
- }
- }
- return (PF_PASS);
-
- } else {
- /*
- * ICMP error message in response to a TCP/UDP packet.
- * Extract the inner TCP/UDP header and search for that state.
- */
-
- struct pf_pdesc pd2;
-#ifdef __FreeBSD__
- bzero(&pd2, sizeof pd2);
-#endif
-#ifdef INET
- struct ip h2;
-#endif /* INET */
-#ifdef INET6
- struct ip6_hdr h2_6;
- int terminal = 0;
-#endif /* INET6 */
-#ifdef __FreeBSD__
- int ipoff2 = 0;
- int off2 = 0;
-#else
- int ipoff2;
- int off2;
-#endif
-
- pd2.af = pd->af;
- /* Payload packet is from the opposite direction. */
- pd2.sidx = (direction == PF_IN) ? 1 : 0;
- pd2.didx = (direction == PF_IN) ? 0 : 1;
- switch (pd->af) {
-#ifdef INET
- case AF_INET:
- /* offset of h2 in mbuf chain */
- ipoff2 = off + ICMP_MINLEN;
-
- if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2),
- NULL, reason, pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMP error message too short "
- "(ip)\n"));
- return (PF_DROP);
- }
- /*
- * ICMP error messages don't refer to non-first
- * fragments
- */
- if (h2.ip_off & htons(IP_OFFMASK)) {
- REASON_SET(reason, PFRES_FRAG);
- return (PF_DROP);
- }
-
- /* offset of protocol header that follows h2 */
- off2 = ipoff2 + (h2.ip_hl << 2);
-
- pd2.proto = h2.ip_p;
- pd2.src = (struct pf_addr *)&h2.ip_src;
- pd2.dst = (struct pf_addr *)&h2.ip_dst;
- pd2.ip_sum = &h2.ip_sum;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- ipoff2 = off + sizeof(struct icmp6_hdr);
-
- if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6),
- NULL, reason, pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMP error message too short "
- "(ip6)\n"));
- return (PF_DROP);
- }
- pd2.proto = h2_6.ip6_nxt;
- pd2.src = (struct pf_addr *)&h2_6.ip6_src;
- pd2.dst = (struct pf_addr *)&h2_6.ip6_dst;
- pd2.ip_sum = NULL;
- off2 = ipoff2 + sizeof(h2_6);
- do {
- switch (pd2.proto) {
- case IPPROTO_FRAGMENT:
- /*
- * ICMPv6 error messages for
- * non-first fragments
- */
- REASON_SET(reason, PFRES_FRAG);
- return (PF_DROP);
- case IPPROTO_AH:
- case IPPROTO_HOPOPTS:
- case IPPROTO_ROUTING:
- case IPPROTO_DSTOPTS: {
- /* get next header and header length */
- struct ip6_ext opt6;
-
- if (!pf_pull_hdr(m, off2, &opt6,
- sizeof(opt6), NULL, reason,
- pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMPv6 short opt\n"));
- return (PF_DROP);
- }
- if (pd2.proto == IPPROTO_AH)
- off2 += (opt6.ip6e_len + 2) * 4;
- else
- off2 += (opt6.ip6e_len + 1) * 8;
- pd2.proto = opt6.ip6e_nxt;
- /* goto the next header */
- break;
- }
- default:
- terminal++;
- break;
- }
- } while (!terminal);
- break;
-#endif /* INET6 */
- }
-
- switch (pd2.proto) {
- case IPPROTO_TCP: {
- struct tcphdr th;
- u_int32_t seq;
- struct pf_state_peer *src, *dst;
- u_int8_t dws;
- int copyback = 0;
-
- /*
- * Only the first 8 bytes of the TCP header can be
- * expected. Don't access any TCP header fields after
- * th_seq, an ackskew test is not possible.
- */
- if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason,
- pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMP error message too short "
- "(tcp)\n"));
- return (PF_DROP);
- }
-
- key.af = pd2.af;
- key.proto = IPPROTO_TCP;
- PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
- PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[pd2.sidx] = th.th_sport;
- key.port[pd2.didx] = th.th_dport;
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- if (direction == (*state)->direction) {
- src = &(*state)->dst;
- dst = &(*state)->src;
- } else {
- src = &(*state)->src;
- dst = &(*state)->dst;
- }
-
- if (src->wscale && dst->wscale)
- dws = dst->wscale & PF_WSCALE_MASK;
- else
- dws = 0;
-
- /* Demodulate sequence number */
- seq = ntohl(th.th_seq) - src->seqdiff;
- if (src->seqdiff) {
- pf_change_a(&th.th_seq, icmpsum,
- htonl(seq), 0);
- copyback = 1;
- }
-
- if (!((*state)->state_flags & PFSTATE_SLOPPY) &&
- (!SEQ_GEQ(src->seqhi, seq) ||
- !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: BAD ICMP %d:%d ",
- icmptype, pd->hdr.icmp->icmp_code);
- pf_print_host(pd->src, 0, pd->af);
- printf(" -> ");
- pf_print_host(pd->dst, 0, pd->af);
- printf(" state: ");
- pf_print_state(*state);
- printf(" seq=%u\n", seq);
- }
- REASON_SET(reason, PFRES_BADSTATE);
- return (PF_DROP);
- } else {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf: OK ICMP %d:%d ",
- icmptype, pd->hdr.icmp->icmp_code);
- pf_print_host(pd->src, 0, pd->af);
- printf(" -> ");
- pf_print_host(pd->dst, 0, pd->af);
- printf(" state: ");
- pf_print_state(*state);
- printf(" seq=%u\n", seq);
- }
- }
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] !=
- (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk =
- (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd2.src,
- &nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != th.th_sport)
- pf_change_icmp(pd2.src, &th.th_sport,
- daddr, &nk->addr[pd2.sidx],
- nk->port[pd2.sidx], NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, pd2.af);
-
- if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != th.th_dport)
- pf_change_icmp(pd2.dst, &th.th_dport,
- NULL, /* XXX Inbound NAT? */
- &nk->addr[pd2.didx],
- nk->port[pd2.didx], NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, pd2.af);
- copyback = 1;
- }
-
- if (copyback) {
- switch (pd2.af) {
-#ifdef INET
- case AF_INET:
- m_copyback(m, off, ICMP_MINLEN,
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp);
- m_copyback(m, ipoff2, sizeof(h2),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- &h2);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- m_copyback(m, off,
- sizeof(struct icmp6_hdr),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp6);
- m_copyback(m, ipoff2, sizeof(h2_6),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- &h2_6);
- break;
-#endif /* INET6 */
- }
-#ifdef __FreeBSD__
- m_copyback(m, off2, 8, (caddr_t)&th);
-#else
- m_copyback(m, off2, 8, &th);
-#endif
- }
-
- return (PF_PASS);
- break;
- }
- case IPPROTO_UDP: {
- struct udphdr uh;
-
- if (!pf_pull_hdr(m, off2, &uh, sizeof(uh),
- NULL, reason, pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMP error message too short "
- "(udp)\n"));
- return (PF_DROP);
- }
-
- key.af = pd2.af;
- key.proto = IPPROTO_UDP;
- PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
- PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[pd2.sidx] = uh.uh_sport;
- key.port[pd2.didx] = uh.uh_dport;
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] !=
- (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk =
- (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd2.src,
- &nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != uh.uh_sport)
- pf_change_icmp(pd2.src, &uh.uh_sport,
- daddr, &nk->addr[pd2.sidx],
- nk->port[pd2.sidx], &uh.uh_sum,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 1, pd2.af);
-
- if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != uh.uh_dport)
- pf_change_icmp(pd2.dst, &uh.uh_dport,
- NULL, /* XXX Inbound NAT? */
- &nk->addr[pd2.didx],
- nk->port[pd2.didx], &uh.uh_sum,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 1, pd2.af);
-
- switch (pd2.af) {
-#ifdef INET
- case AF_INET:
- m_copyback(m, off, ICMP_MINLEN,
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp);
-#ifdef __FreeBSD__
- m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
-#else
- m_copyback(m, ipoff2, sizeof(h2), &h2);
-#endif
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- m_copyback(m, off,
- sizeof(struct icmp6_hdr),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp6);
- m_copyback(m, ipoff2, sizeof(h2_6),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- &h2_6);
- break;
-#endif /* INET6 */
- }
-#ifdef __FreeBSD__
- m_copyback(m, off2, sizeof(uh), (caddr_t)&uh);
-#else
- m_copyback(m, off2, sizeof(uh), &uh);
-#endif
- }
- return (PF_PASS);
- break;
- }
-#ifdef INET
- case IPPROTO_ICMP: {
- struct icmp iih;
-
- if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN,
- NULL, reason, pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMP error message too short i"
- "(icmp)\n"));
- return (PF_DROP);
- }
-
- key.af = pd2.af;
- key.proto = IPPROTO_ICMP;
- PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
- PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[0] = key.port[1] = iih.icmp_id;
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] !=
- (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk =
- (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd2.src,
- &nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != iih.icmp_id)
- pf_change_icmp(pd2.src, &iih.icmp_id,
- daddr, &nk->addr[pd2.sidx],
- nk->port[pd2.sidx], NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, AF_INET);
-
- if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != iih.icmp_id)
- pf_change_icmp(pd2.dst, &iih.icmp_id,
- NULL, /* XXX Inbound NAT? */
- &nk->addr[pd2.didx],
- nk->port[pd2.didx], NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, AF_INET);
-
-#ifdef __FreeBSD__
- m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp);
- m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
- m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih);
-#else
- m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp);
- m_copyback(m, ipoff2, sizeof(h2), &h2);
- m_copyback(m, off2, ICMP_MINLEN, &iih);
-#endif
- }
- return (PF_PASS);
- break;
- }
-#endif /* INET */
-#ifdef INET6
- case IPPROTO_ICMPV6: {
- struct icmp6_hdr iih;
-
- if (!pf_pull_hdr(m, off2, &iih,
- sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: ICMP error message too short "
- "(icmp6)\n"));
- return (PF_DROP);
- }
-
- key.af = pd2.af;
- key.proto = IPPROTO_ICMPV6;
- PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
- PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[0] = key.port[1] = iih.icmp6_id;
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] !=
- (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk =
- (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd2.src,
- &nk->addr[pd2.sidx], pd2.af) ||
- nk->port[pd2.sidx] != iih.icmp6_id)
- pf_change_icmp(pd2.src, &iih.icmp6_id,
- daddr, &nk->addr[pd2.sidx],
- nk->port[pd2.sidx], NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, AF_INET6);
-
- if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af) ||
- nk->port[pd2.didx] != iih.icmp6_id)
- pf_change_icmp(pd2.dst, &iih.icmp6_id,
- NULL, /* XXX Inbound NAT? */
- &nk->addr[pd2.didx],
- nk->port[pd2.didx], NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, AF_INET6);
-
-#ifdef __FreeBSD__
- m_copyback(m, off, sizeof(struct icmp6_hdr),
- (caddr_t)pd->hdr.icmp6);
- m_copyback(m, ipoff2, sizeof(h2_6), (caddr_t)&h2_6);
- m_copyback(m, off2, sizeof(struct icmp6_hdr),
- (caddr_t)&iih);
-#else
- m_copyback(m, off, sizeof(struct icmp6_hdr),
- pd->hdr.icmp6);
- m_copyback(m, ipoff2, sizeof(h2_6), &h2_6);
- m_copyback(m, off2, sizeof(struct icmp6_hdr),
- &iih);
-#endif
- }
- return (PF_PASS);
- break;
- }
-#endif /* INET6 */
- default: {
- key.af = pd2.af;
- key.proto = pd2.proto;
- PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af);
- PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af);
- key.port[0] = key.port[1] = 0;
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] !=
- (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk =
- (*state)->key[pd->didx];
-
- if (PF_ANEQ(pd2.src,
- &nk->addr[pd2.sidx], pd2.af))
- pf_change_icmp(pd2.src, NULL, daddr,
- &nk->addr[pd2.sidx], 0, NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, pd2.af);
-
- if (PF_ANEQ(pd2.dst,
- &nk->addr[pd2.didx], pd2.af))
- pf_change_icmp(pd2.src, NULL,
- NULL, /* XXX Inbound NAT? */
- &nk->addr[pd2.didx], 0, NULL,
- pd2.ip_sum, icmpsum,
- pd->ip_sum, 0, pd2.af);
-
- switch (pd2.af) {
-#ifdef INET
- case AF_INET:
-#ifdef __FreeBSD__
- m_copyback(m, off, ICMP_MINLEN,
- (caddr_t)pd->hdr.icmp);
- m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2);
-#else
- m_copyback(m, off, ICMP_MINLEN,
- pd->hdr.icmp);
- m_copyback(m, ipoff2, sizeof(h2), &h2);
-#endif
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- m_copyback(m, off,
- sizeof(struct icmp6_hdr),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- pd->hdr.icmp6);
- m_copyback(m, ipoff2, sizeof(h2_6),
-#ifdef __FreeBSD__
- (caddr_t)
-#endif
- &h2_6);
- break;
-#endif /* INET6 */
- }
- }
- return (PF_PASS);
- break;
- }
- }
- }
-}
-
-int
-pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif,
- struct mbuf *m, struct pf_pdesc *pd)
-{
- struct pf_state_peer *src, *dst;
- struct pf_state_key_cmp key;
-
- key.af = pd->af;
- key.proto = pd->proto;
- if (direction == PF_IN) {
- PF_ACPY(&key.addr[0], pd->src, key.af);
- PF_ACPY(&key.addr[1], pd->dst, key.af);
- key.port[0] = key.port[1] = 0;
- } else {
- PF_ACPY(&key.addr[1], pd->src, key.af);
- PF_ACPY(&key.addr[0], pd->dst, key.af);
- key.port[1] = key.port[0] = 0;
- }
-
-#ifdef __FreeBSD__
- STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag);
-#else
- STATE_LOOKUP(kif, &key, direction, *state, m);
-#endif
-
- if (direction == (*state)->direction) {
- src = &(*state)->src;
- dst = &(*state)->dst;
- } else {
- src = &(*state)->dst;
- dst = &(*state)->src;
- }
-
- /* update states */
- if (src->state < PFOTHERS_SINGLE)
- src->state = PFOTHERS_SINGLE;
- if (dst->state == PFOTHERS_SINGLE)
- dst->state = PFOTHERS_MULTIPLE;
-
- /* update expire time */
- (*state)->expire = time_second;
- if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE)
- (*state)->timeout = PFTM_OTHER_MULTIPLE;
- else
- (*state)->timeout = PFTM_OTHER_SINGLE;
-
- /* translate source/destination address, if necessary */
- if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
- struct pf_state_key *nk = (*state)->key[pd->didx];
-
-#ifdef __FreeBSD__
- KASSERT(nk, ("%s: nk is null", __FUNCTION__));
- KASSERT(pd, ("%s: pd is null", __FUNCTION__));
- KASSERT(pd->src, ("%s: pd->src is null", __FUNCTION__));
- KASSERT(pd->dst, ("%s: pd->dst is null", __FUNCTION__));
-#else
- KASSERT(nk);
- KASSERT(pd);
- KASSERT(pd->src);
- KASSERT(pd->dst);
-#endif
- switch (pd->af) {
-#ifdef INET
- case AF_INET:
- if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET))
- pf_change_a(&pd->src->v4.s_addr,
- pd->ip_sum,
- nk->addr[pd->sidx].v4.s_addr,
- 0);
-
-
- if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET))
- pf_change_a(&pd->dst->v4.s_addr,
- pd->ip_sum,
- nk->addr[pd->didx].v4.s_addr,
- 0);
-
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET))
- PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af);
-
- if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET))
- PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af);
-#endif /* INET6 */
- }
- }
- return (PF_PASS);
-}
-
-/*
- * ipoff and off are measured from the start of the mbuf chain.
- * h must be at "ipoff" on the mbuf chain.
- */
-void *
-pf_pull_hdr(struct mbuf *m, int off, void *p, int len,
- u_short *actionp, u_short *reasonp, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET: {
- struct ip *h = mtod(m, struct ip *);
- u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
-
- if (fragoff) {
- if (fragoff >= len)
- ACTION_SET(actionp, PF_PASS);
- else {
- ACTION_SET(actionp, PF_DROP);
- REASON_SET(reasonp, PFRES_FRAG);
- }
- return (NULL);
- }
- if (m->m_pkthdr.len < off + len ||
- ntohs(h->ip_len) < off + len) {
- ACTION_SET(actionp, PF_DROP);
- REASON_SET(reasonp, PFRES_SHORT);
- return (NULL);
- }
- break;
- }
-#endif /* INET */
-#ifdef INET6
- case AF_INET6: {
- struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
-
- if (m->m_pkthdr.len < off + len ||
- (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) <
- (unsigned)(off + len)) {
- ACTION_SET(actionp, PF_DROP);
- REASON_SET(reasonp, PFRES_SHORT);
- return (NULL);
- }
- break;
- }
-#endif /* INET6 */
- }
- m_copydata(m, off, len, p);
- return (p);
-}
-
-int
-pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif,
- int rtableid)
-{
-#ifdef __FreeBSD__
-#ifdef RADIX_MPATH
- struct radix_node_head *rnh;
-#endif
-#endif
- struct sockaddr_in *dst;
- int ret = 1;
- int check_mpath;
-#ifndef __FreeBSD__
- extern int ipmultipath;
-#endif
-#ifdef INET6
-#ifndef __FreeBSD__
- extern int ip6_multipath;
-#endif
- struct sockaddr_in6 *dst6;
- struct route_in6 ro;
-#else
- struct route ro;
-#endif
- struct radix_node *rn;
- struct rtentry *rt;
- struct ifnet *ifp;
-
- check_mpath = 0;
-#ifdef __FreeBSD__
-#ifdef RADIX_MPATH
- /* XXX: stick to table 0 for now */
- rnh = rt_tables_get_rnh(0, af);
- if (rnh != NULL && rn_mpath_capable(rnh))
- check_mpath = 1;
-#endif
-#endif
- bzero(&ro, sizeof(ro));
- switch (af) {
- case AF_INET:
- dst = satosin(&ro.ro_dst);
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr = addr->v4;
-#ifndef __FreeBSD__
- if (ipmultipath)
- check_mpath = 1;
-#endif
- break;
-#ifdef INET6
- case AF_INET6:
- /*
- * Skip check for addresses with embedded interface scope,
- * as they would always match anyway.
- */
- if (IN6_IS_SCOPE_EMBED(&addr->v6))
- goto out;
- dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
- dst6->sin6_family = AF_INET6;
- dst6->sin6_len = sizeof(*dst6);
- dst6->sin6_addr = addr->v6;
-#ifndef __FreeBSD__
- if (ip6_multipath)
- check_mpath = 1;
-#endif
- break;
-#endif /* INET6 */
- default:
- return (0);
- }
-
- /* Skip checks for ipsec interfaces */
- if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC)
- goto out;
-
-#ifdef __FreeBSD__
- switch (af) {
-#ifdef INET6
- case AF_INET6:
- in6_rtalloc_ign(&ro, 0, rtableid);
- break;
-#endif
-#ifdef INET
- case AF_INET:
- in_rtalloc_ign((struct route *)&ro, 0, rtableid);
- break;
-#endif
- default:
- rtalloc_ign((struct route *)&ro, 0); /* No/default FIB. */
- break;
- }
-#else /* ! __FreeBSD__ */
- rtalloc_noclone((struct route *)&ro, NO_CLONING);
-#endif
-
- if (ro.ro_rt != NULL) {
- /* No interface given, this is a no-route check */
- if (kif == NULL)
- goto out;
-
- if (kif->pfik_ifp == NULL) {
- ret = 0;
- goto out;
- }
-
- /* Perform uRPF check if passed input interface */
- ret = 0;
- rn = (struct radix_node *)ro.ro_rt;
- do {
- rt = (struct rtentry *)rn;
-#ifndef __FreeBSD__ /* CARPDEV */
- if (rt->rt_ifp->if_type == IFT_CARP)
- ifp = rt->rt_ifp->if_carpdev;
- else
-#endif
- ifp = rt->rt_ifp;
-
- if (kif->pfik_ifp == ifp)
- ret = 1;
-#ifdef __FreeBSD__
-#ifdef RADIX_MPATH
- rn = rn_mpath_next(rn);
-#endif
-#else
- rn = rn_mpath_next(rn, 0);
-#endif
- } while (check_mpath == 1 && rn != NULL && ret == 0);
- } else
- ret = 0;
-out:
- if (ro.ro_rt != NULL)
- RTFREE(ro.ro_rt);
- return (ret);
-}
-
-int
-pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw,
- int rtableid)
-{
- struct sockaddr_in *dst;
-#ifdef INET6
- struct sockaddr_in6 *dst6;
- struct route_in6 ro;
-#else
- struct route ro;
-#endif
- int ret = 0;
-
- bzero(&ro, sizeof(ro));
- switch (af) {
- case AF_INET:
- dst = satosin(&ro.ro_dst);
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr = addr->v4;
- break;
-#ifdef INET6
- case AF_INET6:
- dst6 = (struct sockaddr_in6 *)&ro.ro_dst;
- dst6->sin6_family = AF_INET6;
- dst6->sin6_len = sizeof(*dst6);
- dst6->sin6_addr = addr->v6;
- break;
-#endif /* INET6 */
- default:
- return (0);
- }
-
-#ifdef __FreeBSD__
- switch (af) {
-#ifdef INET6
- case AF_INET6:
- in6_rtalloc_ign(&ro, 0, rtableid);
- break;
-#endif
-#ifdef INET
- case AF_INET:
- in_rtalloc_ign((struct route *)&ro, 0, rtableid);
- break;
-#endif
- default:
- rtalloc_ign((struct route *)&ro, 0);
- break;
- }
-#else /* ! __FreeBSD__ */
- rtalloc_noclone((struct route *)&ro, NO_CLONING);
-#endif
-
- if (ro.ro_rt != NULL) {
-#ifdef __FreeBSD__
- /* XXX_IMPORT: later */
-#else
- if (ro.ro_rt->rt_labelid == aw->v.rtlabel)
- ret = 1;
-#endif
- RTFREE(ro.ro_rt);
- }
-
- return (ret);
-}
-
-#ifdef INET
-void
-pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
- struct pf_state *s, struct pf_pdesc *pd)
-{
- struct mbuf *m0, *m1;
- struct route iproute;
- struct route *ro = NULL;
- struct sockaddr_in *dst;
- struct ip *ip;
- struct ifnet *ifp = NULL;
- struct pf_addr naddr;
- struct pf_src_node *sn = NULL;
- int error = 0;
-#ifdef __FreeBSD__
- int sw_csum;
-#endif
-#ifdef IPSEC
- struct m_tag *mtag;
-#endif /* IPSEC */
-
- if (m == NULL || *m == NULL || r == NULL ||
- (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
- panic("pf_route: invalid parameters");
-
-#ifdef __FreeBSD__
- if (pd->pf_mtag->routed++ > 3) {
-#else
- if ((*m)->m_pkthdr.pf.routed++ > 3) {
-#endif
- m0 = *m;
- *m = NULL;
- goto bad;
- }
-
- if (r->rt == PF_DUPTO) {
-#ifdef __FreeBSD__
- if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
-#else
- if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
-#endif
- return;
- } else {
- if ((r->rt == PF_REPLYTO) == (r->direction == dir))
- return;
- m0 = *m;
- }
-
- if (m0->m_len < sizeof(struct ip)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_route: m0->m_len < sizeof(struct ip)\n"));
- goto bad;
- }
-
- ip = mtod(m0, struct ip *);
-
- ro = &iproute;
- bzero((caddr_t)ro, sizeof(*ro));
- dst = satosin(&ro->ro_dst);
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr = ip->ip_dst;
-
- if (r->rt == PF_FASTROUTE) {
-#ifdef __FreeBSD__
- in_rtalloc_ign(ro, 0, M_GETFIB(m0));
-#else
- rtalloc(ro);
-#endif
- if (ro->ro_rt == 0) {
-#ifdef __FreeBSD__
- KMOD_IPSTAT_INC(ips_noroute);
-#else
- ipstat.ips_noroute++;
-#endif
- goto bad;
- }
-
- ifp = ro->ro_rt->rt_ifp;
- ro->ro_rt->rt_use++;
-
- if (ro->ro_rt->rt_flags & RTF_GATEWAY)
- dst = satosin(ro->ro_rt->rt_gateway);
- } else {
- if (TAILQ_EMPTY(&r->rpool.list)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n"));
- goto bad;
- }
- if (s == NULL) {
- pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
- &naddr, NULL, &sn);
- if (!PF_AZERO(&naddr, AF_INET))
- dst->sin_addr.s_addr = naddr.v4.s_addr;
- ifp = r->rpool.cur->kif ?
- r->rpool.cur->kif->pfik_ifp : NULL;
- } else {
- if (!PF_AZERO(&s->rt_addr, AF_INET))
- dst->sin_addr.s_addr =
- s->rt_addr.v4.s_addr;
- ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
- }
- }
- if (ifp == NULL)
- goto bad;
-
- if (oifp != ifp) {
-#ifdef __FreeBSD__
- PF_UNLOCK();
- if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
- PF_LOCK();
- goto bad;
- } else if (m0 == NULL) {
- PF_LOCK();
- goto done;
- }
- PF_LOCK();
-#else
- if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
- goto bad;
- else if (m0 == NULL)
- goto done;
-#endif
- if (m0->m_len < sizeof(struct ip)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_route: m0->m_len < sizeof(struct ip)\n"));
- goto bad;
- }
- ip = mtod(m0, struct ip *);
- }
-
-#ifdef __FreeBSD__
- /* Copied from FreeBSD 5.1-CURRENT ip_output. */
- m0->m_pkthdr.csum_flags |= CSUM_IP;
- sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist;
- if (sw_csum & CSUM_DELAY_DATA) {
- /*
- * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least)
- */
- NTOHS(ip->ip_len);
- NTOHS(ip->ip_off); /* XXX: needed? */
- in_delayed_cksum(m0);
- HTONS(ip->ip_len);
- HTONS(ip->ip_off);
- sw_csum &= ~CSUM_DELAY_DATA;
- }
- m0->m_pkthdr.csum_flags &= ifp->if_hwassist;
-
- if (ntohs(ip->ip_len) <= ifp->if_mtu ||
- (ifp->if_hwassist & CSUM_FRAGMENT &&
- ((ip->ip_off & htons(IP_DF)) == 0))) {
- /*
- * ip->ip_len = htons(ip->ip_len);
- * ip->ip_off = htons(ip->ip_off);
- */
- ip->ip_sum = 0;
- if (sw_csum & CSUM_DELAY_IP) {
- /* From KAME */
- if (ip->ip_v == IPVERSION &&
- (ip->ip_hl << 2) == sizeof(*ip)) {
- ip->ip_sum = in_cksum_hdr(ip);
- } else {
- ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
- }
- }
- PF_UNLOCK();
- error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro);
- PF_LOCK();
- goto done;
- }
-#else
- /* Copied from ip_output. */
-#ifdef IPSEC
- /*
- * If deferred crypto processing is needed, check that the
- * interface supports it.
- */
- if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL))
- != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) {
- /* Notify IPsec to do its own crypto. */
- ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1));
- goto bad;
- }
-#endif /* IPSEC */
-
- /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */
- if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) {
- if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) ||
- ifp->if_bridge != NULL) {
- in_delayed_cksum(m0);
- m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clr */
- }
- } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) {
- if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
- ifp->if_bridge != NULL) {
- in_delayed_cksum(m0);
- m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clr */
- }
- }
-
- if (ntohs(ip->ip_len) <= ifp->if_mtu) {
- ip->ip_sum = 0;
- if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) &&
- ifp->if_bridge == NULL) {
- m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT;
-#ifdef __FreeBSD__
- KMOD_IPSTAT_INC(ips_outhwcsum);
-#else
- ipstat.ips_outhwcsum++;
-#endif
- } else
- ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
- /* Update relevant hardware checksum stats for TCP/UDP */
- if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT)
- KMOD_TCPSTAT_INC(tcps_outhwcsum);
- else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT)
- KMOD_UDPSTAT_INC(udps_outhwcsum);
- error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL);
- goto done;
- }
-#endif
-
- /*
- * Too large for interface; fragment if possible.
- * Must be able to put at least 8 bytes per fragment.
- */
- if (ip->ip_off & htons(IP_DF)) {
-#ifdef __FreeBSD__
- KMOD_IPSTAT_INC(ips_cantfrag);
-#else
- ipstat.ips_cantfrag++;
-#endif
- if (r->rt != PF_DUPTO) {
-#ifdef __FreeBSD__
- /* icmp_error() expects host byte ordering */
- NTOHS(ip->ip_len);
- NTOHS(ip->ip_off);
- PF_UNLOCK();
- icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
- ifp->if_mtu);
- PF_LOCK();
-#else
- icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0,
- ifp->if_mtu);
-#endif
- goto done;
- } else
- goto bad;
- }
-
- m1 = m0;
-#ifdef __FreeBSD__
- /*
- * XXX: is cheaper + less error prone than own function
- */
- NTOHS(ip->ip_len);
- NTOHS(ip->ip_off);
- error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum);
-#else
- error = ip_fragment(m0, ifp, ifp->if_mtu);
-#endif
- if (error) {
-#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */
- m0 = NULL;
-#endif
- goto bad;
- }
-
- for (m0 = m1; m0; m0 = m1) {
- m1 = m0->m_nextpkt;
- m0->m_nextpkt = 0;
-#ifdef __FreeBSD__
- if (error == 0) {
- PF_UNLOCK();
- error = (*ifp->if_output)(ifp, m0, sintosa(dst),
- NULL);
- PF_LOCK();
- } else
-#else
- if (error == 0)
- error = (*ifp->if_output)(ifp, m0, sintosa(dst),
- NULL);
- else
-#endif
- m_freem(m0);
- }
-
- if (error == 0)
-#ifdef __FreeBSD__
- KMOD_IPSTAT_INC(ips_fragmented);
-#else
- ipstat.ips_fragmented++;
-#endif
-
-done:
- if (r->rt != PF_DUPTO)
- *m = NULL;
- if (ro == &iproute && ro->ro_rt)
- RTFREE(ro->ro_rt);
- return;
-
-bad:
- m_freem(m0);
- goto done;
-}
-#endif /* INET */
-
-#ifdef INET6
-void
-pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
- struct pf_state *s, struct pf_pdesc *pd)
-{
- struct mbuf *m0;
- struct route_in6 ip6route;
- struct route_in6 *ro;
- struct sockaddr_in6 *dst;
- struct ip6_hdr *ip6;
- struct ifnet *ifp = NULL;
- struct pf_addr naddr;
- struct pf_src_node *sn = NULL;
-
- if (m == NULL || *m == NULL || r == NULL ||
- (dir != PF_IN && dir != PF_OUT) || oifp == NULL)
- panic("pf_route6: invalid parameters");
-
-#ifdef __FreeBSD__
- if (pd->pf_mtag->routed++ > 3) {
-#else
- if ((*m)->m_pkthdr.pf.routed++ > 3) {
-#endif
- m0 = *m;
- *m = NULL;
- goto bad;
- }
-
- if (r->rt == PF_DUPTO) {
-#ifdef __FreeBSD__
- if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL)
-#else
- if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL)
-#endif
- return;
- } else {
- if ((r->rt == PF_REPLYTO) == (r->direction == dir))
- return;
- m0 = *m;
- }
-
- if (m0->m_len < sizeof(struct ip6_hdr)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
- goto bad;
- }
- ip6 = mtod(m0, struct ip6_hdr *);
-
- ro = &ip6route;
- bzero((caddr_t)ro, sizeof(*ro));
- dst = (struct sockaddr_in6 *)&ro->ro_dst;
- dst->sin6_family = AF_INET6;
- dst->sin6_len = sizeof(*dst);
- dst->sin6_addr = ip6->ip6_dst;
-
- /* Cheat. XXX why only in the v6 case??? */
- if (r->rt == PF_FASTROUTE) {
-#ifdef __FreeBSD__
- m0->m_flags |= M_SKIP_FIREWALL;
- PF_UNLOCK();
- ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
-#else
- m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
- ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL);
-#endif
- return;
- }
-
- if (TAILQ_EMPTY(&r->rpool.list)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n"));
- goto bad;
- }
- if (s == NULL) {
- pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
- &naddr, NULL, &sn);
- if (!PF_AZERO(&naddr, AF_INET6))
- PF_ACPY((struct pf_addr *)&dst->sin6_addr,
- &naddr, AF_INET6);
- ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
- } else {
- if (!PF_AZERO(&s->rt_addr, AF_INET6))
- PF_ACPY((struct pf_addr *)&dst->sin6_addr,
- &s->rt_addr, AF_INET6);
- ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
- }
- if (ifp == NULL)
- goto bad;
-
- if (oifp != ifp) {
-#ifdef __FreeBSD__
- PF_UNLOCK();
- if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) {
- PF_LOCK();
- goto bad;
- } else if (m0 == NULL) {
- PF_LOCK();
- goto done;
- }
- PF_LOCK();
-#else
- if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
- goto bad;
- else if (m0 == NULL)
- goto done;
-#endif
- if (m0->m_len < sizeof(struct ip6_hdr)) {
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n"));
- goto bad;
- }
- ip6 = mtod(m0, struct ip6_hdr *);
- }
-
- /*
- * If the packet is too large for the outgoing interface,
- * send back an icmp6 error.
- */
- if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr))
- dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index);
- if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) {
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- nd6_output(ifp, ifp, m0, dst, NULL);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- } else {
- in6_ifstat_inc(ifp, ifs6_in_toobig);
-#ifdef __FreeBSD__
- if (r->rt != PF_DUPTO) {
- PF_UNLOCK();
- icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
- PF_LOCK();
- } else
-#else
- if (r->rt != PF_DUPTO)
- icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu);
- else
-#endif
- goto bad;
- }
-
-done:
- if (r->rt != PF_DUPTO)
- *m = NULL;
- return;
-
-bad:
- m_freem(m0);
- goto done;
-}
-#endif /* INET6 */
-
-#ifdef __FreeBSD__
-/*
- * FreeBSD supports cksum offloads for the following drivers.
- * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4),
- * ti(4), txp(4), xl(4)
- *
- * CSUM_DATA_VALID | CSUM_PSEUDO_HDR :
- * network driver performed cksum including pseudo header, need to verify
- * csum_data
- * CSUM_DATA_VALID :
- * network driver performed cksum, needs to additional pseudo header
- * cksum computation with partial csum_data(i.e. lack of H/W support for
- * pseudo header, for instance hme(4), sk(4) and possibly gem(4))
- *
- * After validating the cksum of packet, set both flag CSUM_DATA_VALID and
- * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper
- * TCP/UDP layer.
- * Also, set csum_data to 0xffff to force cksum validation.
- */
-int
-pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af)
-{
- u_int16_t sum = 0;
- int hw_assist = 0;
- struct ip *ip;
-
- if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
- return (1);
- if (m->m_pkthdr.len < off + len)
- return (1);
-
- switch (p) {
- case IPPROTO_TCP:
- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
- if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
- sum = m->m_pkthdr.csum_data;
- } else {
- ip = mtod(m, struct ip *);
- sum = in_pseudo(ip->ip_src.s_addr,
- ip->ip_dst.s_addr, htonl((u_short)len +
- m->m_pkthdr.csum_data + IPPROTO_TCP));
- }
- sum ^= 0xffff;
- ++hw_assist;
- }
- break;
- case IPPROTO_UDP:
- if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) {
- if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) {
- sum = m->m_pkthdr.csum_data;
- } else {
- ip = mtod(m, struct ip *);
- sum = in_pseudo(ip->ip_src.s_addr,
- ip->ip_dst.s_addr, htonl((u_short)len +
- m->m_pkthdr.csum_data + IPPROTO_UDP));
- }
- sum ^= 0xffff;
- ++hw_assist;
- }
- break;
- case IPPROTO_ICMP:
-#ifdef INET6
- case IPPROTO_ICMPV6:
-#endif /* INET6 */
- break;
- default:
- return (1);
- }
-
- if (!hw_assist) {
- switch (af) {
- case AF_INET:
- if (p == IPPROTO_ICMP) {
- if (m->m_len < off)
- return (1);
- m->m_data += off;
- m->m_len -= off;
- sum = in_cksum(m, len);
- m->m_data -= off;
- m->m_len += off;
- } else {
- if (m->m_len < sizeof(struct ip))
- return (1);
- sum = in4_cksum(m, p, off, len);
- }
- break;
-#ifdef INET6
- case AF_INET6:
- if (m->m_len < sizeof(struct ip6_hdr))
- return (1);
- sum = in6_cksum(m, p, off, len);
- break;
-#endif /* INET6 */
- default:
- return (1);
- }
- }
- if (sum) {
- switch (p) {
- case IPPROTO_TCP:
- {
- KMOD_TCPSTAT_INC(tcps_rcvbadsum);
- break;
- }
- case IPPROTO_UDP:
- {
- KMOD_UDPSTAT_INC(udps_badsum);
- break;
- }
-#ifdef INET
- case IPPROTO_ICMP:
- {
- KMOD_ICMPSTAT_INC(icps_checksum);
- break;
- }
-#endif
-#ifdef INET6
- case IPPROTO_ICMPV6:
- {
- KMOD_ICMP6STAT_INC(icp6s_checksum);
- break;
- }
-#endif /* INET6 */
- }
- return (1);
- } else {
- if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
- m->m_pkthdr.csum_flags |=
- (CSUM_DATA_VALID | CSUM_PSEUDO_HDR);
- m->m_pkthdr.csum_data = 0xffff;
- }
- }
- return (0);
-}
-#else /* !__FreeBSD__ */
-
-/*
- * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag
- * off is the offset where the protocol header starts
- * len is the total length of protocol header plus payload
- * returns 0 when the checksum is valid, otherwise returns 1.
- */
-int
-pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p,
- sa_family_t af)
-{
- u_int16_t flag_ok, flag_bad;
- u_int16_t sum;
-
- switch (p) {
- case IPPROTO_TCP:
- flag_ok = M_TCP_CSUM_IN_OK;
- flag_bad = M_TCP_CSUM_IN_BAD;
- break;
- case IPPROTO_UDP:
- flag_ok = M_UDP_CSUM_IN_OK;
- flag_bad = M_UDP_CSUM_IN_BAD;
- break;
- case IPPROTO_ICMP:
-#ifdef INET6
- case IPPROTO_ICMPV6:
-#endif /* INET6 */
- flag_ok = flag_bad = 0;
- break;
- default:
- return (1);
- }
- if (m->m_pkthdr.csum_flags & flag_ok)
- return (0);
- if (m->m_pkthdr.csum_flags & flag_bad)
- return (1);
- if (off < sizeof(struct ip) || len < sizeof(struct udphdr))
- return (1);
- if (m->m_pkthdr.len < off + len)
- return (1);
- switch (af) {
-#ifdef INET
- case AF_INET:
- if (p == IPPROTO_ICMP) {
- if (m->m_len < off)
- return (1);
- m->m_data += off;
- m->m_len -= off;
- sum = in_cksum(m, len);
- m->m_data -= off;
- m->m_len += off;
- } else {
- if (m->m_len < sizeof(struct ip))
- return (1);
- sum = in4_cksum(m, p, off, len);
- }
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (m->m_len < sizeof(struct ip6_hdr))
- return (1);
- sum = in6_cksum(m, p, off, len);
- break;
-#endif /* INET6 */
- default:
- return (1);
- }
- if (sum) {
- m->m_pkthdr.csum_flags |= flag_bad;
- switch (p) {
- case IPPROTO_TCP:
- KMOD_TCPSTAT_INC(tcps_rcvbadsum);
- break;
- case IPPROTO_UDP:
- KMOD_UDPSTAT_INC(udps_badsum);
- break;
-#ifdef INET
- case IPPROTO_ICMP:
- KMOD_ICMPSTAT_INC(icps_checksum);
- break;
-#endif
-#ifdef INET6
- case IPPROTO_ICMPV6:
- KMOD_ICMP6STAT_INC(icp6s_checksum);
- break;
-#endif /* INET6 */
- }
- return (1);
- }
- m->m_pkthdr.csum_flags |= flag_ok;
- return (0);
-}
-#endif
-
-#ifndef __FreeBSD__
-struct pf_divert *
-pf_find_divert(struct mbuf *m)
-{
- struct m_tag *mtag;
-
- if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL)
- return (NULL);
-
- return ((struct pf_divert *)(mtag + 1));
-}
-
-struct pf_divert *
-pf_get_divert(struct mbuf *m)
-{
- struct m_tag *mtag;
-
- if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) {
- mtag = m_tag_get(PACKET_TAG_PF_DIVERT, sizeof(struct pf_divert),
- M_NOWAIT);
- if (mtag == NULL)
- return (NULL);
- bzero(mtag + 1, sizeof(struct pf_divert));
- m_tag_prepend(m, mtag);
- }
-
- return ((struct pf_divert *)(mtag + 1));
-}
-#endif
-
-#ifdef INET
-int
-#ifdef __FreeBSD__
-pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
- struct ether_header *eh, struct inpcb *inp)
-#else
-pf_test(int dir, struct ifnet *ifp, struct mbuf **m0,
- struct ether_header *eh)
-#endif
-{
- struct pfi_kif *kif;
- u_short action, reason = 0, log = 0;
- struct mbuf *m = *m0;
-#ifdef __FreeBSD__
- struct ip *h = NULL;
- struct m_tag *ipfwtag;
- struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr;
-#else
- struct ip *h;
- struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
-#endif
- struct pf_state *s = NULL;
- struct pf_ruleset *ruleset = NULL;
- struct pf_pdesc pd;
- int off, dirndx, pqid = 0;
-
-#ifdef __FreeBSD__
- PF_LOCK();
- if (!V_pf_status.running)
- {
- PF_UNLOCK();
- return (PF_PASS);
- }
-#else
- if (!pf_status.running)
- return (PF_PASS);
-#endif
-
- memset(&pd, 0, sizeof(pd));
-#ifdef __FreeBSD__
- if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
- PF_UNLOCK();
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_test: pf_get_mtag returned NULL\n"));
- return (PF_DROP);
- }
-#endif
-#ifndef __FreeBSD__
- if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
- kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
- else
-#endif
- kif = (struct pfi_kif *)ifp->if_pf_kif;
-
- if (kif == NULL) {
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
- return (PF_DROP);
- }
- if (kif->pfik_flags & PFI_IFLAG_SKIP)
-#ifdef __FreeBSD__
- {
- PF_UNLOCK();
-#endif
- return (PF_PASS);
-#ifdef __FreeBSD__
- }
-#endif
-
-#ifdef __FreeBSD__
- M_ASSERTPKTHDR(m);
-#else
-#ifdef DIAGNOSTIC
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("non-M_PKTHDR is passed to pf_test");
-#endif /* DIAGNOSTIC */
-#endif
-
- if (m->m_pkthdr.len < (int)sizeof(*h)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_SHORT);
- log = 1;
- goto done;
- }
-
-#ifdef __FreeBSD__
- if (m->m_flags & M_SKIP_FIREWALL) {
- PF_UNLOCK();
- return (PF_PASS);
- }
-#else
- if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
- return (PF_PASS);
-#endif
-
-#ifdef __FreeBSD__
- if (ip_divert_ptr != NULL &&
- ((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) {
- struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1);
- if (rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) {
- pd.pf_mtag->flags |= PF_PACKET_LOOPED;
- m_tag_delete(m, ipfwtag);
- }
- if (pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) {
- m->m_flags |= M_FASTFWD_OURS;
- pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT;
- }
- } else
-#endif
- /* We do IP header normalization and packet reassembly here */
- if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) {
- action = PF_DROP;
- goto done;
- }
- m = *m0; /* pf_normalize messes with m0 */
- h = mtod(m, struct ip *);
-
- off = h->ip_hl << 2;
- if (off < (int)sizeof(*h)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_SHORT);
- log = 1;
- goto done;
- }
-
- pd.src = (struct pf_addr *)&h->ip_src;
- pd.dst = (struct pf_addr *)&h->ip_dst;
- pd.sport = pd.dport = NULL;
- pd.ip_sum = &h->ip_sum;
- pd.proto_sum = NULL;
- pd.proto = h->ip_p;
- pd.dir = dir;
- pd.sidx = (dir == PF_IN) ? 0 : 1;
- pd.didx = (dir == PF_IN) ? 1 : 0;
- pd.af = AF_INET;
- pd.tos = h->ip_tos;
- pd.tot_len = ntohs(h->ip_len);
- pd.eh = eh;
-
- /* handle fragments that didn't get reassembled by normalization */
- if (h->ip_off & htons(IP_MF | IP_OFFMASK)) {
- action = pf_test_fragment(&r, dir, kif, m, h,
- &pd, &a, &ruleset);
- goto done;
- }
-
- switch (h->ip_p) {
-
- case IPPROTO_TCP: {
- struct tcphdr th;
-
- pd.hdr.tcp = &th;
- if (!pf_pull_hdr(m, off, &th, sizeof(th),
- &action, &reason, AF_INET)) {
- log = action != PF_PASS;
- goto done;
- }
- pd.p_len = pd.tot_len - off - (th.th_off << 2);
- if ((th.th_flags & TH_ACK) && pd.p_len == 0)
- pqid = 1;
- action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
- if (action == PF_DROP)
- goto done;
- action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
- &reason);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, &ipintrq);
-#endif
- break;
- }
-
- case IPPROTO_UDP: {
- struct udphdr uh;
-
- pd.hdr.udp = &uh;
- if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
- &action, &reason, AF_INET)) {
- log = action != PF_PASS;
- goto done;
- }
- if (uh.uh_dport == 0 ||
- ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
- ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_SHORT);
- goto done;
- }
- action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, &ipintrq);
-#endif
- break;
- }
-
- case IPPROTO_ICMP: {
- struct icmp ih;
-
- pd.hdr.icmp = &ih;
- if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN,
- &action, &reason, AF_INET)) {
- log = action != PF_PASS;
- goto done;
- }
- action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd,
- &reason);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, &ipintrq);
-#endif
- break;
- }
-
-#ifdef INET6
- case IPPROTO_ICMPV6: {
- action = PF_DROP;
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: dropping IPv4 packet with ICMPv6 payload\n"));
- goto done;
- }
-#endif
-
- default:
- action = pf_test_state_other(&s, dir, kif, m, &pd);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif, m, off, h,
- &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif, m, off, h,
- &pd, &a, &ruleset, &ipintrq);
-#endif
- break;
- }
-
-done:
- if (action == PF_PASS && h->ip_hl > 5 &&
- !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_IPOPTIONS);
- log = 1;
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: dropping packet with ip options\n"));
- }
-
- if ((s && s->tag) || r->rtableid >= 0)
-#ifdef __FreeBSD__
- pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag);
-#else
- pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
-#endif
-
- if (dir == PF_IN && s && s->key[PF_SK_STACK])
-#ifdef __FreeBSD__
- pd.pf_mtag->statekey = s->key[PF_SK_STACK];
-#else
- m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK];
-#endif
-
-#ifdef ALTQ
- if (action == PF_PASS && r->qid) {
-#ifdef __FreeBSD__
- if (pqid || (pd.tos & IPTOS_LOWDELAY))
- pd.pf_mtag->qid = r->pqid;
- else
- pd.pf_mtag->qid = r->qid;
- /* add hints for ecn */
- pd.pf_mtag->hdr = h;
-
-#else
- if (pqid || (pd.tos & IPTOS_LOWDELAY))
- m->m_pkthdr.pf.qid = r->pqid;
- else
- m->m_pkthdr.pf.qid = r->qid;
- /* add hints for ecn */
- m->m_pkthdr.pf.hdr = h;
-#endif
- }
-#endif /* ALTQ */
-
- /*
- * connections redirected to loopback should not match sockets
- * bound specifically to loopback due to security implications,
- * see tcp_input() and in_pcblookup_listen().
- */
- if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
- pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
- (s->nat_rule.ptr->action == PF_RDR ||
- s->nat_rule.ptr->action == PF_BINAT) &&
- (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)
-#ifdef __FreeBSD__
- m->m_flags |= M_SKIP_FIREWALL;
-#else
- m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
-#endif
-
-#ifdef __FreeBSD__
- if (action == PF_PASS && r->divert.port &&
- ip_divert_ptr != NULL && !PACKET_LOOPED()) {
-
- ipfwtag = m_tag_alloc(MTAG_IPFW_RULE, 0,
- sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO);
- if (ipfwtag != NULL) {
- ((struct ipfw_rule_ref *)(ipfwtag+1))->info =
- ntohs(r->divert.port);
- ((struct ipfw_rule_ref *)(ipfwtag+1))->rulenum = dir;
-
- m_tag_prepend(m, ipfwtag);
-
- PF_UNLOCK();
-
- if (m->m_flags & M_FASTFWD_OURS) {
- pd.pf_mtag->flags |= PF_FASTFWD_OURS_PRESENT;
- m->m_flags &= ~M_FASTFWD_OURS;
- }
-
- ip_divert_ptr(*m0,
- dir == PF_IN ? DIR_IN : DIR_OUT);
- *m0 = NULL;
- return (action);
- } else {
- /* XXX: ipfw has the same behaviour! */
- action = PF_DROP;
- REASON_SET(&reason, PFRES_MEMORY);
- log = 1;
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: failed to allocate divert tag\n"));
- }
- }
-#else
- if (dir == PF_IN && action == PF_PASS && r->divert.port) {
- struct pf_divert *divert;
-
- if ((divert = pf_get_divert(m))) {
- m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
- divert->port = r->divert.port;
- divert->addr.ipv4 = r->divert.addr.v4;
- }
- }
-#endif
-
- if (log) {
- struct pf_rule *lr;
-
- if (s != NULL && s->nat_rule.ptr != NULL &&
- s->nat_rule.ptr->log & PF_LOG_ALL)
- lr = s->nat_rule.ptr;
- else
- lr = r;
- PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset,
- &pd);
- }
-
- kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
- kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++;
-
- if (action == PF_PASS || r->action == PF_DROP) {
- dirndx = (dir == PF_OUT);
- r->packets[dirndx]++;
- r->bytes[dirndx] += pd.tot_len;
- if (a != NULL) {
- a->packets[dirndx]++;
- a->bytes[dirndx] += pd.tot_len;
- }
- if (s != NULL) {
- if (s->nat_rule.ptr != NULL) {
- s->nat_rule.ptr->packets[dirndx]++;
- s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
- }
- if (s->src_node != NULL) {
- s->src_node->packets[dirndx]++;
- s->src_node->bytes[dirndx] += pd.tot_len;
- }
- if (s->nat_src_node != NULL) {
- s->nat_src_node->packets[dirndx]++;
- s->nat_src_node->bytes[dirndx] += pd.tot_len;
- }
- dirndx = (dir == s->direction) ? 0 : 1;
- s->packets[dirndx]++;
- s->bytes[dirndx] += pd.tot_len;
- }
- tr = r;
- nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
-#ifdef __FreeBSD__
- if (nr != NULL && r == &V_pf_default_rule)
-#else
- if (nr != NULL && r == &pf_default_rule)
-#endif
- tr = nr;
- if (tr->src.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->src.addr.p.tbl,
- (s == NULL) ? pd.src :
- &s->key[(s->direction == PF_IN)]->
- addr[(s->direction == PF_OUT)],
- pd.af, pd.tot_len, dir == PF_OUT,
- r->action == PF_PASS, tr->src.neg);
- if (tr->dst.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->dst.addr.p.tbl,
- (s == NULL) ? pd.dst :
- &s->key[(s->direction == PF_IN)]->
- addr[(s->direction == PF_IN)],
- pd.af, pd.tot_len, dir == PF_OUT,
- r->action == PF_PASS, tr->dst.neg);
- }
-
- switch (action) {
- case PF_SYNPROXY_DROP:
- m_freem(*m0);
- case PF_DEFER:
- *m0 = NULL;
- action = PF_PASS;
- break;
- default:
- /* pf_route can free the mbuf causing *m0 to become NULL */
- if (r->rt)
- pf_route(m0, r, dir, kif->pfik_ifp, s, &pd);
- break;
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- return (action);
-}
-#endif /* INET */
-
-#ifdef INET6
-int
-#ifdef __FreeBSD__
-pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
- struct ether_header *eh, struct inpcb *inp)
-#else
-pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0,
- struct ether_header *eh)
-#endif
-{
- struct pfi_kif *kif;
- u_short action, reason = 0, log = 0;
- struct mbuf *m = *m0, *n = NULL;
-#ifdef __FreeBSD__
- struct ip6_hdr *h = NULL;
- struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr;
-#else
- struct ip6_hdr *h;
- struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr;
-#endif
- struct pf_state *s = NULL;
- struct pf_ruleset *ruleset = NULL;
- struct pf_pdesc pd;
- int off, terminal = 0, dirndx, rh_cnt = 0;
-
-#ifdef __FreeBSD__
- PF_LOCK();
- if (!V_pf_status.running) {
- PF_UNLOCK();
- return (PF_PASS);
- }
-#else
- if (!pf_status.running)
- return (PF_PASS);
-#endif
-
- memset(&pd, 0, sizeof(pd));
-#ifdef __FreeBSD__
- if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) {
- PF_UNLOCK();
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_test: pf_get_mtag returned NULL\n"));
- return (PF_DROP);
- }
-#endif
-#ifndef __FreeBSD__
- if (ifp->if_type == IFT_CARP && ifp->if_carpdev)
- kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif;
- else
-#endif
- kif = (struct pfi_kif *)ifp->if_pf_kif;
-
- if (kif == NULL) {
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- DPFPRINTF(PF_DEBUG_URGENT,
- ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
- return (PF_DROP);
- }
- if (kif->pfik_flags & PFI_IFLAG_SKIP)
-#ifdef __FreeBSD__
- {
- PF_UNLOCK();
-#endif
- return (PF_PASS);
-#ifdef __FreeBSD__
- }
-#endif
-
-#ifdef __FreeBSD__
- M_ASSERTPKTHDR(m);
-#else
-#ifdef DIAGNOSTIC
- if ((m->m_flags & M_PKTHDR) == 0)
- panic("non-M_PKTHDR is passed to pf_test6");
-#endif /* DIAGNOSTIC */
-#endif
-
- if (m->m_pkthdr.len < (int)sizeof(*h)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_SHORT);
- log = 1;
- goto done;
- }
-
-#ifdef __FreeBSD__
- if (pd.pf_mtag->flags & PF_TAG_GENERATED) {
- PF_UNLOCK();
-#else
- if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED)
-#endif
- return (PF_PASS);
-#ifdef __FreeBSD__
- }
-#endif
-
- /* We do IP header normalization and packet reassembly here */
- if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
- action = PF_DROP;
- goto done;
- }
- m = *m0; /* pf_normalize messes with m0 */
- h = mtod(m, struct ip6_hdr *);
-
-#if 1
- /*
- * we do not support jumbogram yet. if we keep going, zero ip6_plen
- * will do something bad, so drop the packet for now.
- */
- if (htons(h->ip6_plen) == 0) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_NORM); /*XXX*/
- goto done;
- }
-#endif
-
- pd.src = (struct pf_addr *)&h->ip6_src;
- pd.dst = (struct pf_addr *)&h->ip6_dst;
- pd.sport = pd.dport = NULL;
- pd.ip_sum = NULL;
- pd.proto_sum = NULL;
- pd.dir = dir;
- pd.sidx = (dir == PF_IN) ? 0 : 1;
- pd.didx = (dir == PF_IN) ? 1 : 0;
- pd.af = AF_INET6;
- pd.tos = 0;
- pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);
- pd.eh = eh;
-
- off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr);
- pd.proto = h->ip6_nxt;
- do {
- switch (pd.proto) {
- case IPPROTO_FRAGMENT:
- action = pf_test_fragment(&r, dir, kif, m, h,
- &pd, &a, &ruleset);
- if (action == PF_DROP)
- REASON_SET(&reason, PFRES_FRAG);
- goto done;
- case IPPROTO_ROUTING: {
- struct ip6_rthdr rthdr;
-
- if (rh_cnt++) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: IPv6 more than one rthdr\n"));
- action = PF_DROP;
- REASON_SET(&reason, PFRES_IPOPTIONS);
- log = 1;
- goto done;
- }
- if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL,
- &reason, pd.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: IPv6 short rthdr\n"));
- action = PF_DROP;
- REASON_SET(&reason, PFRES_SHORT);
- log = 1;
- goto done;
- }
- if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: IPv6 rthdr0\n"));
- action = PF_DROP;
- REASON_SET(&reason, PFRES_IPOPTIONS);
- log = 1;
- goto done;
- }
- /* FALLTHROUGH */
- }
- case IPPROTO_AH:
- case IPPROTO_HOPOPTS:
- case IPPROTO_DSTOPTS: {
- /* get next header and header length */
- struct ip6_ext opt6;
-
- if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6),
- NULL, &reason, pd.af)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: IPv6 short opt\n"));
- action = PF_DROP;
- log = 1;
- goto done;
- }
- if (pd.proto == IPPROTO_AH)
- off += (opt6.ip6e_len + 2) * 4;
- else
- off += (opt6.ip6e_len + 1) * 8;
- pd.proto = opt6.ip6e_nxt;
- /* goto the next header */
- break;
- }
- default:
- terminal++;
- break;
- }
- } while (!terminal);
-
- /* if there's no routing header, use unmodified mbuf for checksumming */
- if (!n)
- n = m;
-
- switch (pd.proto) {
-
- case IPPROTO_TCP: {
- struct tcphdr th;
-
- pd.hdr.tcp = &th;
- if (!pf_pull_hdr(m, off, &th, sizeof(th),
- &action, &reason, AF_INET6)) {
- log = action != PF_PASS;
- goto done;
- }
- pd.p_len = pd.tot_len - off - (th.th_off << 2);
- action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd);
- if (action == PF_DROP)
- goto done;
- action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd,
- &reason);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, &ip6intrq);
-#endif
- break;
- }
-
- case IPPROTO_UDP: {
- struct udphdr uh;
-
- pd.hdr.udp = &uh;
- if (!pf_pull_hdr(m, off, &uh, sizeof(uh),
- &action, &reason, AF_INET6)) {
- log = action != PF_PASS;
- goto done;
- }
- if (uh.uh_dport == 0 ||
- ntohs(uh.uh_ulen) > m->m_pkthdr.len - off ||
- ntohs(uh.uh_ulen) < sizeof(struct udphdr)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_SHORT);
- goto done;
- }
- action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, &ip6intrq);
-#endif
- break;
- }
-
- case IPPROTO_ICMP: {
- action = PF_DROP;
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: dropping IPv6 packet with ICMPv4 payload\n"));
- goto done;
- }
-
- case IPPROTO_ICMPV6: {
- struct icmp6_hdr ih;
-
- pd.hdr.icmp6 = &ih;
- if (!pf_pull_hdr(m, off, &ih, sizeof(ih),
- &action, &reason, AF_INET6)) {
- log = action != PF_PASS;
- goto done;
- }
- action = pf_test_state_icmp(&s, dir, kif,
- m, off, h, &pd, &reason);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif,
- m, off, h, &pd, &a, &ruleset, &ip6intrq);
-#endif
- break;
- }
-
- default:
- action = pf_test_state_other(&s, dir, kif, m, &pd);
- if (action == PF_PASS) {
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_update_state_ptr != NULL)
- pfsync_update_state_ptr(s);
-#else
- pfsync_update_state(s);
-#endif
-#endif /* NPFSYNC */
- r = s->rule.ptr;
- a = s->anchor.ptr;
- log = s->log;
- } else if (s == NULL)
-#ifdef __FreeBSD__
- action = pf_test_rule(&r, &s, dir, kif, m, off, h,
- &pd, &a, &ruleset, NULL, inp);
-#else
- action = pf_test_rule(&r, &s, dir, kif, m, off, h,
- &pd, &a, &ruleset, &ip6intrq);
-#endif
- break;
- }
-
-done:
- if (n != m) {
- m_freem(n);
- n = NULL;
- }
-
- /* handle dangerous IPv6 extension headers. */
- if (action == PF_PASS && rh_cnt &&
- !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) {
- action = PF_DROP;
- REASON_SET(&reason, PFRES_IPOPTIONS);
- log = 1;
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: dropping packet with dangerous v6 headers\n"));
- }
-
- if ((s && s->tag) || r->rtableid >= 0)
-#ifdef __FreeBSD__
- pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag);
-#else
- pf_tag_packet(m, s ? s->tag : 0, r->rtableid);
-#endif
-
- if (dir == PF_IN && s && s->key[PF_SK_STACK])
-#ifdef __FreeBSD__
- pd.pf_mtag->statekey = s->key[PF_SK_STACK];
-#else
- m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK];
-#endif
-
-#ifdef ALTQ
- if (action == PF_PASS && r->qid) {
-#ifdef __FreeBSD__
- if (pd.tos & IPTOS_LOWDELAY)
- pd.pf_mtag->qid = r->pqid;
- else
- pd.pf_mtag->qid = r->qid;
- /* add hints for ecn */
- pd.pf_mtag->hdr = h;
-#else
- if (pd.tos & IPTOS_LOWDELAY)
- m->m_pkthdr.pf.qid = r->pqid;
- else
- m->m_pkthdr.pf.qid = r->qid;
- /* add hints for ecn */
- m->m_pkthdr.pf.hdr = h;
-#endif
- }
-#endif /* ALTQ */
-
- if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP ||
- pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL &&
- (s->nat_rule.ptr->action == PF_RDR ||
- s->nat_rule.ptr->action == PF_BINAT) &&
- IN6_IS_ADDR_LOOPBACK(&pd.dst->v6))
-#ifdef __FreeBSD__
- m->m_flags |= M_SKIP_FIREWALL;
-#else
- m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST;
-#endif
-
-#ifdef __FreeBSD__
- /* XXX: Anybody working on it?! */
- if (r->divert.port)
- printf("pf: divert(9) is not supported for IPv6\n");
-#else
- if (dir == PF_IN && action == PF_PASS && r->divert.port) {
- struct pf_divert *divert;
-
- if ((divert = pf_get_divert(m))) {
- m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
- divert->port = r->divert.port;
- divert->addr.ipv6 = r->divert.addr.v6;
- }
- }
-#endif
-
- if (log) {
- struct pf_rule *lr;
-
- if (s != NULL && s->nat_rule.ptr != NULL &&
- s->nat_rule.ptr->log & PF_LOG_ALL)
- lr = s->nat_rule.ptr;
- else
- lr = r;
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset,
- &pd);
- }
-
- kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len;
- kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++;
-
- if (action == PF_PASS || r->action == PF_DROP) {
- dirndx = (dir == PF_OUT);
- r->packets[dirndx]++;
- r->bytes[dirndx] += pd.tot_len;
- if (a != NULL) {
- a->packets[dirndx]++;
- a->bytes[dirndx] += pd.tot_len;
- }
- if (s != NULL) {
- if (s->nat_rule.ptr != NULL) {
- s->nat_rule.ptr->packets[dirndx]++;
- s->nat_rule.ptr->bytes[dirndx] += pd.tot_len;
- }
- if (s->src_node != NULL) {
- s->src_node->packets[dirndx]++;
- s->src_node->bytes[dirndx] += pd.tot_len;
- }
- if (s->nat_src_node != NULL) {
- s->nat_src_node->packets[dirndx]++;
- s->nat_src_node->bytes[dirndx] += pd.tot_len;
- }
- dirndx = (dir == s->direction) ? 0 : 1;
- s->packets[dirndx]++;
- s->bytes[dirndx] += pd.tot_len;
- }
- tr = r;
- nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule;
-#ifdef __FreeBSD__
- if (nr != NULL && r == &V_pf_default_rule)
-#else
- if (nr != NULL && r == &pf_default_rule)
-#endif
- tr = nr;
- if (tr->src.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->src.addr.p.tbl,
- (s == NULL) ? pd.src :
- &s->key[(s->direction == PF_IN)]->addr[0],
- pd.af, pd.tot_len, dir == PF_OUT,
- r->action == PF_PASS, tr->src.neg);
- if (tr->dst.addr.type == PF_ADDR_TABLE)
- pfr_update_stats(tr->dst.addr.p.tbl,
- (s == NULL) ? pd.dst :
- &s->key[(s->direction == PF_IN)]->addr[1],
- pd.af, pd.tot_len, dir == PF_OUT,
- r->action == PF_PASS, tr->dst.neg);
- }
-
- switch (action) {
- case PF_SYNPROXY_DROP:
- m_freem(*m0);
- case PF_DEFER:
- *m0 = NULL;
- action = PF_PASS;
- break;
- default:
- /* pf_route6 can free the mbuf causing *m0 to become NULL */
- if (r->rt)
- pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd);
- break;
- }
-
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- return (action);
-}
-#endif /* INET6 */
-
-int
-pf_check_congestion(struct ifqueue *ifq)
-{
-#ifdef __FreeBSD__
- /* XXX_IMPORT: later */
- return (0);
-#else
- if (ifq->ifq_congestion)
- return (1);
- else
- return (0);
-#endif
-}
-
-/*
- * must be called whenever any addressing information such as
- * address, port, protocol has changed
- */
-void
-pf_pkt_addr_changed(struct mbuf *m)
-{
-#ifdef __FreeBSD__
- struct pf_mtag *pf_tag;
-
- if ((pf_tag = pf_find_mtag(m)) != NULL)
- pf_tag->statekey = NULL;
-#else
- m->m_pkthdr.pf.statekey = NULL;
-#endif
-}
diff --git a/sys/contrib/pf/net/pf_if.c b/sys/contrib/pf/net/pf_if.c
deleted file mode 100644
index 6336c79..0000000
--- a/sys/contrib/pf/net/pf_if.c
+++ /dev/null
@@ -1,1111 +0,0 @@
-/* $OpenBSD: pf_if.c,v 1.54 2008/06/14 16:55:28 mk Exp $ */
-
-/*
- * Copyright 2005 Henning Brauer <henning@openbsd.org>
- * Copyright 2005 Ryan McBride <mcbride@openbsd.org>
- * Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2003 Cedric Berger
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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(__FreeBSD__)
-#include "opt_inet.h"
-#include "opt_inet6.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#ifdef __FreeBSD__
-#include <sys/malloc.h>
-#endif
-#include <sys/mbuf.h>
-#include <sys/filio.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#ifndef __FreeBSD__
-#include <sys/device.h>
-#endif
-#include <sys/time.h>
-#ifndef __FreeBSD__
-#include <sys/pool.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_types.h>
-#ifdef __FreeBSD__
-#include <net/vnet.h>
-#endif
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-
-#include <net/pfvar.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif /* INET6 */
-
-#ifdef __FreeBSD__
-VNET_DEFINE(struct pfi_kif *, pfi_all);
-VNET_DEFINE(uma_zone_t, pfi_addr_pl);
-VNET_DEFINE(struct pfi_ifhead, pfi_ifs);
-#define V_pfi_ifs VNET(pfi_ifs)
-VNET_DEFINE(long, pfi_update);
-#define V_pfi_update VNET(pfi_update)
-VNET_DEFINE(struct pfr_addr *, pfi_buffer);
-#define V_pfi_buffer VNET(pfi_buffer)
-VNET_DEFINE(int, pfi_buffer_cnt);
-#define V_pfi_buffer_cnt VNET(pfi_buffer_cnt)
-VNET_DEFINE(int, pfi_buffer_max);
-#define V_pfi_buffer_max VNET(pfi_buffer_max)
-#else
-struct pfi_kif *pfi_all = NULL;
-struct pool pfi_addr_pl;
-struct pfi_ifhead pfi_ifs;
-long pfi_update = 1;
-struct pfr_addr *pfi_buffer;
-int pfi_buffer_cnt;
-int pfi_buffer_max;
-#endif
-#ifdef __FreeBSD__
-eventhandler_tag pfi_attach_cookie;
-eventhandler_tag pfi_detach_cookie;
-eventhandler_tag pfi_attach_group_cookie;
-eventhandler_tag pfi_change_group_cookie;
-eventhandler_tag pfi_detach_group_cookie;
-eventhandler_tag pfi_ifaddr_event_cookie;
-#endif
-
-void pfi_kif_update(struct pfi_kif *);
-void pfi_dynaddr_update(struct pfi_dynaddr *dyn);
-void pfi_table_update(struct pfr_ktable *, struct pfi_kif *,
- int, int);
-void pfi_kifaddr_update(void *);
-void pfi_instance_add(struct ifnet *, int, int);
-void pfi_address_add(struct sockaddr *, int, int);
-int pfi_if_compare(struct pfi_kif *, struct pfi_kif *);
-int pfi_skip_if(const char *, struct pfi_kif *);
-int pfi_unmask(void *);
-#ifdef __FreeBSD__
-void pfi_attach_ifnet_event(void * __unused, struct ifnet *);
-void pfi_detach_ifnet_event(void * __unused, struct ifnet *);
-void pfi_attach_group_event(void *, struct ifg_group *);
-void pfi_change_group_event(void *, char *);
-void pfi_detach_group_event(void *, struct ifg_group *);
-void pfi_ifaddr_event(void * __unused, struct ifnet *);
-#endif
-
-RB_PROTOTYPE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
-RB_GENERATE(pfi_ifhead, pfi_kif, pfik_tree, pfi_if_compare);
-
-#define PFI_BUFFER_MAX 0x10000
-#define PFI_MTYPE M_IFADDR
-
-void
-pfi_initialize(void)
-{
-#ifdef __FreeBSD__
- if (V_pfi_all != NULL) /* already initialized */
-#else
- if (pfi_all != NULL) /* already initialized */
-#endif
- return;
-
-#ifndef __FreeBSD__
- pool_init(&V_pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0,
- "pfiaddrpl", &pool_allocator_nointr);
-#endif
-#ifdef __FreeBSD__
- V_pfi_buffer_max = 64;
- V_pfi_buffer = malloc(V_pfi_buffer_max * sizeof(*V_pfi_buffer),
- PFI_MTYPE, M_WAITOK);
-
- if ((V_pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
-#else
- pfi_buffer_max = 64;
- pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
- PFI_MTYPE, M_WAITOK);
-
- if ((pfi_all = pfi_kif_get(IFG_ALL)) == NULL)
-#endif
- panic("pfi_kif_get for pfi_all failed");
-#ifdef __FreeBSD__
- struct ifg_group *ifg;
- struct ifnet *ifp;
-
- IFNET_RLOCK();
- TAILQ_FOREACH(ifg, &V_ifg_head, ifg_next)
- pfi_attach_ifgroup(ifg);
- TAILQ_FOREACH(ifp, &V_ifnet, if_link)
- pfi_attach_ifnet(ifp);
- IFNET_RUNLOCK();
-
- pfi_attach_cookie = EVENTHANDLER_REGISTER(ifnet_arrival_event,
- pfi_attach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
- pfi_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
- pfi_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
- pfi_attach_group_cookie = EVENTHANDLER_REGISTER(group_attach_event,
- pfi_attach_group_event, curvnet, EVENTHANDLER_PRI_ANY);
- pfi_change_group_cookie = EVENTHANDLER_REGISTER(group_change_event,
- pfi_change_group_event, curvnet, EVENTHANDLER_PRI_ANY);
- pfi_detach_group_cookie = EVENTHANDLER_REGISTER(group_detach_event,
- pfi_detach_group_event, curvnet, EVENTHANDLER_PRI_ANY);
- pfi_ifaddr_event_cookie = EVENTHANDLER_REGISTER(ifaddr_event,
- pfi_ifaddr_event, NULL, EVENTHANDLER_PRI_ANY);
-#endif
-}
-
-#ifdef __FreeBSD__
-void
-pfi_cleanup(void)
-{
- struct pfi_kif *p;
-
- PF_UNLOCK();
- EVENTHANDLER_DEREGISTER(ifnet_arrival_event, pfi_attach_cookie);
- EVENTHANDLER_DEREGISTER(ifnet_departure_event, pfi_detach_cookie);
- EVENTHANDLER_DEREGISTER(group_attach_event, pfi_attach_group_cookie);
- EVENTHANDLER_DEREGISTER(group_change_event, pfi_change_group_cookie);
- EVENTHANDLER_DEREGISTER(group_detach_event, pfi_detach_group_cookie);
- EVENTHANDLER_DEREGISTER(ifaddr_event, pfi_ifaddr_event_cookie);
- PF_LOCK();
-
- V_pfi_all = NULL;
- while ((p = RB_MIN(pfi_ifhead, &V_pfi_ifs))) {
- if (p->pfik_rules || p->pfik_states) {
- printf("pfi_cleanup: dangling refs for %s\n",
- p->pfik_name);
- }
-
- RB_REMOVE(pfi_ifhead, &V_pfi_ifs, p);
- free(p, PFI_MTYPE);
- }
-
- free(V_pfi_buffer, PFI_MTYPE);
-}
-#endif
-
-struct pfi_kif *
-pfi_kif_get(const char *kif_name)
-{
- struct pfi_kif *kif;
- struct pfi_kif_cmp s;
-
- bzero(&s, sizeof(s));
- strlcpy(s.pfik_name, kif_name, sizeof(s.pfik_name));
-#ifdef __FreeBSD__
- if ((kif = RB_FIND(pfi_ifhead, &V_pfi_ifs, (struct pfi_kif *)&s)) != NULL)
-#else
- if ((kif = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&s)) != NULL)
-#endif
- return (kif);
-
- /* create new one */
-#ifdef __FreeBSD__
- if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_NOWAIT | M_ZERO)) == NULL)
-#else
- if ((kif = malloc(sizeof(*kif), PFI_MTYPE, M_DONTWAIT|M_ZERO)) == NULL)
-#endif
- return (NULL);
-
- strlcpy(kif->pfik_name, kif_name, sizeof(kif->pfik_name));
-#ifdef __FreeBSD__
- /*
- * It seems that the value of time_second is in unintialzied state
- * when pf sets interface statistics clear time in boot phase if pf
- * was statically linked to kernel. Instead of setting the bogus
- * time value have pfi_get_ifaces handle this case. In
- * pfi_get_ifaces it uses boottime.tv_sec if it sees the time is 0.
- */
- kif->pfik_tzero = time_second > 1 ? time_second : 0;
-#else
- kif->pfik_tzero = time_second;
-#endif
- TAILQ_INIT(&kif->pfik_dynaddrs);
-
-#ifdef __FreeBSD__
- RB_INSERT(pfi_ifhead, &V_pfi_ifs, kif);
-#else
- RB_INSERT(pfi_ifhead, &pfi_ifs, kif);
-#endif
-
- return (kif);
-}
-
-void
-pfi_kif_ref(struct pfi_kif *kif, enum pfi_kif_refs what)
-{
- switch (what) {
- case PFI_KIF_REF_RULE:
- kif->pfik_rules++;
- break;
- case PFI_KIF_REF_STATE:
- kif->pfik_states++;
- break;
- default:
- panic("pfi_kif_ref with unknown type");
- }
-}
-
-void
-pfi_kif_unref(struct pfi_kif *kif, enum pfi_kif_refs what)
-{
- if (kif == NULL)
- return;
-
- switch (what) {
- case PFI_KIF_REF_NONE:
- break;
- case PFI_KIF_REF_RULE:
- if (kif->pfik_rules <= 0) {
- printf("pfi_kif_unref: rules refcount <= 0\n");
- return;
- }
- kif->pfik_rules--;
- break;
- case PFI_KIF_REF_STATE:
- if (kif->pfik_states <= 0) {
- printf("pfi_kif_unref: state refcount <= 0\n");
- return;
- }
- kif->pfik_states--;
- break;
- default:
- panic("pfi_kif_unref with unknown type");
- }
-
-#ifdef __FreeBSD__
- if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == V_pfi_all)
-#else
- if (kif->pfik_ifp != NULL || kif->pfik_group != NULL || kif == pfi_all)
-#endif
- return;
-
- if (kif->pfik_rules || kif->pfik_states)
- return;
-
-#ifdef __FreeBSD__
- RB_REMOVE(pfi_ifhead, &V_pfi_ifs, kif);
-#else
- RB_REMOVE(pfi_ifhead, &pfi_ifs, kif);
-#endif
- free(kif, PFI_MTYPE);
-}
-
-int
-pfi_kif_match(struct pfi_kif *rule_kif, struct pfi_kif *packet_kif)
-{
- struct ifg_list *p;
-
- if (rule_kif == NULL || rule_kif == packet_kif)
- return (1);
-
- if (rule_kif->pfik_group != NULL)
- TAILQ_FOREACH(p, &packet_kif->pfik_ifp->if_groups, ifgl_next)
- if (p->ifgl_group == rule_kif->pfik_group)
- return (1);
-
- return (0);
-}
-
-void
-pfi_attach_ifnet(struct ifnet *ifp)
-{
- struct pfi_kif *kif;
- int s;
-
- pfi_initialize();
- s = splsoftnet();
-#ifdef __FreeBSD__
- V_pfi_update++;
-#else
- pfi_update++;
-#endif
- if ((kif = pfi_kif_get(ifp->if_xname)) == NULL)
- panic("pfi_kif_get failed");
-
- kif->pfik_ifp = ifp;
- ifp->if_pf_kif = (caddr_t)kif;
-
-#ifndef __FreeBSD__
- if ((kif->pfik_ah_cookie = hook_establish(ifp->if_addrhooks, 1,
- pfi_kifaddr_update, kif)) == NULL)
- panic("pfi_attach_ifnet: cannot allocate '%s' address hook",
- ifp->if_xname);
-#endif
-
- pfi_kif_update(kif);
-
- splx(s);
-}
-
-void
-pfi_detach_ifnet(struct ifnet *ifp)
-{
- int s;
- struct pfi_kif *kif;
-
- if ((kif = (struct pfi_kif *)ifp->if_pf_kif) == NULL)
- return;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- V_pfi_update++;
-#else
- pfi_update++;
-#endif
-#ifndef __FreeBSD__
- hook_disestablish(ifp->if_addrhooks, kif->pfik_ah_cookie);
-#endif
- pfi_kif_update(kif);
-
- kif->pfik_ifp = NULL;
- ifp->if_pf_kif = NULL;
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- splx(s);
-}
-
-void
-pfi_attach_ifgroup(struct ifg_group *ifg)
-{
- struct pfi_kif *kif;
- int s;
-
- pfi_initialize();
- s = splsoftnet();
-#ifdef __FreeBSD__
- V_pfi_update++;
-#else
- pfi_update++;
-#endif
- if ((kif = pfi_kif_get(ifg->ifg_group)) == NULL)
- panic("pfi_kif_get failed");
-
- kif->pfik_group = ifg;
- ifg->ifg_pf_kif = (caddr_t)kif;
-
- splx(s);
-}
-
-void
-pfi_detach_ifgroup(struct ifg_group *ifg)
-{
- int s;
- struct pfi_kif *kif;
-
- if ((kif = (struct pfi_kif *)ifg->ifg_pf_kif) == NULL)
- return;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- V_pfi_update++;
-#else
- pfi_update++;
-#endif
-
- kif->pfik_group = NULL;
- ifg->ifg_pf_kif = NULL;
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- splx(s);
-}
-
-void
-pfi_group_change(const char *group)
-{
- struct pfi_kif *kif;
- int s;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- V_pfi_update++;
-#else
- pfi_update++;
-#endif
- if ((kif = pfi_kif_get(group)) == NULL)
- panic("pfi_kif_get failed");
-
- pfi_kif_update(kif);
-
- splx(s);
-}
-
-int
-pfi_match_addr(struct pfi_dynaddr *dyn, struct pf_addr *a, sa_family_t af)
-{
- switch (af) {
-#ifdef INET
- case AF_INET:
- switch (dyn->pfid_acnt4) {
- case 0:
- return (0);
- case 1:
- return (PF_MATCHA(0, &dyn->pfid_addr4,
- &dyn->pfid_mask4, a, AF_INET));
- default:
- return (pfr_match_addr(dyn->pfid_kt, a, AF_INET));
- }
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- switch (dyn->pfid_acnt6) {
- case 0:
- return (0);
- case 1:
- return (PF_MATCHA(0, &dyn->pfid_addr6,
- &dyn->pfid_mask6, a, AF_INET6));
- default:
- return (pfr_match_addr(dyn->pfid_kt, a, AF_INET6));
- }
- break;
-#endif /* INET6 */
- default:
- return (0);
- }
-}
-
-int
-pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
-{
- struct pfi_dynaddr *dyn;
- char tblname[PF_TABLE_NAME_SIZE];
- struct pf_ruleset *ruleset = NULL;
- int s, rv = 0;
-
- if (aw->type != PF_ADDR_DYNIFTL)
- return (0);
-#ifdef __FreeBSD__
- /* XXX: revisit! */
- if ((dyn = pool_get(&V_pfi_addr_pl, PR_WAITOK | PR_ZERO))
-#else
- if ((dyn = pool_get(&pfi_addr_pl, PR_WAITOK | PR_LIMITFAIL | PR_ZERO))
-#endif
- == NULL)
- return (1);
-
- s = splsoftnet();
- if (!strcmp(aw->v.ifname, "self"))
- dyn->pfid_kif = pfi_kif_get(IFG_ALL);
- else
- dyn->pfid_kif = pfi_kif_get(aw->v.ifname);
- if (dyn->pfid_kif == NULL) {
- rv = 1;
- goto _bad;
- }
- pfi_kif_ref(dyn->pfid_kif, PFI_KIF_REF_RULE);
-
- dyn->pfid_net = pfi_unmask(&aw->v.a.mask);
- if (af == AF_INET && dyn->pfid_net == 32)
- dyn->pfid_net = 128;
- strlcpy(tblname, aw->v.ifname, sizeof(tblname));
- if (aw->iflags & PFI_AFLAG_NETWORK)
- strlcat(tblname, ":network", sizeof(tblname));
- if (aw->iflags & PFI_AFLAG_BROADCAST)
- strlcat(tblname, ":broadcast", sizeof(tblname));
- if (aw->iflags & PFI_AFLAG_PEER)
- strlcat(tblname, ":peer", sizeof(tblname));
- if (aw->iflags & PFI_AFLAG_NOALIAS)
- strlcat(tblname, ":0", sizeof(tblname));
- if (dyn->pfid_net != 128)
- snprintf(tblname + strlen(tblname),
- sizeof(tblname) - strlen(tblname), "/%d", dyn->pfid_net);
- if ((ruleset = pf_find_or_create_ruleset(PF_RESERVED_ANCHOR)) == NULL) {
- rv = 1;
- goto _bad;
- }
-
- if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) {
- rv = 1;
- goto _bad;
- }
-
- dyn->pfid_kt->pfrkt_flags |= PFR_TFLAG_ACTIVE;
- dyn->pfid_iflags = aw->iflags;
- dyn->pfid_af = af;
-
- TAILQ_INSERT_TAIL(&dyn->pfid_kif->pfik_dynaddrs, dyn, entry);
- aw->p.dyn = dyn;
- pfi_kif_update(dyn->pfid_kif);
- splx(s);
- return (0);
-
-_bad:
- if (dyn->pfid_kt != NULL)
- pfr_detach_table(dyn->pfid_kt);
- if (ruleset != NULL)
- pf_remove_if_empty_ruleset(ruleset);
- if (dyn->pfid_kif != NULL)
- pfi_kif_unref(dyn->pfid_kif, PFI_KIF_REF_RULE);
-#ifdef __FreeBSD__
- pool_put(&V_pfi_addr_pl, dyn);
-#else
- pool_put(&pfi_addr_pl, dyn);
-#endif
- splx(s);
- return (rv);
-}
-
-void
-pfi_kif_update(struct pfi_kif *kif)
-{
- struct ifg_list *ifgl;
- struct pfi_dynaddr *p;
-
- /* update all dynaddr */
- TAILQ_FOREACH(p, &kif->pfik_dynaddrs, entry)
- pfi_dynaddr_update(p);
-
- /* again for all groups kif is member of */
- if (kif->pfik_ifp != NULL)
- TAILQ_FOREACH(ifgl, &kif->pfik_ifp->if_groups, ifgl_next)
- pfi_kif_update((struct pfi_kif *)
- ifgl->ifgl_group->ifg_pf_kif);
-}
-
-void
-pfi_dynaddr_update(struct pfi_dynaddr *dyn)
-{
- struct pfi_kif *kif;
- struct pfr_ktable *kt;
-
- if (dyn == NULL || dyn->pfid_kif == NULL || dyn->pfid_kt == NULL)
- panic("pfi_dynaddr_update");
-
- kif = dyn->pfid_kif;
- kt = dyn->pfid_kt;
-
-#ifdef __FreeBSD__
- if (kt->pfrkt_larg != V_pfi_update) {
-#else
- if (kt->pfrkt_larg != pfi_update) {
-#endif
- /* this table needs to be brought up-to-date */
- pfi_table_update(kt, kif, dyn->pfid_net, dyn->pfid_iflags);
-#ifdef __FreeBSD__
- kt->pfrkt_larg = V_pfi_update;
-#else
- kt->pfrkt_larg = pfi_update;
-#endif
- }
- pfr_dynaddr_update(kt, dyn);
-}
-
-void
-pfi_table_update(struct pfr_ktable *kt, struct pfi_kif *kif, int net, int flags)
-{
- int e, size2 = 0;
- struct ifg_member *ifgm;
-
-#ifdef __FreeBSD__
- V_pfi_buffer_cnt = 0;
-#else
- pfi_buffer_cnt = 0;
-#endif
-
- if (kif->pfik_ifp != NULL)
- pfi_instance_add(kif->pfik_ifp, net, flags);
- else if (kif->pfik_group != NULL)
- TAILQ_FOREACH(ifgm, &kif->pfik_group->ifg_members, ifgm_next)
- pfi_instance_add(ifgm->ifgm_ifp, net, flags);
-
-#ifdef __FreeBSD__
- if ((e = pfr_set_addrs(&kt->pfrkt_t, V_pfi_buffer, V_pfi_buffer_cnt, &size2,
- NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
- printf("pfi_table_update: cannot set %d new addresses "
- "into table %s: %d\n", V_pfi_buffer_cnt, kt->pfrkt_name, e);
-#else
- if ((e = pfr_set_addrs(&kt->pfrkt_t, pfi_buffer, pfi_buffer_cnt, &size2,
- NULL, NULL, NULL, 0, PFR_TFLAG_ALLMASK)))
- printf("pfi_table_update: cannot set %d new addresses "
- "into table %s: %d\n", pfi_buffer_cnt, kt->pfrkt_name, e);
-#endif
-}
-
-void
-pfi_instance_add(struct ifnet *ifp, int net, int flags)
-{
- struct ifaddr *ia;
- int got4 = 0, got6 = 0;
- int net2, af;
-
- if (ifp == NULL)
- return;
- TAILQ_FOREACH(ia, &ifp->if_addrlist, ifa_list) {
- if (ia->ifa_addr == NULL)
- continue;
- af = ia->ifa_addr->sa_family;
- if (af != AF_INET && af != AF_INET6)
- continue;
-#ifdef __FreeBSD__
- /*
- * XXX: For point-to-point interfaces, (ifname:0) and IPv4,
- * jump over addresses without a proper route to work
- * around a problem with ppp not fully removing the
- * address used during IPCP.
- */
- if ((ifp->if_flags & IFF_POINTOPOINT) &&
- !(ia->ifa_flags & IFA_ROUTE) &&
- (flags & PFI_AFLAG_NOALIAS) && (af == AF_INET))
- continue;
-#endif
- if ((flags & PFI_AFLAG_BROADCAST) && af == AF_INET6)
- continue;
- if ((flags & PFI_AFLAG_BROADCAST) &&
- !(ifp->if_flags & IFF_BROADCAST))
- continue;
- if ((flags & PFI_AFLAG_PEER) &&
- !(ifp->if_flags & IFF_POINTOPOINT))
- continue;
- if ((flags & PFI_AFLAG_NETWORK) && af == AF_INET6 &&
- IN6_IS_ADDR_LINKLOCAL(
- &((struct sockaddr_in6 *)ia->ifa_addr)->sin6_addr))
- continue;
- if (flags & PFI_AFLAG_NOALIAS) {
- if (af == AF_INET && got4)
- continue;
- if (af == AF_INET6 && got6)
- continue;
- }
- if (af == AF_INET)
- got4 = 1;
- else if (af == AF_INET6)
- got6 = 1;
- net2 = net;
- if (net2 == 128 && (flags & PFI_AFLAG_NETWORK)) {
- if (af == AF_INET)
- net2 = pfi_unmask(&((struct sockaddr_in *)
- ia->ifa_netmask)->sin_addr);
- else if (af == AF_INET6)
- net2 = pfi_unmask(&((struct sockaddr_in6 *)
- ia->ifa_netmask)->sin6_addr);
- }
- if (af == AF_INET && net2 > 32)
- net2 = 32;
- if (flags & PFI_AFLAG_BROADCAST)
- pfi_address_add(ia->ifa_broadaddr, af, net2);
- else if (flags & PFI_AFLAG_PEER)
- pfi_address_add(ia->ifa_dstaddr, af, net2);
- else
- pfi_address_add(ia->ifa_addr, af, net2);
- }
-}
-
-void
-pfi_address_add(struct sockaddr *sa, int af, int net)
-{
- struct pfr_addr *p;
- int i;
-
-#ifdef __FreeBSD__
- if (V_pfi_buffer_cnt >= V_pfi_buffer_max) {
- int new_max = V_pfi_buffer_max * 2;
-#else
- if (pfi_buffer_cnt >= pfi_buffer_max) {
- int new_max = pfi_buffer_max * 2;
-#endif
-
- if (new_max > PFI_BUFFER_MAX) {
- printf("pfi_address_add: address buffer full (%d/%d)\n",
-#ifdef __FreeBSD__
- V_pfi_buffer_cnt, PFI_BUFFER_MAX);
-#else
- pfi_buffer_cnt, PFI_BUFFER_MAX);
-#endif
- return;
- }
- p = malloc(new_max * sizeof(*V_pfi_buffer), PFI_MTYPE,
-#ifdef __FreeBSD__
- M_NOWAIT);
-#else
- M_DONTWAIT);
-#endif
- if (p == NULL) {
- printf("pfi_address_add: no memory to grow buffer "
-#ifdef __FreeBSD__
- "(%d/%d)\n", V_pfi_buffer_cnt, PFI_BUFFER_MAX);
-#else
- "(%d/%d)\n", pfi_buffer_cnt, PFI_BUFFER_MAX);
-#endif
- return;
- }
-#ifdef __FreeBSD__
- memcpy(V_pfi_buffer, p, V_pfi_buffer_cnt * sizeof(*V_pfi_buffer));
- /* no need to zero buffer */
- free(V_pfi_buffer, PFI_MTYPE);
- V_pfi_buffer = p;
- V_pfi_buffer_max = new_max;
-#else
- memcpy(pfi_buffer, p, pfi_buffer_cnt * sizeof(*pfi_buffer));
- /* no need to zero buffer */
- free(pfi_buffer, PFI_MTYPE);
- pfi_buffer = p;
- pfi_buffer_max = new_max;
-#endif
- }
- if (af == AF_INET && net > 32)
- net = 128;
-#ifdef __FreeBSD__
- p = V_pfi_buffer + V_pfi_buffer_cnt++;
-#else
- p = pfi_buffer + pfi_buffer_cnt++;
-#endif
- bzero(p, sizeof(*p));
- p->pfra_af = af;
- p->pfra_net = net;
- if (af == AF_INET)
- p->pfra_ip4addr = ((struct sockaddr_in *)sa)->sin_addr;
- else if (af == AF_INET6) {
- p->pfra_ip6addr = ((struct sockaddr_in6 *)sa)->sin6_addr;
- if (IN6_IS_SCOPE_EMBED(&p->pfra_ip6addr))
- p->pfra_ip6addr.s6_addr16[1] = 0;
- }
- /* mask network address bits */
- if (net < 128)
- ((caddr_t)p)[p->pfra_net/8] &= ~(0xFF >> (p->pfra_net%8));
- for (i = (p->pfra_net+7)/8; i < sizeof(p->pfra_u); i++)
- ((caddr_t)p)[i] = 0;
-}
-
-void
-pfi_dynaddr_remove(struct pf_addr_wrap *aw)
-{
- int s;
-
- if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
- aw->p.dyn->pfid_kif == NULL || aw->p.dyn->pfid_kt == NULL)
- return;
-
- s = splsoftnet();
- TAILQ_REMOVE(&aw->p.dyn->pfid_kif->pfik_dynaddrs, aw->p.dyn, entry);
- pfi_kif_unref(aw->p.dyn->pfid_kif, PFI_KIF_REF_RULE);
- aw->p.dyn->pfid_kif = NULL;
- pfr_detach_table(aw->p.dyn->pfid_kt);
- aw->p.dyn->pfid_kt = NULL;
-#ifdef __FreeBSD__
- pool_put(&V_pfi_addr_pl, aw->p.dyn);
-#else
- pool_put(&pfi_addr_pl, aw->p.dyn);
-#endif
- aw->p.dyn = NULL;
- splx(s);
-}
-
-void
-pfi_dynaddr_copyout(struct pf_addr_wrap *aw)
-{
- if (aw->type != PF_ADDR_DYNIFTL || aw->p.dyn == NULL ||
- aw->p.dyn->pfid_kif == NULL)
- return;
- aw->p.dyncnt = aw->p.dyn->pfid_acnt4 + aw->p.dyn->pfid_acnt6;
-}
-
-void
-pfi_kifaddr_update(void *v)
-{
- int s;
- struct pfi_kif *kif = (struct pfi_kif *)v;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- V_pfi_update++;
-#else
- pfi_update++;
-#endif
- pfi_kif_update(kif);
- splx(s);
-}
-
-int
-pfi_if_compare(struct pfi_kif *p, struct pfi_kif *q)
-{
- return (strncmp(p->pfik_name, q->pfik_name, IFNAMSIZ));
-}
-
-void
-pfi_update_status(const char *name, struct pf_status *pfs)
-{
- struct pfi_kif *p;
- struct pfi_kif_cmp key;
- struct ifg_member p_member, *ifgm;
- TAILQ_HEAD(, ifg_member) ifg_members;
- int i, j, k, s;
-
- strlcpy(key.pfik_name, name, sizeof(key.pfik_name));
- s = splsoftnet();
-#ifdef __FreeBSD__
- p = RB_FIND(pfi_ifhead, &V_pfi_ifs, (struct pfi_kif *)&key);
-#else
- p = RB_FIND(pfi_ifhead, &pfi_ifs, (struct pfi_kif *)&key);
-#endif
- if (p == NULL) {
- splx(s);
- return;
- }
- if (p->pfik_group != NULL) {
- bcopy(&p->pfik_group->ifg_members, &ifg_members,
- sizeof(ifg_members));
- } else {
- /* build a temporary list for p only */
- bzero(&p_member, sizeof(p_member));
- p_member.ifgm_ifp = p->pfik_ifp;
- TAILQ_INIT(&ifg_members);
- TAILQ_INSERT_TAIL(&ifg_members, &p_member, ifgm_next);
- }
- if (pfs) {
- bzero(pfs->pcounters, sizeof(pfs->pcounters));
- bzero(pfs->bcounters, sizeof(pfs->bcounters));
- }
- TAILQ_FOREACH(ifgm, &ifg_members, ifgm_next) {
- if (ifgm->ifgm_ifp == NULL)
- continue;
- p = (struct pfi_kif *)ifgm->ifgm_ifp->if_pf_kif;
-
- /* just clear statistics */
- if (pfs == NULL) {
- bzero(p->pfik_packets, sizeof(p->pfik_packets));
- bzero(p->pfik_bytes, sizeof(p->pfik_bytes));
- p->pfik_tzero = time_second;
- continue;
- }
- for (i = 0; i < 2; i++)
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++) {
- pfs->pcounters[i][j][k] +=
- p->pfik_packets[i][j][k];
- pfs->bcounters[i][j] +=
- p->pfik_bytes[i][j][k];
- }
- }
- splx(s);
-}
-
-int
-pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
-{
- struct pfi_kif *p, *nextp;
- int s, n = 0;
-#ifdef __FreeBSD__
- int error;
-#endif
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- for (p = RB_MIN(pfi_ifhead, &V_pfi_ifs); p; p = nextp) {
- nextp = RB_NEXT(pfi_ifhead, &V_pfi_ifs, p);
-#else
- for (p = RB_MIN(pfi_ifhead, &pfi_ifs); p; p = nextp) {
- nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
-#endif
- if (pfi_skip_if(name, p))
- continue;
- if (*size > n++) {
- if (!p->pfik_tzero)
- p->pfik_tzero = time_second;
- pfi_kif_ref(p, PFI_KIF_REF_RULE);
-#ifdef __FreeBSD__
- PF_COPYOUT(p, buf++, sizeof(*buf), error);
- if (error) {
-#else
- if (copyout(p, buf++, sizeof(*buf))) {
-#endif
- pfi_kif_unref(p, PFI_KIF_REF_RULE);
- splx(s);
- return (EFAULT);
- }
-#ifdef __FreeBSD__
- nextp = RB_NEXT(pfi_ifhead, &V_pfi_ifs, p);
-#else
- nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
-#endif
- pfi_kif_unref(p, PFI_KIF_REF_RULE);
- }
- }
- splx(s);
- *size = n;
- return (0);
-}
-
-int
-pfi_skip_if(const char *filter, struct pfi_kif *p)
-{
- int n;
-
- if (filter == NULL || !*filter)
- return (0);
- if (!strcmp(p->pfik_name, filter))
- return (0); /* exact match */
- n = strlen(filter);
- if (n < 1 || n >= IFNAMSIZ)
- return (1); /* sanity check */
- if (filter[n-1] >= '0' && filter[n-1] <= '9')
- return (1); /* only do exact match in that case */
- if (strncmp(p->pfik_name, filter, n))
- return (1); /* prefix doesn't match */
- return (p->pfik_name[n] < '0' || p->pfik_name[n] > '9');
-}
-
-int
-pfi_set_flags(const char *name, int flags)
-{
- struct pfi_kif *p;
- int s;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
-#else
- RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
-#endif
- if (pfi_skip_if(name, p))
- continue;
- p->pfik_flags |= flags;
- }
- splx(s);
- return (0);
-}
-
-int
-pfi_clear_flags(const char *name, int flags)
-{
- struct pfi_kif *p;
- int s;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- RB_FOREACH(p, pfi_ifhead, &V_pfi_ifs) {
-#else
- RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
-#endif
- if (pfi_skip_if(name, p))
- continue;
- p->pfik_flags &= ~flags;
- }
- splx(s);
- return (0);
-}
-
-/* from pf_print_state.c */
-int
-pfi_unmask(void *addr)
-{
- struct pf_addr *m = addr;
- int i = 31, j = 0, b = 0;
- u_int32_t tmp;
-
- while (j < 4 && m->addr32[j] == 0xffffffff) {
- b += 32;
- j++;
- }
- if (j < 4) {
- tmp = ntohl(m->addr32[j]);
- for (i = 31; tmp & (1 << i); --i)
- b++;
- }
- return (b);
-}
-
-#ifdef __FreeBSD__
-void
-pfi_attach_ifnet_event(void *arg __unused, struct ifnet *ifp)
-{
-
- CURVNET_SET(ifp->if_vnet);
- PF_LOCK();
- pfi_attach_ifnet(ifp);
-#ifdef ALTQ
- pf_altq_ifnet_event(ifp, 0);
-#endif
- PF_UNLOCK();
- CURVNET_RESTORE();
-}
-
-void
-pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
-{
-
- CURVNET_SET(ifp->if_vnet);
- PF_LOCK();
- pfi_detach_ifnet(ifp);
-#ifdef ALTQ
- pf_altq_ifnet_event(ifp, 1);
-#endif
- PF_UNLOCK();
- CURVNET_RESTORE();
-}
-
-void
-pfi_attach_group_event(void *arg , struct ifg_group *ifg)
-{
-
- CURVNET_SET((struct vnet *)arg);
- PF_LOCK();
- pfi_attach_ifgroup(ifg);
- PF_UNLOCK();
- CURVNET_RESTORE();
-}
-
-void
-pfi_change_group_event(void *arg, char *gname)
-{
-
- CURVNET_SET((struct vnet *)arg);
- PF_LOCK();
- pfi_group_change(gname);
- PF_UNLOCK();
- CURVNET_RESTORE();
-}
-
-void
-pfi_detach_group_event(void *arg, struct ifg_group *ifg)
-{
-
- CURVNET_SET((struct vnet *)arg);
- PF_LOCK();
- pfi_detach_ifgroup(ifg);
- PF_UNLOCK();
- CURVNET_RESTORE();
-}
-
-void
-pfi_ifaddr_event(void *arg __unused, struct ifnet *ifp)
-{
-
- CURVNET_SET(ifp->if_vnet);
- PF_LOCK();
- if (ifp && ifp->if_pf_kif)
- pfi_kifaddr_update(ifp->if_pf_kif);
- PF_UNLOCK();
- CURVNET_RESTORE();
-}
-#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/pf_ioctl.c b/sys/contrib/pf/net/pf_ioctl.c
deleted file mode 100644
index 6b5d8f5..0000000
--- a/sys/contrib/pf/net/pf_ioctl.c
+++ /dev/null
@@ -1,4420 +0,0 @@
-/* $OpenBSD: pf_ioctl.c,v 1.213 2009/02/15 21:46:12 mbalmer Exp $ */
-
-/*
- * Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002,2003 Henning Brauer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- * Effort sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- *
- */
-
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_bpf.h"
-#include "opt_pf.h"
-
-#define NPFSYNC 1
-
-#ifdef DEV_PFLOG
-#define NPFLOG DEV_PFLOG
-#else
-#define NPFLOG 0
-#endif
-
-#else /* !__FreeBSD__ */
-#include "pfsync.h"
-#include "pflog.h"
-#endif /* __FreeBSD__ */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/filio.h>
-#include <sys/fcntl.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/time.h>
-#ifdef __FreeBSD__
-#include <sys/ucred.h>
-#include <sys/jail.h>
-#include <sys/module.h>
-#include <sys/conf.h>
-#include <sys/proc.h>
-#include <sys/sysctl.h>
-#else
-#include <sys/timeout.h>
-#include <sys/pool.h>
-#endif
-#include <sys/proc.h>
-#include <sys/malloc.h>
-#include <sys/kthread.h>
-#ifndef __FreeBSD__
-#include <sys/rwlock.h>
-#include <uvm/uvm_extern.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_types.h>
-#ifdef __FreeBSD__
-#include <net/vnet.h>
-#endif
-#include <net/route.h>
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_icmp.h>
-
-#ifdef __FreeBSD__
-#include <sys/md5.h>
-#else
-#include <dev/rndvar.h>
-#include <crypto/md5.h>
-#endif
-#include <net/pfvar.h>
-
-#include <net/if_pfsync.h>
-
-#if NPFLOG > 0
-#include <net/if_pflog.h>
-#endif /* NPFLOG > 0 */
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#include <netinet/in_pcb.h>
-#endif /* INET6 */
-
-#ifdef ALTQ
-#include <altq/altq.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/limits.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
-#include <net/pfil.h>
-#endif /* __FreeBSD__ */
-
-#ifdef __FreeBSD__
-void init_zone_var(void);
-void cleanup_pf_zone(void);
-int pfattach(void);
-#else
-void pfattach(int);
-void pf_thread_create(void *);
-int pfopen(dev_t, int, int, struct proc *);
-int pfclose(dev_t, int, int, struct proc *);
-#endif
-struct pf_pool *pf_get_pool(char *, u_int32_t, u_int8_t, u_int32_t,
- u_int8_t, u_int8_t, u_int8_t);
-
-void pf_mv_pool(struct pf_palist *, struct pf_palist *);
-void pf_empty_pool(struct pf_palist *);
-#ifdef __FreeBSD__
-int pfioctl(struct cdev *, u_long, caddr_t, int, struct thread *);
-#else
-int pfioctl(dev_t, u_long, caddr_t, int, struct proc *);
-#endif
-#ifdef ALTQ
-int pf_begin_altq(u_int32_t *);
-int pf_rollback_altq(u_int32_t);
-int pf_commit_altq(u_int32_t);
-int pf_enable_altq(struct pf_altq *);
-int pf_disable_altq(struct pf_altq *);
-#endif /* ALTQ */
-int pf_begin_rules(u_int32_t *, int, const char *);
-int pf_rollback_rules(u_int32_t, int, char *);
-int pf_setup_pfsync_matching(struct pf_ruleset *);
-void pf_hash_rule(MD5_CTX *, struct pf_rule *);
-void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
-int pf_commit_rules(u_int32_t, int, char *);
-int pf_addr_setup(struct pf_ruleset *,
- struct pf_addr_wrap *, sa_family_t);
-void pf_addr_copyout(struct pf_addr_wrap *);
-
-#define TAGID_MAX 50000
-
-#ifdef __FreeBSD__
-VNET_DEFINE(struct pf_rule, pf_default_rule);
-VNET_DEFINE(struct sx, pf_consistency_lock);
-
-#ifdef ALTQ
-static VNET_DEFINE(int, pf_altq_running);
-#define V_pf_altq_running VNET(pf_altq_running)
-#endif
-
-TAILQ_HEAD(pf_tags, pf_tagname);
-
-#define V_pf_tags VNET(pf_tags)
-VNET_DEFINE(struct pf_tags, pf_tags);
-#define V_pf_qids VNET(pf_qids)
-VNET_DEFINE(struct pf_tags, pf_qids);
-
-#else /* !__FreeBSD__ */
-struct pf_rule pf_default_rule;
-struct rwlock pf_consistency_lock = RWLOCK_INITIALIZER("pfcnslk");
-#ifdef ALTQ
-static int pf_altq_running;
-#endif
-
-TAILQ_HEAD(pf_tags, pf_tagname) pf_tags = TAILQ_HEAD_INITIALIZER(pf_tags),
- pf_qids = TAILQ_HEAD_INITIALIZER(pf_qids);
-#endif /* __FreeBSD__ */
-
-#if (PF_QNAME_SIZE != PF_TAG_NAME_SIZE)
-#error PF_QNAME_SIZE must be equal to PF_TAG_NAME_SIZE
-#endif
-
-u_int16_t tagname2tag(struct pf_tags *, char *);
-void tag2tagname(struct pf_tags *, u_int16_t, char *);
-void tag_unref(struct pf_tags *, u_int16_t);
-int pf_rtlabel_add(struct pf_addr_wrap *);
-void pf_rtlabel_remove(struct pf_addr_wrap *);
-void pf_rtlabel_copyout(struct pf_addr_wrap *);
-
-#ifdef __FreeBSD__
-#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
-#else
-#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
-#endif
-
-#ifdef __FreeBSD__
-struct cdev *pf_dev;
-
-/*
- * XXX - These are new and need to be checked when moveing to a new version
- */
-static void pf_clear_states(void);
-static int pf_clear_tables(void);
-static void pf_clear_srcnodes(void);
-/*
- * XXX - These are new and need to be checked when moveing to a new version
- */
-
-/*
- * Wrapper functions for pfil(9) hooks
- */
-#ifdef INET
-static int pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp,
- int dir, struct inpcb *inp);
-static int pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp,
- int dir, struct inpcb *inp);
-#endif
-#ifdef INET6
-static int pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp,
- int dir, struct inpcb *inp);
-static int pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp,
- int dir, struct inpcb *inp);
-#endif
-
-static int hook_pf(void);
-static int dehook_pf(void);
-static int shutdown_pf(void);
-static int pf_load(void);
-static int pf_unload(void);
-
-static struct cdevsw pf_cdevsw = {
- .d_ioctl = pfioctl,
- .d_name = PF_NAME,
- .d_version = D_VERSION,
-};
-
-static volatile VNET_DEFINE(int, pf_pfil_hooked);
-#define V_pf_pfil_hooked VNET(pf_pfil_hooked)
-VNET_DEFINE(int, pf_end_threads);
-struct mtx pf_task_mtx;
-
-/* pfsync */
-pfsync_state_import_t *pfsync_state_import_ptr = NULL;
-pfsync_insert_state_t *pfsync_insert_state_ptr = NULL;
-pfsync_update_state_t *pfsync_update_state_ptr = NULL;
-pfsync_delete_state_t *pfsync_delete_state_ptr = NULL;
-pfsync_clear_states_t *pfsync_clear_states_ptr = NULL;
-pfsync_state_in_use_t *pfsync_state_in_use_ptr = NULL;
-pfsync_defer_t *pfsync_defer_ptr = NULL;
-pfsync_up_t *pfsync_up_ptr = NULL;
-/* pflow */
-export_pflow_t *export_pflow_ptr = NULL;
-/* pflog */
-pflog_packet_t *pflog_packet_ptr = NULL;
-
-VNET_DEFINE(int, debug_pfugidhack);
-SYSCTL_VNET_INT(_debug, OID_AUTO, pfugidhack, CTLFLAG_RW,
- &VNET_NAME(debug_pfugidhack), 0,
- "Enable/disable pf user/group rules mpsafe hack");
-
-static void
-init_pf_mutex(void)
-{
-
- mtx_init(&pf_task_mtx, "pf task mtx", NULL, MTX_DEF);
-}
-
-static void
-destroy_pf_mutex(void)
-{
-
- mtx_destroy(&pf_task_mtx);
-}
-void
-init_zone_var(void)
-{
- V_pf_src_tree_pl = V_pf_rule_pl = NULL;
- V_pf_state_pl = V_pf_state_key_pl = V_pf_state_item_pl = NULL;
- V_pf_altq_pl = V_pf_pooladdr_pl = NULL;
- V_pf_frent_pl = V_pf_frag_pl = V_pf_cache_pl = V_pf_cent_pl = NULL;
- V_pf_state_scrub_pl = NULL;
- V_pfr_ktable_pl = V_pfr_kentry_pl = V_pfr_kcounters_pl = NULL;
-}
-
-void
-cleanup_pf_zone(void)
-{
- UMA_DESTROY(V_pf_src_tree_pl);
- UMA_DESTROY(V_pf_rule_pl);
- UMA_DESTROY(V_pf_state_pl);
- UMA_DESTROY(V_pf_state_key_pl);
- UMA_DESTROY(V_pf_state_item_pl);
- UMA_DESTROY(V_pf_altq_pl);
- UMA_DESTROY(V_pf_pooladdr_pl);
- UMA_DESTROY(V_pf_frent_pl);
- UMA_DESTROY(V_pf_frag_pl);
- UMA_DESTROY(V_pf_cache_pl);
- UMA_DESTROY(V_pf_cent_pl);
- UMA_DESTROY(V_pfr_ktable_pl);
- UMA_DESTROY(V_pfr_kentry_pl);
- UMA_DESTROY(V_pfr_kcounters_pl);
- UMA_DESTROY(V_pf_state_scrub_pl);
- UMA_DESTROY(V_pfi_addr_pl);
-}
-
-int
-pfattach(void)
-{
- u_int32_t *my_timeout = V_pf_default_rule.timeout;
- int error = 1;
-
- do {
- UMA_CREATE(V_pf_src_tree_pl, struct pf_src_node, "pfsrctrpl");
- UMA_CREATE(V_pf_rule_pl, struct pf_rule, "pfrulepl");
- UMA_CREATE(V_pf_state_pl, struct pf_state, "pfstatepl");
- UMA_CREATE(V_pf_state_key_pl, struct pf_state, "pfstatekeypl");
- UMA_CREATE(V_pf_state_item_pl, struct pf_state, "pfstateitempl");
- UMA_CREATE(V_pf_altq_pl, struct pf_altq, "pfaltqpl");
- UMA_CREATE(V_pf_pooladdr_pl, struct pf_pooladdr, "pfpooladdrpl");
- UMA_CREATE(V_pfr_ktable_pl, struct pfr_ktable, "pfrktable");
- UMA_CREATE(V_pfr_kentry_pl, struct pfr_kentry, "pfrkentry");
- UMA_CREATE(V_pfr_kcounters_pl, struct pfr_kcounters, "pfrkcounters");
- UMA_CREATE(V_pf_frent_pl, struct pf_frent, "pffrent");
- UMA_CREATE(V_pf_frag_pl, struct pf_fragment, "pffrag");
- UMA_CREATE(V_pf_cache_pl, struct pf_fragment, "pffrcache");
- UMA_CREATE(V_pf_cent_pl, struct pf_frcache, "pffrcent");
- UMA_CREATE(V_pf_state_scrub_pl, struct pf_state_scrub,
- "pfstatescrub");
- UMA_CREATE(V_pfi_addr_pl, struct pfi_dynaddr, "pfiaddrpl");
- error = 0;
- } while(0);
- if (error) {
- cleanup_pf_zone();
- return (error);
- }
- pfr_initialize();
- pfi_initialize();
- if ( (error = pf_osfp_initialize()) ) {
- cleanup_pf_zone();
- pf_osfp_cleanup();
- return (error);
- }
-
- V_pf_pool_limits[PF_LIMIT_STATES].pp = V_pf_state_pl;
- V_pf_pool_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT;
- V_pf_pool_limits[PF_LIMIT_SRC_NODES].pp = V_pf_src_tree_pl;
- V_pf_pool_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT;
- V_pf_pool_limits[PF_LIMIT_FRAGS].pp = V_pf_frent_pl;
- V_pf_pool_limits[PF_LIMIT_FRAGS].limit = PFFRAG_FRENT_HIWAT;
- V_pf_pool_limits[PF_LIMIT_TABLES].pp = V_pfr_ktable_pl;
- V_pf_pool_limits[PF_LIMIT_TABLES].limit = PFR_KTABLE_HIWAT;
- V_pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].pp = V_pfr_kentry_pl;
- V_pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit = PFR_KENTRY_HIWAT;
- uma_zone_set_max(V_pf_pool_limits[PF_LIMIT_STATES].pp,
- V_pf_pool_limits[PF_LIMIT_STATES].limit);
-
- RB_INIT(&V_tree_src_tracking);
- RB_INIT(&V_pf_anchors);
- pf_init_ruleset(&pf_main_ruleset);
-
- TAILQ_INIT(&V_pf_altqs[0]);
- TAILQ_INIT(&V_pf_altqs[1]);
- TAILQ_INIT(&V_pf_pabuf);
- V_pf_altqs_active = &V_pf_altqs[0];
- V_pf_altqs_inactive = &V_pf_altqs[1];
- TAILQ_INIT(&V_state_list);
-
- /* default rule should never be garbage collected */
- V_pf_default_rule.entries.tqe_prev = &V_pf_default_rule.entries.tqe_next;
- V_pf_default_rule.action = PF_PASS;
- V_pf_default_rule.nr = -1;
- V_pf_default_rule.rtableid = -1;
-
- /* initialize default timeouts */
- my_timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
- my_timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
- my_timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
- my_timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
- my_timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
- my_timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
- my_timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
- my_timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
- my_timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
- my_timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
- my_timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
- my_timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
- my_timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
- my_timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
- my_timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
- my_timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
- my_timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
- my_timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
- my_timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
- my_timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
-
- pf_normalize_init();
-
- bzero(&V_pf_status, sizeof(V_pf_status));
- V_pf_status.debug = PF_DEBUG_URGENT;
-
- V_pf_pfil_hooked = 0;
-
- /* XXX do our best to avoid a conflict */
- V_pf_status.hostid = arc4random();
-
- if (kproc_create(pf_purge_thread, curvnet, NULL, 0, 0, "pfpurge"))
- return (ENXIO);
-
- m_addr_chg_pf_p = pf_pkt_addr_changed;
-
- return (error);
-}
-#else /* !__FreeBSD__ */
-
-void
-pfattach(int num)
-{
- u_int32_t *timeout = pf_default_rule.timeout;
-
- pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
- &pool_allocator_nointr);
- pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
- "pfsrctrpl", NULL);
- pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
- NULL);
- pool_init(&pf_state_key_pl, sizeof(struct pf_state_key), 0, 0, 0,
- "pfstatekeypl", NULL);
- pool_init(&pf_state_item_pl, sizeof(struct pf_state_item), 0, 0, 0,
- "pfstateitempl", NULL);
- pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
- &pool_allocator_nointr);
- pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
- "pfpooladdrpl", &pool_allocator_nointr);
- pfr_initialize();
- pfi_initialize();
- pf_osfp_initialize();
-
- pool_sethardlimit(pf_pool_limits[PF_LIMIT_STATES].pp,
- pf_pool_limits[PF_LIMIT_STATES].limit, NULL, 0);
-
- if (physmem <= atop(100*1024*1024))
- pf_pool_limits[PF_LIMIT_TABLE_ENTRIES].limit =
- PFR_KENTRY_HIWAT_SMALL;
-
- RB_INIT(&tree_src_tracking);
- RB_INIT(&pf_anchors);
- pf_init_ruleset(&pf_main_ruleset);
- TAILQ_INIT(&pf_altqs[0]);
- TAILQ_INIT(&pf_altqs[1]);
- TAILQ_INIT(&pf_pabuf);
- pf_altqs_active = &pf_altqs[0];
- pf_altqs_inactive = &pf_altqs[1];
- TAILQ_INIT(&state_list);
-
- /* default rule should never be garbage collected */
- pf_default_rule.entries.tqe_prev = &pf_default_rule.entries.tqe_next;
- pf_default_rule.action = PF_PASS;
- pf_default_rule.nr = -1;
- pf_default_rule.rtableid = -1;
-
- /* initialize default timeouts */
- timeout[PFTM_TCP_FIRST_PACKET] = PFTM_TCP_FIRST_PACKET_VAL;
- timeout[PFTM_TCP_OPENING] = PFTM_TCP_OPENING_VAL;
- timeout[PFTM_TCP_ESTABLISHED] = PFTM_TCP_ESTABLISHED_VAL;
- timeout[PFTM_TCP_CLOSING] = PFTM_TCP_CLOSING_VAL;
- timeout[PFTM_TCP_FIN_WAIT] = PFTM_TCP_FIN_WAIT_VAL;
- timeout[PFTM_TCP_CLOSED] = PFTM_TCP_CLOSED_VAL;
- timeout[PFTM_UDP_FIRST_PACKET] = PFTM_UDP_FIRST_PACKET_VAL;
- timeout[PFTM_UDP_SINGLE] = PFTM_UDP_SINGLE_VAL;
- timeout[PFTM_UDP_MULTIPLE] = PFTM_UDP_MULTIPLE_VAL;
- timeout[PFTM_ICMP_FIRST_PACKET] = PFTM_ICMP_FIRST_PACKET_VAL;
- timeout[PFTM_ICMP_ERROR_REPLY] = PFTM_ICMP_ERROR_REPLY_VAL;
- timeout[PFTM_OTHER_FIRST_PACKET] = PFTM_OTHER_FIRST_PACKET_VAL;
- timeout[PFTM_OTHER_SINGLE] = PFTM_OTHER_SINGLE_VAL;
- timeout[PFTM_OTHER_MULTIPLE] = PFTM_OTHER_MULTIPLE_VAL;
- timeout[PFTM_FRAG] = PFTM_FRAG_VAL;
- timeout[PFTM_INTERVAL] = PFTM_INTERVAL_VAL;
- timeout[PFTM_SRC_NODE] = PFTM_SRC_NODE_VAL;
- timeout[PFTM_TS_DIFF] = PFTM_TS_DIFF_VAL;
- timeout[PFTM_ADAPTIVE_START] = PFSTATE_ADAPT_START;
- timeout[PFTM_ADAPTIVE_END] = PFSTATE_ADAPT_END;
-
- pf_normalize_init();
- bzero(&pf_status, sizeof(pf_status));
- pf_status.debug = PF_DEBUG_URGENT;
-
- /* XXX do our best to avoid a conflict */
- pf_status.hostid = arc4random();
-
- /* require process context to purge states, so perform in a thread */
- kthread_create_deferred(pf_thread_create, NULL);
-}
-
-void
-pf_thread_create(void *v)
-{
- if (kthread_create(pf_purge_thread, NULL, NULL, "pfpurge"))
- panic("pfpurge thread");
-}
-
-int
-pfopen(dev_t dev, int flags, int fmt, struct proc *p)
-{
- if (minor(dev) >= 1)
- return (ENXIO);
- return (0);
-}
-
-int
-pfclose(dev_t dev, int flags, int fmt, struct proc *p)
-{
- if (minor(dev) >= 1)
- return (ENXIO);
- return (0);
-}
-#endif
-
-struct pf_pool *
-pf_get_pool(char *anchor, u_int32_t ticket, u_int8_t rule_action,
- u_int32_t rule_number, u_int8_t r_last, u_int8_t active,
- u_int8_t check_ticket)
-{
- struct pf_ruleset *ruleset;
- struct pf_rule *rule;
- int rs_num;
-
- ruleset = pf_find_ruleset(anchor);
- if (ruleset == NULL)
- return (NULL);
- rs_num = pf_get_ruleset_number(rule_action);
- if (rs_num >= PF_RULESET_MAX)
- return (NULL);
- if (active) {
- if (check_ticket && ticket !=
- ruleset->rules[rs_num].active.ticket)
- return (NULL);
- if (r_last)
- rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
- pf_rulequeue);
- else
- rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
- } else {
- if (check_ticket && ticket !=
- ruleset->rules[rs_num].inactive.ticket)
- return (NULL);
- if (r_last)
- rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
- pf_rulequeue);
- else
- rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
- }
- if (!r_last) {
- while ((rule != NULL) && (rule->nr != rule_number))
- rule = TAILQ_NEXT(rule, entries);
- }
- if (rule == NULL)
- return (NULL);
-
- return (&rule->rpool);
-}
-
-void
-pf_mv_pool(struct pf_palist *poola, struct pf_palist *poolb)
-{
- struct pf_pooladdr *mv_pool_pa;
-
- while ((mv_pool_pa = TAILQ_FIRST(poola)) != NULL) {
- TAILQ_REMOVE(poola, mv_pool_pa, entries);
- TAILQ_INSERT_TAIL(poolb, mv_pool_pa, entries);
- }
-}
-
-void
-pf_empty_pool(struct pf_palist *poola)
-{
- struct pf_pooladdr *empty_pool_pa;
-
- while ((empty_pool_pa = TAILQ_FIRST(poola)) != NULL) {
- pfi_dynaddr_remove(&empty_pool_pa->addr);
- pf_tbladdr_remove(&empty_pool_pa->addr);
- pfi_kif_unref(empty_pool_pa->kif, PFI_KIF_REF_RULE);
- TAILQ_REMOVE(poola, empty_pool_pa, entries);
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, empty_pool_pa);
-#else
- pool_put(&pf_pooladdr_pl, empty_pool_pa);
-#endif
- }
-}
-
-void
-pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
-{
- if (rulequeue != NULL) {
- if (rule->states_cur <= 0) {
- /*
- * XXX - we need to remove the table *before* detaching
- * the rule to make sure the table code does not delete
- * the anchor under our feet.
- */
- pf_tbladdr_remove(&rule->src.addr);
- pf_tbladdr_remove(&rule->dst.addr);
- if (rule->overload_tbl)
- pfr_detach_table(rule->overload_tbl);
- }
- TAILQ_REMOVE(rulequeue, rule, entries);
- rule->entries.tqe_prev = NULL;
- rule->nr = -1;
- }
-
- if (rule->states_cur > 0 || rule->src_nodes > 0 ||
- rule->entries.tqe_prev != NULL)
- return;
- pf_tag_unref(rule->tag);
- pf_tag_unref(rule->match_tag);
-#ifdef ALTQ
- if (rule->pqid != rule->qid)
- pf_qid_unref(rule->pqid);
- pf_qid_unref(rule->qid);
-#endif
- pf_rtlabel_remove(&rule->src.addr);
- pf_rtlabel_remove(&rule->dst.addr);
- pfi_dynaddr_remove(&rule->src.addr);
- pfi_dynaddr_remove(&rule->dst.addr);
- if (rulequeue == NULL) {
- pf_tbladdr_remove(&rule->src.addr);
- pf_tbladdr_remove(&rule->dst.addr);
- if (rule->overload_tbl)
- pfr_detach_table(rule->overload_tbl);
- }
- pfi_kif_unref(rule->kif, PFI_KIF_REF_RULE);
- pf_anchor_remove(rule);
- pf_empty_pool(&rule->rpool.list);
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, rule);
-#else
- pool_put(&pf_rule_pl, rule);
-#endif
-}
-
-u_int16_t
-tagname2tag(struct pf_tags *head, char *tagname)
-{
- struct pf_tagname *tag, *p = NULL;
- u_int16_t new_tagid = 1;
-
- TAILQ_FOREACH(tag, head, entries)
- if (strcmp(tagname, tag->name) == 0) {
- tag->ref++;
- return (tag->tag);
- }
-
- /*
- * to avoid fragmentation, we do a linear search from the beginning
- * and take the first free slot we find. if there is none or the list
- * is empty, append a new entry at the end.
- */
-
- /* new entry */
- if (!TAILQ_EMPTY(head))
- for (p = TAILQ_FIRST(head); p != NULL &&
- p->tag == new_tagid; p = TAILQ_NEXT(p, entries))
- new_tagid = p->tag + 1;
-
- if (new_tagid > TAGID_MAX)
- return (0);
-
- /* allocate and fill new struct pf_tagname */
- tag = malloc(sizeof(*tag), M_TEMP, M_NOWAIT|M_ZERO);
- if (tag == NULL)
- return (0);
- strlcpy(tag->name, tagname, sizeof(tag->name));
- tag->tag = new_tagid;
- tag->ref++;
-
- if (p != NULL) /* insert new entry before p */
- TAILQ_INSERT_BEFORE(p, tag, entries);
- else /* either list empty or no free slot in between */
- TAILQ_INSERT_TAIL(head, tag, entries);
-
- return (tag->tag);
-}
-
-void
-tag2tagname(struct pf_tags *head, u_int16_t tagid, char *p)
-{
- struct pf_tagname *tag;
-
- TAILQ_FOREACH(tag, head, entries)
- if (tag->tag == tagid) {
- strlcpy(p, tag->name, PF_TAG_NAME_SIZE);
- return;
- }
-}
-
-void
-tag_unref(struct pf_tags *head, u_int16_t tag)
-{
- struct pf_tagname *p, *next;
-
- if (tag == 0)
- return;
-
- for (p = TAILQ_FIRST(head); p != NULL; p = next) {
- next = TAILQ_NEXT(p, entries);
- if (tag == p->tag) {
- if (--p->ref == 0) {
- TAILQ_REMOVE(head, p, entries);
- free(p, M_TEMP);
- }
- break;
- }
- }
-}
-
-u_int16_t
-pf_tagname2tag(char *tagname)
-{
-#ifdef __FreeBSD__
- return (tagname2tag(&V_pf_tags, tagname));
-#else
- return (tagname2tag(&pf_tags, tagname));
-#endif
-}
-
-void
-pf_tag2tagname(u_int16_t tagid, char *p)
-{
-#ifdef __FreeBSD__
- tag2tagname(&V_pf_tags, tagid, p);
-#else
- tag2tagname(&pf_tags, tagid, p);
-#endif
-}
-
-void
-pf_tag_ref(u_int16_t tag)
-{
- struct pf_tagname *t;
-
-#ifdef __FreeBSD__
- TAILQ_FOREACH(t, &V_pf_tags, entries)
-#else
- TAILQ_FOREACH(t, &pf_tags, entries)
-#endif
- if (t->tag == tag)
- break;
- if (t != NULL)
- t->ref++;
-}
-
-void
-pf_tag_unref(u_int16_t tag)
-{
-#ifdef __FreeBSD__
- tag_unref(&V_pf_tags, tag);
-#else
- tag_unref(&pf_tags, tag);
-#endif
-}
-
-int
-pf_rtlabel_add(struct pf_addr_wrap *a)
-{
-#ifdef __FreeBSD__
- /* XXX_IMPORT: later */
- return (0);
-#else
- if (a->type == PF_ADDR_RTLABEL &&
- (a->v.rtlabel = rtlabel_name2id(a->v.rtlabelname)) == 0)
- return (-1);
- return (0);
-#endif
-}
-
-void
-pf_rtlabel_remove(struct pf_addr_wrap *a)
-{
-#ifdef __FreeBSD__
- /* XXX_IMPORT: later */
-#else
- if (a->type == PF_ADDR_RTLABEL)
- rtlabel_unref(a->v.rtlabel);
-#endif
-}
-
-void
-pf_rtlabel_copyout(struct pf_addr_wrap *a)
-{
-#ifdef __FreeBSD__
- /* XXX_IMPORT: later */
- if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel)
- strlcpy(a->v.rtlabelname, "?", sizeof(a->v.rtlabelname));
-#else
- const char *name;
-
- if (a->type == PF_ADDR_RTLABEL && a->v.rtlabel) {
- if ((name = rtlabel_id2name(a->v.rtlabel)) == NULL)
- strlcpy(a->v.rtlabelname, "?",
- sizeof(a->v.rtlabelname));
- else
- strlcpy(a->v.rtlabelname, name,
- sizeof(a->v.rtlabelname));
- }
-#endif
-}
-
-#ifdef ALTQ
-u_int32_t
-pf_qname2qid(char *qname)
-{
-#ifdef __FreeBSD__
- return ((u_int32_t)tagname2tag(&V_pf_qids, qname));
-#else
- return ((u_int32_t)tagname2tag(&pf_qids, qname));
-#endif
-}
-
-void
-pf_qid2qname(u_int32_t qid, char *p)
-{
-#ifdef __FreeBSD__
- tag2tagname(&V_pf_qids, (u_int16_t)qid, p);
-#else
- tag2tagname(&pf_qids, (u_int16_t)qid, p);
-#endif
-}
-
-void
-pf_qid_unref(u_int32_t qid)
-{
-#ifdef __FreeBSD__
- tag_unref(&V_pf_qids, (u_int16_t)qid);
-#else
- tag_unref(&pf_qids, (u_int16_t)qid);
-#endif
-}
-
-int
-pf_begin_altq(u_int32_t *ticket)
-{
- struct pf_altq *altq;
- int error = 0;
-
- /* Purge the old altq list */
-#ifdef __FreeBSD__
- while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)) != NULL) {
- TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries);
- if (altq->qname[0] == 0 &&
- (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
-#else
- while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) {
- TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
- if (altq->qname[0] == 0) {
-#endif
- /* detach and destroy the discipline */
- error = altq_remove(altq);
- } else
- pf_qid_unref(altq->qid);
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, altq);
-#else
- pool_put(&pf_altq_pl, altq);
-#endif
- }
- if (error)
- return (error);
-#ifdef __FreeBSD__
- *ticket = ++V_ticket_altqs_inactive;
- V_altqs_inactive_open = 1;
-#else
- *ticket = ++ticket_altqs_inactive;
- altqs_inactive_open = 1;
-#endif
- return (0);
-}
-
-int
-pf_rollback_altq(u_int32_t ticket)
-{
- struct pf_altq *altq;
- int error = 0;
-
-#ifdef __FreeBSD__
- if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
- return (0);
- /* Purge the old altq list */
- while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)) != NULL) {
- TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries);
- if (altq->qname[0] == 0 &&
- (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
-#else
- if (!altqs_inactive_open || ticket != ticket_altqs_inactive)
- return (0);
- /* Purge the old altq list */
- while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) {
- TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
- if (altq->qname[0] == 0) {
-#endif
- /* detach and destroy the discipline */
- error = altq_remove(altq);
- } else
- pf_qid_unref(altq->qid);
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, altq);
-#else
- pool_put(&pf_altq_pl, altq);
-#endif
- }
-#ifdef __FreeBSD__
- V_altqs_inactive_open = 0;
-#else
- altqs_inactive_open = 0;
-#endif
- return (error);
-}
-
-int
-pf_commit_altq(u_int32_t ticket)
-{
- struct pf_altqqueue *old_altqs;
- struct pf_altq *altq;
- int s, err, error = 0;
-
-#ifdef __FreeBSD__
- if (!V_altqs_inactive_open || ticket != V_ticket_altqs_inactive)
-#else
- if (!altqs_inactive_open || ticket != ticket_altqs_inactive)
-#endif
- return (EBUSY);
-
- /* swap altqs, keep the old. */
- s = splsoftnet();
-#ifdef __FreeBSD__
- old_altqs = V_pf_altqs_active;
- V_pf_altqs_active = V_pf_altqs_inactive;
- V_pf_altqs_inactive = old_altqs;
- V_ticket_altqs_active = V_ticket_altqs_inactive;
-#else
- old_altqs = pf_altqs_active;
- pf_altqs_active = pf_altqs_inactive;
- pf_altqs_inactive = old_altqs;
- ticket_altqs_active = ticket_altqs_inactive;
-#endif
-
- /* Attach new disciplines */
-#ifdef __FreeBSD__
- TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
- if (altq->qname[0] == 0 &&
- (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
-#else
- TAILQ_FOREACH(altq, pf_altqs_active, entries) {
- if (altq->qname[0] == 0) {
-#endif
- /* attach the discipline */
- error = altq_pfattach(altq);
-#ifdef __FreeBSD__
- if (error == 0 && V_pf_altq_running)
-#else
- if (error == 0 && pf_altq_running)
-#endif
- error = pf_enable_altq(altq);
- if (error != 0) {
- splx(s);
- return (error);
- }
- }
- }
-
- /* Purge the old altq list */
-#ifdef __FreeBSD__
- while ((altq = TAILQ_FIRST(V_pf_altqs_inactive)) != NULL) {
- TAILQ_REMOVE(V_pf_altqs_inactive, altq, entries);
- if (altq->qname[0] == 0 &&
- (altq->local_flags & PFALTQ_FLAG_IF_REMOVED) == 0) {
-#else
- while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) {
- TAILQ_REMOVE(pf_altqs_inactive, altq, entries);
- if (altq->qname[0] == 0) {
-#endif
- /* detach and destroy the discipline */
-#ifdef __FreeBSD__
- if (V_pf_altq_running)
-#else
- if (pf_altq_running)
-#endif
- error = pf_disable_altq(altq);
- err = altq_pfdetach(altq);
- if (err != 0 && error == 0)
- error = err;
- err = altq_remove(altq);
- if (err != 0 && error == 0)
- error = err;
- } else
- pf_qid_unref(altq->qid);
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, altq);
-#else
- pool_put(&pf_altq_pl, altq);
-#endif
- }
- splx(s);
-
-#ifdef __FreeBSD__
- V_altqs_inactive_open = 0;
-#else
- altqs_inactive_open = 0;
-#endif
- return (error);
-}
-
-int
-pf_enable_altq(struct pf_altq *altq)
-{
- struct ifnet *ifp;
- struct tb_profile tb;
- int s, error = 0;
-
- if ((ifp = ifunit(altq->ifname)) == NULL)
- return (EINVAL);
-
- if (ifp->if_snd.altq_type != ALTQT_NONE)
- error = altq_enable(&ifp->if_snd);
-
- /* set tokenbucket regulator */
- if (error == 0 && ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
- tb.rate = altq->ifbandwidth;
- tb.depth = altq->tbrsize;
- s = splnet();
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- error = tbr_set(&ifp->if_snd, &tb);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- splx(s);
- }
-
- return (error);
-}
-
-int
-pf_disable_altq(struct pf_altq *altq)
-{
- struct ifnet *ifp;
- struct tb_profile tb;
- int s, error;
-
- if ((ifp = ifunit(altq->ifname)) == NULL)
- return (EINVAL);
-
- /*
- * when the discipline is no longer referenced, it was overridden
- * by a new one. if so, just return.
- */
- if (altq->altq_disc != ifp->if_snd.altq_disc)
- return (0);
-
- error = altq_disable(&ifp->if_snd);
-
- if (error == 0) {
- /* clear tokenbucket regulator */
- tb.rate = 0;
- s = splnet();
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- error = tbr_set(&ifp->if_snd, &tb);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- splx(s);
- }
-
- return (error);
-}
-
-#ifdef __FreeBSD__
-void
-pf_altq_ifnet_event(struct ifnet *ifp, int remove)
-{
- struct ifnet *ifp1;
- struct pf_altq *a1, *a2, *a3;
- u_int32_t ticket;
- int error = 0;
-
- /* Interrupt userland queue modifications */
-#ifdef __FreeBSD__
- if (V_altqs_inactive_open)
- pf_rollback_altq(V_ticket_altqs_inactive);
-#else
- if (altqs_inactive_open)
- pf_rollback_altq(ticket_altqs_inactive);
-#endif
-
- /* Start new altq ruleset */
- if (pf_begin_altq(&ticket))
- return;
-
- /* Copy the current active set */
-#ifdef __FreeBSD__
- TAILQ_FOREACH(a1, V_pf_altqs_active, entries) {
- a2 = pool_get(&V_pf_altq_pl, PR_NOWAIT);
-#else
- TAILQ_FOREACH(a1, pf_altqs_active, entries) {
- a2 = pool_get(&pf_altq_pl, PR_NOWAIT);
-#endif
- if (a2 == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(a1, a2, sizeof(struct pf_altq));
-
- if (a2->qname[0] != 0) {
- if ((a2->qid = pf_qname2qid(a2->qname)) == 0) {
- error = EBUSY;
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, a2);
-#else
- pool_put(&pf_altq_pl, a2);
-#endif
- break;
- }
- a2->altq_disc = NULL;
-#ifdef __FreeBSD__
- TAILQ_FOREACH(a3, V_pf_altqs_inactive, entries) {
-#else
- TAILQ_FOREACH(a3, pf_altqs_inactive, entries) {
-#endif
- if (strncmp(a3->ifname, a2->ifname,
- IFNAMSIZ) == 0 && a3->qname[0] == 0) {
- a2->altq_disc = a3->altq_disc;
- break;
- }
- }
- }
- /* Deactivate the interface in question */
- a2->local_flags &= ~PFALTQ_FLAG_IF_REMOVED;
- if ((ifp1 = ifunit(a2->ifname)) == NULL ||
- (remove && ifp1 == ifp)) {
- a2->local_flags |= PFALTQ_FLAG_IF_REMOVED;
- } else {
- PF_UNLOCK();
- error = altq_add(a2);
- PF_LOCK();
-
-#ifdef __FreeBSD__
- if (ticket != V_ticket_altqs_inactive)
-#else
- if (ticket != ticket_altqs_inactive)
-#endif
- error = EBUSY;
-
- if (error) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, a2);
-#else
- pool_put(&pf_altq_pl, a2);
-#endif
- break;
- }
- }
-
-#ifdef __FreeBSD__
- TAILQ_INSERT_TAIL(V_pf_altqs_inactive, a2, entries);
-#else
- TAILQ_INSERT_TAIL(pf_altqs_inactive, a2, entries);
-#endif
- }
-
- if (error != 0)
- pf_rollback_altq(ticket);
- else
- pf_commit_altq(ticket);
- }
-#endif
-#endif /* ALTQ */
-
-int
-pf_begin_rules(u_int32_t *ticket, int rs_num, const char *anchor)
-{
- struct pf_ruleset *rs;
- struct pf_rule *rule;
-
- if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
- return (EINVAL);
- rs = pf_find_or_create_ruleset(anchor);
- if (rs == NULL)
- return (EINVAL);
- while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
- pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
- rs->rules[rs_num].inactive.rcount--;
- }
- *ticket = ++rs->rules[rs_num].inactive.ticket;
- rs->rules[rs_num].inactive.open = 1;
- return (0);
-}
-
-int
-pf_rollback_rules(u_int32_t ticket, int rs_num, char *anchor)
-{
- struct pf_ruleset *rs;
- struct pf_rule *rule;
-
- if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
- return (EINVAL);
- rs = pf_find_ruleset(anchor);
- if (rs == NULL || !rs->rules[rs_num].inactive.open ||
- rs->rules[rs_num].inactive.ticket != ticket)
- return (0);
- while ((rule = TAILQ_FIRST(rs->rules[rs_num].inactive.ptr)) != NULL) {
- pf_rm_rule(rs->rules[rs_num].inactive.ptr, rule);
- rs->rules[rs_num].inactive.rcount--;
- }
- rs->rules[rs_num].inactive.open = 0;
- return (0);
-}
-
-#define PF_MD5_UPD(st, elm) \
- MD5Update(ctx, (u_int8_t *) &(st)->elm, sizeof((st)->elm))
-
-#define PF_MD5_UPD_STR(st, elm) \
- MD5Update(ctx, (u_int8_t *) (st)->elm, strlen((st)->elm))
-
-#define PF_MD5_UPD_HTONL(st, elm, stor) do { \
- (stor) = htonl((st)->elm); \
- MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int32_t));\
-} while (0)
-
-#define PF_MD5_UPD_HTONS(st, elm, stor) do { \
- (stor) = htons((st)->elm); \
- MD5Update(ctx, (u_int8_t *) &(stor), sizeof(u_int16_t));\
-} while (0)
-
-void
-pf_hash_rule_addr(MD5_CTX *ctx, struct pf_rule_addr *pfr)
-{
- PF_MD5_UPD(pfr, addr.type);
- switch (pfr->addr.type) {
- case PF_ADDR_DYNIFTL:
- PF_MD5_UPD(pfr, addr.v.ifname);
- PF_MD5_UPD(pfr, addr.iflags);
- break;
- case PF_ADDR_TABLE:
- PF_MD5_UPD(pfr, addr.v.tblname);
- break;
- case PF_ADDR_ADDRMASK:
- /* XXX ignore af? */
- PF_MD5_UPD(pfr, addr.v.a.addr.addr32);
- PF_MD5_UPD(pfr, addr.v.a.mask.addr32);
- break;
- case PF_ADDR_RTLABEL:
- PF_MD5_UPD(pfr, addr.v.rtlabelname);
- break;
- }
-
- PF_MD5_UPD(pfr, port[0]);
- PF_MD5_UPD(pfr, port[1]);
- PF_MD5_UPD(pfr, neg);
- PF_MD5_UPD(pfr, port_op);
-}
-
-void
-pf_hash_rule(MD5_CTX *ctx, struct pf_rule *rule)
-{
- u_int16_t x;
- u_int32_t y;
-
- pf_hash_rule_addr(ctx, &rule->src);
- pf_hash_rule_addr(ctx, &rule->dst);
- PF_MD5_UPD_STR(rule, label);
- PF_MD5_UPD_STR(rule, ifname);
- PF_MD5_UPD_STR(rule, match_tagname);
- PF_MD5_UPD_HTONS(rule, match_tag, x); /* dup? */
- PF_MD5_UPD_HTONL(rule, os_fingerprint, y);
- PF_MD5_UPD_HTONL(rule, prob, y);
- PF_MD5_UPD_HTONL(rule, uid.uid[0], y);
- PF_MD5_UPD_HTONL(rule, uid.uid[1], y);
- PF_MD5_UPD(rule, uid.op);
- PF_MD5_UPD_HTONL(rule, gid.gid[0], y);
- PF_MD5_UPD_HTONL(rule, gid.gid[1], y);
- PF_MD5_UPD(rule, gid.op);
- PF_MD5_UPD_HTONL(rule, rule_flag, y);
- PF_MD5_UPD(rule, action);
- PF_MD5_UPD(rule, direction);
- PF_MD5_UPD(rule, af);
- PF_MD5_UPD(rule, quick);
- PF_MD5_UPD(rule, ifnot);
- PF_MD5_UPD(rule, match_tag_not);
- PF_MD5_UPD(rule, natpass);
- PF_MD5_UPD(rule, keep_state);
- PF_MD5_UPD(rule, proto);
- PF_MD5_UPD(rule, type);
- PF_MD5_UPD(rule, code);
- PF_MD5_UPD(rule, flags);
- PF_MD5_UPD(rule, flagset);
- PF_MD5_UPD(rule, allow_opts);
- PF_MD5_UPD(rule, rt);
- PF_MD5_UPD(rule, tos);
-}
-
-int
-pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
-{
- struct pf_ruleset *rs;
- struct pf_rule *rule, **old_array;
- struct pf_rulequeue *old_rules;
- int s, error;
- u_int32_t old_rcount;
-
- if (rs_num < 0 || rs_num >= PF_RULESET_MAX)
- return (EINVAL);
- rs = pf_find_ruleset(anchor);
- if (rs == NULL || !rs->rules[rs_num].inactive.open ||
- ticket != rs->rules[rs_num].inactive.ticket)
- return (EBUSY);
-
- /* Calculate checksum for the main ruleset */
- if (rs == &pf_main_ruleset) {
- error = pf_setup_pfsync_matching(rs);
- if (error != 0)
- return (error);
- }
-
- /* Swap rules, keep the old. */
- s = splsoftnet();
- old_rules = rs->rules[rs_num].active.ptr;
- old_rcount = rs->rules[rs_num].active.rcount;
- old_array = rs->rules[rs_num].active.ptr_array;
-
- rs->rules[rs_num].active.ptr =
- rs->rules[rs_num].inactive.ptr;
- rs->rules[rs_num].active.ptr_array =
- rs->rules[rs_num].inactive.ptr_array;
- rs->rules[rs_num].active.rcount =
- rs->rules[rs_num].inactive.rcount;
- rs->rules[rs_num].inactive.ptr = old_rules;
- rs->rules[rs_num].inactive.ptr_array = old_array;
- rs->rules[rs_num].inactive.rcount = old_rcount;
-
- rs->rules[rs_num].active.ticket =
- rs->rules[rs_num].inactive.ticket;
- pf_calc_skip_steps(rs->rules[rs_num].active.ptr);
-
-
- /* Purge the old rule list. */
- while ((rule = TAILQ_FIRST(old_rules)) != NULL)
- pf_rm_rule(old_rules, rule);
- if (rs->rules[rs_num].inactive.ptr_array)
- free(rs->rules[rs_num].inactive.ptr_array, M_TEMP);
- rs->rules[rs_num].inactive.ptr_array = NULL;
- rs->rules[rs_num].inactive.rcount = 0;
- rs->rules[rs_num].inactive.open = 0;
- pf_remove_if_empty_ruleset(rs);
- splx(s);
- return (0);
-}
-
-int
-pf_setup_pfsync_matching(struct pf_ruleset *rs)
-{
- MD5_CTX ctx;
- struct pf_rule *rule;
- int rs_cnt;
- u_int8_t digest[PF_MD5_DIGEST_LENGTH];
-
- MD5Init(&ctx);
- for (rs_cnt = 0; rs_cnt < PF_RULESET_MAX; rs_cnt++) {
- /* XXX PF_RULESET_SCRUB as well? */
- if (rs_cnt == PF_RULESET_SCRUB)
- continue;
-
- if (rs->rules[rs_cnt].inactive.ptr_array)
- free(rs->rules[rs_cnt].inactive.ptr_array, M_TEMP);
- rs->rules[rs_cnt].inactive.ptr_array = NULL;
-
- if (rs->rules[rs_cnt].inactive.rcount) {
- rs->rules[rs_cnt].inactive.ptr_array =
- malloc(sizeof(caddr_t) *
- rs->rules[rs_cnt].inactive.rcount,
- M_TEMP, M_NOWAIT);
-
- if (!rs->rules[rs_cnt].inactive.ptr_array)
- return (ENOMEM);
- }
-
- TAILQ_FOREACH(rule, rs->rules[rs_cnt].inactive.ptr,
- entries) {
- pf_hash_rule(&ctx, rule);
- (rs->rules[rs_cnt].inactive.ptr_array)[rule->nr] = rule;
- }
- }
-
- MD5Final(digest, &ctx);
-#ifdef __FreeBSD__
- memcpy(V_pf_status.pf_chksum, digest, sizeof(V_pf_status.pf_chksum));
-#else
- memcpy(pf_status.pf_chksum, digest, sizeof(pf_status.pf_chksum));
-#endif
- return (0);
-}
-
-int
-pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr,
- sa_family_t af)
-{
- if (pfi_dynaddr_setup(addr, af) ||
- pf_tbladdr_setup(ruleset, addr))
- return (EINVAL);
-
- return (0);
-}
-
-void
-pf_addr_copyout(struct pf_addr_wrap *addr)
-{
- pfi_dynaddr_copyout(addr);
- pf_tbladdr_copyout(addr);
- pf_rtlabel_copyout(addr);
-}
-
-int
-#ifdef __FreeBSD__
-pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
-#else
-pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
-#endif
-{
- struct pf_pooladdr *pa = NULL;
- struct pf_pool *pool = NULL;
-#ifndef __FreeBSD__
- int s;
-#endif
- int error = 0;
-
- CURVNET_SET(TD_TO_VNET(td));
-
- /* XXX keep in sync with switch() below */
-#ifdef __FreeBSD__
- if (securelevel_gt(td->td_ucred, 2))
-#else
- if (securelevel > 1)
-#endif
- switch (cmd) {
- case DIOCGETRULES:
- case DIOCGETRULE:
- case DIOCGETADDRS:
- case DIOCGETADDR:
- case DIOCGETSTATE:
- case DIOCSETSTATUSIF:
- case DIOCGETSTATUS:
- case DIOCCLRSTATUS:
- case DIOCNATLOOK:
- case DIOCSETDEBUG:
- case DIOCGETSTATES:
- case DIOCGETTIMEOUT:
- case DIOCCLRRULECTRS:
- case DIOCGETLIMIT:
- case DIOCGETALTQS:
- case DIOCGETALTQ:
- case DIOCGETQSTATS:
- case DIOCGETRULESETS:
- case DIOCGETRULESET:
- case DIOCRGETTABLES:
- case DIOCRGETTSTATS:
- case DIOCRCLRTSTATS:
- case DIOCRCLRADDRS:
- case DIOCRADDADDRS:
- case DIOCRDELADDRS:
- case DIOCRSETADDRS:
- case DIOCRGETADDRS:
- case DIOCRGETASTATS:
- case DIOCRCLRASTATS:
- case DIOCRTSTADDRS:
- case DIOCOSFPGET:
- case DIOCGETSRCNODES:
- case DIOCCLRSRCNODES:
- case DIOCIGETIFACES:
-#ifdef __FreeBSD__
- case DIOCGIFSPEED:
-#endif
- case DIOCSETIFFLAG:
- case DIOCCLRIFFLAG:
- break;
- case DIOCRCLRTABLES:
- case DIOCRADDTABLES:
- case DIOCRDELTABLES:
- case DIOCRSETTFLAGS:
- if (((struct pfioc_table *)addr)->pfrio_flags &
- PFR_FLAG_DUMMY)
- break; /* dummy operation ok */
- return (EPERM);
- default:
- return (EPERM);
- }
-
- if (!(flags & FWRITE))
- switch (cmd) {
- case DIOCGETRULES:
- case DIOCGETADDRS:
- case DIOCGETADDR:
- case DIOCGETSTATE:
- case DIOCGETSTATUS:
- case DIOCGETSTATES:
- case DIOCGETTIMEOUT:
- case DIOCGETLIMIT:
- case DIOCGETALTQS:
- case DIOCGETALTQ:
- case DIOCGETQSTATS:
- case DIOCGETRULESETS:
- case DIOCGETRULESET:
- case DIOCNATLOOK:
- case DIOCRGETTABLES:
- case DIOCRGETTSTATS:
- case DIOCRGETADDRS:
- case DIOCRGETASTATS:
- case DIOCRTSTADDRS:
- case DIOCOSFPGET:
- case DIOCGETSRCNODES:
- case DIOCIGETIFACES:
-#ifdef __FreeBSD__
- case DIOCGIFSPEED:
-#endif
- break;
- case DIOCRCLRTABLES:
- case DIOCRADDTABLES:
- case DIOCRDELTABLES:
- case DIOCRCLRTSTATS:
- case DIOCRCLRADDRS:
- case DIOCRADDADDRS:
- case DIOCRDELADDRS:
- case DIOCRSETADDRS:
- case DIOCRSETTFLAGS:
- if (((struct pfioc_table *)addr)->pfrio_flags &
- PFR_FLAG_DUMMY) {
- flags |= FWRITE; /* need write lock for dummy */
- break; /* dummy operation ok */
- }
- return (EACCES);
- case DIOCGETRULE:
- if (((struct pfioc_rule *)addr)->action ==
- PF_GET_CLR_CNTR)
- return (EACCES);
- break;
- default:
- return (EACCES);
- }
-
- if (flags & FWRITE)
-#ifdef __FreeBSD__
- sx_xlock(&V_pf_consistency_lock);
- else
- sx_slock(&V_pf_consistency_lock);
-#else
- rw_enter_write(&pf_consistency_lock);
- else
- rw_enter_read(&pf_consistency_lock);
-#endif
-
-#ifdef __FreeBSD__
- PF_LOCK();
-#else
- s = splsoftnet();
-#endif
- switch (cmd) {
-
- case DIOCSTART:
-#ifdef __FreeBSD__
- if (V_pf_status.running)
-#else
- if (pf_status.running)
-#endif
- error = EEXIST;
- else {
-#ifdef __FreeBSD__
- PF_UNLOCK();
- error = hook_pf();
- PF_LOCK();
- if (error) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: pfil registeration fail\n"));
- break;
- }
- V_pf_status.running = 1;
- V_pf_status.since = time_second;
-
- if (V_pf_status.stateid == 0) {
- V_pf_status.stateid = time_second;
- V_pf_status.stateid = V_pf_status.stateid << 32;
- }
-#else
- pf_status.running = 1;
- pf_status.since = time_second;
-
- if (pf_status.stateid == 0) {
- pf_status.stateid = time_second;
- pf_status.stateid = pf_status.stateid << 32;
- }
-#endif
- DPFPRINTF(PF_DEBUG_MISC, ("pf: started\n"));
- }
- break;
-
- case DIOCSTOP:
-#ifdef __FreeBSD__
- if (!V_pf_status.running)
- error = ENOENT;
- else {
- V_pf_status.running = 0;
- PF_UNLOCK();
- error = dehook_pf();
- PF_LOCK();
- if (error) {
- V_pf_status.running = 1;
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: pfil unregisteration failed\n"));
- }
- V_pf_status.since = time_second;
-#else
- if (!pf_status.running)
- error = ENOENT;
- else {
- pf_status.running = 0;
- pf_status.since = time_second;
-#endif
- DPFPRINTF(PF_DEBUG_MISC, ("pf: stopped\n"));
- }
- break;
-
- case DIOCADDRULE: {
- struct pfioc_rule *pr = (struct pfioc_rule *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rule *rule, *tail;
- struct pf_pooladdr *pa;
- int rs_num;
-
- pr->anchor[sizeof(pr->anchor) - 1] = 0;
- ruleset = pf_find_ruleset(pr->anchor);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- rs_num = pf_get_ruleset_number(pr->rule.action);
- if (rs_num >= PF_RULESET_MAX) {
- error = EINVAL;
- break;
- }
- if (pr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
- error = EINVAL;
- break;
- }
- if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
-#ifdef __FreeBSD__
- DPFPRINTF(PF_DEBUG_MISC,
- ("ticket: %d != [%d]%d\n", pr->ticket, rs_num,
- ruleset->rules[rs_num].inactive.ticket));
-#endif
- error = EBUSY;
- break;
- }
-#ifdef __FreeBSD__
- if (pr->pool_ticket != V_ticket_pabuf) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pool_ticket: %d != %d\n", pr->pool_ticket,
- V_ticket_pabuf));
-#else
- if (pr->pool_ticket != ticket_pabuf) {
-#endif
- error = EBUSY;
- break;
- }
-#ifdef __FreeBSD__
- rule = pool_get(&V_pf_rule_pl, PR_NOWAIT);
-#else
- rule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL);
-#endif
- if (rule == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pr->rule, rule, sizeof(struct pf_rule));
-#ifdef __FreeBSD__
- rule->cuid = td->td_ucred->cr_ruid;
- rule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
-#else
- rule->cuid = p->p_cred->p_ruid;
- rule->cpid = p->p_pid;
-#endif
- rule->anchor = NULL;
- rule->kif = NULL;
- TAILQ_INIT(&rule->rpool.list);
- /* initialize refcounting */
- rule->states_cur = 0;
- rule->src_nodes = 0;
- rule->entries.tqe_prev = NULL;
-#ifndef INET
- if (rule->af == AF_INET) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, rule);
-#else
- pool_put(&pf_rule_pl, rule);
-#endif
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (rule->af == AF_INET6) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, rule);
-#else
- pool_put(&pf_rule_pl, rule);
-#endif
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
- pf_rulequeue);
- if (tail)
- rule->nr = tail->nr + 1;
- else
- rule->nr = 0;
- if (rule->ifname[0]) {
- rule->kif = pfi_kif_get(rule->ifname);
- if (rule->kif == NULL) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, rule);
-#else
- pool_put(&pf_rule_pl, rule);
-#endif
- error = EINVAL;
- break;
- }
- pfi_kif_ref(rule->kif, PFI_KIF_REF_RULE);
- }
-
-#ifdef __FreeBSD__ /* ROUTING */
- if (rule->rtableid > 0 && rule->rtableid >= rt_numfibs)
-#else
- if (rule->rtableid > 0 && !rtable_exists(rule->rtableid))
-#endif
- error = EBUSY;
-
-#ifdef ALTQ
- /* set queue IDs */
- if (rule->qname[0] != 0) {
- if ((rule->qid = pf_qname2qid(rule->qname)) == 0)
- error = EBUSY;
- else if (rule->pqname[0] != 0) {
- if ((rule->pqid =
- pf_qname2qid(rule->pqname)) == 0)
- error = EBUSY;
- } else
- rule->pqid = rule->qid;
- }
-#endif
- if (rule->tagname[0])
- if ((rule->tag = pf_tagname2tag(rule->tagname)) == 0)
- error = EBUSY;
- if (rule->match_tagname[0])
- if ((rule->match_tag =
- pf_tagname2tag(rule->match_tagname)) == 0)
- error = EBUSY;
- if (rule->rt && !rule->direction)
- error = EINVAL;
-#if NPFLOG > 0
- if (!rule->log)
- rule->logif = 0;
- if (rule->logif >= PFLOGIFS_MAX)
- error = EINVAL;
-#endif
- if (pf_rtlabel_add(&rule->src.addr) ||
- pf_rtlabel_add(&rule->dst.addr))
- error = EBUSY;
- if (pf_addr_setup(ruleset, &rule->src.addr, rule->af))
- error = EINVAL;
- if (pf_addr_setup(ruleset, &rule->dst.addr, rule->af))
- error = EINVAL;
- if (pf_anchor_setup(rule, ruleset, pr->anchor_call))
- error = EINVAL;
-#ifdef __FreeBSD__
- TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
-#else
- TAILQ_FOREACH(pa, &pf_pabuf, entries)
-#endif
- if (pf_tbladdr_setup(ruleset, &pa->addr))
- error = EINVAL;
-
- if (rule->overload_tblname[0]) {
- if ((rule->overload_tbl = pfr_attach_table(ruleset,
- rule->overload_tblname, 0)) == NULL)
- error = EINVAL;
- else
- rule->overload_tbl->pfrkt_flags |=
- PFR_TFLAG_ACTIVE;
- }
-
-#ifdef __FreeBSD__
- pf_mv_pool(&V_pf_pabuf, &rule->rpool.list);
-#else
- pf_mv_pool(&pf_pabuf, &rule->rpool.list);
-#endif
- if (((((rule->action == PF_NAT) || (rule->action == PF_RDR) ||
- (rule->action == PF_BINAT)) && rule->anchor == NULL) ||
- (rule->rt > PF_FASTROUTE)) &&
- (TAILQ_FIRST(&rule->rpool.list) == NULL))
- error = EINVAL;
-
- if (error) {
- pf_rm_rule(NULL, rule);
- break;
- }
-
-#ifdef __FreeBSD__
- if (!V_debug_pfugidhack && (rule->uid.op || rule->gid.op ||
- rule->log & PF_LOG_SOCKET_LOOKUP)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: debug.pfugidhack enabled\n"));
- V_debug_pfugidhack = 1;
- }
-#endif
- rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
- rule->evaluations = rule->packets[0] = rule->packets[1] =
- rule->bytes[0] = rule->bytes[1] = 0;
- TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
- rule, entries);
- ruleset->rules[rs_num].inactive.rcount++;
- break;
- }
-
- case DIOCGETRULES: {
- struct pfioc_rule *pr = (struct pfioc_rule *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rule *tail;
- int rs_num;
-
- pr->anchor[sizeof(pr->anchor) - 1] = 0;
- ruleset = pf_find_ruleset(pr->anchor);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- rs_num = pf_get_ruleset_number(pr->rule.action);
- if (rs_num >= PF_RULESET_MAX) {
- error = EINVAL;
- break;
- }
- tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
- pf_rulequeue);
- if (tail)
- pr->nr = tail->nr + 1;
- else
- pr->nr = 0;
- pr->ticket = ruleset->rules[rs_num].active.ticket;
- break;
- }
-
- case DIOCGETRULE: {
- struct pfioc_rule *pr = (struct pfioc_rule *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rule *rule;
- int rs_num, i;
-
- pr->anchor[sizeof(pr->anchor) - 1] = 0;
- ruleset = pf_find_ruleset(pr->anchor);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- rs_num = pf_get_ruleset_number(pr->rule.action);
- if (rs_num >= PF_RULESET_MAX) {
- error = EINVAL;
- break;
- }
- if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
- error = EBUSY;
- break;
- }
- rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
- while ((rule != NULL) && (rule->nr != pr->nr))
- rule = TAILQ_NEXT(rule, entries);
- if (rule == NULL) {
- error = EBUSY;
- break;
- }
- bcopy(rule, &pr->rule, sizeof(struct pf_rule));
- if (pf_anchor_copyout(ruleset, rule, pr)) {
- error = EBUSY;
- break;
- }
- pf_addr_copyout(&pr->rule.src.addr);
- pf_addr_copyout(&pr->rule.dst.addr);
- for (i = 0; i < PF_SKIP_COUNT; ++i)
- if (rule->skip[i].ptr == NULL)
- pr->rule.skip[i].nr = -1;
- else
- pr->rule.skip[i].nr =
- rule->skip[i].ptr->nr;
-
- if (pr->action == PF_GET_CLR_CNTR) {
- rule->evaluations = 0;
- rule->packets[0] = rule->packets[1] = 0;
- rule->bytes[0] = rule->bytes[1] = 0;
- rule->states_tot = 0;
- }
- break;
- }
-
- case DIOCCHANGERULE: {
- struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rule *oldrule = NULL, *newrule = NULL;
- u_int32_t nr = 0;
- int rs_num;
-
- if (!(pcr->action == PF_CHANGE_REMOVE ||
- pcr->action == PF_CHANGE_GET_TICKET) &&
-#ifdef __FreeBSD__
- pcr->pool_ticket != V_ticket_pabuf) {
-#else
- pcr->pool_ticket != ticket_pabuf) {
-#endif
- error = EBUSY;
- break;
- }
-
- if (pcr->action < PF_CHANGE_ADD_HEAD ||
- pcr->action > PF_CHANGE_GET_TICKET) {
- error = EINVAL;
- break;
- }
- ruleset = pf_find_ruleset(pcr->anchor);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- rs_num = pf_get_ruleset_number(pcr->rule.action);
- if (rs_num >= PF_RULESET_MAX) {
- error = EINVAL;
- break;
- }
-
- if (pcr->action == PF_CHANGE_GET_TICKET) {
- pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
- break;
- } else {
- if (pcr->ticket !=
- ruleset->rules[rs_num].active.ticket) {
- error = EINVAL;
- break;
- }
- if (pcr->rule.return_icmp >> 8 > ICMP_MAXTYPE) {
- error = EINVAL;
- break;
- }
- }
-
- if (pcr->action != PF_CHANGE_REMOVE) {
-#ifdef __FreeBSD__
- newrule = pool_get(&V_pf_rule_pl, PR_NOWAIT);
-#else
- newrule = pool_get(&pf_rule_pl, PR_WAITOK|PR_LIMITFAIL);
-#endif
- if (newrule == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pcr->rule, newrule, sizeof(struct pf_rule));
-#ifdef __FreeBSD__
- newrule->cuid = td->td_ucred->cr_ruid;
- newrule->cpid = td->td_proc ? td->td_proc->p_pid : 0;
-#else
- newrule->cuid = p->p_cred->p_ruid;
- newrule->cpid = p->p_pid;
-#endif
- TAILQ_INIT(&newrule->rpool.list);
- /* initialize refcounting */
- newrule->states_cur = 0;
- newrule->entries.tqe_prev = NULL;
-#ifndef INET
- if (newrule->af == AF_INET) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, newrule);
-#else
- pool_put(&pf_rule_pl, newrule);
-#endif
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (newrule->af == AF_INET6) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, newrule);
-#else
- pool_put(&pf_rule_pl, newrule);
-#endif
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (newrule->ifname[0]) {
- newrule->kif = pfi_kif_get(newrule->ifname);
- if (newrule->kif == NULL) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_rule_pl, newrule);
-#else
- pool_put(&pf_rule_pl, newrule);
-#endif
- error = EINVAL;
- break;
- }
- pfi_kif_ref(newrule->kif, PFI_KIF_REF_RULE);
- } else
- newrule->kif = NULL;
-
- if (newrule->rtableid > 0 &&
-#ifdef __FreeBSD__ /* ROUTING */
- newrule->rtableid >= rt_numfibs)
-#else
- !rtable_exists(newrule->rtableid))
-#endif
- error = EBUSY;
-
-#ifdef ALTQ
- /* set queue IDs */
- if (newrule->qname[0] != 0) {
- if ((newrule->qid =
- pf_qname2qid(newrule->qname)) == 0)
- error = EBUSY;
- else if (newrule->pqname[0] != 0) {
- if ((newrule->pqid =
- pf_qname2qid(newrule->pqname)) == 0)
- error = EBUSY;
- } else
- newrule->pqid = newrule->qid;
- }
-#endif /* ALTQ */
- if (newrule->tagname[0])
- if ((newrule->tag =
- pf_tagname2tag(newrule->tagname)) == 0)
- error = EBUSY;
- if (newrule->match_tagname[0])
- if ((newrule->match_tag = pf_tagname2tag(
- newrule->match_tagname)) == 0)
- error = EBUSY;
- if (newrule->rt && !newrule->direction)
- error = EINVAL;
-#if NPFLOG > 0
- if (!newrule->log)
- newrule->logif = 0;
- if (newrule->logif >= PFLOGIFS_MAX)
- error = EINVAL;
-#endif
- if (pf_rtlabel_add(&newrule->src.addr) ||
- pf_rtlabel_add(&newrule->dst.addr))
- error = EBUSY;
- if (pf_addr_setup(ruleset, &newrule->src.addr, newrule->af))
- error = EINVAL;
- if (pf_addr_setup(ruleset, &newrule->dst.addr, newrule->af))
- error = EINVAL;
- if (pf_anchor_setup(newrule, ruleset, pcr->anchor_call))
- error = EINVAL;
-#ifdef __FreeBSD__
- TAILQ_FOREACH(pa, &V_pf_pabuf, entries)
-#else
- TAILQ_FOREACH(pa, &pf_pabuf, entries)
-#endif
- if (pf_tbladdr_setup(ruleset, &pa->addr))
- error = EINVAL;
-
- if (newrule->overload_tblname[0]) {
- if ((newrule->overload_tbl = pfr_attach_table(
- ruleset, newrule->overload_tblname, 0)) ==
- NULL)
- error = EINVAL;
- else
- newrule->overload_tbl->pfrkt_flags |=
- PFR_TFLAG_ACTIVE;
- }
-
-#ifdef __FreeBSD__
- pf_mv_pool(&V_pf_pabuf, &newrule->rpool.list);
-#else
- pf_mv_pool(&pf_pabuf, &newrule->rpool.list);
-#endif
- if (((((newrule->action == PF_NAT) ||
- (newrule->action == PF_RDR) ||
- (newrule->action == PF_BINAT) ||
- (newrule->rt > PF_FASTROUTE)) &&
- !newrule->anchor)) &&
- (TAILQ_FIRST(&newrule->rpool.list) == NULL))
- error = EINVAL;
-
- if (error) {
- pf_rm_rule(NULL, newrule);
- break;
- }
-
-#ifdef __FreeBSD__
- if (!V_debug_pfugidhack && (newrule->uid.op ||
- newrule->gid.op ||
- newrule->log & PF_LOG_SOCKET_LOOKUP)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: debug.pfugidhack enabled\n"));
- V_debug_pfugidhack = 1;
- }
-#endif
-
- newrule->rpool.cur = TAILQ_FIRST(&newrule->rpool.list);
- newrule->evaluations = 0;
- newrule->packets[0] = newrule->packets[1] = 0;
- newrule->bytes[0] = newrule->bytes[1] = 0;
- }
-#ifdef __FreeBSD__
- pf_empty_pool(&V_pf_pabuf);
-#else
- pf_empty_pool(&pf_pabuf);
-#endif
-
- if (pcr->action == PF_CHANGE_ADD_HEAD)
- oldrule = TAILQ_FIRST(
- ruleset->rules[rs_num].active.ptr);
- else if (pcr->action == PF_CHANGE_ADD_TAIL)
- oldrule = TAILQ_LAST(
- ruleset->rules[rs_num].active.ptr, pf_rulequeue);
- else {
- oldrule = TAILQ_FIRST(
- ruleset->rules[rs_num].active.ptr);
- while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
- oldrule = TAILQ_NEXT(oldrule, entries);
- if (oldrule == NULL) {
- if (newrule != NULL)
- pf_rm_rule(NULL, newrule);
- error = EINVAL;
- break;
- }
- }
-
- if (pcr->action == PF_CHANGE_REMOVE) {
- pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule);
- ruleset->rules[rs_num].active.rcount--;
- } else {
- if (oldrule == NULL)
- TAILQ_INSERT_TAIL(
- ruleset->rules[rs_num].active.ptr,
- newrule, entries);
- else if (pcr->action == PF_CHANGE_ADD_HEAD ||
- pcr->action == PF_CHANGE_ADD_BEFORE)
- TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
- else
- TAILQ_INSERT_AFTER(
- ruleset->rules[rs_num].active.ptr,
- oldrule, newrule, entries);
- ruleset->rules[rs_num].active.rcount++;
- }
-
- nr = 0;
- TAILQ_FOREACH(oldrule,
- ruleset->rules[rs_num].active.ptr, entries)
- oldrule->nr = nr++;
-
- ruleset->rules[rs_num].active.ticket++;
-
- pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
- pf_remove_if_empty_ruleset(ruleset);
-
- break;
- }
-
- case DIOCCLRSTATES: {
- struct pf_state *s, *nexts;
- struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
- u_int killed = 0;
-
-#ifdef __FreeBSD__
- for (s = RB_MIN(pf_state_tree_id, &V_tree_id); s; s = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, s);
-#else
- for (s = RB_MIN(pf_state_tree_id, &tree_id); s; s = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &tree_id, s);
-#endif
-
- if (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
- s->kif->pfik_name)) {
-#if NPFSYNC > 0
- /* don't send out individual delete messages */
- SET(s->state_flags, PFSTATE_NOSYNC);
-#endif
- pf_unlink_state(s);
- killed++;
- }
- }
- psk->psk_killed = killed;
-#if NPFSYNC > 0
-#ifdef __FreeBSD__
- if (pfsync_clear_states_ptr != NULL)
- pfsync_clear_states_ptr(V_pf_status.hostid, psk->psk_ifname);
-#else
- pfsync_clear_states(pf_status.hostid, psk->psk_ifname);
-#endif
-#endif
- break;
- }
-
- case DIOCKILLSTATES: {
- struct pf_state *s, *nexts;
- struct pf_state_key *sk;
- struct pf_addr *srcaddr, *dstaddr;
- u_int16_t srcport, dstport;
- struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
- u_int killed = 0;
-
- if (psk->psk_pfcmp.id) {
- if (psk->psk_pfcmp.creatorid == 0)
-#ifdef __FreeBSD__
- psk->psk_pfcmp.creatorid = V_pf_status.hostid;
-#else
- psk->psk_pfcmp.creatorid = pf_status.hostid;
-#endif
- if ((s = pf_find_state_byid(&psk->psk_pfcmp))) {
- pf_unlink_state(s);
- psk->psk_killed = 1;
- }
- break;
- }
-
-#ifdef __FreeBSD__
- for (s = RB_MIN(pf_state_tree_id, &V_tree_id); s;
- s = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &V_tree_id, s);
-#else
- for (s = RB_MIN(pf_state_tree_id, &tree_id); s;
- s = nexts) {
- nexts = RB_NEXT(pf_state_tree_id, &tree_id, s);
-#endif
- sk = s->key[PF_SK_WIRE];
-
- if (s->direction == PF_OUT) {
- srcaddr = &sk->addr[1];
- dstaddr = &sk->addr[0];
- srcport = sk->port[0];
- dstport = sk->port[0];
- } else {
- srcaddr = &sk->addr[0];
- dstaddr = &sk->addr[1];
- srcport = sk->port[0];
- dstport = sk->port[0];
- }
- if ((!psk->psk_af || sk->af == psk->psk_af)
- && (!psk->psk_proto || psk->psk_proto ==
- sk->proto) &&
- PF_MATCHA(psk->psk_src.neg,
- &psk->psk_src.addr.v.a.addr,
- &psk->psk_src.addr.v.a.mask,
- srcaddr, sk->af) &&
- PF_MATCHA(psk->psk_dst.neg,
- &psk->psk_dst.addr.v.a.addr,
- &psk->psk_dst.addr.v.a.mask,
- dstaddr, sk->af) &&
- (psk->psk_src.port_op == 0 ||
- pf_match_port(psk->psk_src.port_op,
- psk->psk_src.port[0], psk->psk_src.port[1],
- srcport)) &&
- (psk->psk_dst.port_op == 0 ||
- pf_match_port(psk->psk_dst.port_op,
- psk->psk_dst.port[0], psk->psk_dst.port[1],
- dstport)) &&
- (!psk->psk_label[0] || (s->rule.ptr->label[0] &&
- !strcmp(psk->psk_label, s->rule.ptr->label))) &&
- (!psk->psk_ifname[0] || !strcmp(psk->psk_ifname,
- s->kif->pfik_name))) {
- pf_unlink_state(s);
- killed++;
- }
- }
- psk->psk_killed = killed;
- break;
- }
-
- case DIOCADDSTATE: {
- struct pfioc_state *ps = (struct pfioc_state *)addr;
- struct pfsync_state *sp = &ps->state;
-
- if (sp->timeout >= PFTM_MAX &&
- sp->timeout != PFTM_UNTIL_PACKET) {
- error = EINVAL;
- break;
- }
-#ifdef __FreeBSD__
- if (pfsync_state_import_ptr != NULL)
- error = pfsync_state_import_ptr(sp, PFSYNC_SI_IOCTL);
-#else
- error = pfsync_state_import(sp, PFSYNC_SI_IOCTL);
-#endif
- break;
- }
-
- case DIOCGETSTATE: {
- struct pfioc_state *ps = (struct pfioc_state *)addr;
- struct pf_state *s;
- struct pf_state_cmp id_key;
-
- bcopy(ps->state.id, &id_key.id, sizeof(id_key.id));
- id_key.creatorid = ps->state.creatorid;
-
- s = pf_find_state_byid(&id_key);
- if (s == NULL) {
- error = ENOENT;
- break;
- }
-
- pfsync_state_export(&ps->state, s);
- break;
- }
-
- case DIOCGETSTATES: {
- struct pfioc_states *ps = (struct pfioc_states *)addr;
- struct pf_state *state;
- struct pfsync_state *p, *pstore;
- u_int32_t nr = 0;
-
- if (ps->ps_len == 0) {
-#ifdef __FreeBSD__
- nr = V_pf_status.states;
-#else
- nr = pf_status.states;
-#endif
- ps->ps_len = sizeof(struct pfsync_state) * nr;
- break;
- }
-
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
-
- p = ps->ps_states;
-
-#ifdef __FreeBSD__
- state = TAILQ_FIRST(&V_state_list);
-#else
- state = TAILQ_FIRST(&state_list);
-#endif
- while (state) {
- if (state->timeout != PFTM_UNLINKED) {
- if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
- break;
- pfsync_state_export(pstore, state);
-#ifdef __FreeBSD__
- PF_COPYOUT(pstore, p, sizeof(*p), error);
-#else
- error = copyout(pstore, p, sizeof(*p));
-#endif
- if (error) {
- free(pstore, M_TEMP);
- goto fail;
- }
- p++;
- nr++;
- }
- state = TAILQ_NEXT(state, entry_list);
- }
-
- ps->ps_len = sizeof(struct pfsync_state) * nr;
-
- free(pstore, M_TEMP);
- break;
- }
-
- case DIOCGETSTATUS: {
- struct pf_status *s = (struct pf_status *)addr;
-#ifdef __FreeBSD__
- bcopy(&V_pf_status, s, sizeof(struct pf_status));
-#else
- bcopy(&pf_status, s, sizeof(struct pf_status));
-#endif
- pfi_update_status(s->ifname, s);
- break;
- }
-
- case DIOCSETSTATUSIF: {
- struct pfioc_if *pi = (struct pfioc_if *)addr;
-
- if (pi->ifname[0] == 0) {
-#ifdef __FreeBSD__
- bzero(V_pf_status.ifname, IFNAMSIZ);
-#else
- bzero(pf_status.ifname, IFNAMSIZ);
-#endif
- break;
- }
-#ifdef __FreeBSD__
- strlcpy(V_pf_status.ifname, pi->ifname, IFNAMSIZ);
-#else
- strlcpy(pf_status.ifname, pi->ifname, IFNAMSIZ);
-#endif
- break;
- }
-
- case DIOCCLRSTATUS: {
-#ifdef __FreeBSD__
- bzero(V_pf_status.counters, sizeof(V_pf_status.counters));
- bzero(V_pf_status.fcounters, sizeof(V_pf_status.fcounters));
- bzero(V_pf_status.scounters, sizeof(V_pf_status.scounters));
- V_pf_status.since = time_second;
- if (*V_pf_status.ifname)
- pfi_update_status(V_pf_status.ifname, NULL);
-#else
- bzero(pf_status.counters, sizeof(pf_status.counters));
- bzero(pf_status.fcounters, sizeof(pf_status.fcounters));
- bzero(pf_status.scounters, sizeof(pf_status.scounters));
- pf_status.since = time_second;
- if (*pf_status.ifname)
- pfi_update_status(pf_status.ifname, NULL);
-#endif
- break;
- }
-
- case DIOCNATLOOK: {
- struct pfioc_natlook *pnl = (struct pfioc_natlook *)addr;
- struct pf_state_key *sk;
- struct pf_state *state;
- struct pf_state_key_cmp key;
- int m = 0, direction = pnl->direction;
- int sidx, didx;
-
- /* NATLOOK src and dst are reversed, so reverse sidx/didx */
- sidx = (direction == PF_IN) ? 1 : 0;
- didx = (direction == PF_IN) ? 0 : 1;
-
- if (!pnl->proto ||
- PF_AZERO(&pnl->saddr, pnl->af) ||
- PF_AZERO(&pnl->daddr, pnl->af) ||
- ((pnl->proto == IPPROTO_TCP ||
- pnl->proto == IPPROTO_UDP) &&
- (!pnl->dport || !pnl->sport)))
- error = EINVAL;
- else {
- key.af = pnl->af;
- key.proto = pnl->proto;
- PF_ACPY(&key.addr[sidx], &pnl->saddr, pnl->af);
- key.port[sidx] = pnl->sport;
- PF_ACPY(&key.addr[didx], &pnl->daddr, pnl->af);
- key.port[didx] = pnl->dport;
-
- state = pf_find_state_all(&key, direction, &m);
-
- if (m > 1)
- error = E2BIG; /* more than one state */
- else if (state != NULL) {
- sk = state->key[sidx];
- PF_ACPY(&pnl->rsaddr, &sk->addr[sidx], sk->af);
- pnl->rsport = sk->port[sidx];
- PF_ACPY(&pnl->rdaddr, &sk->addr[didx], sk->af);
- pnl->rdport = sk->port[didx];
- } else
- error = ENOENT;
- }
- break;
- }
-
- case DIOCSETTIMEOUT: {
- struct pfioc_tm *pt = (struct pfioc_tm *)addr;
- int old;
-
- if (pt->timeout < 0 || pt->timeout >= PFTM_MAX ||
- pt->seconds < 0) {
- error = EINVAL;
- goto fail;
- }
-#ifdef __FreeBSD__
- old = V_pf_default_rule.timeout[pt->timeout];
-#else
- old = pf_default_rule.timeout[pt->timeout];
-#endif
- if (pt->timeout == PFTM_INTERVAL && pt->seconds == 0)
- pt->seconds = 1;
-#ifdef __FreeBSD__
- V_pf_default_rule.timeout[pt->timeout] = pt->seconds;
-#else
- pf_default_rule.timeout[pt->timeout] = pt->seconds;
-#endif
- if (pt->timeout == PFTM_INTERVAL && pt->seconds < old)
- wakeup(pf_purge_thread);
- pt->seconds = old;
- break;
- }
-
- case DIOCGETTIMEOUT: {
- struct pfioc_tm *pt = (struct pfioc_tm *)addr;
-
- if (pt->timeout < 0 || pt->timeout >= PFTM_MAX) {
- error = EINVAL;
- goto fail;
- }
-#ifdef __FreeBSD__
- pt->seconds = V_pf_default_rule.timeout[pt->timeout];
-#else
- pt->seconds = pf_default_rule.timeout[pt->timeout];
-#endif
- break;
- }
-
- case DIOCGETLIMIT: {
- struct pfioc_limit *pl = (struct pfioc_limit *)addr;
-
- if (pl->index < 0 || pl->index >= PF_LIMIT_MAX) {
- error = EINVAL;
- goto fail;
- }
-#ifdef __FreeBSD__
- pl->limit = V_pf_pool_limits[pl->index].limit;
-#else
- pl->limit = pf_pool_limits[pl->index].limit;
-#endif
- break;
- }
-
- case DIOCSETLIMIT: {
- struct pfioc_limit *pl = (struct pfioc_limit *)addr;
- int old_limit;
-
- if (pl->index < 0 || pl->index >= PF_LIMIT_MAX ||
-#ifdef __FreeBSD__
- V_pf_pool_limits[pl->index].pp == NULL) {
-#else
- pf_pool_limits[pl->index].pp == NULL) {
-#endif
- error = EINVAL;
- goto fail;
- }
-#ifdef __FreeBSD__
- uma_zone_set_max(V_pf_pool_limits[pl->index].pp, pl->limit);
- old_limit = V_pf_pool_limits[pl->index].limit;
- V_pf_pool_limits[pl->index].limit = pl->limit;
- pl->limit = old_limit;
-#else
- if (pool_sethardlimit(pf_pool_limits[pl->index].pp,
- pl->limit, NULL, 0) != 0) {
- error = EBUSY;
- goto fail;
- }
- old_limit = pf_pool_limits[pl->index].limit;
- pf_pool_limits[pl->index].limit = pl->limit;
- pl->limit = old_limit;
-#endif
- break;
- }
-
- case DIOCSETDEBUG: {
- u_int32_t *level = (u_int32_t *)addr;
-
-#ifdef __FreeBSD__
- V_pf_status.debug = *level;
-#else
- pf_status.debug = *level;
-#endif
- break;
- }
-
- case DIOCCLRRULECTRS: {
- /* obsoleted by DIOCGETRULE with action=PF_GET_CLR_CNTR */
- struct pf_ruleset *ruleset = &pf_main_ruleset;
- struct pf_rule *rule;
-
- TAILQ_FOREACH(rule,
- ruleset->rules[PF_RULESET_FILTER].active.ptr, entries) {
- rule->evaluations = 0;
- rule->packets[0] = rule->packets[1] = 0;
- rule->bytes[0] = rule->bytes[1] = 0;
- }
- break;
- }
-
-#ifdef __FreeBSD__
- case DIOCGIFSPEED: {
- struct pf_ifspeed *psp = (struct pf_ifspeed *)addr;
- struct pf_ifspeed ps;
- struct ifnet *ifp;
-
- if (psp->ifname[0] != 0) {
- /* Can we completely trust user-land? */
- strlcpy(ps.ifname, psp->ifname, IFNAMSIZ);
- ifp = ifunit(ps.ifname);
- if (ifp != NULL)
- psp->baudrate = ifp->if_baudrate;
- else
- error = EINVAL;
- } else
- error = EINVAL;
- break;
- }
-#endif /* __FreeBSD__ */
-
-#ifdef ALTQ
- case DIOCSTARTALTQ: {
- struct pf_altq *altq;
-
- /* enable all altq interfaces on active list */
-#ifdef __FreeBSD__
- TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
- if (altq->qname[0] == 0 && (altq->local_flags &
- PFALTQ_FLAG_IF_REMOVED) == 0) {
-#else
- TAILQ_FOREACH(altq, pf_altqs_active, entries) {
- if (altq->qname[0] == 0) {
-#endif
- error = pf_enable_altq(altq);
- if (error != 0)
- break;
- }
- }
- if (error == 0)
-#ifdef __FreeBSD__
- V_pf_altq_running = 1;
-#else
- pf_altq_running = 1;
-#endif
- DPFPRINTF(PF_DEBUG_MISC, ("altq: started\n"));
- break;
- }
-
- case DIOCSTOPALTQ: {
- struct pf_altq *altq;
-
- /* disable all altq interfaces on active list */
-#ifdef __FreeBSD__
- TAILQ_FOREACH(altq, V_pf_altqs_active, entries) {
- if (altq->qname[0] == 0 && (altq->local_flags &
- PFALTQ_FLAG_IF_REMOVED) == 0) {
-#else
- TAILQ_FOREACH(altq, pf_altqs_active, entries) {
- if (altq->qname[0] == 0) {
-#endif
- error = pf_disable_altq(altq);
- if (error != 0)
- break;
- }
- }
- if (error == 0)
-#ifdef __FreeBSD__
- V_pf_altq_running = 0;
-#else
- pf_altq_running = 0;
-#endif
- DPFPRINTF(PF_DEBUG_MISC, ("altq: stopped\n"));
- break;
- }
-
- case DIOCADDALTQ: {
- struct pfioc_altq *pa = (struct pfioc_altq *)addr;
- struct pf_altq *altq, *a;
-
-#ifdef __FreeBSD__
- if (pa->ticket != V_ticket_altqs_inactive) {
-#else
- if (pa->ticket != ticket_altqs_inactive) {
-#endif
- error = EBUSY;
- break;
- }
-#ifdef __FreeBSD__
- altq = pool_get(&V_pf_altq_pl, PR_NOWAIT);
-#else
- altq = pool_get(&pf_altq_pl, PR_WAITOK|PR_LIMITFAIL);
-#endif
- if (altq == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pa->altq, altq, sizeof(struct pf_altq));
-#ifdef __FreeBSD__
- altq->local_flags = 0;
-#endif
-
- /*
- * if this is for a queue, find the discipline and
- * copy the necessary fields
- */
- if (altq->qname[0] != 0) {
- if ((altq->qid = pf_qname2qid(altq->qname)) == 0) {
- error = EBUSY;
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, altq);
-#else
- pool_put(&pf_altq_pl, altq);
-#endif
- break;
- }
- altq->altq_disc = NULL;
-#ifdef __FreeBSD__
- TAILQ_FOREACH(a, V_pf_altqs_inactive, entries) {
-#else
- TAILQ_FOREACH(a, pf_altqs_inactive, entries) {
-#endif
- if (strncmp(a->ifname, altq->ifname,
- IFNAMSIZ) == 0 && a->qname[0] == 0) {
- altq->altq_disc = a->altq_disc;
- break;
- }
- }
- }
-
-#ifdef __FreeBSD__
- struct ifnet *ifp;
-
- if ((ifp = ifunit(altq->ifname)) == NULL) {
- altq->local_flags |= PFALTQ_FLAG_IF_REMOVED;
- } else {
- PF_UNLOCK();
-#endif
- error = altq_add(altq);
-#ifdef __FreeBSD__
- PF_LOCK();
- }
-#endif
- if (error) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_altq_pl, altq);
-#else
- pool_put(&pf_altq_pl, altq);
-#endif
- break;
- }
-
-#ifdef __FreeBSD__
- TAILQ_INSERT_TAIL(V_pf_altqs_inactive, altq, entries);
-#else
- TAILQ_INSERT_TAIL(pf_altqs_inactive, altq, entries);
-#endif
- bcopy(altq, &pa->altq, sizeof(struct pf_altq));
- break;
- }
-
- case DIOCGETALTQS: {
- struct pfioc_altq *pa = (struct pfioc_altq *)addr;
- struct pf_altq *altq;
-
- pa->nr = 0;
-#ifdef __FreeBSD__
- TAILQ_FOREACH(altq, V_pf_altqs_active, entries)
- pa->nr++;
- pa->ticket = V_ticket_altqs_active;
-#else
- TAILQ_FOREACH(altq, pf_altqs_active, entries)
- pa->nr++;
- pa->ticket = ticket_altqs_active;
-#endif
- break;
- }
-
- case DIOCGETALTQ: {
- struct pfioc_altq *pa = (struct pfioc_altq *)addr;
- struct pf_altq *altq;
- u_int32_t nr;
-
-#ifdef __FreeBSD__
- if (pa->ticket != V_ticket_altqs_active) {
-#else
- if (pa->ticket != ticket_altqs_active) {
-#endif
- error = EBUSY;
- break;
- }
- nr = 0;
-#ifdef __FreeBSD__
- altq = TAILQ_FIRST(V_pf_altqs_active);
-#else
- altq = TAILQ_FIRST(pf_altqs_active);
-#endif
- while ((altq != NULL) && (nr < pa->nr)) {
- altq = TAILQ_NEXT(altq, entries);
- nr++;
- }
- if (altq == NULL) {
- error = EBUSY;
- break;
- }
- bcopy(altq, &pa->altq, sizeof(struct pf_altq));
- break;
- }
-
- case DIOCCHANGEALTQ:
- /* CHANGEALTQ not supported yet! */
- error = ENODEV;
- break;
-
- case DIOCGETQSTATS: {
- struct pfioc_qstats *pq = (struct pfioc_qstats *)addr;
- struct pf_altq *altq;
- u_int32_t nr;
- int nbytes;
-
-#ifdef __FreeBSD__
- if (pq->ticket != V_ticket_altqs_active) {
-#else
- if (pq->ticket != ticket_altqs_active) {
-#endif
- error = EBUSY;
- break;
- }
- nbytes = pq->nbytes;
- nr = 0;
-#ifdef __FreeBSD__
- altq = TAILQ_FIRST(V_pf_altqs_active);
-#else
- altq = TAILQ_FIRST(pf_altqs_active);
-#endif
- while ((altq != NULL) && (nr < pq->nr)) {
- altq = TAILQ_NEXT(altq, entries);
- nr++;
- }
- if (altq == NULL) {
- error = EBUSY;
- break;
- }
-
-#ifdef __FreeBSD__
- if ((altq->local_flags & PFALTQ_FLAG_IF_REMOVED) != 0) {
- error = ENXIO;
- break;
- }
- PF_UNLOCK();
-#endif
- error = altq_getqstats(altq, pq->buf, &nbytes);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- if (error == 0) {
- pq->scheduler = altq->scheduler;
- pq->nbytes = nbytes;
- }
- break;
- }
-#endif /* ALTQ */
-
- case DIOCBEGINADDRS: {
- struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
-
-#ifdef __FreeBSD__
- pf_empty_pool(&V_pf_pabuf);
- pp->ticket = ++V_ticket_pabuf;
-#else
- pf_empty_pool(&pf_pabuf);
- pp->ticket = ++ticket_pabuf;
-#endif
- break;
- }
-
- case DIOCADDADDR: {
- struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
-
-#ifdef __FreeBSD__
- if (pp->ticket != V_ticket_pabuf) {
-#else
- if (pp->ticket != ticket_pabuf) {
-#endif
- error = EBUSY;
- break;
- }
-#ifndef INET
- if (pp->af == AF_INET) {
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (pp->af == AF_INET6) {
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (pp->addr.addr.type != PF_ADDR_ADDRMASK &&
- pp->addr.addr.type != PF_ADDR_DYNIFTL &&
- pp->addr.addr.type != PF_ADDR_TABLE) {
- error = EINVAL;
- break;
- }
-#ifdef __FreeBSD__
- pa = pool_get(&V_pf_pooladdr_pl, PR_NOWAIT);
-#else
- pa = pool_get(&pf_pooladdr_pl, PR_WAITOK|PR_LIMITFAIL);
-#endif
- if (pa == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pp->addr, pa, sizeof(struct pf_pooladdr));
- if (pa->ifname[0]) {
- pa->kif = pfi_kif_get(pa->ifname);
- if (pa->kif == NULL) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, pa);
-#else
- pool_put(&pf_pooladdr_pl, pa);
-#endif
- error = EINVAL;
- break;
- }
- pfi_kif_ref(pa->kif, PFI_KIF_REF_RULE);
- }
- if (pfi_dynaddr_setup(&pa->addr, pp->af)) {
- pfi_dynaddr_remove(&pa->addr);
- pfi_kif_unref(pa->kif, PFI_KIF_REF_RULE);
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, pa);
-#else
- pool_put(&pf_pooladdr_pl, pa);
-#endif
- error = EINVAL;
- break;
- }
-#ifdef __FreeBSD__
- TAILQ_INSERT_TAIL(&V_pf_pabuf, pa, entries);
-#else
- TAILQ_INSERT_TAIL(&pf_pabuf, pa, entries);
-#endif
- break;
- }
-
- case DIOCGETADDRS: {
- struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
-
- pp->nr = 0;
- pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
- pp->r_num, 0, 1, 0);
- if (pool == NULL) {
- error = EBUSY;
- break;
- }
- TAILQ_FOREACH(pa, &pool->list, entries)
- pp->nr++;
- break;
- }
-
- case DIOCGETADDR: {
- struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
- u_int32_t nr = 0;
-
- pool = pf_get_pool(pp->anchor, pp->ticket, pp->r_action,
- pp->r_num, 0, 1, 1);
- if (pool == NULL) {
- error = EBUSY;
- break;
- }
- pa = TAILQ_FIRST(&pool->list);
- while ((pa != NULL) && (nr < pp->nr)) {
- pa = TAILQ_NEXT(pa, entries);
- nr++;
- }
- if (pa == NULL) {
- error = EBUSY;
- break;
- }
- bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
- pf_addr_copyout(&pp->addr.addr);
- break;
- }
-
- case DIOCCHANGEADDR: {
- struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
- struct pf_pooladdr *oldpa = NULL, *newpa = NULL;
- struct pf_ruleset *ruleset;
-
- if (pca->action < PF_CHANGE_ADD_HEAD ||
- pca->action > PF_CHANGE_REMOVE) {
- error = EINVAL;
- break;
- }
- if (pca->addr.addr.type != PF_ADDR_ADDRMASK &&
- pca->addr.addr.type != PF_ADDR_DYNIFTL &&
- pca->addr.addr.type != PF_ADDR_TABLE) {
- error = EINVAL;
- break;
- }
-
- ruleset = pf_find_ruleset(pca->anchor);
- if (ruleset == NULL) {
- error = EBUSY;
- break;
- }
- pool = pf_get_pool(pca->anchor, pca->ticket, pca->r_action,
- pca->r_num, pca->r_last, 1, 1);
- if (pool == NULL) {
- error = EBUSY;
- break;
- }
- if (pca->action != PF_CHANGE_REMOVE) {
-#ifdef __FreeBSD__
- newpa = pool_get(&V_pf_pooladdr_pl,
- PR_NOWAIT);
-#else
- newpa = pool_get(&pf_pooladdr_pl,
- PR_WAITOK|PR_LIMITFAIL);
-#endif
- if (newpa == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
-#ifndef INET
- if (pca->af == AF_INET) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, newpa);
-#else
- pool_put(&pf_pooladdr_pl, newpa);
-#endif
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (pca->af == AF_INET6) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, newpa);
-#else
- pool_put(&pf_pooladdr_pl, newpa);
-#endif
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (newpa->ifname[0]) {
- newpa->kif = pfi_kif_get(newpa->ifname);
- if (newpa->kif == NULL) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, newpa);
-#else
- pool_put(&pf_pooladdr_pl, newpa);
-#endif
- error = EINVAL;
- break;
- }
- pfi_kif_ref(newpa->kif, PFI_KIF_REF_RULE);
- } else
- newpa->kif = NULL;
- if (pfi_dynaddr_setup(&newpa->addr, pca->af) ||
- pf_tbladdr_setup(ruleset, &newpa->addr)) {
- pfi_dynaddr_remove(&newpa->addr);
- pfi_kif_unref(newpa->kif, PFI_KIF_REF_RULE);
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, newpa);
-#else
- pool_put(&pf_pooladdr_pl, newpa);
-#endif
- error = EINVAL;
- break;
- }
- }
-
- if (pca->action == PF_CHANGE_ADD_HEAD)
- oldpa = TAILQ_FIRST(&pool->list);
- else if (pca->action == PF_CHANGE_ADD_TAIL)
- oldpa = TAILQ_LAST(&pool->list, pf_palist);
- else {
- int i = 0;
-
- oldpa = TAILQ_FIRST(&pool->list);
- while ((oldpa != NULL) && (i < pca->nr)) {
- oldpa = TAILQ_NEXT(oldpa, entries);
- i++;
- }
- if (oldpa == NULL) {
- error = EINVAL;
- break;
- }
- }
-
- if (pca->action == PF_CHANGE_REMOVE) {
- TAILQ_REMOVE(&pool->list, oldpa, entries);
- pfi_dynaddr_remove(&oldpa->addr);
- pf_tbladdr_remove(&oldpa->addr);
- pfi_kif_unref(oldpa->kif, PFI_KIF_REF_RULE);
-#ifdef __FreeBSD__
- pool_put(&V_pf_pooladdr_pl, oldpa);
-#else
- pool_put(&pf_pooladdr_pl, oldpa);
-#endif
- } else {
- if (oldpa == NULL)
- TAILQ_INSERT_TAIL(&pool->list, newpa, entries);
- else if (pca->action == PF_CHANGE_ADD_HEAD ||
- pca->action == PF_CHANGE_ADD_BEFORE)
- TAILQ_INSERT_BEFORE(oldpa, newpa, entries);
- else
- TAILQ_INSERT_AFTER(&pool->list, oldpa,
- newpa, entries);
- }
-
- pool->cur = TAILQ_FIRST(&pool->list);
- PF_ACPY(&pool->counter, &pool->cur->addr.v.a.addr,
- pca->af);
- break;
- }
-
- case DIOCGETRULESETS: {
- struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
- struct pf_ruleset *ruleset;
- struct pf_anchor *anchor;
-
- pr->path[sizeof(pr->path) - 1] = 0;
- if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
- error = EINVAL;
- break;
- }
- pr->nr = 0;
- if (ruleset->anchor == NULL) {
- /* XXX kludge for pf_main_ruleset */
-#ifdef __FreeBSD__
- RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)
-#else
- RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
-#endif
- if (anchor->parent == NULL)
- pr->nr++;
- } else {
- RB_FOREACH(anchor, pf_anchor_node,
- &ruleset->anchor->children)
- pr->nr++;
- }
- break;
- }
-
- case DIOCGETRULESET: {
- struct pfioc_ruleset *pr = (struct pfioc_ruleset *)addr;
- struct pf_ruleset *ruleset;
- struct pf_anchor *anchor;
- u_int32_t nr = 0;
-
- pr->path[sizeof(pr->path) - 1] = 0;
- if ((ruleset = pf_find_ruleset(pr->path)) == NULL) {
- error = EINVAL;
- break;
- }
- pr->name[0] = 0;
- if (ruleset->anchor == NULL) {
- /* XXX kludge for pf_main_ruleset */
-#ifdef __FreeBSD__
- RB_FOREACH(anchor, pf_anchor_global, &V_pf_anchors)
-#else
- RB_FOREACH(anchor, pf_anchor_global, &pf_anchors)
-#endif
- if (anchor->parent == NULL && nr++ == pr->nr) {
- strlcpy(pr->name, anchor->name,
- sizeof(pr->name));
- break;
- }
- } else {
- RB_FOREACH(anchor, pf_anchor_node,
- &ruleset->anchor->children)
- if (nr++ == pr->nr) {
- strlcpy(pr->name, anchor->name,
- sizeof(pr->name));
- break;
- }
- }
- if (!pr->name[0])
- error = EBUSY;
- break;
- }
-
- case DIOCRCLRTABLES: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != 0) {
- error = ENODEV;
- break;
- }
- error = pfr_clr_tables(&io->pfrio_table, &io->pfrio_ndel,
- io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRADDTABLES: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_table)) {
- error = ENODEV;
- break;
- }
- error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size,
- &io->pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRDELTABLES: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_table)) {
- error = ENODEV;
- break;
- }
- error = pfr_del_tables(io->pfrio_buffer, io->pfrio_size,
- &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRGETTABLES: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_table)) {
- error = ENODEV;
- break;
- }
- error = pfr_get_tables(&io->pfrio_table, io->pfrio_buffer,
- &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRGETTSTATS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_tstats)) {
- error = ENODEV;
- break;
- }
- error = pfr_get_tstats(&io->pfrio_table, io->pfrio_buffer,
- &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRCLRTSTATS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_table)) {
- error = ENODEV;
- break;
- }
- error = pfr_clr_tstats(io->pfrio_buffer, io->pfrio_size,
- &io->pfrio_nzero, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRSETTFLAGS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_table)) {
- error = ENODEV;
- break;
- }
- error = pfr_set_tflags(io->pfrio_buffer, io->pfrio_size,
- io->pfrio_setflag, io->pfrio_clrflag, &io->pfrio_nchange,
- &io->pfrio_ndel, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRCLRADDRS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != 0) {
- error = ENODEV;
- break;
- }
- error = pfr_clr_addrs(&io->pfrio_table, &io->pfrio_ndel,
- io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRADDADDRS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_add_addrs(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_size, &io->pfrio_nadd, io->pfrio_flags |
- PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRDELADDRS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
- PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRSETADDRS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_set_addrs(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_size, &io->pfrio_size2, &io->pfrio_nadd,
- &io->pfrio_ndel, &io->pfrio_nchange, io->pfrio_flags |
- PFR_FLAG_USERIOCTL, 0);
- break;
- }
-
- case DIOCRGETADDRS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_get_addrs(&io->pfrio_table, io->pfrio_buffer,
- &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRGETASTATS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_astats)) {
- error = ENODEV;
- break;
- }
- error = pfr_get_astats(&io->pfrio_table, io->pfrio_buffer,
- &io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRCLRASTATS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_clr_astats(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_size, &io->pfrio_nzero, io->pfrio_flags |
- PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRTSTADDRS: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_tst_addrs(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_size, &io->pfrio_nmatch, io->pfrio_flags |
- PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCRINADEFINE: {
- struct pfioc_table *io = (struct pfioc_table *)addr;
-
- if (io->pfrio_esize != sizeof(struct pfr_addr)) {
- error = ENODEV;
- break;
- }
- error = pfr_ina_define(&io->pfrio_table, io->pfrio_buffer,
- io->pfrio_size, &io->pfrio_nadd, &io->pfrio_naddr,
- io->pfrio_ticket, io->pfrio_flags | PFR_FLAG_USERIOCTL);
- break;
- }
-
- case DIOCOSFPADD: {
- struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
- error = pf_osfp_add(io);
- break;
- }
-
- case DIOCOSFPGET: {
- struct pf_osfp_ioctl *io = (struct pf_osfp_ioctl *)addr;
- error = pf_osfp_get(io);
- break;
- }
-
- case DIOCXBEGIN: {
- struct pfioc_trans *io = (struct pfioc_trans *)addr;
- struct pfioc_trans_e *ioe;
- struct pfr_table *table;
- int i;
-
- if (io->esize != sizeof(*ioe)) {
- error = ENODEV;
- goto fail;
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
- table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < io->size; i++) {
-#ifdef __FreeBSD__
- PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
- if (error) {
-#else
- if (copyin(io->array+i, ioe, sizeof(*ioe))) {
-#endif
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EFAULT;
- goto fail;
- }
- switch (ioe->rs_num) {
-#ifdef ALTQ
- case PF_RULESET_ALTQ:
- if (ioe->anchor[0]) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EINVAL;
- goto fail;
- }
- if ((error = pf_begin_altq(&ioe->ticket))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail;
- }
- break;
-#endif /* ALTQ */
- case PF_RULESET_TABLE:
- bzero(table, sizeof(*table));
- strlcpy(table->pfrt_anchor, ioe->anchor,
- sizeof(table->pfrt_anchor));
- if ((error = pfr_ina_begin(table,
- &ioe->ticket, NULL, 0))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail;
- }
- break;
- default:
- if ((error = pf_begin_rules(&ioe->ticket,
- ioe->rs_num, ioe->anchor))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail;
- }
- break;
- }
-#ifdef __FreeBSD__
- PF_COPYOUT(ioe, io->array+i, sizeof(io->array[i]),
- error);
- if (error) {
-#else
- if (copyout(ioe, io->array+i, sizeof(io->array[i]))) {
-#endif
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EFAULT;
- goto fail;
- }
- }
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- break;
- }
-
- case DIOCXROLLBACK: {
- struct pfioc_trans *io = (struct pfioc_trans *)addr;
- struct pfioc_trans_e *ioe;
- struct pfr_table *table;
- int i;
-
- if (io->esize != sizeof(*ioe)) {
- error = ENODEV;
- goto fail;
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
- table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- for (i = 0; i < io->size; i++) {
-#ifdef __FreeBSD__
- PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
- if (error) {
-#else
- if (copyin(io->array+i, ioe, sizeof(*ioe))) {
-#endif
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EFAULT;
- goto fail;
- }
- switch (ioe->rs_num) {
-#ifdef ALTQ
- case PF_RULESET_ALTQ:
- if (ioe->anchor[0]) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EINVAL;
- goto fail;
- }
- if ((error = pf_rollback_altq(ioe->ticket))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail; /* really bad */
- }
- break;
-#endif /* ALTQ */
- case PF_RULESET_TABLE:
- bzero(table, sizeof(*table));
- strlcpy(table->pfrt_anchor, ioe->anchor,
- sizeof(table->pfrt_anchor));
- if ((error = pfr_ina_rollback(table,
- ioe->ticket, NULL, 0))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail; /* really bad */
- }
- break;
- default:
- if ((error = pf_rollback_rules(ioe->ticket,
- ioe->rs_num, ioe->anchor))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail; /* really bad */
- }
- break;
- }
- }
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- break;
- }
-
- case DIOCXCOMMIT: {
- struct pfioc_trans *io = (struct pfioc_trans *)addr;
- struct pfioc_trans_e *ioe;
- struct pfr_table *table;
- struct pf_ruleset *rs;
- int i;
-
- if (io->esize != sizeof(*ioe)) {
- error = ENODEV;
- goto fail;
- }
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- ioe = malloc(sizeof(*ioe), M_TEMP, M_WAITOK);
- table = malloc(sizeof(*table), M_TEMP, M_WAITOK);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- /* first makes sure everything will succeed */
- for (i = 0; i < io->size; i++) {
-#ifdef __FreeBSD__
- PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
- if (error) {
-#else
- if (copyin(io->array+i, ioe, sizeof(*ioe))) {
-#endif
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EFAULT;
- goto fail;
- }
- switch (ioe->rs_num) {
-#ifdef ALTQ
- case PF_RULESET_ALTQ:
- if (ioe->anchor[0]) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EINVAL;
- goto fail;
- }
-#ifdef __FreeBSD__
- if (!V_altqs_inactive_open || ioe->ticket !=
- V_ticket_altqs_inactive) {
-#else
- if (!altqs_inactive_open || ioe->ticket !=
- ticket_altqs_inactive) {
-#endif
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EBUSY;
- goto fail;
- }
- break;
-#endif /* ALTQ */
- case PF_RULESET_TABLE:
- rs = pf_find_ruleset(ioe->anchor);
- if (rs == NULL || !rs->topen || ioe->ticket !=
- rs->tticket) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EBUSY;
- goto fail;
- }
- break;
- default:
- if (ioe->rs_num < 0 || ioe->rs_num >=
- PF_RULESET_MAX) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EINVAL;
- goto fail;
- }
- rs = pf_find_ruleset(ioe->anchor);
- if (rs == NULL ||
- !rs->rules[ioe->rs_num].inactive.open ||
- rs->rules[ioe->rs_num].inactive.ticket !=
- ioe->ticket) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EBUSY;
- goto fail;
- }
- break;
- }
- }
- /* now do the commit - no errors should happen here */
- for (i = 0; i < io->size; i++) {
-#ifdef __FreeBSD__
- PF_COPYIN(io->array+i, ioe, sizeof(*ioe), error);
- if (error) {
-#else
- if (copyin(io->array+i, ioe, sizeof(*ioe))) {
-#endif
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- error = EFAULT;
- goto fail;
- }
- switch (ioe->rs_num) {
-#ifdef ALTQ
- case PF_RULESET_ALTQ:
- if ((error = pf_commit_altq(ioe->ticket))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail; /* really bad */
- }
- break;
-#endif /* ALTQ */
- case PF_RULESET_TABLE:
- bzero(table, sizeof(*table));
- strlcpy(table->pfrt_anchor, ioe->anchor,
- sizeof(table->pfrt_anchor));
- if ((error = pfr_ina_commit(table, ioe->ticket,
- NULL, NULL, 0))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail; /* really bad */
- }
- break;
- default:
- if ((error = pf_commit_rules(ioe->ticket,
- ioe->rs_num, ioe->anchor))) {
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- goto fail; /* really bad */
- }
- break;
- }
- }
- free(table, M_TEMP);
- free(ioe, M_TEMP);
- break;
- }
-
- case DIOCGETSRCNODES: {
- struct pfioc_src_nodes *psn = (struct pfioc_src_nodes *)addr;
- struct pf_src_node *n, *p, *pstore;
- u_int32_t nr = 0;
- int space = psn->psn_len;
-
- if (space == 0) {
-#ifdef __FreeBSD__
- RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking)
-#else
- RB_FOREACH(n, pf_src_tree, &tree_src_tracking)
-#endif
- nr++;
- psn->psn_len = sizeof(struct pf_src_node) * nr;
- break;
- }
-
-#ifdef __FreeBSD__
- PF_UNLOCK();
-#endif
- pstore = malloc(sizeof(*pstore), M_TEMP, M_WAITOK);
-#ifdef __FreeBSD__
- PF_LOCK();
-#endif
- p = psn->psn_src_nodes;
-#ifdef __FreeBSD__
- RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
-#else
- RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
-#endif
- int secs = time_second, diff;
-
- if ((nr + 1) * sizeof(*p) > (unsigned)psn->psn_len)
- break;
-
- bcopy(n, pstore, sizeof(*pstore));
- if (n->rule.ptr != NULL)
- pstore->rule.nr = n->rule.ptr->nr;
- pstore->creation = secs - pstore->creation;
- if (pstore->expire > secs)
- pstore->expire -= secs;
- else
- pstore->expire = 0;
-
- /* adjust the connection rate estimate */
- diff = secs - n->conn_rate.last;
- if (diff >= n->conn_rate.seconds)
- pstore->conn_rate.count = 0;
- else
- pstore->conn_rate.count -=
- n->conn_rate.count * diff /
- n->conn_rate.seconds;
-
-#ifdef __FreeBSD__
- PF_COPYOUT(pstore, p, sizeof(*p), error);
-#else
- error = copyout(pstore, p, sizeof(*p));
-#endif
- if (error) {
- free(pstore, M_TEMP);
- goto fail;
- }
- p++;
- nr++;
- }
- psn->psn_len = sizeof(struct pf_src_node) * nr;
-
- free(pstore, M_TEMP);
- break;
- }
-
- case DIOCCLRSRCNODES: {
- struct pf_src_node *n;
- struct pf_state *state;
-
-#ifdef __FreeBSD__
- RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
-#else
- RB_FOREACH(state, pf_state_tree_id, &tree_id) {
-#endif
- state->src_node = NULL;
- state->nat_src_node = NULL;
- }
-#ifdef __FreeBSD__
- RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
-#else
- RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
-#endif
- n->expire = 1;
- n->states = 0;
- }
- pf_purge_expired_src_nodes(1);
-#ifdef __FreeBSD__
- V_pf_status.src_nodes = 0;
-#else
- pf_status.src_nodes = 0;
-#endif
- break;
- }
-
- case DIOCKILLSRCNODES: {
- struct pf_src_node *sn;
- struct pf_state *s;
- struct pfioc_src_node_kill *psnk =
- (struct pfioc_src_node_kill *)addr;
- u_int killed = 0;
-
-#ifdef __FreeBSD__
- RB_FOREACH(sn, pf_src_tree, &V_tree_src_tracking) {
-#else
- RB_FOREACH(sn, pf_src_tree, &tree_src_tracking) {
-#endif
- if (PF_MATCHA(psnk->psnk_src.neg,
- &psnk->psnk_src.addr.v.a.addr,
- &psnk->psnk_src.addr.v.a.mask,
- &sn->addr, sn->af) &&
- PF_MATCHA(psnk->psnk_dst.neg,
- &psnk->psnk_dst.addr.v.a.addr,
- &psnk->psnk_dst.addr.v.a.mask,
- &sn->raddr, sn->af)) {
- /* Handle state to src_node linkage */
- if (sn->states != 0) {
- RB_FOREACH(s, pf_state_tree_id,
-#ifdef __FreeBSD__
- &V_tree_id) {
-#else
- &tree_id) {
-#endif
- if (s->src_node == sn)
- s->src_node = NULL;
- if (s->nat_src_node == sn)
- s->nat_src_node = NULL;
- }
- sn->states = 0;
- }
- sn->expire = 1;
- killed++;
- }
- }
-
- if (killed > 0)
- pf_purge_expired_src_nodes(1);
-
- psnk->psnk_killed = killed;
- break;
- }
-
- case DIOCSETHOSTID: {
- u_int32_t *hostid = (u_int32_t *)addr;
-
-#ifdef __FreeBSD__
- if (*hostid == 0)
- V_pf_status.hostid = arc4random();
- else
- V_pf_status.hostid = *hostid;
-#else
- if (*hostid == 0)
- pf_status.hostid = arc4random();
- else
- pf_status.hostid = *hostid;
-#endif
- break;
- }
-
- case DIOCOSFPFLUSH:
- pf_osfp_flush();
- break;
-
- case DIOCIGETIFACES: {
- struct pfioc_iface *io = (struct pfioc_iface *)addr;
-
- if (io->pfiio_esize != sizeof(struct pfi_kif)) {
- error = ENODEV;
- break;
- }
- error = pfi_get_ifaces(io->pfiio_name, io->pfiio_buffer,
- &io->pfiio_size);
- break;
- }
-
- case DIOCSETIFFLAG: {
- struct pfioc_iface *io = (struct pfioc_iface *)addr;
-
- error = pfi_set_flags(io->pfiio_name, io->pfiio_flags);
- break;
- }
-
- case DIOCCLRIFFLAG: {
- struct pfioc_iface *io = (struct pfioc_iface *)addr;
-
- error = pfi_clear_flags(io->pfiio_name, io->pfiio_flags);
- break;
- }
-
- default:
- error = ENODEV;
- break;
- }
-fail:
-#ifdef __FreeBSD__
- PF_UNLOCK();
-
- if (flags & FWRITE)
- sx_xunlock(&V_pf_consistency_lock);
- else
- sx_sunlock(&V_pf_consistency_lock);
-#else
- splx(s);
- if (flags & FWRITE)
- rw_exit_write(&pf_consistency_lock);
- else
- rw_exit_read(&pf_consistency_lock);
-#endif
-
- CURVNET_RESTORE();
-
- return (error);
-}
-
-#ifdef __FreeBSD__
-void
-pfsync_state_export(struct pfsync_state *sp, struct pf_state *st)
-{
- bzero(sp, sizeof(struct pfsync_state));
-
- /* copy from state key */
- sp->key[PF_SK_WIRE].addr[0] = st->key[PF_SK_WIRE]->addr[0];
- sp->key[PF_SK_WIRE].addr[1] = st->key[PF_SK_WIRE]->addr[1];
- sp->key[PF_SK_WIRE].port[0] = st->key[PF_SK_WIRE]->port[0];
- sp->key[PF_SK_WIRE].port[1] = st->key[PF_SK_WIRE]->port[1];
- sp->key[PF_SK_STACK].addr[0] = st->key[PF_SK_STACK]->addr[0];
- sp->key[PF_SK_STACK].addr[1] = st->key[PF_SK_STACK]->addr[1];
- sp->key[PF_SK_STACK].port[0] = st->key[PF_SK_STACK]->port[0];
- sp->key[PF_SK_STACK].port[1] = st->key[PF_SK_STACK]->port[1];
- sp->proto = st->key[PF_SK_WIRE]->proto;
- sp->af = st->key[PF_SK_WIRE]->af;
-
- /* copy from state */
- strlcpy(sp->ifname, st->kif->pfik_name, sizeof(sp->ifname));
- bcopy(&st->rt_addr, &sp->rt_addr, sizeof(sp->rt_addr));
- sp->creation = htonl(time_second - st->creation);
- sp->expire = pf_state_expires(st);
- if (sp->expire <= time_second)
- sp->expire = htonl(0);
- else
- sp->expire = htonl(sp->expire - time_second);
-
- sp->direction = st->direction;
- sp->log = st->log;
- sp->timeout = st->timeout;
- sp->state_flags = st->state_flags;
- if (st->src_node)
- sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
- if (st->nat_src_node)
- sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
-
- bcopy(&st->id, &sp->id, sizeof(sp->id));
- sp->creatorid = st->creatorid;
- pf_state_peer_hton(&st->src, &sp->src);
- pf_state_peer_hton(&st->dst, &sp->dst);
-
- if (st->rule.ptr == NULL)
- sp->rule = htonl(-1);
- else
- sp->rule = htonl(st->rule.ptr->nr);
- if (st->anchor.ptr == NULL)
- sp->anchor = htonl(-1);
- else
- sp->anchor = htonl(st->anchor.ptr->nr);
- if (st->nat_rule.ptr == NULL)
- sp->nat_rule = htonl(-1);
- else
- sp->nat_rule = htonl(st->nat_rule.ptr->nr);
-
- pf_state_counter_hton(st->packets[0], sp->packets[0]);
- pf_state_counter_hton(st->packets[1], sp->packets[1]);
- pf_state_counter_hton(st->bytes[0], sp->bytes[0]);
- pf_state_counter_hton(st->bytes[1], sp->bytes[1]);
-
-}
-
-/*
- * XXX - Check for version missmatch!!!
- */
-static void
-pf_clear_states(void)
-{
- struct pf_state *state;
-
-#ifdef __FreeBSD__
- RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
-#else
- RB_FOREACH(state, pf_state_tree_id, &tree_id) {
-#endif
- state->timeout = PFTM_PURGE;
-#if NPFSYNC
- /* don't send out individual delete messages */
- state->sync_state = PFSTATE_NOSYNC;
-#endif
- pf_unlink_state(state);
- }
-
-#if 0 /* NPFSYNC */
-/*
- * XXX This is called on module unload, we do not want to sync that over? */
- */
- pfsync_clear_states(V_pf_status.hostid, psk->psk_ifname);
-#endif
-}
-
-static int
-pf_clear_tables(void)
-{
- struct pfioc_table io;
- int error;
-
- bzero(&io, sizeof(io));
-
- error = pfr_clr_tables(&io.pfrio_table, &io.pfrio_ndel,
- io.pfrio_flags);
-
- return (error);
-}
-
-static void
-pf_clear_srcnodes(void)
-{
- struct pf_src_node *n;
- struct pf_state *state;
-
-#ifdef __FreeBSD__
- RB_FOREACH(state, pf_state_tree_id, &V_tree_id) {
-#else
- RB_FOREACH(state, pf_state_tree_id, &tree_id) {
-#endif
- state->src_node = NULL;
- state->nat_src_node = NULL;
- }
-#ifdef __FreeBSD__
- RB_FOREACH(n, pf_src_tree, &V_tree_src_tracking) {
-#else
- RB_FOREACH(n, pf_src_tree, &tree_src_tracking) {
-#endif
- n->expire = 1;
- n->states = 0;
- }
-}
-/*
- * XXX - Check for version missmatch!!!
- */
-
-/*
- * Duplicate pfctl -Fa operation to get rid of as much as we can.
- */
-static int
-shutdown_pf(void)
-{
- int error = 0;
- u_int32_t t[5];
- char nn = '\0';
-
- V_pf_status.running = 0;
- do {
- if ((error = pf_begin_rules(&t[0], PF_RULESET_SCRUB, &nn))
- != 0) {
- DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: SCRUB\n"));
- break;
- }
- if ((error = pf_begin_rules(&t[1], PF_RULESET_FILTER, &nn))
- != 0) {
- DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: FILTER\n"));
- break; /* XXX: rollback? */
- }
- if ((error = pf_begin_rules(&t[2], PF_RULESET_NAT, &nn))
- != 0) {
- DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: NAT\n"));
- break; /* XXX: rollback? */
- }
- if ((error = pf_begin_rules(&t[3], PF_RULESET_BINAT, &nn))
- != 0) {
- DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: BINAT\n"));
- break; /* XXX: rollback? */
- }
- if ((error = pf_begin_rules(&t[4], PF_RULESET_RDR, &nn))
- != 0) {
- DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: RDR\n"));
- break; /* XXX: rollback? */
- }
-
- /* XXX: these should always succeed here */
- pf_commit_rules(t[0], PF_RULESET_SCRUB, &nn);
- pf_commit_rules(t[1], PF_RULESET_FILTER, &nn);
- pf_commit_rules(t[2], PF_RULESET_NAT, &nn);
- pf_commit_rules(t[3], PF_RULESET_BINAT, &nn);
- pf_commit_rules(t[4], PF_RULESET_RDR, &nn);
-
- if ((error = pf_clear_tables()) != 0)
- break;
-
- #ifdef ALTQ
- if ((error = pf_begin_altq(&t[0])) != 0) {
- DPFPRINTF(PF_DEBUG_MISC, ("shutdown_pf: ALTQ\n"));
- break;
- }
- pf_commit_altq(t[0]);
- #endif
-
- pf_clear_states();
-
- pf_clear_srcnodes();
-
- /* status does not use malloced mem so no need to cleanup */
- /* fingerprints and interfaces have thier own cleanup code */
- } while(0);
-
- return (error);
-}
-
-#ifdef INET
-static int
-pf_check_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
- struct inpcb *inp)
-{
- /*
- * XXX Wed Jul 9 22:03:16 2003 UTC
- * OpenBSD has changed its byte ordering convention on ip_len/ip_off
- * in network stack. OpenBSD's network stack have converted
- * ip_len/ip_off to host byte order frist as FreeBSD.
- * Now this is not true anymore , so we should convert back to network
- * byte order.
- */
- struct ip *h = NULL;
- int chk;
-
- if ((*m)->m_pkthdr.len >= (int)sizeof(struct ip)) {
- /* if m_pkthdr.len is less than ip header, pf will handle. */
- h = mtod(*m, struct ip *);
- HTONS(h->ip_len);
- HTONS(h->ip_off);
- }
- CURVNET_SET(ifp->if_vnet);
- chk = pf_test(PF_IN, ifp, m, NULL, inp);
- CURVNET_RESTORE();
- if (chk && *m) {
- m_freem(*m);
- *m = NULL;
- }
- if (*m != NULL) {
- /* pf_test can change ip header location */
- h = mtod(*m, struct ip *);
- NTOHS(h->ip_len);
- NTOHS(h->ip_off);
- }
- return chk;
-}
-
-static int
-pf_check_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
- struct inpcb *inp)
-{
- /*
- * XXX Wed Jul 9 22:03:16 2003 UTC
- * OpenBSD has changed its byte ordering convention on ip_len/ip_off
- * in network stack. OpenBSD's network stack have converted
- * ip_len/ip_off to host byte order frist as FreeBSD.
- * Now this is not true anymore , so we should convert back to network
- * byte order.
- */
- struct ip *h = NULL;
- int chk;
-
- /* We need a proper CSUM befor we start (s. OpenBSD ip_output) */
- if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
- in_delayed_cksum(*m);
- (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
- }
- if ((*m)->m_pkthdr.len >= (int)sizeof(*h)) {
- /* if m_pkthdr.len is less than ip header, pf will handle. */
- h = mtod(*m, struct ip *);
- HTONS(h->ip_len);
- HTONS(h->ip_off);
- }
- CURVNET_SET(ifp->if_vnet);
- chk = pf_test(PF_OUT, ifp, m, NULL, inp);
- CURVNET_RESTORE();
- if (chk && *m) {
- m_freem(*m);
- *m = NULL;
- }
- if (*m != NULL) {
- /* pf_test can change ip header location */
- h = mtod(*m, struct ip *);
- NTOHS(h->ip_len);
- NTOHS(h->ip_off);
- }
- return chk;
-}
-#endif
-
-#ifdef INET6
-static int
-pf_check6_in(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
- struct inpcb *inp)
-{
-
- /*
- * IPv6 is not affected by ip_len/ip_off byte order changes.
- */
- int chk;
-
- /*
- * In case of loopback traffic IPv6 uses the real interface in
- * order to support scoped addresses. In order to support stateful
- * filtering we have change this to lo0 as it is the case in IPv4.
- */
- CURVNET_SET(ifp->if_vnet);
- chk = pf_test6(PF_IN, (*m)->m_flags & M_LOOP ? V_loif : ifp, m,
- NULL, inp);
- CURVNET_RESTORE();
- if (chk && *m) {
- m_freem(*m);
- *m = NULL;
- }
- return chk;
-}
-
-static int
-pf_check6_out(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
- struct inpcb *inp)
-{
- /*
- * IPv6 does not affected ip_len/ip_off byte order changes.
- */
- int chk;
-
- /* We need a proper CSUM before we start (s. OpenBSD ip_output) */
- if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
-#ifdef INET
- /* XXX-BZ copy&paste error from r126261? */
- in_delayed_cksum(*m);
-#endif
- (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
- }
- CURVNET_SET(ifp->if_vnet);
- chk = pf_test6(PF_OUT, ifp, m, NULL, inp);
- CURVNET_RESTORE();
- if (chk && *m) {
- m_freem(*m);
- *m = NULL;
- }
- return chk;
-}
-#endif /* INET6 */
-
-static int
-hook_pf(void)
-{
-#ifdef INET
- struct pfil_head *pfh_inet;
-#endif
-#ifdef INET6
- struct pfil_head *pfh_inet6;
-#endif
-
- PF_UNLOCK_ASSERT();
-
- if (V_pf_pfil_hooked)
- return (0);
-
-#ifdef INET
- pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
- if (pfh_inet == NULL)
- return (ESRCH); /* XXX */
- pfil_add_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
- pfil_add_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
-#endif
-#ifdef INET6
- pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
- if (pfh_inet6 == NULL) {
-#ifdef INET
- pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
- pfh_inet);
- pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
- pfh_inet);
-#endif
- return (ESRCH); /* XXX */
- }
- pfil_add_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
- pfil_add_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
-#endif
-
- V_pf_pfil_hooked = 1;
- return (0);
-}
-
-static int
-dehook_pf(void)
-{
-#ifdef INET
- struct pfil_head *pfh_inet;
-#endif
-#ifdef INET6
- struct pfil_head *pfh_inet6;
-#endif
-
- PF_UNLOCK_ASSERT();
-
- if (V_pf_pfil_hooked == 0)
- return (0);
-
-#ifdef INET
- pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
- if (pfh_inet == NULL)
- return (ESRCH); /* XXX */
- pfil_remove_hook(pf_check_in, NULL, PFIL_IN | PFIL_WAITOK,
- pfh_inet);
- pfil_remove_hook(pf_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
- pfh_inet);
-#endif
-#ifdef INET6
- pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
- if (pfh_inet6 == NULL)
- return (ESRCH); /* XXX */
- pfil_remove_hook(pf_check6_in, NULL, PFIL_IN | PFIL_WAITOK,
- pfh_inet6);
- pfil_remove_hook(pf_check6_out, NULL, PFIL_OUT | PFIL_WAITOK,
- pfh_inet6);
-#endif
-
- V_pf_pfil_hooked = 0;
- return (0);
-}
-
-static int
-pf_load(void)
-{
- VNET_ITERATOR_DECL(vnet_iter);
-
- VNET_LIST_RLOCK();
- VNET_FOREACH(vnet_iter) {
- CURVNET_SET(vnet_iter);
- V_pf_pfil_hooked = 0;
- V_pf_end_threads = 0;
- V_debug_pfugidhack = 0;
- TAILQ_INIT(&V_pf_tags);
- TAILQ_INIT(&V_pf_qids);
- CURVNET_RESTORE();
- }
- VNET_LIST_RUNLOCK();
-
- init_pf_mutex();
- pf_dev = make_dev(&pf_cdevsw, 0, 0, 0, 0600, PF_NAME);
- init_zone_var();
- sx_init(&V_pf_consistency_lock, "pf_statetbl_lock");
- if (pfattach() < 0)
- return (ENOMEM);
-
- return (0);
-}
-
-static int
-pf_unload(void)
-{
- int error = 0;
-
- PF_LOCK();
- V_pf_status.running = 0;
- PF_UNLOCK();
- m_addr_chg_pf_p = NULL;
- error = dehook_pf();
- if (error) {
- /*
- * Should not happen!
- * XXX Due to error code ESRCH, kldunload will show
- * a message like 'No such process'.
- */
- printf("%s : pfil unregisteration fail\n", __FUNCTION__);
- return error;
- }
- PF_LOCK();
- shutdown_pf();
- V_pf_end_threads = 1;
- while (V_pf_end_threads < 2) {
- wakeup_one(pf_purge_thread);
- msleep(pf_purge_thread, &pf_task_mtx, 0, "pftmo", hz);
- }
- pfi_cleanup();
- pf_osfp_flush();
- pf_osfp_cleanup();
- cleanup_pf_zone();
- PF_UNLOCK();
- destroy_dev(pf_dev);
- destroy_pf_mutex();
- sx_destroy(&V_pf_consistency_lock);
- return error;
-}
-
-static int
-pf_modevent(module_t mod, int type, void *data)
-{
- int error = 0;
-
- switch(type) {
- case MOD_LOAD:
- error = pf_load();
- break;
- case MOD_QUIESCE:
- /*
- * Module should not be unloaded due to race conditions.
- */
- error = EPERM;
- break;
- case MOD_UNLOAD:
- error = pf_unload();
- break;
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-static moduledata_t pf_mod = {
- "pf",
- pf_modevent,
- 0
-};
-
-DECLARE_MODULE(pf, pf_mod, SI_SUB_PSEUDO, SI_ORDER_FIRST);
-MODULE_VERSION(pf, PF_MODVER);
-#endif /* __FreeBSD__ */
diff --git a/sys/contrib/pf/net/pf_lb.c b/sys/contrib/pf/net/pf_lb.c
deleted file mode 100644
index 4adc6f0..0000000
--- a/sys/contrib/pf/net/pf_lb.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/* $OpenBSD: pf_lb.c,v 1.2 2009/02/12 02:13:15 sthen Exp $ */
-
-/*
- * Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002 - 2008 Henning Brauer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- * Effort sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- *
- */
-
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#ifdef __FreeBSD__
-#include "opt_bpf.h"
-#include "opt_pf.h"
-
-#ifdef DEV_BPF
-#define NBPFILTER DEV_BPF
-#else
-#define NBPFILTER 0
-#endif
-
-#ifdef DEV_PFLOG
-#define NPFLOG DEV_PFLOG
-#else
-#define NPFLOG 0
-#endif
-
-#ifdef DEV_PFSYNC
-#define NPFSYNC DEV_PFSYNC
-#else
-#define NPFSYNC 0
-#endif
-
-#ifdef DEV_PFLOW
-#define NPFLOW DEV_PFLOW
-#else
-#define NPFLOW 0
-#endif
-
-#else
-#include "bpfilter.h"
-#include "pflog.h"
-#include "pfsync.h"
-#include "pflow.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/filio.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/time.h>
-#ifdef __FreeBSD__
-#include <sys/sysctl.h>
-#endif
-#ifndef __FreeBSD__
-#include <sys/pool.h>
-#endif
-#include <sys/proc.h>
-#ifdef __FreeBSD__
-#include <sys/kthread.h>
-#include <sys/lock.h>
-#include <sys/sx.h>
-#else
-#include <sys/rwlock.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <sys/md5.h>
-#else
-#include <crypto/md5.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/bpf.h>
-#include <net/route.h>
-#include <net/radix_mpath.h>
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcp_seq.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/in_pcb.h>
-#include <netinet/tcp_timer.h>
-#include <netinet/tcp_var.h>
-#include <netinet/udp_var.h>
-#include <netinet/icmp_var.h>
-#include <netinet/if_ether.h>
-
-#ifndef __FreeBSD__
-#include <dev/rndvar.h>
-#endif
-#include <net/pfvar.h>
-#include <net/if_pflog.h>
-#include <net/if_pflow.h>
-
-#if NPFSYNC > 0
-#include <net/if_pfsync.h>
-#endif /* NPFSYNC > 0 */
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#include <netinet/in_pcb.h>
-#include <netinet/icmp6.h>
-#include <netinet6/nd6.h>
-#endif /* INET6 */
-
-
-#ifdef __FreeBSD__
-#define DPFPRINTF(n, x) if (V_pf_status.debug >= (n)) printf x
-#else
-#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
-#endif
-
-/*
- * Global variables
- */
-
-void pf_hash(struct pf_addr *, struct pf_addr *,
- struct pf_poolhashkey *, sa_family_t);
-struct pf_rule *pf_match_translation(struct pf_pdesc *, struct mbuf *,
- int, int, struct pfi_kif *,
- struct pf_addr *, u_int16_t, struct pf_addr *,
- u_int16_t, int);
-int pf_get_sport(sa_family_t, u_int8_t, struct pf_rule *,
- struct pf_addr *, struct pf_addr *, u_int16_t,
- struct pf_addr *, u_int16_t*, u_int16_t, u_int16_t,
- struct pf_src_node **);
-
-#define mix(a,b,c) \
- do { \
- a -= b; a -= c; a ^= (c >> 13); \
- b -= c; b -= a; b ^= (a << 8); \
- c -= a; c -= b; c ^= (b >> 13); \
- a -= b; a -= c; a ^= (c >> 12); \
- b -= c; b -= a; b ^= (a << 16); \
- c -= a; c -= b; c ^= (b >> 5); \
- a -= b; a -= c; a ^= (c >> 3); \
- b -= c; b -= a; b ^= (a << 10); \
- c -= a; c -= b; c ^= (b >> 15); \
- } while (0)
-
-/*
- * hash function based on bridge_hash in if_bridge.c
- */
-void
-pf_hash(struct pf_addr *inaddr, struct pf_addr *hash,
- struct pf_poolhashkey *key, sa_family_t af)
-{
- u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = key->key32[0];
-
- switch (af) {
-#ifdef INET
- case AF_INET:
- a += inaddr->addr32[0];
- b += key->key32[1];
- mix(a, b, c);
- hash->addr32[0] = c + key->key32[2];
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- a += inaddr->addr32[0];
- b += inaddr->addr32[2];
- mix(a, b, c);
- hash->addr32[0] = c;
- a += inaddr->addr32[1];
- b += inaddr->addr32[3];
- c += key->key32[1];
- mix(a, b, c);
- hash->addr32[1] = c;
- a += inaddr->addr32[2];
- b += inaddr->addr32[1];
- c += key->key32[2];
- mix(a, b, c);
- hash->addr32[2] = c;
- a += inaddr->addr32[3];
- b += inaddr->addr32[0];
- c += key->key32[3];
- mix(a, b, c);
- hash->addr32[3] = c;
- break;
-#endif /* INET6 */
- }
-}
-
-struct pf_rule *
-pf_match_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
- int direction, struct pfi_kif *kif, struct pf_addr *saddr, u_int16_t sport,
- struct pf_addr *daddr, u_int16_t dport, int rs_num)
-{
- struct pf_rule *r, *rm = NULL;
- struct pf_ruleset *ruleset = NULL;
- int tag = -1;
- int rtableid = -1;
- int asd = 0;
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
- while (r && rm == NULL) {
- struct pf_rule_addr *src = NULL, *dst = NULL;
- struct pf_addr_wrap *xdst = NULL;
-
- if (r->action == PF_BINAT && direction == PF_IN) {
- src = &r->dst;
- if (r->rpool.cur != NULL)
- xdst = &r->rpool.cur->addr;
- } else {
- src = &r->src;
- dst = &r->dst;
- }
-
- r->evaluations++;
- if (pfi_kif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != direction)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != pd->af)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != pd->proto)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&src->addr, saddr, pd->af,
- src->neg, kif, M_GETFIB(m)))
- r = r->skip[src == &r->src ? PF_SKIP_SRC_ADDR :
- PF_SKIP_DST_ADDR].ptr;
- else if (src->port_op && !pf_match_port(src->port_op,
- src->port[0], src->port[1], sport))
- r = r->skip[src == &r->src ? PF_SKIP_SRC_PORT :
- PF_SKIP_DST_PORT].ptr;
- else if (dst != NULL &&
- PF_MISMATCHAW(&dst->addr, daddr, pd->af, dst->neg, NULL,
- M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- else if (xdst != NULL && PF_MISMATCHAW(xdst, daddr, pd->af,
- 0, NULL, M_GETFIB(m)))
- r = TAILQ_NEXT(r, entries);
- else if (dst != NULL && dst->port_op &&
- !pf_match_port(dst->port_op, dst->port[0],
- dst->port[1], dport))
- r = r->skip[PF_SKIP_DST_PORT].ptr;
-#ifdef __FreeBSD__
- else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
-#else
- else if (r->match_tag && !pf_match_tag(m, r, &tag))
-#endif
- r = TAILQ_NEXT(r, entries);
- else if (r->os_fingerprint != PF_OSFP_ANY && (pd->proto !=
- IPPROTO_TCP || !pf_osfp_match(pf_osfp_fingerprint(pd, m,
- off, pd->hdr.tcp), r->os_fingerprint)))
- r = TAILQ_NEXT(r, entries);
- else {
- if (r->tag)
- tag = r->tag;
- if (r->rtableid >= 0)
- rtableid = r->rtableid;
- if (r->anchor == NULL) {
- rm = r;
- } else
- pf_step_into_anchor(&asd, &ruleset, rs_num,
- &r, NULL, NULL);
- }
- if (r == NULL)
- pf_step_out_of_anchor(&asd, &ruleset, rs_num, &r,
- NULL, NULL);
- }
-#ifdef __FreeBSD__
- if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag))
-#else
- if (pf_tag_packet(m, tag, rtableid))
-#endif
- return (NULL);
- if (rm != NULL && (rm->action == PF_NONAT ||
- rm->action == PF_NORDR || rm->action == PF_NOBINAT))
- return (NULL);
- return (rm);
-}
-
-int
-pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r,
- struct pf_addr *saddr, struct pf_addr *daddr, u_int16_t dport,
- struct pf_addr *naddr, u_int16_t *nport, u_int16_t low, u_int16_t high,
- struct pf_src_node **sn)
-{
- struct pf_state_key_cmp key;
- struct pf_addr init_addr;
- u_int16_t cut;
-
- bzero(&init_addr, sizeof(init_addr));
- if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
- return (1);
-
- if (proto == IPPROTO_ICMP) {
- low = 1;
- high = 65535;
- }
-
- do {
- key.af = af;
- key.proto = proto;
- PF_ACPY(&key.addr[1], daddr, key.af);
- PF_ACPY(&key.addr[0], naddr, key.af);
- key.port[1] = dport;
-
- /*
- * port search; start random, step;
- * similar 2 portloop in in_pcbbind
- */
- if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP ||
- proto == IPPROTO_ICMP)) {
- key.port[0] = dport;
- if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
- return (0);
- } else if (low == 0 && high == 0) {
- key.port[0] = *nport;
- if (pf_find_state_all(&key, PF_IN, NULL) == NULL)
- return (0);
- } else if (low == high) {
- key.port[0] = htons(low);
- if (pf_find_state_all(&key, PF_IN, NULL) == NULL) {
- *nport = htons(low);
- return (0);
- }
- } else {
- u_int16_t tmp;
-
- if (low > high) {
- tmp = low;
- low = high;
- high = tmp;
- }
- /* low < high */
-#ifdef __FreeBSD__
- cut = htonl(arc4random()) % (1 + high - low) + low;
-#else
- cut = arc4random_uniform(1 + high - low) + low;
-#endif
- /* low <= cut <= high */
- for (tmp = cut; tmp <= high; ++(tmp)) {
- key.port[0] = htons(tmp);
- if (pf_find_state_all(&key, PF_IN, NULL) ==
-#ifdef __FreeBSD__
- NULL) {
-#else
- NULL && !in_baddynamic(tmp, proto)) {
-#endif
- *nport = htons(tmp);
- return (0);
- }
- }
- for (tmp = cut - 1; tmp >= low; --(tmp)) {
- key.port[0] = htons(tmp);
- if (pf_find_state_all(&key, PF_IN, NULL) ==
-#ifdef __FreeBSD__
- NULL) {
-#else
- NULL && !in_baddynamic(tmp, proto)) {
-#endif
- *nport = htons(tmp);
- return (0);
- }
- }
- }
-
- switch (r->rpool.opts & PF_POOL_TYPEMASK) {
- case PF_POOL_RANDOM:
- case PF_POOL_ROUNDROBIN:
- if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
- return (1);
- break;
- case PF_POOL_NONE:
- case PF_POOL_SRCHASH:
- case PF_POOL_BITMASK:
- default:
- return (1);
- }
- } while (! PF_AEQ(&init_addr, naddr, af) );
- return (1); /* none available */
-}
-
-int
-pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
- struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sn)
-{
- unsigned char hash[16];
- struct pf_pool *rpool = &r->rpool;
- struct pf_addr *raddr = &rpool->cur->addr.v.a.addr;
- struct pf_addr *rmask = &rpool->cur->addr.v.a.mask;
- struct pf_pooladdr *acur = rpool->cur;
- struct pf_src_node k;
-
- if (*sn == NULL && r->rpool.opts & PF_POOL_STICKYADDR &&
- (r->rpool.opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
- k.af = af;
- PF_ACPY(&k.addr, saddr, af);
- if (r->rule_flag & PFRULE_RULESRCTRACK ||
- r->rpool.opts & PF_POOL_STICKYADDR)
- k.rule.ptr = r;
- else
- k.rule.ptr = NULL;
-#ifdef __FreeBSD__
- V_pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
- *sn = RB_FIND(pf_src_tree, &V_tree_src_tracking, &k);
-#else
- pf_status.scounters[SCNT_SRC_NODE_SEARCH]++;
- *sn = RB_FIND(pf_src_tree, &tree_src_tracking, &k);
-#endif
- if (*sn != NULL && !PF_AZERO(&(*sn)->raddr, af)) {
- PF_ACPY(naddr, &(*sn)->raddr, af);
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- printf("pf_map_addr: src tracking maps ");
- pf_print_host(&k.addr, 0, af);
- printf(" to ");
- pf_print_host(naddr, 0, af);
- printf("\n");
- }
- return (0);
- }
- }
-
- if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
- return (1);
- if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
- switch (af) {
-#ifdef INET
- case AF_INET:
- if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
- (rpool->opts & PF_POOL_TYPEMASK) !=
- PF_POOL_ROUNDROBIN)
- return (1);
- raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
- rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
- (rpool->opts & PF_POOL_TYPEMASK) !=
- PF_POOL_ROUNDROBIN)
- return (1);
- raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
- rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
- break;
-#endif /* INET6 */
- }
- } else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
- if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
- return (1); /* unsupported */
- } else {
- raddr = &rpool->cur->addr.v.a.addr;
- rmask = &rpool->cur->addr.v.a.mask;
- }
-
- switch (rpool->opts & PF_POOL_TYPEMASK) {
- case PF_POOL_NONE:
- PF_ACPY(naddr, raddr, af);
- break;
- case PF_POOL_BITMASK:
- PF_POOLMASK(naddr, raddr, rmask, saddr, af);
- break;
- case PF_POOL_RANDOM:
- if (init_addr != NULL && PF_AZERO(init_addr, af)) {
- switch (af) {
-#ifdef INET
- case AF_INET:
- rpool->counter.addr32[0] = htonl(arc4random());
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (rmask->addr32[3] != 0xffffffff)
- rpool->counter.addr32[3] =
- htonl(arc4random());
- else
- break;
- if (rmask->addr32[2] != 0xffffffff)
- rpool->counter.addr32[2] =
- htonl(arc4random());
- else
- break;
- if (rmask->addr32[1] != 0xffffffff)
- rpool->counter.addr32[1] =
- htonl(arc4random());
- else
- break;
- if (rmask->addr32[0] != 0xffffffff)
- rpool->counter.addr32[0] =
- htonl(arc4random());
- break;
-#endif /* INET6 */
- }
- PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
- PF_ACPY(init_addr, naddr, af);
-
- } else {
- PF_AINC(&rpool->counter, af);
- PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
- }
- break;
- case PF_POOL_SRCHASH:
- pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
- PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
- break;
- case PF_POOL_ROUNDROBIN:
- if (rpool->cur->addr.type == PF_ADDR_TABLE) {
- if (!pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af))
- goto get_addr;
- } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
- if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af))
- goto get_addr;
- } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
- goto get_addr;
-
- try_next:
- if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL)
- rpool->cur = TAILQ_FIRST(&rpool->list);
- if (rpool->cur->addr.type == PF_ADDR_TABLE) {
- rpool->tblidx = -1;
- if (pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af)) {
- /* table contains no address of type 'af' */
- if (rpool->cur != acur)
- goto try_next;
- return (1);
- }
- } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
- rpool->tblidx = -1;
- if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af)) {
- /* table contains no address of type 'af' */
- if (rpool->cur != acur)
- goto try_next;
- return (1);
- }
- } else {
- raddr = &rpool->cur->addr.v.a.addr;
- rmask = &rpool->cur->addr.v.a.mask;
- PF_ACPY(&rpool->counter, raddr, af);
- }
-
- get_addr:
- PF_ACPY(naddr, &rpool->counter, af);
- if (init_addr != NULL && PF_AZERO(init_addr, af))
- PF_ACPY(init_addr, naddr, af);
- PF_AINC(&rpool->counter, af);
- break;
- }
- if (*sn != NULL)
- PF_ACPY(&(*sn)->raddr, naddr, af);
-
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC &&
-#else
- if (pf_status.debug >= PF_DEBUG_MISC &&
-#endif
- (rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
- printf("pf_map_addr: selected address ");
- pf_print_host(naddr, 0, af);
- printf("\n");
- }
-
- return (0);
-}
-
-struct pf_rule *
-pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off, int direction,
- struct pfi_kif *kif, struct pf_src_node **sn,
- struct pf_state_key **skw, struct pf_state_key **sks,
- struct pf_state_key **skp, struct pf_state_key **nkp,
- struct pf_addr *saddr, struct pf_addr *daddr,
- u_int16_t sport, u_int16_t dport)
-{
- struct pf_rule *r = NULL;
-
-
- if (direction == PF_OUT) {
- r = pf_match_translation(pd, m, off, direction, kif, saddr,
- sport, daddr, dport, PF_RULESET_BINAT);
- if (r == NULL)
- r = pf_match_translation(pd, m, off, direction, kif,
- saddr, sport, daddr, dport, PF_RULESET_NAT);
- } else {
- r = pf_match_translation(pd, m, off, direction, kif, saddr,
- sport, daddr, dport, PF_RULESET_RDR);
- if (r == NULL)
- r = pf_match_translation(pd, m, off, direction, kif,
- saddr, sport, daddr, dport, PF_RULESET_BINAT);
- }
-
- if (r != NULL) {
- struct pf_addr *naddr;
- u_int16_t *nport;
-
- if (pf_state_key_setup(pd, r, skw, sks, skp, nkp,
- saddr, daddr, sport, dport))
- return r;
-
- /* XXX We only modify one side for now. */
- naddr = &(*nkp)->addr[1];
- nport = &(*nkp)->port[1];
-
- switch (r->action) {
- case PF_NONAT:
- case PF_NOBINAT:
- case PF_NORDR:
- return (NULL);
- case PF_NAT:
- if (pf_get_sport(pd->af, pd->proto, r, saddr,
- daddr, dport, naddr, nport, r->rpool.proxy_port[0],
- r->rpool.proxy_port[1], sn)) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: NAT proxy port allocation "
- "(%u-%u) failed\n",
- r->rpool.proxy_port[0],
- r->rpool.proxy_port[1]));
- return (NULL);
- }
- break;
- case PF_BINAT:
- switch (direction) {
- case PF_OUT:
- if (r->rpool.cur->addr.type == PF_ADDR_DYNIFTL){
- switch (pd->af) {
-#ifdef INET
- case AF_INET:
- if (r->rpool.cur->addr.p.dyn->
- pfid_acnt4 < 1)
- return (NULL);
- PF_POOLMASK(naddr,
- &r->rpool.cur->addr.p.dyn->
- pfid_addr4,
- &r->rpool.cur->addr.p.dyn->
- pfid_mask4,
- saddr, AF_INET);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (r->rpool.cur->addr.p.dyn->
- pfid_acnt6 < 1)
- return (NULL);
- PF_POOLMASK(naddr,
- &r->rpool.cur->addr.p.dyn->
- pfid_addr6,
- &r->rpool.cur->addr.p.dyn->
- pfid_mask6,
- saddr, AF_INET6);
- break;
-#endif /* INET6 */
- }
- } else
- PF_POOLMASK(naddr,
- &r->rpool.cur->addr.v.a.addr,
- &r->rpool.cur->addr.v.a.mask,
- saddr, pd->af);
- break;
- case PF_IN:
- if (r->src.addr.type == PF_ADDR_DYNIFTL) {
- switch (pd->af) {
-#ifdef INET
- case AF_INET:
- if (r->src.addr.p.dyn->
- pfid_acnt4 < 1)
- return (NULL);
- PF_POOLMASK(naddr,
- &r->src.addr.p.dyn->
- pfid_addr4,
- &r->src.addr.p.dyn->
- pfid_mask4,
- daddr, AF_INET);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (r->src.addr.p.dyn->
- pfid_acnt6 < 1)
- return (NULL);
- PF_POOLMASK(naddr,
- &r->src.addr.p.dyn->
- pfid_addr6,
- &r->src.addr.p.dyn->
- pfid_mask6,
- daddr, AF_INET6);
- break;
-#endif /* INET6 */
- }
- } else
- PF_POOLMASK(naddr,
- &r->src.addr.v.a.addr,
- &r->src.addr.v.a.mask, daddr,
- pd->af);
- break;
- }
- break;
- case PF_RDR: {
- if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
- return (NULL);
- if ((r->rpool.opts & PF_POOL_TYPEMASK) ==
- PF_POOL_BITMASK)
- PF_POOLMASK(naddr, naddr,
- &r->rpool.cur->addr.v.a.mask, daddr,
- pd->af);
-
- if (r->rpool.proxy_port[1]) {
- u_int32_t tmp_nport;
-
- tmp_nport = ((ntohs(dport) -
- ntohs(r->dst.port[0])) %
- (r->rpool.proxy_port[1] -
- r->rpool.proxy_port[0] + 1)) +
- r->rpool.proxy_port[0];
-
- /* wrap around if necessary */
- if (tmp_nport > 65535)
- tmp_nport -= 65535;
- *nport = htons((u_int16_t)tmp_nport);
- } else if (r->rpool.proxy_port[0])
- *nport = htons(r->rpool.proxy_port[0]);
- break;
- }
- default:
- return (NULL);
- }
- /*
- * Translation was a NOP.
- * Pretend there was no match.
- */
- if (!bcmp(*skp, *nkp, sizeof(struct pf_state_key_cmp))) {
-#ifdef __FreeBSD__
- pool_put(&V_pf_state_key_pl, *nkp);
- pool_put(&V_pf_state_key_pl, *skp);
-#else
- pool_put(&pf_state_key_pl, *nkp);
- pool_put(&pf_state_key_pl, *skp);
-#endif
- *skw = *sks = *nkp = *skp = NULL;
- return (NULL);
- }
- }
-
- return (r);
-}
-
diff --git a/sys/contrib/pf/net/pf_mtag.h b/sys/contrib/pf/net/pf_mtag.h
deleted file mode 100644
index 141a867..0000000
--- a/sys/contrib/pf/net/pf_mtag.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/* $FreeBSD$ */
-/*
- * Copyright (c) 2001 Daniel Hartmeier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- */
-
-#ifndef _NET_PF_MTAG_H_
-#define _NET_PF_MTAG_H_
-
-#ifdef _KERNEL
-
-#define PF_TAG_GENERATED 0x01
-#define PF_TAG_FRAGCACHE 0x02
-#define PF_TAG_TRANSLATE_LOCALHOST 0x04
-#define PF_PACKET_LOOPED 0x08
-#define PF_FASTFWD_OURS_PRESENT 0x10
-
-struct pf_mtag {
- void *hdr; /* saved hdr pos in mbuf, for ECN */
- void *statekey; /* pf stackside statekey */
- u_int32_t qid; /* queue id */
- u_int rtableid; /* alternate routing table id */
- u_int16_t tag; /* tag id */
- u_int8_t flags;
- u_int8_t routed;
-};
-
-static __inline struct pf_mtag *pf_find_mtag(struct mbuf *);
-static __inline struct pf_mtag *pf_get_mtag(struct mbuf *);
-
-static __inline struct pf_mtag *
-pf_find_mtag(struct mbuf *m)
-{
- struct m_tag *mtag;
-
- if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL)
- return (NULL);
-
- return ((struct pf_mtag *)(mtag + 1));
-}
-
-static __inline struct pf_mtag *
-pf_get_mtag(struct mbuf *m)
-{
- struct m_tag *mtag;
-
- if ((mtag = m_tag_find(m, PACKET_TAG_PF, NULL)) == NULL) {
- mtag = m_tag_get(PACKET_TAG_PF, sizeof(struct pf_mtag),
- M_NOWAIT);
- if (mtag == NULL)
- return (NULL);
- bzero(mtag + 1, sizeof(struct pf_mtag));
- m_tag_prepend(m, mtag);
- }
-
- return ((struct pf_mtag *)(mtag + 1));
-}
-#endif /* _KERNEL */
-#endif /* _NET_PF_MTAG_H_ */
diff --git a/sys/contrib/pf/net/pf_norm.c b/sys/contrib/pf/net/pf_norm.c
deleted file mode 100644
index 2b20c85..0000000
--- a/sys/contrib/pf/net/pf_norm.c
+++ /dev/null
@@ -1,2359 +0,0 @@
-/* $OpenBSD: pf_norm.c,v 1.114 2009/01/29 14:11:45 henning Exp $ */
-
-/*
- * Copyright 2001 Niels Provos <provos@citi.umich.edu>
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
- */
-
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_pf.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#ifdef DEV_PFLOG
-#define NPFLOG DEV_PFLOG
-#else
-#define NPFLOG 0
-#endif
-#else
-#include "pflog.h"
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/filio.h>
-#include <sys/fcntl.h>
-#include <sys/socket.h>
-#include <sys/kernel.h>
-#include <sys/time.h>
-#ifndef __FreeBSD__
-#include <sys/pool.h>
-
-#include <dev/rndvar.h>
-#endif
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/bpf.h>
-#include <net/route.h>
-#include <net/if_pflog.h>
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/tcp.h>
-#include <netinet/tcp_seq.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif /* INET6 */
-
-#include <net/pfvar.h>
-
-#ifndef __FreeBSD__
-struct pf_frent {
- LIST_ENTRY(pf_frent) fr_next;
- struct ip *fr_ip;
- struct mbuf *fr_m;
-};
-
-struct pf_frcache {
- LIST_ENTRY(pf_frcache) fr_next;
- uint16_t fr_off;
- uint16_t fr_end;
-};
-#endif
-
-#define PFFRAG_SEENLAST 0x0001 /* Seen the last fragment for this */
-#define PFFRAG_NOBUFFER 0x0002 /* Non-buffering fragment cache */
-#define PFFRAG_DROP 0x0004 /* Drop all fragments */
-#define BUFFER_FRAGMENTS(fr) (!((fr)->fr_flags & PFFRAG_NOBUFFER))
-
-#ifndef __FreeBSD__
-struct pf_fragment {
- RB_ENTRY(pf_fragment) fr_entry;
- TAILQ_ENTRY(pf_fragment) frag_next;
- struct in_addr fr_src;
- struct in_addr fr_dst;
- u_int8_t fr_p; /* protocol of this fragment */
- u_int8_t fr_flags; /* status flags */
- u_int16_t fr_id; /* fragment id for reassemble */
- u_int16_t fr_max; /* fragment data max */
- u_int32_t fr_timeout;
-#define fr_queue fr_u.fru_queue
-#define fr_cache fr_u.fru_cache
- union {
- LIST_HEAD(pf_fragq, pf_frent) fru_queue; /* buffering */
- LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
- } fr_u;
-};
-#endif
-
-#ifdef __FreeBSD__
-TAILQ_HEAD(pf_fragqueue, pf_fragment);
-TAILQ_HEAD(pf_cachequeue, pf_fragment);
-VNET_DEFINE(struct pf_fragqueue, pf_fragqueue);
-#define V_pf_fragqueue VNET(pf_fragqueue)
-VNET_DEFINE(struct pf_cachequeue, pf_cachequeue);
-#define V_pf_cachequeue VNET(pf_cachequeue)
-#else
-TAILQ_HEAD(pf_fragqueue, pf_fragment) pf_fragqueue;
-TAILQ_HEAD(pf_cachequeue, pf_fragment) pf_cachequeue;
-#endif
-
-#ifndef __FreeBSD__
-static __inline int pf_frag_compare(struct pf_fragment *,
- struct pf_fragment *);
-#else
-static int pf_frag_compare(struct pf_fragment *,
- struct pf_fragment *);
-#endif
-
-#ifdef __FreeBSD__
-RB_HEAD(pf_frag_tree, pf_fragment);
-VNET_DEFINE(struct pf_frag_tree, pf_frag_tree);
-#define V_pf_frag_tree VNET(pf_frag_tree)
-VNET_DEFINE(struct pf_frag_tree, pf_cache_tree);
-#define V_pf_cache_tree VNET(pf_cache_tree)
-#else
-RB_HEAD(pf_frag_tree, pf_fragment) pf_frag_tree, pf_cache_tree;
-#endif
-RB_PROTOTYPE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
-RB_GENERATE(pf_frag_tree, pf_fragment, fr_entry, pf_frag_compare);
-
-/* Private prototypes */
-void pf_ip2key(struct pf_fragment *, struct ip *);
-void pf_remove_fragment(struct pf_fragment *);
-void pf_flush_fragments(void);
-void pf_free_fragment(struct pf_fragment *);
-struct pf_fragment *pf_find_fragment(struct ip *, struct pf_frag_tree *);
-struct mbuf *pf_reassemble(struct mbuf **, struct pf_fragment **,
- struct pf_frent *, int);
-struct mbuf *pf_fragcache(struct mbuf **, struct ip*,
- struct pf_fragment **, int, int, int *);
-int pf_normalize_tcpopt(struct pf_rule *, struct mbuf *,
- struct tcphdr *, int, sa_family_t);
-void pf_scrub_ip(struct mbuf **, u_int32_t, u_int8_t,
- u_int8_t);
-#ifdef INET6
-void pf_scrub_ip6(struct mbuf **, u_int8_t);
-#endif
-#ifdef __FreeBSD__
-#define DPFPRINTF(x) do { \
- if (V_pf_status.debug >= PF_DEBUG_MISC) { \
- printf("%s: ", __func__); \
- printf x ; \
- } \
-} while(0)
-#else
-#define DPFPRINTF(x) do { \
- if (pf_status.debug >= PF_DEBUG_MISC) { \
- printf("%s: ", __func__); \
- printf x ; \
- } \
-} while(0)
-#endif
-
-/* Globals */
-#ifdef __FreeBSD__
-VNET_DEFINE(uma_zone_t, pf_frent_pl);
-VNET_DEFINE(uma_zone_t, pf_frag_pl);
-VNET_DEFINE(uma_zone_t, pf_cache_pl);
-VNET_DEFINE(uma_zone_t, pf_cent_pl);
-VNET_DEFINE(uma_zone_t, pf_state_scrub_pl);
-
-VNET_DEFINE(int, pf_nfrents);
-#define V_pf_nfrents VNET(pf_nfrents)
-VNET_DEFINE(int, pf_ncache);
-#define V_pf_ncache VNET(pf_ncache)
-#else
-struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
-struct pool pf_state_scrub_pl;
-int pf_nfrents, pf_ncache;
-#endif
-
-void
-pf_normalize_init(void)
-{
-#ifdef __FreeBSD__
- /*
- * XXX
- * No high water mark support(It's hint not hard limit).
- * uma_zone_set_max(pf_frag_pl, PFFRAG_FRAG_HIWAT);
- */
- uma_zone_set_max(V_pf_frent_pl, PFFRAG_FRENT_HIWAT);
- uma_zone_set_max(V_pf_cache_pl, PFFRAG_FRCACHE_HIWAT);
- uma_zone_set_max(V_pf_cent_pl, PFFRAG_FRCENT_HIWAT);
-#else
- pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent",
- NULL);
- pool_init(&pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag",
- NULL);
- pool_init(&pf_cache_pl, sizeof(struct pf_fragment), 0, 0, 0,
- "pffrcache", NULL);
- pool_init(&pf_cent_pl, sizeof(struct pf_frcache), 0, 0, 0, "pffrcent",
- NULL);
- pool_init(&pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
- "pfstscr", NULL);
-
- pool_sethiwat(&pf_frag_pl, PFFRAG_FRAG_HIWAT);
- pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0);
- pool_sethardlimit(&pf_cache_pl, PFFRAG_FRCACHE_HIWAT, NULL, 0);
- pool_sethardlimit(&pf_cent_pl, PFFRAG_FRCENT_HIWAT, NULL, 0);
-#endif
-
-#ifdef __FreeBSD__
- TAILQ_INIT(&V_pf_fragqueue);
- TAILQ_INIT(&V_pf_cachequeue);
-#else
- TAILQ_INIT(&pf_fragqueue);
- TAILQ_INIT(&pf_cachequeue);
-#endif
-}
-
-#ifdef __FreeBSD__
-static int
-#else
-static __inline int
-#endif
-pf_frag_compare(struct pf_fragment *a, struct pf_fragment *b)
-{
- int diff;
-
- if ((diff = a->fr_id - b->fr_id))
- return (diff);
- else if ((diff = a->fr_p - b->fr_p))
- return (diff);
- else if (a->fr_src.s_addr < b->fr_src.s_addr)
- return (-1);
- else if (a->fr_src.s_addr > b->fr_src.s_addr)
- return (1);
- else if (a->fr_dst.s_addr < b->fr_dst.s_addr)
- return (-1);
- else if (a->fr_dst.s_addr > b->fr_dst.s_addr)
- return (1);
- return (0);
-}
-
-void
-pf_purge_expired_fragments(void)
-{
- struct pf_fragment *frag;
-#ifdef __FreeBSD__
- u_int32_t expire = time_second -
- V_pf_default_rule.timeout[PFTM_FRAG];
-#else
- u_int32_t expire = time_second -
- pf_default_rule.timeout[PFTM_FRAG];
-#endif
-
-#ifdef __FreeBSD__
- while ((frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue)) != NULL) {
- KASSERT((BUFFER_FRAGMENTS(frag)),
- ("BUFFER_FRAGMENTS(frag) == 0: %s", __FUNCTION__));
-#else
- while ((frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue)) != NULL) {
- KASSERT(BUFFER_FRAGMENTS(frag));
-#endif
- if (frag->fr_timeout > expire)
- break;
-
- DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
- pf_free_fragment(frag);
- }
-
-#ifdef __FreeBSD__
- while ((frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue)) != NULL) {
- KASSERT((!BUFFER_FRAGMENTS(frag)),
- ("BUFFER_FRAGMENTS(frag) != 0: %s", __FUNCTION__));
-#else
- while ((frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue)) != NULL) {
- KASSERT(!BUFFER_FRAGMENTS(frag));
-#endif
- if (frag->fr_timeout > expire)
- break;
-
- DPFPRINTF(("expiring %d(%p)\n", frag->fr_id, frag));
- pf_free_fragment(frag);
-#ifdef __FreeBSD__
- KASSERT((TAILQ_EMPTY(&V_pf_cachequeue) ||
- TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue) != frag),
- ("!(TAILQ_EMPTY() || TAILQ_LAST() == farg): %s",
- __FUNCTION__));
-#else
- KASSERT(TAILQ_EMPTY(&pf_cachequeue) ||
- TAILQ_LAST(&pf_cachequeue, pf_cachequeue) != frag);
-#endif
- }
-}
-
-/*
- * Try to flush old fragments to make space for new ones
- */
-
-void
-pf_flush_fragments(void)
-{
- struct pf_fragment *frag;
- int goal;
-
-#ifdef __FreeBSD__
- goal = V_pf_nfrents * 9 / 10;
- DPFPRINTF(("trying to free > %d frents\n",
- V_pf_nfrents - goal));
- while (goal < V_pf_nfrents) {
-#else
- goal = pf_nfrents * 9 / 10;
- DPFPRINTF(("trying to free > %d frents\n",
- pf_nfrents - goal));
- while (goal < pf_nfrents) {
-#endif
-#ifdef __FreeBSD__
- frag = TAILQ_LAST(&V_pf_fragqueue, pf_fragqueue);
-#else
- frag = TAILQ_LAST(&pf_fragqueue, pf_fragqueue);
-#endif
- if (frag == NULL)
- break;
- pf_free_fragment(frag);
- }
-
-
-#ifdef __FreeBSD__
- goal = V_pf_ncache * 9 / 10;
- DPFPRINTF(("trying to free > %d cache entries\n",
- V_pf_ncache - goal));
- while (goal < V_pf_ncache) {
-#else
- goal = pf_ncache * 9 / 10;
- DPFPRINTF(("trying to free > %d cache entries\n",
- pf_ncache - goal));
- while (goal < pf_ncache) {
-#endif
-#ifdef __FreeBSD__
- frag = TAILQ_LAST(&V_pf_cachequeue, pf_cachequeue);
-#else
- frag = TAILQ_LAST(&pf_cachequeue, pf_cachequeue);
-#endif
- if (frag == NULL)
- break;
- pf_free_fragment(frag);
- }
-}
-
-/* Frees the fragments and all associated entries */
-
-void
-pf_free_fragment(struct pf_fragment *frag)
-{
- struct pf_frent *frent;
- struct pf_frcache *frcache;
-
- /* Free all fragments */
- if (BUFFER_FRAGMENTS(frag)) {
- for (frent = LIST_FIRST(&frag->fr_queue); frent;
- frent = LIST_FIRST(&frag->fr_queue)) {
- LIST_REMOVE(frent, fr_next);
-
- m_freem(frent->fr_m);
-#ifdef __FreeBSD__
- pool_put(&V_pf_frent_pl, frent);
- V_pf_nfrents--;
-#else
- pool_put(&pf_frent_pl, frent);
- pf_nfrents--;
-#endif
- }
- } else {
- for (frcache = LIST_FIRST(&frag->fr_cache); frcache;
- frcache = LIST_FIRST(&frag->fr_cache)) {
- LIST_REMOVE(frcache, fr_next);
-
-#ifdef __FreeBSD__
- KASSERT((LIST_EMPTY(&frag->fr_cache) ||
- LIST_FIRST(&frag->fr_cache)->fr_off >
- frcache->fr_end),
- ("! (LIST_EMPTY() || LIST_FIRST()->fr_off >"
- " frcache->fr_end): %s", __FUNCTION__));
-
- pool_put(&V_pf_cent_pl, frcache);
- V_pf_ncache--;
-#else
- KASSERT(LIST_EMPTY(&frag->fr_cache) ||
- LIST_FIRST(&frag->fr_cache)->fr_off >
- frcache->fr_end);
-
- pool_put(&pf_cent_pl, frcache);
- pf_ncache--;
-#endif
- }
- }
-
- pf_remove_fragment(frag);
-}
-
-void
-pf_ip2key(struct pf_fragment *key, struct ip *ip)
-{
- key->fr_p = ip->ip_p;
- key->fr_id = ip->ip_id;
- key->fr_src.s_addr = ip->ip_src.s_addr;
- key->fr_dst.s_addr = ip->ip_dst.s_addr;
-}
-
-struct pf_fragment *
-pf_find_fragment(struct ip *ip, struct pf_frag_tree *tree)
-{
- struct pf_fragment key;
- struct pf_fragment *frag;
-
- pf_ip2key(&key, ip);
-
- frag = RB_FIND(pf_frag_tree, tree, &key);
- if (frag != NULL) {
- /* XXX Are we sure we want to update the timeout? */
- frag->fr_timeout = time_second;
- if (BUFFER_FRAGMENTS(frag)) {
-#ifdef __FreeBSD__
- TAILQ_REMOVE(&V_pf_fragqueue, frag, frag_next);
- TAILQ_INSERT_HEAD(&V_pf_fragqueue, frag, frag_next);
-#else
- TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
- TAILQ_INSERT_HEAD(&pf_fragqueue, frag, frag_next);
-#endif
- } else {
-#ifdef __FreeBSD__
- TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
- TAILQ_INSERT_HEAD(&V_pf_cachequeue, frag, frag_next);
-#else
- TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
- TAILQ_INSERT_HEAD(&pf_cachequeue, frag, frag_next);
-#endif
- }
- }
-
- return (frag);
-}
-
-/* Removes a fragment from the fragment queue and frees the fragment */
-
-void
-pf_remove_fragment(struct pf_fragment *frag)
-{
- if (BUFFER_FRAGMENTS(frag)) {
-#ifdef __FreeBSD__
- RB_REMOVE(pf_frag_tree, &V_pf_frag_tree, frag);
- TAILQ_REMOVE(&V_pf_fragqueue, frag, frag_next);
- pool_put(&V_pf_frag_pl, frag);
-#else
- RB_REMOVE(pf_frag_tree, &pf_frag_tree, frag);
- TAILQ_REMOVE(&pf_fragqueue, frag, frag_next);
- pool_put(&pf_frag_pl, frag);
-#endif
- } else {
-#ifdef __FreeBSD__
- RB_REMOVE(pf_frag_tree, &V_pf_cache_tree, frag);
- TAILQ_REMOVE(&V_pf_cachequeue, frag, frag_next);
- pool_put(&V_pf_cache_pl, frag);
-#else
- RB_REMOVE(pf_frag_tree, &pf_cache_tree, frag);
- TAILQ_REMOVE(&pf_cachequeue, frag, frag_next);
- pool_put(&pf_cache_pl, frag);
-#endif
- }
-}
-
-#define FR_IP_OFF(fr) ((ntohs((fr)->fr_ip->ip_off) & IP_OFFMASK) << 3)
-struct mbuf *
-pf_reassemble(struct mbuf **m0, struct pf_fragment **frag,
- struct pf_frent *frent, int mff)
-{
- struct mbuf *m = *m0, *m2;
- struct pf_frent *frea, *next;
- struct pf_frent *frep = NULL;
- struct ip *ip = frent->fr_ip;
- int hlen = ip->ip_hl << 2;
- u_int16_t off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
- u_int16_t ip_len = ntohs(ip->ip_len) - ip->ip_hl * 4;
- u_int16_t max = ip_len + off;
-
-#ifdef __FreeBSD__
- KASSERT((*frag == NULL || BUFFER_FRAGMENTS(*frag)),
- ("! (*frag == NULL || BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
-#else
- KASSERT(*frag == NULL || BUFFER_FRAGMENTS(*frag));
-#endif
-
- /* Strip off ip header */
- m->m_data += hlen;
- m->m_len -= hlen;
-
- /* Create a new reassembly queue for this packet */
- if (*frag == NULL) {
-#ifdef __FreeBSD__
- *frag = pool_get(&V_pf_frag_pl, PR_NOWAIT);
-#else
- *frag = pool_get(&pf_frag_pl, PR_NOWAIT);
-#endif
- if (*frag == NULL) {
- pf_flush_fragments();
-#ifdef __FreeBSD__
- *frag = pool_get(&V_pf_frag_pl, PR_NOWAIT);
-#else
- *frag = pool_get(&pf_frag_pl, PR_NOWAIT);
-#endif
- if (*frag == NULL)
- goto drop_fragment;
- }
-
- (*frag)->fr_flags = 0;
- (*frag)->fr_max = 0;
- (*frag)->fr_src = frent->fr_ip->ip_src;
- (*frag)->fr_dst = frent->fr_ip->ip_dst;
- (*frag)->fr_p = frent->fr_ip->ip_p;
- (*frag)->fr_id = frent->fr_ip->ip_id;
- (*frag)->fr_timeout = time_second;
- LIST_INIT(&(*frag)->fr_queue);
-
-#ifdef __FreeBSD__
- RB_INSERT(pf_frag_tree, &V_pf_frag_tree, *frag);
- TAILQ_INSERT_HEAD(&V_pf_fragqueue, *frag, frag_next);
-#else
- RB_INSERT(pf_frag_tree, &pf_frag_tree, *frag);
- TAILQ_INSERT_HEAD(&pf_fragqueue, *frag, frag_next);
-#endif
-
- /* We do not have a previous fragment */
- frep = NULL;
- goto insert;
- }
-
- /*
- * Find a fragment after the current one:
- * - off contains the real shifted offset.
- */
- LIST_FOREACH(frea, &(*frag)->fr_queue, fr_next) {
- if (FR_IP_OFF(frea) > off)
- break;
- frep = frea;
- }
-
-#ifdef __FreeBSD__
- KASSERT((frep != NULL || frea != NULL),
- ("!(frep != NULL || frea != NULL): %s", __FUNCTION__));;
-#else
- KASSERT(frep != NULL || frea != NULL);
-#endif
-
- if (frep != NULL &&
- FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl *
- 4 > off)
- {
- u_int16_t precut;
-
- precut = FR_IP_OFF(frep) + ntohs(frep->fr_ip->ip_len) -
- frep->fr_ip->ip_hl * 4 - off;
- if (precut >= ip_len)
- goto drop_fragment;
- m_adj(frent->fr_m, precut);
- DPFPRINTF(("overlap -%d\n", precut));
- /* Enforce 8 byte boundaries */
- ip->ip_off = htons(ntohs(ip->ip_off) + (precut >> 3));
- off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
- ip_len -= precut;
- ip->ip_len = htons(ip_len);
- }
-
- for (; frea != NULL && ip_len + off > FR_IP_OFF(frea);
- frea = next)
- {
- u_int16_t aftercut;
-
- aftercut = ip_len + off - FR_IP_OFF(frea);
- DPFPRINTF(("adjust overlap %d\n", aftercut));
- if (aftercut < ntohs(frea->fr_ip->ip_len) - frea->fr_ip->ip_hl
- * 4)
- {
- frea->fr_ip->ip_len =
- htons(ntohs(frea->fr_ip->ip_len) - aftercut);
- frea->fr_ip->ip_off = htons(ntohs(frea->fr_ip->ip_off) +
- (aftercut >> 3));
- m_adj(frea->fr_m, aftercut);
- break;
- }
-
- /* This fragment is completely overlapped, lose it */
- next = LIST_NEXT(frea, fr_next);
- m_freem(frea->fr_m);
- LIST_REMOVE(frea, fr_next);
-#ifdef __FreeBSD__
- pool_put(&V_pf_frent_pl, frea);
- V_pf_nfrents--;
-#else
- pool_put(&pf_frent_pl, frea);
- pf_nfrents--;
-#endif
- }
-
- insert:
- /* Update maximum data size */
- if ((*frag)->fr_max < max)
- (*frag)->fr_max = max;
- /* This is the last segment */
- if (!mff)
- (*frag)->fr_flags |= PFFRAG_SEENLAST;
-
- if (frep == NULL)
- LIST_INSERT_HEAD(&(*frag)->fr_queue, frent, fr_next);
- else
- LIST_INSERT_AFTER(frep, frent, fr_next);
-
- /* Check if we are completely reassembled */
- if (!((*frag)->fr_flags & PFFRAG_SEENLAST))
- return (NULL);
-
- /* Check if we have all the data */
- off = 0;
- for (frep = LIST_FIRST(&(*frag)->fr_queue); frep; frep = next) {
- next = LIST_NEXT(frep, fr_next);
-
- off += ntohs(frep->fr_ip->ip_len) - frep->fr_ip->ip_hl * 4;
- if (off < (*frag)->fr_max &&
- (next == NULL || FR_IP_OFF(next) != off))
- {
- DPFPRINTF(("missing fragment at %d, next %d, max %d\n",
- off, next == NULL ? -1 : FR_IP_OFF(next),
- (*frag)->fr_max));
- return (NULL);
- }
- }
- DPFPRINTF(("%d < %d?\n", off, (*frag)->fr_max));
- if (off < (*frag)->fr_max)
- return (NULL);
-
- /* We have all the data */
- frent = LIST_FIRST(&(*frag)->fr_queue);
-#ifdef __FreeBSD__
- KASSERT((frent != NULL), ("frent == NULL: %s", __FUNCTION__));
-#else
- KASSERT(frent != NULL);
-#endif
- if ((frent->fr_ip->ip_hl << 2) + off > IP_MAXPACKET) {
- DPFPRINTF(("drop: too big: %d\n", off));
- pf_free_fragment(*frag);
- *frag = NULL;
- return (NULL);
- }
- next = LIST_NEXT(frent, fr_next);
-
- /* Magic from ip_input */
- ip = frent->fr_ip;
- m = frent->fr_m;
- m2 = m->m_next;
- m->m_next = NULL;
- m_cat(m, m2);
-#ifdef __FreeBSD__
- pool_put(&V_pf_frent_pl, frent);
- V_pf_nfrents--;
-#else
- pool_put(&pf_frent_pl, frent);
- pf_nfrents--;
-#endif
- for (frent = next; frent != NULL; frent = next) {
- next = LIST_NEXT(frent, fr_next);
-
- m2 = frent->fr_m;
-#ifdef __FreeBSD__
- pool_put(&V_pf_frent_pl, frent);
- V_pf_nfrents--;
-#else
- pool_put(&pf_frent_pl, frent);
- pf_nfrents--;
-#endif
-#ifdef __FreeBSD__
- m->m_pkthdr.csum_flags &= m2->m_pkthdr.csum_flags;
- m->m_pkthdr.csum_data += m2->m_pkthdr.csum_data;
-#endif
- m_cat(m, m2);
- }
-
-#ifdef __FreeBSD__
- while (m->m_pkthdr.csum_data & 0xffff0000)
- m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
- (m->m_pkthdr.csum_data >> 16);
-#endif
- ip->ip_src = (*frag)->fr_src;
- ip->ip_dst = (*frag)->fr_dst;
-
- /* Remove from fragment queue */
- pf_remove_fragment(*frag);
- *frag = NULL;
-
- hlen = ip->ip_hl << 2;
- ip->ip_len = htons(off + hlen);
- m->m_len += hlen;
- m->m_data -= hlen;
-
- /* some debugging cruft by sklower, below, will go away soon */
- /* XXX this should be done elsewhere */
- if (m->m_flags & M_PKTHDR) {
- int plen = 0;
- for (m2 = m; m2; m2 = m2->m_next)
- plen += m2->m_len;
- m->m_pkthdr.len = plen;
- }
-
- DPFPRINTF(("complete: %p(%d)\n", m, ntohs(ip->ip_len)));
- return (m);
-
- drop_fragment:
- /* Oops - fail safe - drop packet */
-#ifdef __FreeBSD__
- pool_put(&V_pf_frent_pl, frent);
- V_pf_nfrents--;
-#else
- pool_put(&pf_frent_pl, frent);
- pf_nfrents--;
-#endif
- m_freem(m);
- return (NULL);
-}
-
-struct mbuf *
-pf_fragcache(struct mbuf **m0, struct ip *h, struct pf_fragment **frag, int mff,
- int drop, int *nomem)
-{
- struct mbuf *m = *m0;
- struct pf_frcache *frp, *fra, *cur = NULL;
- int ip_len = ntohs(h->ip_len) - (h->ip_hl << 2);
- u_int16_t off = ntohs(h->ip_off) << 3;
- u_int16_t max = ip_len + off;
- int hosed = 0;
-
-#ifdef __FreeBSD__
- KASSERT((*frag == NULL || !BUFFER_FRAGMENTS(*frag)),
- ("!(*frag == NULL || !BUFFER_FRAGMENTS(*frag)): %s", __FUNCTION__));
-#else
- KASSERT(*frag == NULL || !BUFFER_FRAGMENTS(*frag));
-#endif
-
- /* Create a new range queue for this packet */
- if (*frag == NULL) {
-#ifdef __FreeBSD__
- *frag = pool_get(&V_pf_cache_pl, PR_NOWAIT);
-#else
- *frag = pool_get(&pf_cache_pl, PR_NOWAIT);
-#endif
- if (*frag == NULL) {
- pf_flush_fragments();
-#ifdef __FreeBSD__
- *frag = pool_get(&V_pf_cache_pl, PR_NOWAIT);
-#else
- *frag = pool_get(&pf_cache_pl, PR_NOWAIT);
-#endif
- if (*frag == NULL)
- goto no_mem;
- }
-
- /* Get an entry for the queue */
-#ifdef __FreeBSD__
- cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
- if (cur == NULL) {
- pool_put(&V_pf_cache_pl, *frag);
-#else
- cur = pool_get(&pf_cent_pl, PR_NOWAIT);
- if (cur == NULL) {
- pool_put(&pf_cache_pl, *frag);
-#endif
- *frag = NULL;
- goto no_mem;
- }
-#ifdef __FreeBSD__
- V_pf_ncache++;
-#else
- pf_ncache++;
-#endif
-
- (*frag)->fr_flags = PFFRAG_NOBUFFER;
- (*frag)->fr_max = 0;
- (*frag)->fr_src = h->ip_src;
- (*frag)->fr_dst = h->ip_dst;
- (*frag)->fr_p = h->ip_p;
- (*frag)->fr_id = h->ip_id;
- (*frag)->fr_timeout = time_second;
-
- cur->fr_off = off;
- cur->fr_end = max;
- LIST_INIT(&(*frag)->fr_cache);
- LIST_INSERT_HEAD(&(*frag)->fr_cache, cur, fr_next);
-
-#ifdef __FreeBSD__
- RB_INSERT(pf_frag_tree, &V_pf_cache_tree, *frag);
- TAILQ_INSERT_HEAD(&V_pf_cachequeue, *frag, frag_next);
-#else
- RB_INSERT(pf_frag_tree, &pf_cache_tree, *frag);
- TAILQ_INSERT_HEAD(&pf_cachequeue, *frag, frag_next);
-#endif
-
- DPFPRINTF(("fragcache[%d]: new %d-%d\n", h->ip_id, off, max));
-
- goto pass;
- }
-
- /*
- * Find a fragment after the current one:
- * - off contains the real shifted offset.
- */
- frp = NULL;
- LIST_FOREACH(fra, &(*frag)->fr_cache, fr_next) {
- if (fra->fr_off > off)
- break;
- frp = fra;
- }
-
-#ifdef __FreeBSD__
- KASSERT((frp != NULL || fra != NULL),
- ("!(frp != NULL || fra != NULL): %s", __FUNCTION__));
-#else
- KASSERT(frp != NULL || fra != NULL);
-#endif
-
- if (frp != NULL) {
- int precut;
-
- precut = frp->fr_end - off;
- if (precut >= ip_len) {
- /* Fragment is entirely a duplicate */
- DPFPRINTF(("fragcache[%d]: dead (%d-%d) %d-%d\n",
- h->ip_id, frp->fr_off, frp->fr_end, off, max));
- goto drop_fragment;
- }
- if (precut == 0) {
- /* They are adjacent. Fixup cache entry */
- DPFPRINTF(("fragcache[%d]: adjacent (%d-%d) %d-%d\n",
- h->ip_id, frp->fr_off, frp->fr_end, off, max));
- frp->fr_end = max;
- } else if (precut > 0) {
- /* The first part of this payload overlaps with a
- * fragment that has already been passed.
- * Need to trim off the first part of the payload.
- * But to do so easily, we need to create another
- * mbuf to throw the original header into.
- */
-
- DPFPRINTF(("fragcache[%d]: chop %d (%d-%d) %d-%d\n",
- h->ip_id, precut, frp->fr_off, frp->fr_end, off,
- max));
-
- off += precut;
- max -= precut;
- /* Update the previous frag to encompass this one */
- frp->fr_end = max;
-
- if (!drop) {
- /* XXX Optimization opportunity
- * This is a very heavy way to trim the payload.
- * we could do it much faster by diddling mbuf
- * internals but that would be even less legible
- * than this mbuf magic. For my next trick,
- * I'll pull a rabbit out of my laptop.
- */
-#ifdef __FreeBSD__
- *m0 = m_dup(m, M_DONTWAIT);
-#else
- *m0 = m_copym2(m, 0, h->ip_hl << 2, M_NOWAIT);
-#endif
- if (*m0 == NULL)
- goto no_mem;
-#ifdef __FreeBSD__
- /* From KAME Project : We have missed this! */
- m_adj(*m0, (h->ip_hl << 2) -
- (*m0)->m_pkthdr.len);
-
- KASSERT(((*m0)->m_next == NULL),
- ("(*m0)->m_next != NULL: %s",
- __FUNCTION__));
-#else
- KASSERT((*m0)->m_next == NULL);
-#endif
- m_adj(m, precut + (h->ip_hl << 2));
- m_cat(*m0, m);
- m = *m0;
- if (m->m_flags & M_PKTHDR) {
- int plen = 0;
- struct mbuf *t;
- for (t = m; t; t = t->m_next)
- plen += t->m_len;
- m->m_pkthdr.len = plen;
- }
-
-
- h = mtod(m, struct ip *);
-
-#ifdef __FreeBSD__
- KASSERT(((int)m->m_len ==
- ntohs(h->ip_len) - precut),
- ("m->m_len != ntohs(h->ip_len) - precut: %s",
- __FUNCTION__));
-#else
- KASSERT((int)m->m_len ==
- ntohs(h->ip_len) - precut);
-#endif
- h->ip_off = htons(ntohs(h->ip_off) +
- (precut >> 3));
- h->ip_len = htons(ntohs(h->ip_len) - precut);
- } else {
- hosed++;
- }
- } else {
- /* There is a gap between fragments */
-
- DPFPRINTF(("fragcache[%d]: gap %d (%d-%d) %d-%d\n",
- h->ip_id, -precut, frp->fr_off, frp->fr_end, off,
- max));
-
-#ifdef __FreeBSD__
- cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
-#else
- cur = pool_get(&pf_cent_pl, PR_NOWAIT);
-#endif
- if (cur == NULL)
- goto no_mem;
-#ifdef __FreeBSD__
- V_pf_ncache++;
-#else
- pf_ncache++;
-#endif
-
- cur->fr_off = off;
- cur->fr_end = max;
- LIST_INSERT_AFTER(frp, cur, fr_next);
- }
- }
-
- if (fra != NULL) {
- int aftercut;
- int merge = 0;
-
- aftercut = max - fra->fr_off;
- if (aftercut == 0) {
- /* Adjacent fragments */
- DPFPRINTF(("fragcache[%d]: adjacent %d-%d (%d-%d)\n",
- h->ip_id, off, max, fra->fr_off, fra->fr_end));
- fra->fr_off = off;
- merge = 1;
- } else if (aftercut > 0) {
- /* Need to chop off the tail of this fragment */
- DPFPRINTF(("fragcache[%d]: chop %d %d-%d (%d-%d)\n",
- h->ip_id, aftercut, off, max, fra->fr_off,
- fra->fr_end));
- fra->fr_off = off;
- max -= aftercut;
-
- merge = 1;
-
- if (!drop) {
- m_adj(m, -aftercut);
- if (m->m_flags & M_PKTHDR) {
- int plen = 0;
- struct mbuf *t;
- for (t = m; t; t = t->m_next)
- plen += t->m_len;
- m->m_pkthdr.len = plen;
- }
- h = mtod(m, struct ip *);
-#ifdef __FreeBSD__
- KASSERT(((int)m->m_len == ntohs(h->ip_len) - aftercut),
- ("m->m_len != ntohs(h->ip_len) - aftercut: %s",
- __FUNCTION__));
-#else
- KASSERT((int)m->m_len ==
- ntohs(h->ip_len) - aftercut);
-#endif
- h->ip_len = htons(ntohs(h->ip_len) - aftercut);
- } else {
- hosed++;
- }
- } else if (frp == NULL) {
- /* There is a gap between fragments */
- DPFPRINTF(("fragcache[%d]: gap %d %d-%d (%d-%d)\n",
- h->ip_id, -aftercut, off, max, fra->fr_off,
- fra->fr_end));
-
-#ifdef __FreeBSD__
- cur = pool_get(&V_pf_cent_pl, PR_NOWAIT);
-#else
- cur = pool_get(&pf_cent_pl, PR_NOWAIT);
-#endif
- if (cur == NULL)
- goto no_mem;
-#ifdef __FreeBSD__
- V_pf_ncache++;
-#else
- pf_ncache++;
-#endif
-
- cur->fr_off = off;
- cur->fr_end = max;
- LIST_INSERT_BEFORE(fra, cur, fr_next);
- }
-
-
- /* Need to glue together two separate fragment descriptors */
- if (merge) {
- if (cur && fra->fr_off <= cur->fr_end) {
- /* Need to merge in a previous 'cur' */
- DPFPRINTF(("fragcache[%d]: adjacent(merge "
- "%d-%d) %d-%d (%d-%d)\n",
- h->ip_id, cur->fr_off, cur->fr_end, off,
- max, fra->fr_off, fra->fr_end));
- fra->fr_off = cur->fr_off;
- LIST_REMOVE(cur, fr_next);
-#ifdef __FreeBSD__
- pool_put(&V_pf_cent_pl, cur);
- V_pf_ncache--;
-#else
- pool_put(&pf_cent_pl, cur);
- pf_ncache--;
-#endif
- cur = NULL;
-
- } else if (frp && fra->fr_off <= frp->fr_end) {
- /* Need to merge in a modified 'frp' */
-#ifdef __FreeBSD__
- KASSERT((cur == NULL), ("cur != NULL: %s",
- __FUNCTION__));
-#else
- KASSERT(cur == NULL);
-#endif
- DPFPRINTF(("fragcache[%d]: adjacent(merge "
- "%d-%d) %d-%d (%d-%d)\n",
- h->ip_id, frp->fr_off, frp->fr_end, off,
- max, fra->fr_off, fra->fr_end));
- fra->fr_off = frp->fr_off;
- LIST_REMOVE(frp, fr_next);
-#ifdef __FreeBSD__
- pool_put(&V_pf_cent_pl, frp);
- V_pf_ncache--;
-#else
- pool_put(&pf_cent_pl, frp);
- pf_ncache--;
-#endif
- frp = NULL;
-
- }
- }
- }
-
- if (hosed) {
- /*
- * We must keep tracking the overall fragment even when
- * we're going to drop it anyway so that we know when to
- * free the overall descriptor. Thus we drop the frag late.
- */
- goto drop_fragment;
- }
-
-
- pass:
- /* Update maximum data size */
- if ((*frag)->fr_max < max)
- (*frag)->fr_max = max;
-
- /* This is the last segment */
- if (!mff)
- (*frag)->fr_flags |= PFFRAG_SEENLAST;
-
- /* Check if we are completely reassembled */
- if (((*frag)->fr_flags & PFFRAG_SEENLAST) &&
- LIST_FIRST(&(*frag)->fr_cache)->fr_off == 0 &&
- LIST_FIRST(&(*frag)->fr_cache)->fr_end == (*frag)->fr_max) {
- /* Remove from fragment queue */
- DPFPRINTF(("fragcache[%d]: done 0-%d\n", h->ip_id,
- (*frag)->fr_max));
- pf_free_fragment(*frag);
- *frag = NULL;
- }
-
- return (m);
-
- no_mem:
- *nomem = 1;
-
- /* Still need to pay attention to !IP_MF */
- if (!mff && *frag != NULL)
- (*frag)->fr_flags |= PFFRAG_SEENLAST;
-
- m_freem(m);
- return (NULL);
-
- drop_fragment:
-
- /* Still need to pay attention to !IP_MF */
- if (!mff && *frag != NULL)
- (*frag)->fr_flags |= PFFRAG_SEENLAST;
-
- if (drop) {
- /* This fragment has been deemed bad. Don't reass */
- if (((*frag)->fr_flags & PFFRAG_DROP) == 0)
- DPFPRINTF(("fragcache[%d]: dropping overall fragment\n",
- h->ip_id));
- (*frag)->fr_flags |= PFFRAG_DROP;
- }
-
- m_freem(m);
- return (NULL);
-}
-
-#ifdef INET
-int
-pf_normalize_ip(struct mbuf **m0, int dir, struct pfi_kif *kif, u_short *reason,
- struct pf_pdesc *pd)
-{
- struct mbuf *m = *m0;
- struct pf_rule *r;
- struct pf_frent *frent;
- struct pf_fragment *frag = NULL;
- struct ip *h = mtod(m, struct ip *);
- int mff = (ntohs(h->ip_off) & IP_MF);
- int hlen = h->ip_hl << 2;
- u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
- u_int16_t max;
- int ip_len;
- int ip_off;
- int tag = -1;
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
- while (r != NULL) {
- r->evaluations++;
- if (pfi_kif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != dir)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != AF_INET)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != h->ip_p)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr,
- (struct pf_addr *)&h->ip_src.s_addr, AF_INET,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr,
- (struct pf_addr *)&h->ip_dst.s_addr, AF_INET,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
-#ifdef __FreeBSD__
- else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag))
-#else
- else if (r->match_tag && !pf_match_tag(m, r, &tag))
-#endif
- r = TAILQ_NEXT(r, entries);
- else
- break;
- }
-
- if (r == NULL || r->action == PF_NOSCRUB)
- return (PF_PASS);
- else {
- r->packets[dir == PF_OUT]++;
- r->bytes[dir == PF_OUT] += pd->tot_len;
- }
-
- /* Check for illegal packets */
- if (hlen < (int)sizeof(struct ip))
- goto drop;
-
- if (hlen > ntohs(h->ip_len))
- goto drop;
-
- /* Clear IP_DF if the rule uses the no-df option */
- if (r->rule_flag & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
- u_int16_t ip_off = h->ip_off;
-
- h->ip_off &= htons(~IP_DF);
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
- }
-
- /* We will need other tests here */
- if (!fragoff && !mff)
- goto no_fragment;
-
- /* We're dealing with a fragment now. Don't allow fragments
- * with IP_DF to enter the cache. If the flag was cleared by
- * no-df above, fine. Otherwise drop it.
- */
- if (h->ip_off & htons(IP_DF)) {
- DPFPRINTF(("IP_DF\n"));
- goto bad;
- }
-
- ip_len = ntohs(h->ip_len) - hlen;
- ip_off = (ntohs(h->ip_off) & IP_OFFMASK) << 3;
-
- /* All fragments are 8 byte aligned */
- if (mff && (ip_len & 0x7)) {
- DPFPRINTF(("mff and %d\n", ip_len));
- goto bad;
- }
-
- /* Respect maximum length */
- if (fragoff + ip_len > IP_MAXPACKET) {
- DPFPRINTF(("max packet %d\n", fragoff + ip_len));
- goto bad;
- }
- max = fragoff + ip_len;
-
- if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0) {
- /* Fully buffer all of the fragments */
-
-#ifdef __FreeBSD__
- frag = pf_find_fragment(h, &V_pf_frag_tree);
-#else
- frag = pf_find_fragment(h, &pf_frag_tree);
-#endif
-
- /* Check if we saw the last fragment already */
- if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
- max > frag->fr_max)
- goto bad;
-
- /* Get an entry for the fragment queue */
-#ifdef __FreeBSD__
- frent = pool_get(&V_pf_frent_pl, PR_NOWAIT);
-#else
- frent = pool_get(&pf_frent_pl, PR_NOWAIT);
-#endif
- if (frent == NULL) {
- REASON_SET(reason, PFRES_MEMORY);
- return (PF_DROP);
- }
-#ifdef __FreeBSD__
- V_pf_nfrents++;
-#else
- pf_nfrents++;
-#endif
- frent->fr_ip = h;
- frent->fr_m = m;
-
- /* Might return a completely reassembled mbuf, or NULL */
- DPFPRINTF(("reass frag %d @ %d-%d\n", h->ip_id, fragoff, max));
- *m0 = m = pf_reassemble(m0, &frag, frent, mff);
-
- if (m == NULL)
- return (PF_DROP);
-
- /* use mtag from concatenated mbuf chain */
- pd->pf_mtag = pf_find_mtag(m);
-#ifdef DIAGNOSTIC
- if (pd->pf_mtag == NULL) {
- printf("%s: pf_find_mtag returned NULL(1)\n", __func__);
- if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
- m_freem(m);
- *m0 = NULL;
- goto no_mem;
- }
- }
-#endif
- if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
- goto drop;
-
- h = mtod(m, struct ip *);
- } else {
- /* non-buffering fragment cache (drops or masks overlaps) */
- int nomem = 0;
-
-#ifdef __FreeBSD__
- if (dir == PF_OUT && pd->pf_mtag->flags & PF_TAG_FRAGCACHE) {
-#else
- if (dir == PF_OUT && m->m_pkthdr.pf.flags & PF_TAG_FRAGCACHE) {
-#endif
- /*
- * Already passed the fragment cache in the
- * input direction. If we continued, it would
- * appear to be a dup and would be dropped.
- */
- goto fragment_pass;
- }
-
-#ifdef __FreeBSD__
- frag = pf_find_fragment(h, &V_pf_cache_tree);
-#else
- frag = pf_find_fragment(h, &pf_cache_tree);
-#endif
-
- /* Check if we saw the last fragment already */
- if (frag != NULL && (frag->fr_flags & PFFRAG_SEENLAST) &&
- max > frag->fr_max) {
- if (r->rule_flag & PFRULE_FRAGDROP)
- frag->fr_flags |= PFFRAG_DROP;
- goto bad;
- }
-
- *m0 = m = pf_fragcache(m0, h, &frag, mff,
- (r->rule_flag & PFRULE_FRAGDROP) ? 1 : 0, &nomem);
- if (m == NULL) {
- if (nomem)
- goto no_mem;
- goto drop;
- }
-
- /* use mtag from copied and trimmed mbuf chain */
- pd->pf_mtag = pf_find_mtag(m);
-#ifdef DIAGNOSTIC
- if (pd->pf_mtag == NULL) {
- printf("%s: pf_find_mtag returned NULL(2)\n", __func__);
- if ((pd->pf_mtag = pf_get_mtag(m)) == NULL) {
- m_freem(m);
- *m0 = NULL;
- goto no_mem;
- }
- }
-#endif
- if (dir == PF_IN)
-#ifdef __FreeBSD__
- pd->pf_mtag->flags |= PF_TAG_FRAGCACHE;
-#else
- m->m_pkthdr.pf.flags |= PF_TAG_FRAGCACHE;
-#endif
-
- if (frag != NULL && (frag->fr_flags & PFFRAG_DROP))
- goto drop;
- goto fragment_pass;
- }
-
- no_fragment:
- /* At this point, only IP_DF is allowed in ip_off */
- if (h->ip_off & ~htons(IP_DF)) {
- u_int16_t ip_off = h->ip_off;
-
- h->ip_off &= htons(IP_DF);
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
- }
-
- /* not missing a return here */
-
- fragment_pass:
- pf_scrub_ip(&m, r->rule_flag, r->min_ttl, r->set_tos);
-
- if ((r->rule_flag & (PFRULE_FRAGCROP|PFRULE_FRAGDROP)) == 0)
- pd->flags |= PFDESC_IP_REAS;
- return (PF_PASS);
-
- no_mem:
- REASON_SET(reason, PFRES_MEMORY);
- if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
- return (PF_DROP);
-
- drop:
- REASON_SET(reason, PFRES_NORM);
- if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
- return (PF_DROP);
-
- bad:
- DPFPRINTF(("dropping bad fragment\n"));
-
- /* Free associated fragments */
- if (frag != NULL)
- pf_free_fragment(frag);
-
- REASON_SET(reason, PFRES_FRAG);
- if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, *reason, r, NULL, NULL, pd);
-
- return (PF_DROP);
-}
-#endif
-
-#ifdef INET6
-int
-pf_normalize_ip6(struct mbuf **m0, int dir, struct pfi_kif *kif,
- u_short *reason, struct pf_pdesc *pd)
-{
- struct mbuf *m = *m0;
- struct pf_rule *r;
- struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
- int off;
- struct ip6_ext ext;
- struct ip6_opt opt;
- struct ip6_opt_jumbo jumbo;
- struct ip6_frag frag;
- u_int32_t jumbolen = 0, plen;
- u_int16_t fragoff = 0;
- int optend;
- int ooff;
- u_int8_t proto;
- int terminal;
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
- while (r != NULL) {
- r->evaluations++;
- if (pfi_kif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != dir)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != AF_INET6)
- r = r->skip[PF_SKIP_AF].ptr;
-#if 0 /* header chain! */
- else if (r->proto && r->proto != h->ip6_nxt)
- r = r->skip[PF_SKIP_PROTO].ptr;
-#endif
- else if (PF_MISMATCHAW(&r->src.addr,
- (struct pf_addr *)&h->ip6_src, AF_INET6,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr,
- (struct pf_addr *)&h->ip6_dst, AF_INET6,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- else
- break;
- }
-
- if (r == NULL || r->action == PF_NOSCRUB)
- return (PF_PASS);
- else {
- r->packets[dir == PF_OUT]++;
- r->bytes[dir == PF_OUT] += pd->tot_len;
- }
-
- /* Check for illegal packets */
- if (sizeof(struct ip6_hdr) + IPV6_MAXPACKET < m->m_pkthdr.len)
- goto drop;
-
- off = sizeof(struct ip6_hdr);
- proto = h->ip6_nxt;
- terminal = 0;
- do {
- switch (proto) {
- case IPPROTO_FRAGMENT:
- goto fragment;
- break;
- case IPPROTO_AH:
- case IPPROTO_ROUTING:
- case IPPROTO_DSTOPTS:
- if (!pf_pull_hdr(m, off, &ext, sizeof(ext), NULL,
- NULL, AF_INET6))
- goto shortpkt;
- if (proto == IPPROTO_AH)
- off += (ext.ip6e_len + 2) * 4;
- else
- off += (ext.ip6e_len + 1) * 8;
- proto = ext.ip6e_nxt;
- break;
- case IPPROTO_HOPOPTS:
- if (!pf_pull_hdr(m, off, &ext, sizeof(ext), NULL,
- NULL, AF_INET6))
- goto shortpkt;
- optend = off + (ext.ip6e_len + 1) * 8;
- ooff = off + sizeof(ext);
- do {
- if (!pf_pull_hdr(m, ooff, &opt.ip6o_type,
- sizeof(opt.ip6o_type), NULL, NULL,
- AF_INET6))
- goto shortpkt;
- if (opt.ip6o_type == IP6OPT_PAD1) {
- ooff++;
- continue;
- }
- if (!pf_pull_hdr(m, ooff, &opt, sizeof(opt),
- NULL, NULL, AF_INET6))
- goto shortpkt;
- if (ooff + sizeof(opt) + opt.ip6o_len > optend)
- goto drop;
- switch (opt.ip6o_type) {
- case IP6OPT_JUMBO:
- if (h->ip6_plen != 0)
- goto drop;
- if (!pf_pull_hdr(m, ooff, &jumbo,
- sizeof(jumbo), NULL, NULL,
- AF_INET6))
- goto shortpkt;
- memcpy(&jumbolen, jumbo.ip6oj_jumbo_len,
- sizeof(jumbolen));
- jumbolen = ntohl(jumbolen);
- if (jumbolen <= IPV6_MAXPACKET)
- goto drop;
- if (sizeof(struct ip6_hdr) + jumbolen !=
- m->m_pkthdr.len)
- goto drop;
- break;
- default:
- break;
- }
- ooff += sizeof(opt) + opt.ip6o_len;
- } while (ooff < optend);
-
- off = optend;
- proto = ext.ip6e_nxt;
- break;
- default:
- terminal = 1;
- break;
- }
- } while (!terminal);
-
- /* jumbo payload option must be present, or plen > 0 */
- if (ntohs(h->ip6_plen) == 0)
- plen = jumbolen;
- else
- plen = ntohs(h->ip6_plen);
- if (plen == 0)
- goto drop;
- if (sizeof(struct ip6_hdr) + plen > m->m_pkthdr.len)
- goto shortpkt;
-
- pf_scrub_ip6(&m, r->min_ttl);
-
- return (PF_PASS);
-
- fragment:
- if (ntohs(h->ip6_plen) == 0 || jumbolen)
- goto drop;
- plen = ntohs(h->ip6_plen);
-
- if (!pf_pull_hdr(m, off, &frag, sizeof(frag), NULL, NULL, AF_INET6))
- goto shortpkt;
- fragoff = ntohs(frag.ip6f_offlg & IP6F_OFF_MASK);
- if (fragoff + (plen - off - sizeof(frag)) > IPV6_MAXPACKET)
- goto badfrag;
-
- /* do something about it */
- /* remember to set pd->flags |= PFDESC_IP_REAS */
- return (PF_PASS);
-
- shortpkt:
- REASON_SET(reason, PFRES_SHORT);
- if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
- return (PF_DROP);
-
- drop:
- REASON_SET(reason, PFRES_NORM);
- if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
- return (PF_DROP);
-
- badfrag:
- REASON_SET(reason, PFRES_FRAG);
- if (r != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET6, dir, *reason, r, NULL, NULL, pd);
- return (PF_DROP);
-}
-#endif /* INET6 */
-
-int
-pf_normalize_tcp(int dir, struct pfi_kif *kif, struct mbuf *m, int ipoff,
- int off, void *h, struct pf_pdesc *pd)
-{
- struct pf_rule *r, *rm = NULL;
- struct tcphdr *th = pd->hdr.tcp;
- int rewrite = 0;
- u_short reason;
- u_int8_t flags;
- sa_family_t af = pd->af;
-
- r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_SCRUB].active.ptr);
- while (r != NULL) {
- r->evaluations++;
- if (pfi_kif_match(r->kif, kif) == r->ifnot)
- r = r->skip[PF_SKIP_IFP].ptr;
- else if (r->direction && r->direction != dir)
- r = r->skip[PF_SKIP_DIR].ptr;
- else if (r->af && r->af != af)
- r = r->skip[PF_SKIP_AF].ptr;
- else if (r->proto && r->proto != pd->proto)
- r = r->skip[PF_SKIP_PROTO].ptr;
- else if (PF_MISMATCHAW(&r->src.addr, pd->src, af,
- r->src.neg, kif, M_GETFIB(m)))
- r = r->skip[PF_SKIP_SRC_ADDR].ptr;
- else if (r->src.port_op && !pf_match_port(r->src.port_op,
- r->src.port[0], r->src.port[1], th->th_sport))
- r = r->skip[PF_SKIP_SRC_PORT].ptr;
- else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af,
- r->dst.neg, NULL, M_GETFIB(m)))
- r = r->skip[PF_SKIP_DST_ADDR].ptr;
- else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
- r->dst.port[0], r->dst.port[1], th->th_dport))
- r = r->skip[PF_SKIP_DST_PORT].ptr;
- else if (r->os_fingerprint != PF_OSFP_ANY && !pf_osfp_match(
- pf_osfp_fingerprint(pd, m, off, th),
- r->os_fingerprint))
- r = TAILQ_NEXT(r, entries);
- else {
- rm = r;
- break;
- }
- }
-
- if (rm == NULL || rm->action == PF_NOSCRUB)
- return (PF_PASS);
- else {
- r->packets[dir == PF_OUT]++;
- r->bytes[dir == PF_OUT] += pd->tot_len;
- }
-
- if (rm->rule_flag & PFRULE_REASSEMBLE_TCP)
- pd->flags |= PFDESC_TCP_NORM;
-
- flags = th->th_flags;
- if (flags & TH_SYN) {
- /* Illegal packet */
- if (flags & TH_RST)
- goto tcp_drop;
-
- if (flags & TH_FIN)
- flags &= ~TH_FIN;
- } else {
- /* Illegal packet */
- if (!(flags & (TH_ACK|TH_RST)))
- goto tcp_drop;
- }
-
- if (!(flags & TH_ACK)) {
- /* These flags are only valid if ACK is set */
- if ((flags & TH_FIN) || (flags & TH_PUSH) || (flags & TH_URG))
- goto tcp_drop;
- }
-
- /* Check for illegal header length */
- if (th->th_off < (sizeof(struct tcphdr) >> 2))
- goto tcp_drop;
-
- /* If flags changed, or reserved data set, then adjust */
- if (flags != th->th_flags || th->th_x2 != 0) {
- u_int16_t ov, nv;
-
- ov = *(u_int16_t *)(&th->th_ack + 1);
- th->th_flags = flags;
- th->th_x2 = 0;
- nv = *(u_int16_t *)(&th->th_ack + 1);
-
- th->th_sum = pf_cksum_fixup(th->th_sum, ov, nv, 0);
- rewrite = 1;
- }
-
- /* Remove urgent pointer, if TH_URG is not set */
- if (!(flags & TH_URG) && th->th_urp) {
- th->th_sum = pf_cksum_fixup(th->th_sum, th->th_urp, 0, 0);
- th->th_urp = 0;
- rewrite = 1;
- }
-
- /* Process options */
- if (r->max_mss && pf_normalize_tcpopt(r, m, th, off, pd->af))
- rewrite = 1;
-
- /* copy back packet headers if we sanitized */
- if (rewrite)
-#ifdef __FreeBSD__
- m_copyback(m, off, sizeof(*th), (caddr_t)th);
-#else
- m_copyback(m, off, sizeof(*th), th);
-#endif
-
- return (PF_PASS);
-
- tcp_drop:
- REASON_SET(&reason, PFRES_NORM);
- if (rm != NULL && r->log)
- PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, r, NULL, NULL, pd);
- return (PF_DROP);
-}
-
-int
-pf_normalize_tcp_init(struct mbuf *m, int off, struct pf_pdesc *pd,
- struct tcphdr *th, struct pf_state_peer *src, struct pf_state_peer *dst)
-{
- u_int32_t tsval, tsecr;
- u_int8_t hdr[60];
- u_int8_t *opt;
-
-#ifdef __FreeBSD__
- KASSERT((src->scrub == NULL),
- ("pf_normalize_tcp_init: src->scrub != NULL"));
-
- src->scrub = pool_get(&V_pf_state_scrub_pl, PR_NOWAIT);
-#else
- KASSERT(src->scrub == NULL);
-
- src->scrub = pool_get(&pf_state_scrub_pl, PR_NOWAIT);
-#endif
- if (src->scrub == NULL)
- return (1);
- bzero(src->scrub, sizeof(*src->scrub));
-
- switch (pd->af) {
-#ifdef INET
- case AF_INET: {
- struct ip *h = mtod(m, struct ip *);
- src->scrub->pfss_ttl = h->ip_ttl;
- break;
- }
-#endif /* INET */
-#ifdef INET6
- case AF_INET6: {
- struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
- src->scrub->pfss_ttl = h->ip6_hlim;
- break;
- }
-#endif /* INET6 */
- }
-
-
- /*
- * All normalizations below are only begun if we see the start of
- * the connections. They must all set an enabled bit in pfss_flags
- */
- if ((th->th_flags & TH_SYN) == 0)
- return (0);
-
-
- if (th->th_off > (sizeof(struct tcphdr) >> 2) && src->scrub &&
- pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
- /* Diddle with TCP options */
- int hlen;
- opt = hdr + sizeof(struct tcphdr);
- hlen = (th->th_off << 2) - sizeof(struct tcphdr);
- while (hlen >= TCPOLEN_TIMESTAMP) {
- switch (*opt) {
- case TCPOPT_EOL: /* FALLTHROUGH */
- case TCPOPT_NOP:
- opt++;
- hlen--;
- break;
- case TCPOPT_TIMESTAMP:
- if (opt[1] >= TCPOLEN_TIMESTAMP) {
- src->scrub->pfss_flags |=
- PFSS_TIMESTAMP;
- src->scrub->pfss_ts_mod =
- htonl(arc4random());
-
- /* note PFSS_PAWS not set yet */
- memcpy(&tsval, &opt[2],
- sizeof(u_int32_t));
- memcpy(&tsecr, &opt[6],
- sizeof(u_int32_t));
- src->scrub->pfss_tsval0 = ntohl(tsval);
- src->scrub->pfss_tsval = ntohl(tsval);
- src->scrub->pfss_tsecr = ntohl(tsecr);
- getmicrouptime(&src->scrub->pfss_last);
- }
- /* FALLTHROUGH */
- default:
- hlen -= MAX(opt[1], 2);
- opt += MAX(opt[1], 2);
- break;
- }
- }
- }
-
- return (0);
-}
-
-void
-pf_normalize_tcp_cleanup(struct pf_state *state)
-{
-#ifdef __FreeBSD__
- if (state->src.scrub)
- pool_put(&V_pf_state_scrub_pl, state->src.scrub);
- if (state->dst.scrub)
- pool_put(&V_pf_state_scrub_pl, state->dst.scrub);
-#else
- if (state->src.scrub)
- pool_put(&pf_state_scrub_pl, state->src.scrub);
- if (state->dst.scrub)
- pool_put(&pf_state_scrub_pl, state->dst.scrub);
-#endif
-
- /* Someday... flush the TCP segment reassembly descriptors. */
-}
-
-int
-pf_normalize_tcp_stateful(struct mbuf *m, int off, struct pf_pdesc *pd,
- u_short *reason, struct tcphdr *th, struct pf_state *state,
- struct pf_state_peer *src, struct pf_state_peer *dst, int *writeback)
-{
- struct timeval uptime;
- u_int32_t tsval, tsecr;
- u_int tsval_from_last;
- u_int8_t hdr[60];
- u_int8_t *opt;
- int copyback = 0;
- int got_ts = 0;
-
-#ifdef __FreeBSD__
- KASSERT((src->scrub || dst->scrub),
- ("pf_normalize_tcp_statefull: src->scrub && dst->scrub!"));
-#else
- KASSERT(src->scrub || dst->scrub);
-#endif
-
- /*
- * Enforce the minimum TTL seen for this connection. Negate a common
- * technique to evade an intrusion detection system and confuse
- * firewall state code.
- */
- switch (pd->af) {
-#ifdef INET
- case AF_INET: {
- if (src->scrub) {
- struct ip *h = mtod(m, struct ip *);
- if (h->ip_ttl > src->scrub->pfss_ttl)
- src->scrub->pfss_ttl = h->ip_ttl;
- h->ip_ttl = src->scrub->pfss_ttl;
- }
- break;
- }
-#endif /* INET */
-#ifdef INET6
- case AF_INET6: {
- if (src->scrub) {
- struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
- if (h->ip6_hlim > src->scrub->pfss_ttl)
- src->scrub->pfss_ttl = h->ip6_hlim;
- h->ip6_hlim = src->scrub->pfss_ttl;
- }
- break;
- }
-#endif /* INET6 */
- }
-
- if (th->th_off > (sizeof(struct tcphdr) >> 2) &&
- ((src->scrub && (src->scrub->pfss_flags & PFSS_TIMESTAMP)) ||
- (dst->scrub && (dst->scrub->pfss_flags & PFSS_TIMESTAMP))) &&
- pf_pull_hdr(m, off, hdr, th->th_off << 2, NULL, NULL, pd->af)) {
- /* Diddle with TCP options */
- int hlen;
- opt = hdr + sizeof(struct tcphdr);
- hlen = (th->th_off << 2) - sizeof(struct tcphdr);
- while (hlen >= TCPOLEN_TIMESTAMP) {
- switch (*opt) {
- case TCPOPT_EOL: /* FALLTHROUGH */
- case TCPOPT_NOP:
- opt++;
- hlen--;
- break;
- case TCPOPT_TIMESTAMP:
- /* Modulate the timestamps. Can be used for
- * NAT detection, OS uptime determination or
- * reboot detection.
- */
-
- if (got_ts) {
- /* Huh? Multiple timestamps!? */
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- DPFPRINTF(("multiple TS??"));
- pf_print_state(state);
- printf("\n");
- }
- REASON_SET(reason, PFRES_TS);
- return (PF_DROP);
- }
- if (opt[1] >= TCPOLEN_TIMESTAMP) {
- memcpy(&tsval, &opt[2],
- sizeof(u_int32_t));
- if (tsval && src->scrub &&
- (src->scrub->pfss_flags &
- PFSS_TIMESTAMP)) {
- tsval = ntohl(tsval);
- pf_change_a(&opt[2],
- &th->th_sum,
- htonl(tsval +
- src->scrub->pfss_ts_mod),
- 0);
- copyback = 1;
- }
-
- /* Modulate TS reply iff valid (!0) */
- memcpy(&tsecr, &opt[6],
- sizeof(u_int32_t));
- if (tsecr && dst->scrub &&
- (dst->scrub->pfss_flags &
- PFSS_TIMESTAMP)) {
- tsecr = ntohl(tsecr)
- - dst->scrub->pfss_ts_mod;
- pf_change_a(&opt[6],
- &th->th_sum, htonl(tsecr),
- 0);
- copyback = 1;
- }
- got_ts = 1;
- }
- /* FALLTHROUGH */
- default:
- hlen -= MAX(opt[1], 2);
- opt += MAX(opt[1], 2);
- break;
- }
- }
- if (copyback) {
- /* Copyback the options, caller copys back header */
- *writeback = 1;
- m_copyback(m, off + sizeof(struct tcphdr),
- (th->th_off << 2) - sizeof(struct tcphdr), hdr +
- sizeof(struct tcphdr));
- }
- }
-
-
- /*
- * Must invalidate PAWS checks on connections idle for too long.
- * The fastest allowed timestamp clock is 1ms. That turns out to
- * be about 24 days before it wraps. XXX Right now our lowerbound
- * TS echo check only works for the first 12 days of a connection
- * when the TS has exhausted half its 32bit space
- */
-#define TS_MAX_IDLE (24*24*60*60)
-#define TS_MAX_CONN (12*24*60*60) /* XXX remove when better tsecr check */
-
- getmicrouptime(&uptime);
- if (src->scrub && (src->scrub->pfss_flags & PFSS_PAWS) &&
- (uptime.tv_sec - src->scrub->pfss_last.tv_sec > TS_MAX_IDLE ||
- time_second - state->creation > TS_MAX_CONN)) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- DPFPRINTF(("src idled out of PAWS\n"));
- pf_print_state(state);
- printf("\n");
- }
- src->scrub->pfss_flags = (src->scrub->pfss_flags & ~PFSS_PAWS)
- | PFSS_PAWS_IDLED;
- }
- if (dst->scrub && (dst->scrub->pfss_flags & PFSS_PAWS) &&
- uptime.tv_sec - dst->scrub->pfss_last.tv_sec > TS_MAX_IDLE) {
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- DPFPRINTF(("dst idled out of PAWS\n"));
- pf_print_state(state);
- printf("\n");
- }
- dst->scrub->pfss_flags = (dst->scrub->pfss_flags & ~PFSS_PAWS)
- | PFSS_PAWS_IDLED;
- }
-
- if (got_ts && src->scrub && dst->scrub &&
- (src->scrub->pfss_flags & PFSS_PAWS) &&
- (dst->scrub->pfss_flags & PFSS_PAWS)) {
- /* Validate that the timestamps are "in-window".
- * RFC1323 describes TCP Timestamp options that allow
- * measurement of RTT (round trip time) and PAWS
- * (protection against wrapped sequence numbers). PAWS
- * gives us a set of rules for rejecting packets on
- * long fat pipes (packets that were somehow delayed
- * in transit longer than the time it took to send the
- * full TCP sequence space of 4Gb). We can use these
- * rules and infer a few others that will let us treat
- * the 32bit timestamp and the 32bit echoed timestamp
- * as sequence numbers to prevent a blind attacker from
- * inserting packets into a connection.
- *
- * RFC1323 tells us:
- * - The timestamp on this packet must be greater than
- * or equal to the last value echoed by the other
- * endpoint. The RFC says those will be discarded
- * since it is a dup that has already been acked.
- * This gives us a lowerbound on the timestamp.
- * timestamp >= other last echoed timestamp
- * - The timestamp will be less than or equal to
- * the last timestamp plus the time between the
- * last packet and now. The RFC defines the max
- * clock rate as 1ms. We will allow clocks to be
- * up to 10% fast and will allow a total difference
- * or 30 seconds due to a route change. And this
- * gives us an upperbound on the timestamp.
- * timestamp <= last timestamp + max ticks
- * We have to be careful here. Windows will send an
- * initial timestamp of zero and then initialize it
- * to a random value after the 3whs; presumably to
- * avoid a DoS by having to call an expensive RNG
- * during a SYN flood. Proof MS has at least one
- * good security geek.
- *
- * - The TCP timestamp option must also echo the other
- * endpoints timestamp. The timestamp echoed is the
- * one carried on the earliest unacknowledged segment
- * on the left edge of the sequence window. The RFC
- * states that the host will reject any echoed
- * timestamps that were larger than any ever sent.
- * This gives us an upperbound on the TS echo.
- * tescr <= largest_tsval
- * - The lowerbound on the TS echo is a little more
- * tricky to determine. The other endpoint's echoed
- * values will not decrease. But there may be
- * network conditions that re-order packets and
- * cause our view of them to decrease. For now the
- * only lowerbound we can safely determine is that
- * the TS echo will never be less than the original
- * TS. XXX There is probably a better lowerbound.
- * Remove TS_MAX_CONN with better lowerbound check.
- * tescr >= other original TS
- *
- * It is also important to note that the fastest
- * timestamp clock of 1ms will wrap its 32bit space in
- * 24 days. So we just disable TS checking after 24
- * days of idle time. We actually must use a 12d
- * connection limit until we can come up with a better
- * lowerbound to the TS echo check.
- */
- struct timeval delta_ts;
- int ts_fudge;
-
-
- /*
- * PFTM_TS_DIFF is how many seconds of leeway to allow
- * a host's timestamp. This can happen if the previous
- * packet got delayed in transit for much longer than
- * this packet.
- */
- if ((ts_fudge = state->rule.ptr->timeout[PFTM_TS_DIFF]) == 0)
-#ifdef __FreeBSD__
- ts_fudge = V_pf_default_rule.timeout[PFTM_TS_DIFF];
-#else
- ts_fudge = pf_default_rule.timeout[PFTM_TS_DIFF];
-#endif
-
-
- /* Calculate max ticks since the last timestamp */
-#define TS_MAXFREQ 1100 /* RFC max TS freq of 1Khz + 10% skew */
-#define TS_MICROSECS 1000000 /* microseconds per second */
-#ifdef __FreeBSD__
-#ifndef timersub
-#define timersub(tvp, uvp, vvp) \
- do { \
- (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
- (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
- if ((vvp)->tv_usec < 0) { \
- (vvp)->tv_sec--; \
- (vvp)->tv_usec += 1000000; \
- } \
- } while (0)
-#endif
-#endif
- timersub(&uptime, &src->scrub->pfss_last, &delta_ts);
- tsval_from_last = (delta_ts.tv_sec + ts_fudge) * TS_MAXFREQ;
- tsval_from_last += delta_ts.tv_usec / (TS_MICROSECS/TS_MAXFREQ);
-
-
- if ((src->state >= TCPS_ESTABLISHED &&
- dst->state >= TCPS_ESTABLISHED) &&
- (SEQ_LT(tsval, dst->scrub->pfss_tsecr) ||
- SEQ_GT(tsval, src->scrub->pfss_tsval + tsval_from_last) ||
- (tsecr && (SEQ_GT(tsecr, dst->scrub->pfss_tsval) ||
- SEQ_LT(tsecr, dst->scrub->pfss_tsval0))))) {
- /* Bad RFC1323 implementation or an insertion attack.
- *
- * - Solaris 2.6 and 2.7 are known to send another ACK
- * after the FIN,FIN|ACK,ACK closing that carries
- * an old timestamp.
- */
-
- DPFPRINTF(("Timestamp failed %c%c%c%c\n",
- SEQ_LT(tsval, dst->scrub->pfss_tsecr) ? '0' : ' ',
- SEQ_GT(tsval, src->scrub->pfss_tsval +
- tsval_from_last) ? '1' : ' ',
- SEQ_GT(tsecr, dst->scrub->pfss_tsval) ? '2' : ' ',
- SEQ_LT(tsecr, dst->scrub->pfss_tsval0)? '3' : ' '));
-#ifdef __FreeBSD__
- DPFPRINTF((" tsval: %u tsecr: %u +ticks: %u "
- "idle: %jus %lums\n",
- tsval, tsecr, tsval_from_last,
- (uintmax_t)delta_ts.tv_sec,
- delta_ts.tv_usec / 1000));
- DPFPRINTF((" src->tsval: %u tsecr: %u\n",
- src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
- DPFPRINTF((" dst->tsval: %u tsecr: %u tsval0: %u"
- "\n", dst->scrub->pfss_tsval,
- dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
-#else
- DPFPRINTF((" tsval: %lu tsecr: %lu +ticks: %lu "
- "idle: %lus %lums\n",
- tsval, tsecr, tsval_from_last, delta_ts.tv_sec,
- delta_ts.tv_usec / 1000));
- DPFPRINTF((" src->tsval: %lu tsecr: %lu\n",
- src->scrub->pfss_tsval, src->scrub->pfss_tsecr));
- DPFPRINTF((" dst->tsval: %lu tsecr: %lu tsval0: %lu"
- "\n", dst->scrub->pfss_tsval,
- dst->scrub->pfss_tsecr, dst->scrub->pfss_tsval0));
-#endif
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- pf_print_state(state);
- pf_print_flags(th->th_flags);
- printf("\n");
- }
- REASON_SET(reason, PFRES_TS);
- return (PF_DROP);
- }
-
- /* XXX I'd really like to require tsecr but it's optional */
-
- } else if (!got_ts && (th->th_flags & TH_RST) == 0 &&
- ((src->state == TCPS_ESTABLISHED && dst->state == TCPS_ESTABLISHED)
- || pd->p_len > 0 || (th->th_flags & TH_SYN)) &&
- src->scrub && dst->scrub &&
- (src->scrub->pfss_flags & PFSS_PAWS) &&
- (dst->scrub->pfss_flags & PFSS_PAWS)) {
- /* Didn't send a timestamp. Timestamps aren't really useful
- * when:
- * - connection opening or closing (often not even sent).
- * but we must not let an attacker to put a FIN on a
- * data packet to sneak it through our ESTABLISHED check.
- * - on a TCP reset. RFC suggests not even looking at TS.
- * - on an empty ACK. The TS will not be echoed so it will
- * probably not help keep the RTT calculation in sync and
- * there isn't as much danger when the sequence numbers
- * got wrapped. So some stacks don't include TS on empty
- * ACKs :-(
- *
- * To minimize the disruption to mostly RFC1323 conformant
- * stacks, we will only require timestamps on data packets.
- *
- * And what do ya know, we cannot require timestamps on data
- * packets. There appear to be devices that do legitimate
- * TCP connection hijacking. There are HTTP devices that allow
- * a 3whs (with timestamps) and then buffer the HTTP request.
- * If the intermediate device has the HTTP response cache, it
- * will spoof the response but not bother timestamping its
- * packets. So we can look for the presence of a timestamp in
- * the first data packet and if there, require it in all future
- * packets.
- */
-
- if (pd->p_len > 0 && (src->scrub->pfss_flags & PFSS_DATA_TS)) {
- /*
- * Hey! Someone tried to sneak a packet in. Or the
- * stack changed its RFC1323 behavior?!?!
- */
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC) {
-#else
- if (pf_status.debug >= PF_DEBUG_MISC) {
-#endif
- DPFPRINTF(("Did not receive expected RFC1323 "
- "timestamp\n"));
- pf_print_state(state);
- pf_print_flags(th->th_flags);
- printf("\n");
- }
- REASON_SET(reason, PFRES_TS);
- return (PF_DROP);
- }
- }
-
-
- /*
- * We will note if a host sends his data packets with or without
- * timestamps. And require all data packets to contain a timestamp
- * if the first does. PAWS implicitly requires that all data packets be
- * timestamped. But I think there are middle-man devices that hijack
- * TCP streams immediately after the 3whs and don't timestamp their
- * packets (seen in a WWW accelerator or cache).
- */
- if (pd->p_len > 0 && src->scrub && (src->scrub->pfss_flags &
- (PFSS_TIMESTAMP|PFSS_DATA_TS|PFSS_DATA_NOTS)) == PFSS_TIMESTAMP) {
- if (got_ts)
- src->scrub->pfss_flags |= PFSS_DATA_TS;
- else {
- src->scrub->pfss_flags |= PFSS_DATA_NOTS;
-#ifdef __FreeBSD__
- if (V_pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
-#else
- if (pf_status.debug >= PF_DEBUG_MISC && dst->scrub &&
-#endif
- (dst->scrub->pfss_flags & PFSS_TIMESTAMP)) {
- /* Don't warn if other host rejected RFC1323 */
- DPFPRINTF(("Broken RFC1323 stack did not "
- "timestamp data packet. Disabled PAWS "
- "security.\n"));
- pf_print_state(state);
- pf_print_flags(th->th_flags);
- printf("\n");
- }
- }
- }
-
-
- /*
- * Update PAWS values
- */
- if (got_ts && src->scrub && PFSS_TIMESTAMP == (src->scrub->pfss_flags &
- (PFSS_PAWS_IDLED|PFSS_TIMESTAMP))) {
- getmicrouptime(&src->scrub->pfss_last);
- if (SEQ_GEQ(tsval, src->scrub->pfss_tsval) ||
- (src->scrub->pfss_flags & PFSS_PAWS) == 0)
- src->scrub->pfss_tsval = tsval;
-
- if (tsecr) {
- if (SEQ_GEQ(tsecr, src->scrub->pfss_tsecr) ||
- (src->scrub->pfss_flags & PFSS_PAWS) == 0)
- src->scrub->pfss_tsecr = tsecr;
-
- if ((src->scrub->pfss_flags & PFSS_PAWS) == 0 &&
- (SEQ_LT(tsval, src->scrub->pfss_tsval0) ||
- src->scrub->pfss_tsval0 == 0)) {
- /* tsval0 MUST be the lowest timestamp */
- src->scrub->pfss_tsval0 = tsval;
- }
-
- /* Only fully initialized after a TS gets echoed */
- if ((src->scrub->pfss_flags & PFSS_PAWS) == 0)
- src->scrub->pfss_flags |= PFSS_PAWS;
- }
- }
-
- /* I have a dream.... TCP segment reassembly.... */
- return (0);
-}
-
-int
-pf_normalize_tcpopt(struct pf_rule *r, struct mbuf *m, struct tcphdr *th,
- int off, sa_family_t af)
-{
- u_int16_t *mss;
- int thoff;
- int opt, cnt, optlen = 0;
- int rewrite = 0;
-#ifdef __FreeBSD__
- u_char opts[TCP_MAXOLEN];
-#else
- u_char opts[MAX_TCPOPTLEN];
-#endif
- u_char *optp = opts;
-
- thoff = th->th_off << 2;
- cnt = thoff - sizeof(struct tcphdr);
-
- if (cnt > 0 && !pf_pull_hdr(m, off + sizeof(*th), opts, cnt,
- NULL, NULL, af))
- return (rewrite);
-
- for (; cnt > 0; cnt -= optlen, optp += optlen) {
- opt = optp[0];
- if (opt == TCPOPT_EOL)
- break;
- if (opt == TCPOPT_NOP)
- optlen = 1;
- else {
- if (cnt < 2)
- break;
- optlen = optp[1];
- if (optlen < 2 || optlen > cnt)
- break;
- }
- switch (opt) {
- case TCPOPT_MAXSEG:
- mss = (u_int16_t *)(optp + 2);
- if ((ntohs(*mss)) > r->max_mss) {
- th->th_sum = pf_cksum_fixup(th->th_sum,
- *mss, htons(r->max_mss), 0);
- *mss = htons(r->max_mss);
- rewrite = 1;
- }
- break;
- default:
- break;
- }
- }
-
- if (rewrite)
- m_copyback(m, off + sizeof(*th), thoff - sizeof(*th), opts);
-
- return (rewrite);
-}
-
-void
-pf_scrub_ip(struct mbuf **m0, u_int32_t flags, u_int8_t min_ttl, u_int8_t tos)
-{
- struct mbuf *m = *m0;
- struct ip *h = mtod(m, struct ip *);
-
- /* Clear IP_DF if no-df was requested */
- if (flags & PFRULE_NODF && h->ip_off & htons(IP_DF)) {
- u_int16_t ip_off = h->ip_off;
-
- h->ip_off &= htons(~IP_DF);
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_off, h->ip_off, 0);
- }
-
- /* Enforce a minimum ttl, may cause endless packet loops */
- if (min_ttl && h->ip_ttl < min_ttl) {
- u_int16_t ip_ttl = h->ip_ttl;
-
- h->ip_ttl = min_ttl;
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_ttl, h->ip_ttl, 0);
- }
-
- /* Enforce tos */
- if (flags & PFRULE_SET_TOS) {
- u_int16_t ov, nv;
-
- ov = *(u_int16_t *)h;
- h->ip_tos = tos;
- nv = *(u_int16_t *)h;
-
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ov, nv, 0);
- }
-
- /* random-id, but not for fragments */
- if (flags & PFRULE_RANDOMID && !(h->ip_off & ~htons(IP_DF))) {
- u_int16_t ip_id = h->ip_id;
-
- h->ip_id = ip_randomid();
- h->ip_sum = pf_cksum_fixup(h->ip_sum, ip_id, h->ip_id, 0);
- }
-}
-
-#ifdef INET6
-void
-pf_scrub_ip6(struct mbuf **m0, u_int8_t min_ttl)
-{
- struct mbuf *m = *m0;
- struct ip6_hdr *h = mtod(m, struct ip6_hdr *);
-
- /* Enforce a minimum ttl, may cause endless packet loops */
- if (min_ttl && h->ip6_hlim < min_ttl)
- h->ip6_hlim = min_ttl;
-}
-#endif
diff --git a/sys/contrib/pf/net/pf_osfp.c b/sys/contrib/pf/net/pf_osfp.c
deleted file mode 100644
index dcd8af7..0000000
--- a/sys/contrib/pf/net/pf_osfp.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/* $OpenBSD: pf_osfp.c,v 1.14 2008/06/12 18:17:01 henning Exp $ */
-
-/*
- * Copyright (c) 2003 Mike Frantzen <frantzen@w4g.org>
- *
- * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
- *
- */
-
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#ifdef _KERNEL
-#include <sys/systm.h>
-#ifndef __FreeBSD__
-#include <sys/pool.h>
-#endif
-#endif /* _KERNEL */
-#include <sys/mbuf.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#include <net/if.h>
-#include <net/pfvar.h>
-
-#include <netinet/ip6.h>
-#ifdef _KERNEL
-#include <netinet6/in6_var.h>
-#endif
-
-
-#ifdef _KERNEL
-#ifdef __FreeBSD__
-#define DPFPRINTF(format, x...) \
- if (V_pf_status.debug >= PF_DEBUG_NOISY) \
- printf(format , ##x)
-#else
-#define DPFPRINTF(format, x...) \
- if (pf_status.debug >= PF_DEBUG_NOISY) \
- printf(format , ##x)
-#endif
-#ifdef __FreeBSD__
-typedef uma_zone_t pool_t;
-#else
-typedef struct pool pool_t;
-#endif
-
-#else
-/* Userland equivalents so we can lend code to tcpdump et al. */
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-#define pool_t int
-#define pool_get(pool, flags) malloc(*(pool))
-#define pool_put(pool, item) free(item)
-#define pool_init(pool, size, a, ao, f, m, p) (*(pool)) = (size)
-
-#ifdef __FreeBSD__
-#define NTOHS(x) (x) = ntohs((u_int16_t)(x))
-#endif
-
-#ifdef PFDEBUG
-#include <sys/stdarg.h>
-#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
-#else
-#define DPFPRINTF(format, x...) ((void)0)
-#endif /* PFDEBUG */
-#endif /* _KERNEL */
-
-
-#ifdef __FreeBSD__
-SLIST_HEAD(pf_osfp_list, pf_os_fingerprint);
-VNET_DEFINE(struct pf_osfp_list, pf_osfp_list);
-#define V_pf_osfp_list VNET(pf_osfp_list)
-VNET_DEFINE(pool_t, pf_osfp_entry_pl);
-#define pf_osfp_entry_pl VNET(pf_osfp_entry_pl)
-VNET_DEFINE(pool_t, pf_osfp_pl);
-#define pf_osfp_pl VNET(pf_osfp_pl)
-#else
-SLIST_HEAD(pf_osfp_list, pf_os_fingerprint) pf_osfp_list;
-pool_t pf_osfp_entry_pl;
-pool_t pf_osfp_pl;
-#endif
-
-struct pf_os_fingerprint *pf_osfp_find(struct pf_osfp_list *,
- struct pf_os_fingerprint *, u_int8_t);
-struct pf_os_fingerprint *pf_osfp_find_exact(struct pf_osfp_list *,
- struct pf_os_fingerprint *);
-void pf_osfp_insert(struct pf_osfp_list *,
- struct pf_os_fingerprint *);
-
-
-#ifdef _KERNEL
-/*
- * Passively fingerprint the OS of the host (IPv4 TCP SYN packets only)
- * Returns the list of possible OSes.
- */
-struct pf_osfp_enlist *
-pf_osfp_fingerprint(struct pf_pdesc *pd, struct mbuf *m, int off,
- const struct tcphdr *tcp)
-{
- struct ip *ip;
- struct ip6_hdr *ip6;
- char hdr[60];
-
- if ((pd->af != PF_INET && pd->af != PF_INET6) ||
- pd->proto != IPPROTO_TCP || (tcp->th_off << 2) < sizeof(*tcp))
- return (NULL);
-
- if (pd->af == PF_INET) {
- ip = mtod(m, struct ip *);
- ip6 = (struct ip6_hdr *)NULL;
- } else {
- ip = (struct ip *)NULL;
- ip6 = mtod(m, struct ip6_hdr *);
- }
- if (!pf_pull_hdr(m, off, hdr, tcp->th_off << 2, NULL, NULL,
- pd->af)) return (NULL);
-
- return (pf_osfp_fingerprint_hdr(ip, ip6, (struct tcphdr *)hdr));
-}
-#endif /* _KERNEL */
-
-struct pf_osfp_enlist *
-pf_osfp_fingerprint_hdr(const struct ip *ip, const struct ip6_hdr *ip6, const struct tcphdr *tcp)
-{
- struct pf_os_fingerprint fp, *fpresult;
- int cnt, optlen = 0;
- const u_int8_t *optp;
-#ifdef _KERNEL
- char srcname[128];
-#else
- char srcname[NI_MAXHOST];
-#endif
-
- if ((tcp->th_flags & (TH_SYN|TH_ACK)) != TH_SYN)
- return (NULL);
- if (ip) {
- if ((ip->ip_off & htons(IP_OFFMASK)) != 0)
- return (NULL);
- }
-
- memset(&fp, 0, sizeof(fp));
-
- if (ip) {
-#ifndef _KERNEL
- struct sockaddr_in sin;
-#endif
-
- fp.fp_psize = ntohs(ip->ip_len);
- fp.fp_ttl = ip->ip_ttl;
- if (ip->ip_off & htons(IP_DF))
- fp.fp_flags |= PF_OSFP_DF;
-#ifdef _KERNEL
- strlcpy(srcname, inet_ntoa(ip->ip_src), sizeof(srcname));
-#else
- memset(&sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_addr = ip->ip_src;
- (void)getnameinfo((struct sockaddr *)&sin,
- sizeof(struct sockaddr_in), srcname, sizeof(srcname),
- NULL, 0, NI_NUMERICHOST);
-#endif
- }
-#ifdef INET6
- else if (ip6) {
-#ifndef _KERNEL
- struct sockaddr_in6 sin6;
-#endif
-
- /* jumbo payload? */
- fp.fp_psize = sizeof(struct ip6_hdr) + ntohs(ip6->ip6_plen);
- fp.fp_ttl = ip6->ip6_hlim;
- fp.fp_flags |= PF_OSFP_DF;
- fp.fp_flags |= PF_OSFP_INET6;
-#ifdef _KERNEL
- strlcpy(srcname, ip6_sprintf((struct in6_addr *)&ip6->ip6_src),
- sizeof(srcname));
-#else
- memset(&sin6, 0, sizeof(sin6));
- sin6.sin6_family = AF_INET6;
- sin6.sin6_len = sizeof(struct sockaddr_in6);
- sin6.sin6_addr = ip6->ip6_src;
- (void)getnameinfo((struct sockaddr *)&sin6,
- sizeof(struct sockaddr_in6), srcname, sizeof(srcname),
- NULL, 0, NI_NUMERICHOST);
-#endif
- }
-#endif
- else
- return (NULL);
- fp.fp_wsize = ntohs(tcp->th_win);
-
-
- cnt = (tcp->th_off << 2) - sizeof(*tcp);
- optp = (const u_int8_t *)((const char *)tcp + sizeof(*tcp));
- for (; cnt > 0; cnt -= optlen, optp += optlen) {
- if (*optp == TCPOPT_EOL)
- break;
-
- fp.fp_optcnt++;
- if (*optp == TCPOPT_NOP) {
- fp.fp_tcpopts = (fp.fp_tcpopts << PF_OSFP_TCPOPT_BITS) |
- PF_OSFP_TCPOPT_NOP;
- optlen = 1;
- } else {
- if (cnt < 2)
- return (NULL);
- optlen = optp[1];
- if (optlen > cnt || optlen < 2)
- return (NULL);
- switch (*optp) {
- case TCPOPT_MAXSEG:
- if (optlen >= TCPOLEN_MAXSEG)
- memcpy(&fp.fp_mss, &optp[2],
- sizeof(fp.fp_mss));
- fp.fp_tcpopts = (fp.fp_tcpopts <<
- PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_MSS;
- NTOHS(fp.fp_mss);
- break;
- case TCPOPT_WINDOW:
- if (optlen >= TCPOLEN_WINDOW)
- memcpy(&fp.fp_wscale, &optp[2],
- sizeof(fp.fp_wscale));
- NTOHS(fp.fp_wscale);
- fp.fp_tcpopts = (fp.fp_tcpopts <<
- PF_OSFP_TCPOPT_BITS) |
- PF_OSFP_TCPOPT_WSCALE;
- break;
- case TCPOPT_SACK_PERMITTED:
- fp.fp_tcpopts = (fp.fp_tcpopts <<
- PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_SACK;
- break;
- case TCPOPT_TIMESTAMP:
- if (optlen >= TCPOLEN_TIMESTAMP) {
- u_int32_t ts;
- memcpy(&ts, &optp[2], sizeof(ts));
- if (ts == 0)
- fp.fp_flags |= PF_OSFP_TS0;
-
- }
- fp.fp_tcpopts = (fp.fp_tcpopts <<
- PF_OSFP_TCPOPT_BITS) | PF_OSFP_TCPOPT_TS;
- break;
- default:
- return (NULL);
- }
- }
- optlen = MAX(optlen, 1); /* paranoia */
- }
-
- DPFPRINTF("fingerprinted %s:%d %d:%d:%d:%d:%llx (%d) "
- "(TS=%s,M=%s%d,W=%s%d)\n",
- srcname, ntohs(tcp->th_sport),
- fp.fp_wsize, fp.fp_ttl, (fp.fp_flags & PF_OSFP_DF) != 0,
- fp.fp_psize, (long long int)fp.fp_tcpopts, fp.fp_optcnt,
- (fp.fp_flags & PF_OSFP_TS0) ? "0" : "",
- (fp.fp_flags & PF_OSFP_MSS_MOD) ? "%" :
- (fp.fp_flags & PF_OSFP_MSS_DC) ? "*" : "",
- fp.fp_mss,
- (fp.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" :
- (fp.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
- fp.fp_wscale);
-
-#ifdef __FreeBSD__
- if ((fpresult = pf_osfp_find(&V_pf_osfp_list, &fp,
-#else
- if ((fpresult = pf_osfp_find(&pf_osfp_list, &fp,
-#endif
- PF_OSFP_MAXTTL_OFFSET)))
- return (&fpresult->fp_oses);
- return (NULL);
-}
-
-/* Match a fingerprint ID against a list of OSes */
-int
-pf_osfp_match(struct pf_osfp_enlist *list, pf_osfp_t os)
-{
- struct pf_osfp_entry *entry;
- int os_class, os_version, os_subtype;
- int en_class, en_version, en_subtype;
-
- if (os == PF_OSFP_ANY)
- return (1);
- if (list == NULL) {
- DPFPRINTF("osfp no match against %x\n", os);
- return (os == PF_OSFP_UNKNOWN);
- }
- PF_OSFP_UNPACK(os, os_class, os_version, os_subtype);
- SLIST_FOREACH(entry, list, fp_entry) {
- PF_OSFP_UNPACK(entry->fp_os, en_class, en_version, en_subtype);
- if ((os_class == PF_OSFP_ANY || en_class == os_class) &&
- (os_version == PF_OSFP_ANY || en_version == os_version) &&
- (os_subtype == PF_OSFP_ANY || en_subtype == os_subtype)) {
- DPFPRINTF("osfp matched %s %s %s %x==%x\n",
- entry->fp_class_nm, entry->fp_version_nm,
- entry->fp_subtype_nm, os, entry->fp_os);
- return (1);
- }
- }
- DPFPRINTF("fingerprint 0x%x didn't match\n", os);
- return (0);
-}
-
-/* Initialize the OS fingerprint system */
-#ifdef __FreeBSD__
-int
-#else
-void
-#endif
-pf_osfp_initialize(void)
-{
-#if defined(__FreeBSD__) && defined(_KERNEL)
- int error = ENOMEM;
-
- do {
- pf_osfp_entry_pl = pf_osfp_pl = NULL;
- UMA_CREATE(pf_osfp_entry_pl, struct pf_osfp_entry, "pfospfen");
- UMA_CREATE(pf_osfp_pl, struct pf_os_fingerprint, "pfosfp");
- error = 0;
- } while(0);
-
- SLIST_INIT(&V_pf_osfp_list);
-#else
- pool_init(&pf_osfp_entry_pl, sizeof(struct pf_osfp_entry), 0, 0, 0,
- "pfosfpen", &pool_allocator_nointr);
- pool_init(&pf_osfp_pl, sizeof(struct pf_os_fingerprint), 0, 0, 0,
- "pfosfp", &pool_allocator_nointr);
- SLIST_INIT(&pf_osfp_list);
-#endif
-
-#ifdef __FreeBSD__
-#ifdef _KERNEL
- return (error);
-#else
- return (0);
-#endif
-#endif
-}
-
-#if defined(__FreeBSD__) && (_KERNEL)
-void
-pf_osfp_cleanup(void)
-{
-
- UMA_DESTROY(pf_osfp_entry_pl);
- UMA_DESTROY(pf_osfp_pl);
-}
-#endif
-
-/* Flush the fingerprint list */
-void
-pf_osfp_flush(void)
-{
- struct pf_os_fingerprint *fp;
- struct pf_osfp_entry *entry;
-
-#ifdef __FreeBSD__
- while ((fp = SLIST_FIRST(&V_pf_osfp_list))) {
- SLIST_REMOVE_HEAD(&V_pf_osfp_list, fp_next);
-#else
- while ((fp = SLIST_FIRST(&pf_osfp_list))) {
- SLIST_REMOVE_HEAD(&pf_osfp_list, fp_next);
-#endif
- while ((entry = SLIST_FIRST(&fp->fp_oses))) {
- SLIST_REMOVE_HEAD(&fp->fp_oses, fp_entry);
- pool_put(&pf_osfp_entry_pl, entry);
- }
- pool_put(&pf_osfp_pl, fp);
- }
-}
-
-
-/* Add a fingerprint */
-int
-pf_osfp_add(struct pf_osfp_ioctl *fpioc)
-{
- struct pf_os_fingerprint *fp, fpadd;
- struct pf_osfp_entry *entry;
-
- memset(&fpadd, 0, sizeof(fpadd));
- fpadd.fp_tcpopts = fpioc->fp_tcpopts;
- fpadd.fp_wsize = fpioc->fp_wsize;
- fpadd.fp_psize = fpioc->fp_psize;
- fpadd.fp_mss = fpioc->fp_mss;
- fpadd.fp_flags = fpioc->fp_flags;
- fpadd.fp_optcnt = fpioc->fp_optcnt;
- fpadd.fp_wscale = fpioc->fp_wscale;
- fpadd.fp_ttl = fpioc->fp_ttl;
-
-#if 0 /* XXX RYAN wants to fix logging */
- DPFPRINTF("adding osfp %s %s %s = %s%d:%d:%d:%s%d:0x%llx %d "
- "(TS=%s,M=%s%d,W=%s%d) %x\n",
- fpioc->fp_os.fp_class_nm, fpioc->fp_os.fp_version_nm,
- fpioc->fp_os.fp_subtype_nm,
- (fpadd.fp_flags & PF_OSFP_WSIZE_MOD) ? "%" :
- (fpadd.fp_flags & PF_OSFP_WSIZE_MSS) ? "S" :
- (fpadd.fp_flags & PF_OSFP_WSIZE_MTU) ? "T" :
- (fpadd.fp_flags & PF_OSFP_WSIZE_DC) ? "*" : "",
- fpadd.fp_wsize,
- fpadd.fp_ttl,
- (fpadd.fp_flags & PF_OSFP_DF) ? 1 : 0,
- (fpadd.fp_flags & PF_OSFP_PSIZE_MOD) ? "%" :
- (fpadd.fp_flags & PF_OSFP_PSIZE_DC) ? "*" : "",
- fpadd.fp_psize,
- (long long int)fpadd.fp_tcpopts, fpadd.fp_optcnt,
- (fpadd.fp_flags & PF_OSFP_TS0) ? "0" : "",
- (fpadd.fp_flags & PF_OSFP_MSS_MOD) ? "%" :
- (fpadd.fp_flags & PF_OSFP_MSS_DC) ? "*" : "",
- fpadd.fp_mss,
- (fpadd.fp_flags & PF_OSFP_WSCALE_MOD) ? "%" :
- (fpadd.fp_flags & PF_OSFP_WSCALE_DC) ? "*" : "",
- fpadd.fp_wscale,
- fpioc->fp_os.fp_os);
-#endif
-
-#ifdef __FreeBSD__
- if ((fp = pf_osfp_find_exact(&V_pf_osfp_list, &fpadd))) {
-#else
- if ((fp = pf_osfp_find_exact(&pf_osfp_list, &fpadd))) {
-#endif
- SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
- if (PF_OSFP_ENTRY_EQ(entry, &fpioc->fp_os))
- return (EEXIST);
- }
- if ((entry = pool_get(&pf_osfp_entry_pl,
-#ifdef __FreeBSD__
- PR_NOWAIT)) == NULL)
-#else
- PR_WAITOK|PR_LIMITFAIL)) == NULL)
-#endif
- return (ENOMEM);
- } else {
- if ((fp = pool_get(&pf_osfp_pl,
-#ifdef __FreeBSD__
- PR_NOWAIT)) == NULL)
-#else
- PR_WAITOK|PR_LIMITFAIL)) == NULL)
-#endif
- return (ENOMEM);
- memset(fp, 0, sizeof(*fp));
- fp->fp_tcpopts = fpioc->fp_tcpopts;
- fp->fp_wsize = fpioc->fp_wsize;
- fp->fp_psize = fpioc->fp_psize;
- fp->fp_mss = fpioc->fp_mss;
- fp->fp_flags = fpioc->fp_flags;
- fp->fp_optcnt = fpioc->fp_optcnt;
- fp->fp_wscale = fpioc->fp_wscale;
- fp->fp_ttl = fpioc->fp_ttl;
- SLIST_INIT(&fp->fp_oses);
- if ((entry = pool_get(&pf_osfp_entry_pl,
-#ifdef __FreeBSD__
- PR_NOWAIT)) == NULL) {
-#else
- PR_WAITOK|PR_LIMITFAIL)) == NULL) {
-#endif
- pool_put(&pf_osfp_pl, fp);
- return (ENOMEM);
- }
-#ifdef __FreeBSD__
- pf_osfp_insert(&V_pf_osfp_list, fp);
-#else
- pf_osfp_insert(&pf_osfp_list, fp);
-#endif
- }
- memcpy(entry, &fpioc->fp_os, sizeof(*entry));
-
- /* Make sure the strings are NUL terminated */
- entry->fp_class_nm[sizeof(entry->fp_class_nm)-1] = '\0';
- entry->fp_version_nm[sizeof(entry->fp_version_nm)-1] = '\0';
- entry->fp_subtype_nm[sizeof(entry->fp_subtype_nm)-1] = '\0';
-
- SLIST_INSERT_HEAD(&fp->fp_oses, entry, fp_entry);
-
-#ifdef PFDEBUG
- if ((fp = pf_osfp_validate()))
- printf("Invalid fingerprint list\n");
-#endif /* PFDEBUG */
- return (0);
-}
-
-
-/* Find a fingerprint in the list */
-struct pf_os_fingerprint *
-pf_osfp_find(struct pf_osfp_list *list, struct pf_os_fingerprint *find,
- u_int8_t ttldiff)
-{
- struct pf_os_fingerprint *f;
-
-#define MATCH_INT(_MOD, _DC, _field) \
- if ((f->fp_flags & _DC) == 0) { \
- if ((f->fp_flags & _MOD) == 0) { \
- if (f->_field != find->_field) \
- continue; \
- } else { \
- if (f->_field == 0 || find->_field % f->_field) \
- continue; \
- } \
- }
-
- SLIST_FOREACH(f, list, fp_next) {
- if (f->fp_tcpopts != find->fp_tcpopts ||
- f->fp_optcnt != find->fp_optcnt ||
- f->fp_ttl < find->fp_ttl ||
- f->fp_ttl - find->fp_ttl > ttldiff ||
- (f->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)) !=
- (find->fp_flags & (PF_OSFP_DF|PF_OSFP_TS0)))
- continue;
-
- MATCH_INT(PF_OSFP_PSIZE_MOD, PF_OSFP_PSIZE_DC, fp_psize)
- MATCH_INT(PF_OSFP_MSS_MOD, PF_OSFP_MSS_DC, fp_mss)
- MATCH_INT(PF_OSFP_WSCALE_MOD, PF_OSFP_WSCALE_DC, fp_wscale)
- if ((f->fp_flags & PF_OSFP_WSIZE_DC) == 0) {
- if (f->fp_flags & PF_OSFP_WSIZE_MSS) {
- if (find->fp_mss == 0)
- continue;
-
-/*
- * Some "smart" NAT devices and DSL routers will tweak the MSS size and
- * will set it to whatever is suitable for the link type.
- */
-#define SMART_MSS 1460
- if ((find->fp_wsize % find->fp_mss ||
- find->fp_wsize / find->fp_mss !=
- f->fp_wsize) &&
- (find->fp_wsize % SMART_MSS ||
- find->fp_wsize / SMART_MSS !=
- f->fp_wsize))
- continue;
- } else if (f->fp_flags & PF_OSFP_WSIZE_MTU) {
- if (find->fp_mss == 0)
- continue;
-
-#define MTUOFF (sizeof(struct ip) + sizeof(struct tcphdr))
-#define SMART_MTU (SMART_MSS + MTUOFF)
- if ((find->fp_wsize % (find->fp_mss + MTUOFF) ||
- find->fp_wsize / (find->fp_mss + MTUOFF) !=
- f->fp_wsize) &&
- (find->fp_wsize % SMART_MTU ||
- find->fp_wsize / SMART_MTU !=
- f->fp_wsize))
- continue;
- } else if (f->fp_flags & PF_OSFP_WSIZE_MOD) {
- if (f->fp_wsize == 0 || find->fp_wsize %
- f->fp_wsize)
- continue;
- } else {
- if (f->fp_wsize != find->fp_wsize)
- continue;
- }
- }
- return (f);
- }
-
- return (NULL);
-}
-
-/* Find an exact fingerprint in the list */
-struct pf_os_fingerprint *
-pf_osfp_find_exact(struct pf_osfp_list *list, struct pf_os_fingerprint *find)
-{
- struct pf_os_fingerprint *f;
-
- SLIST_FOREACH(f, list, fp_next) {
- if (f->fp_tcpopts == find->fp_tcpopts &&
- f->fp_wsize == find->fp_wsize &&
- f->fp_psize == find->fp_psize &&
- f->fp_mss == find->fp_mss &&
- f->fp_flags == find->fp_flags &&
- f->fp_optcnt == find->fp_optcnt &&
- f->fp_wscale == find->fp_wscale &&
- f->fp_ttl == find->fp_ttl)
- return (f);
- }
-
- return (NULL);
-}
-
-/* Insert a fingerprint into the list */
-void
-pf_osfp_insert(struct pf_osfp_list *list, struct pf_os_fingerprint *ins)
-{
- struct pf_os_fingerprint *f, *prev = NULL;
-
- /* XXX need to go semi tree based. can key on tcp options */
-
- SLIST_FOREACH(f, list, fp_next)
- prev = f;
- if (prev)
- SLIST_INSERT_AFTER(prev, ins, fp_next);
- else
- SLIST_INSERT_HEAD(list, ins, fp_next);
-}
-
-/* Fill a fingerprint by its number (from an ioctl) */
-int
-pf_osfp_get(struct pf_osfp_ioctl *fpioc)
-{
- struct pf_os_fingerprint *fp;
- struct pf_osfp_entry *entry;
- int num = fpioc->fp_getnum;
- int i = 0;
-
-
- memset(fpioc, 0, sizeof(*fpioc));
-#ifdef __FreeBSD__
- SLIST_FOREACH(fp, &V_pf_osfp_list, fp_next) {
-#else
- SLIST_FOREACH(fp, &pf_osfp_list, fp_next) {
-#endif
- SLIST_FOREACH(entry, &fp->fp_oses, fp_entry) {
- if (i++ == num) {
- fpioc->fp_mss = fp->fp_mss;
- fpioc->fp_wsize = fp->fp_wsize;
- fpioc->fp_flags = fp->fp_flags;
- fpioc->fp_psize = fp->fp_psize;
- fpioc->fp_ttl = fp->fp_ttl;
- fpioc->fp_wscale = fp->fp_wscale;
- fpioc->fp_getnum = num;
- memcpy(&fpioc->fp_os, entry,
- sizeof(fpioc->fp_os));
- return (0);
- }
- }
- }
-
- return (EBUSY);
-}
-
-
-/* Validate that each signature is reachable */
-struct pf_os_fingerprint *
-pf_osfp_validate(void)
-{
- struct pf_os_fingerprint *f, *f2, find;
-
-#ifdef __FreeBSD__
- SLIST_FOREACH(f, &V_pf_osfp_list, fp_next) {
-#else
- SLIST_FOREACH(f, &pf_osfp_list, fp_next) {
-#endif
- memcpy(&find, f, sizeof(find));
-
- /* We do a few MSS/th_win percolations to make things unique */
- if (find.fp_mss == 0)
- find.fp_mss = 128;
- if (f->fp_flags & PF_OSFP_WSIZE_MSS)
- find.fp_wsize *= find.fp_mss;
- else if (f->fp_flags & PF_OSFP_WSIZE_MTU)
- find.fp_wsize *= (find.fp_mss + 40);
- else if (f->fp_flags & PF_OSFP_WSIZE_MOD)
- find.fp_wsize *= 2;
-#ifdef __FreeBSD__
- if (f != (f2 = pf_osfp_find(&V_pf_osfp_list, &find, 0))) {
-#else
- if (f != (f2 = pf_osfp_find(&pf_osfp_list, &find, 0))) {
-#endif
- if (f2)
- printf("Found \"%s %s %s\" instead of "
- "\"%s %s %s\"\n",
- SLIST_FIRST(&f2->fp_oses)->fp_class_nm,
- SLIST_FIRST(&f2->fp_oses)->fp_version_nm,
- SLIST_FIRST(&f2->fp_oses)->fp_subtype_nm,
- SLIST_FIRST(&f->fp_oses)->fp_class_nm,
- SLIST_FIRST(&f->fp_oses)->fp_version_nm,
- SLIST_FIRST(&f->fp_oses)->fp_subtype_nm);
- else
- printf("Couldn't find \"%s %s %s\"\n",
- SLIST_FIRST(&f->fp_oses)->fp_class_nm,
- SLIST_FIRST(&f->fp_oses)->fp_version_nm,
- SLIST_FIRST(&f->fp_oses)->fp_subtype_nm);
- return (f);
- }
- }
- return (NULL);
-}
diff --git a/sys/contrib/pf/net/pf_ruleset.c b/sys/contrib/pf/net/pf_ruleset.c
deleted file mode 100644
index ca8667c..0000000
--- a/sys/contrib/pf/net/pf_ruleset.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/* $OpenBSD: pf_ruleset.c,v 1.2 2008/12/18 15:31:37 dhill Exp $ */
-
-/*
- * Copyright (c) 2001 Daniel Hartmeier
- * Copyright (c) 2002,2003 Henning Brauer
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- * Effort sponsored in part by the Defense Advanced Research Projects
- * Agency (DARPA) and Air Force Research Laboratory, Air Force
- * Materiel Command, USAF, under agreement number F30602-01-2-0537.
- *
- */
-
-#ifdef __FreeBSD__
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#include <sys/param.h>
-#include <sys/socket.h>
-#ifdef _KERNEL
-# include <sys/systm.h>
-#endif /* _KERNEL */
-#include <sys/mbuf.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-
-#include <net/if.h>
-#include <net/pfvar.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#endif /* INET6 */
-
-
-#ifdef _KERNEL
-#ifdef __FreeBSD__
-#define DPFPRINTF(format, x...) \
- if (V_pf_status.debug >= PF_DEBUG_NOISY) \
- printf(format , ##x)
-#else
-#define DPFPRINTF(format, x...) \
- if (pf_status.debug >= PF_DEBUG_NOISY) \
- printf(format , ##x)
-#endif
-#ifdef __FreeBSD__
-#define rs_malloc(x) malloc(x, M_TEMP, M_NOWAIT|M_ZERO)
-#else
-#define rs_malloc(x) malloc(x, M_TEMP, M_WAITOK|M_CANFAIL|M_ZERO)
-#endif
-#define rs_free(x) free(x, M_TEMP)
-
-#else
-/* Userland equivalents so we can lend code to pfctl et al. */
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define rs_malloc(x) calloc(1, x)
-#define rs_free(x) free(x)
-
-#ifdef PFDEBUG
-#include <sys/stdarg.h>
-#define DPFPRINTF(format, x...) fprintf(stderr, format , ##x)
-#else
-#define DPFPRINTF(format, x...) ((void)0)
-#endif /* PFDEBUG */
-#endif /* _KERNEL */
-
-#if defined(__FreeBSD__) && !defined(_KERNEL)
-#undef V_pf_anchors
-#define V_pf_anchors pf_anchors
-
-#undef pf_main_ruleset
-#define pf_main_ruleset pf_main_anchor.ruleset
-#endif
-
-#if defined(__FreeBSD__) && defined(_KERNEL)
-VNET_DEFINE(struct pf_anchor_global, pf_anchors);
-VNET_DEFINE(struct pf_anchor, pf_main_anchor);
-#else
-struct pf_anchor_global pf_anchors;
-struct pf_anchor pf_main_anchor;
-#endif
-
-static __inline int pf_anchor_compare(struct pf_anchor *, struct pf_anchor *);
-
-RB_GENERATE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
-RB_GENERATE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
-
-static __inline int
-pf_anchor_compare(struct pf_anchor *a, struct pf_anchor *b)
-{
- int c = strcmp(a->path, b->path);
-
- return (c ? (c < 0 ? -1 : 1) : 0);
-}
-
-int
-pf_get_ruleset_number(u_int8_t action)
-{
- switch (action) {
- case PF_SCRUB:
- case PF_NOSCRUB:
- return (PF_RULESET_SCRUB);
- break;
- case PF_PASS:
- case PF_DROP:
- return (PF_RULESET_FILTER);
- break;
- case PF_NAT:
- case PF_NONAT:
- return (PF_RULESET_NAT);
- break;
- case PF_BINAT:
- case PF_NOBINAT:
- return (PF_RULESET_BINAT);
- break;
- case PF_RDR:
- case PF_NORDR:
- return (PF_RULESET_RDR);
- break;
- default:
- return (PF_RULESET_MAX);
- break;
- }
-}
-
-void
-pf_init_ruleset(struct pf_ruleset *ruleset)
-{
- int i;
-
- memset(ruleset, 0, sizeof(struct pf_ruleset));
- for (i = 0; i < PF_RULESET_MAX; i++) {
- TAILQ_INIT(&ruleset->rules[i].queues[0]);
- TAILQ_INIT(&ruleset->rules[i].queues[1]);
- ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
- ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
- }
-}
-
-struct pf_anchor *
-pf_find_anchor(const char *path)
-{
- struct pf_anchor *key, *found;
-
- key = (struct pf_anchor *)rs_malloc(sizeof(*key));
- if (key == NULL)
- return (NULL);
- strlcpy(key->path, path, sizeof(key->path));
-#ifdef __FreeBSD__
- found = RB_FIND(pf_anchor_global, &V_pf_anchors, key);
-#else
- found = RB_FIND(pf_anchor_global, &pf_anchors, key);
-#endif
- rs_free(key);
- return (found);
-}
-
-struct pf_ruleset *
-pf_find_ruleset(const char *path)
-{
- struct pf_anchor *anchor;
-
- while (*path == '/')
- path++;
- if (!*path)
- return (&pf_main_ruleset);
- anchor = pf_find_anchor(path);
- if (anchor == NULL)
- return (NULL);
- else
- return (&anchor->ruleset);
-}
-
-struct pf_ruleset *
-pf_find_or_create_ruleset(const char *path)
-{
- char *p, *q, *r;
- struct pf_ruleset *ruleset;
-#ifdef __FreeBSD__
- struct pf_anchor *anchor = NULL, *dup, *parent = NULL;
-#else
- struct pf_anchor *anchor, *dup, *parent = NULL;
-#endif
-
- if (path[0] == 0)
- return (&pf_main_ruleset);
- while (*path == '/')
- path++;
- ruleset = pf_find_ruleset(path);
- if (ruleset != NULL)
- return (ruleset);
- p = (char *)rs_malloc(MAXPATHLEN);
- if (p == NULL)
- return (NULL);
- strlcpy(p, path, MAXPATHLEN);
- while (parent == NULL && (q = strrchr(p, '/')) != NULL) {
- *q = 0;
- if ((ruleset = pf_find_ruleset(p)) != NULL) {
- parent = ruleset->anchor;
- break;
- }
- }
- if (q == NULL)
- q = p;
- else
- q++;
- strlcpy(p, path, MAXPATHLEN);
- if (!*q) {
- rs_free(p);
- return (NULL);
- }
- while ((r = strchr(q, '/')) != NULL || *q) {
- if (r != NULL)
- *r = 0;
- if (!*q || strlen(q) >= PF_ANCHOR_NAME_SIZE ||
- (parent != NULL && strlen(parent->path) >=
- MAXPATHLEN - PF_ANCHOR_NAME_SIZE - 1)) {
- rs_free(p);
- return (NULL);
- }
- anchor = (struct pf_anchor *)rs_malloc(sizeof(*anchor));
- if (anchor == NULL) {
- rs_free(p);
- return (NULL);
- }
- RB_INIT(&anchor->children);
- strlcpy(anchor->name, q, sizeof(anchor->name));
- if (parent != NULL) {
- strlcpy(anchor->path, parent->path,
- sizeof(anchor->path));
- strlcat(anchor->path, "/", sizeof(anchor->path));
- }
- strlcat(anchor->path, anchor->name, sizeof(anchor->path));
-#ifdef __FreeBSD__
- if ((dup = RB_INSERT(pf_anchor_global, &V_pf_anchors, anchor)) !=
-#else
- if ((dup = RB_INSERT(pf_anchor_global, &pf_anchors, anchor)) !=
-#endif
- NULL) {
- printf("pf_find_or_create_ruleset: RB_INSERT1 "
- "'%s' '%s' collides with '%s' '%s'\n",
- anchor->path, anchor->name, dup->path, dup->name);
- rs_free(anchor);
- rs_free(p);
- return (NULL);
- }
- if (parent != NULL) {
- anchor->parent = parent;
- if ((dup = RB_INSERT(pf_anchor_node, &parent->children,
- anchor)) != NULL) {
- printf("pf_find_or_create_ruleset: "
- "RB_INSERT2 '%s' '%s' collides with "
- "'%s' '%s'\n", anchor->path, anchor->name,
- dup->path, dup->name);
-#ifdef __FreeBSD__
- RB_REMOVE(pf_anchor_global, &V_pf_anchors,
-#else
- RB_REMOVE(pf_anchor_global, &pf_anchors,
-#endif
- anchor);
- rs_free(anchor);
- rs_free(p);
- return (NULL);
- }
- }
- pf_init_ruleset(&anchor->ruleset);
- anchor->ruleset.anchor = anchor;
- parent = anchor;
- if (r != NULL)
- q = r + 1;
- else
- *q = 0;
- }
- rs_free(p);
- return (&anchor->ruleset);
-}
-
-void
-pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
-{
- struct pf_anchor *parent;
- int i;
-
- while (ruleset != NULL) {
- if (ruleset == &pf_main_ruleset || ruleset->anchor == NULL ||
- !RB_EMPTY(&ruleset->anchor->children) ||
- ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||
- ruleset->topen)
- return;
- for (i = 0; i < PF_RULESET_MAX; ++i)
- if (!TAILQ_EMPTY(ruleset->rules[i].active.ptr) ||
- !TAILQ_EMPTY(ruleset->rules[i].inactive.ptr) ||
- ruleset->rules[i].inactive.open)
- return;
-#ifdef __FreeBSD__
- RB_REMOVE(pf_anchor_global, &V_pf_anchors, ruleset->anchor);
-#else
- RB_REMOVE(pf_anchor_global, &pf_anchors, ruleset->anchor);
-#endif
- if ((parent = ruleset->anchor->parent) != NULL)
- RB_REMOVE(pf_anchor_node, &parent->children,
- ruleset->anchor);
- rs_free(ruleset->anchor);
- if (parent == NULL)
- return;
- ruleset = &parent->ruleset;
- }
-}
-
-int
-pf_anchor_setup(struct pf_rule *r, const struct pf_ruleset *s,
- const char *name)
-{
- char *p, *path;
- struct pf_ruleset *ruleset;
-
- r->anchor = NULL;
- r->anchor_relative = 0;
- r->anchor_wildcard = 0;
- if (!name[0])
- return (0);
- path = (char *)rs_malloc(MAXPATHLEN);
- if (path == NULL)
- return (1);
- if (name[0] == '/')
- strlcpy(path, name + 1, MAXPATHLEN);
- else {
- /* relative path */
- r->anchor_relative = 1;
- if (s->anchor == NULL || !s->anchor->path[0])
- path[0] = 0;
- else
- strlcpy(path, s->anchor->path, MAXPATHLEN);
- while (name[0] == '.' && name[1] == '.' && name[2] == '/') {
- if (!path[0]) {
- printf("pf_anchor_setup: .. beyond root\n");
- rs_free(path);
- return (1);
- }
- if ((p = strrchr(path, '/')) != NULL)
- *p = 0;
- else
- path[0] = 0;
- r->anchor_relative++;
- name += 3;
- }
- if (path[0])
- strlcat(path, "/", MAXPATHLEN);
- strlcat(path, name, MAXPATHLEN);
- }
- if ((p = strrchr(path, '/')) != NULL && !strcmp(p, "/*")) {
- r->anchor_wildcard = 1;
- *p = 0;
- }
- ruleset = pf_find_or_create_ruleset(path);
- rs_free(path);
- if (ruleset == NULL || ruleset->anchor == NULL) {
- printf("pf_anchor_setup: ruleset\n");
- return (1);
- }
- r->anchor = ruleset->anchor;
- r->anchor->refcnt++;
- return (0);
-}
-
-int
-pf_anchor_copyout(const struct pf_ruleset *rs, const struct pf_rule *r,
- struct pfioc_rule *pr)
-{
- pr->anchor_call[0] = 0;
- if (r->anchor == NULL)
- return (0);
- if (!r->anchor_relative) {
- strlcpy(pr->anchor_call, "/", sizeof(pr->anchor_call));
- strlcat(pr->anchor_call, r->anchor->path,
- sizeof(pr->anchor_call));
- } else {
- char *a, *p;
- int i;
-
- a = (char *)rs_malloc(MAXPATHLEN);
- if (a == NULL)
- return (1);
- if (rs->anchor == NULL)
- a[0] = 0;
- else
- strlcpy(a, rs->anchor->path, MAXPATHLEN);
- for (i = 1; i < r->anchor_relative; ++i) {
- if ((p = strrchr(a, '/')) == NULL)
- p = a;
- *p = 0;
- strlcat(pr->anchor_call, "../",
- sizeof(pr->anchor_call));
- }
- if (strncmp(a, r->anchor->path, strlen(a))) {
- printf("pf_anchor_copyout: '%s' '%s'\n", a,
- r->anchor->path);
- rs_free(a);
- return (1);
- }
- if (strlen(r->anchor->path) > strlen(a))
- strlcat(pr->anchor_call, r->anchor->path + (a[0] ?
- strlen(a) + 1 : 0), sizeof(pr->anchor_call));
- rs_free(a);
- }
- if (r->anchor_wildcard)
- strlcat(pr->anchor_call, pr->anchor_call[0] ? "/*" : "*",
- sizeof(pr->anchor_call));
- return (0);
-}
-
-void
-pf_anchor_remove(struct pf_rule *r)
-{
- if (r->anchor == NULL)
- return;
- if (r->anchor->refcnt <= 0) {
- printf("pf_anchor_remove: broken refcount\n");
- r->anchor = NULL;
- return;
- }
- if (!--r->anchor->refcnt)
- pf_remove_if_empty_ruleset(&r->anchor->ruleset);
- r->anchor = NULL;
-}
diff --git a/sys/contrib/pf/net/pf_table.c b/sys/contrib/pf/net/pf_table.c
deleted file mode 100644
index ea77e31..0000000
--- a/sys/contrib/pf/net/pf_table.c
+++ /dev/null
@@ -1,2516 +0,0 @@
-/* $OpenBSD: pf_table.c,v 1.79 2008/10/08 06:24:50 mcbride Exp $ */
-
-/*
- * Copyright (c) 2002 Cedric Berger
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- */
-
-#ifdef __FreeBSD__
-#include "opt_inet.h"
-#include "opt_inet6.h"
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-#endif
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/socket.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#ifdef __FreeBSD__
-#include <sys/malloc.h>
-#else
-#include <sys/pool.h>
-#endif
-
-#include <net/if.h>
-#include <net/route.h>
-#include <netinet/in.h>
-#ifndef __FreeBSD__
-#include <netinet/ip_ipsp.h>
-#endif
-#include <net/pfvar.h>
-
-#define ACCEPT_FLAGS(flags, oklist) \
- do { \
- if ((flags & ~(oklist)) & \
- PFR_FLAG_ALLMASK) \
- return (EINVAL); \
- } while (0)
-
-#ifdef __FreeBSD__
-static inline int
-_copyin(const void *uaddr, void *kaddr, size_t len)
-{
- int r;
-
- PF_UNLOCK();
- r = copyin(uaddr, kaddr, len);
- PF_LOCK();
-
- return (r);
-}
-
-static inline int
-_copyout(const void *uaddr, void *kaddr, size_t len)
-{
- int r;
-
- PF_UNLOCK();
- r = copyout(uaddr, kaddr, len);
- PF_LOCK();
-
- return (r);
-}
-
-#define COPYIN(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- _copyin((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-
-#define COPYOUT(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- _copyout((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-
-#else
-#define COPYIN(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- copyin((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-
-#define COPYOUT(from, to, size, flags) \
- ((flags & PFR_FLAG_USERIOCTL) ? \
- copyout((from), (to), (size)) : \
- (bcopy((from), (to), (size)), 0))
-#endif
-
-#define FILLIN_SIN(sin, addr) \
- do { \
- (sin).sin_len = sizeof(sin); \
- (sin).sin_family = AF_INET; \
- (sin).sin_addr = (addr); \
- } while (0)
-
-#define FILLIN_SIN6(sin6, addr) \
- do { \
- (sin6).sin6_len = sizeof(sin6); \
- (sin6).sin6_family = AF_INET6; \
- (sin6).sin6_addr = (addr); \
- } while (0)
-
-#define SWAP(type, a1, a2) \
- do { \
- type tmp = a1; \
- a1 = a2; \
- a2 = tmp; \
- } while (0)
-
-#define SUNION2PF(su, af) (((af)==AF_INET) ? \
- (struct pf_addr *)&(su)->sin.sin_addr : \
- (struct pf_addr *)&(su)->sin6.sin6_addr)
-
-#define AF_BITS(af) (((af)==AF_INET)?32:128)
-#define ADDR_NETWORK(ad) ((ad)->pfra_net < AF_BITS((ad)->pfra_af))
-#define KENTRY_NETWORK(ke) ((ke)->pfrke_net < AF_BITS((ke)->pfrke_af))
-#define KENTRY_RNF_ROOT(ke) \
- ((((struct radix_node *)(ke))->rn_flags & RNF_ROOT) != 0)
-
-#define NO_ADDRESSES (-1)
-#define ENQUEUE_UNMARKED_ONLY (1)
-#define INVERT_NEG_FLAG (1)
-
-struct pfr_walktree {
- enum pfrw_op {
- PFRW_MARK,
- PFRW_SWEEP,
- PFRW_ENQUEUE,
- PFRW_GET_ADDRS,
- PFRW_GET_ASTATS,
- PFRW_POOL_GET,
- PFRW_DYNADDR_UPDATE
- } pfrw_op;
- union {
- struct pfr_addr *pfrw1_addr;
- struct pfr_astats *pfrw1_astats;
- struct pfr_kentryworkq *pfrw1_workq;
- struct pfr_kentry *pfrw1_kentry;
- struct pfi_dynaddr *pfrw1_dyn;
- } pfrw_1;
- int pfrw_free;
- int pfrw_flags;
-};
-#define pfrw_addr pfrw_1.pfrw1_addr
-#define pfrw_astats pfrw_1.pfrw1_astats
-#define pfrw_workq pfrw_1.pfrw1_workq
-#define pfrw_kentry pfrw_1.pfrw1_kentry
-#define pfrw_dyn pfrw_1.pfrw1_dyn
-#define pfrw_cnt pfrw_free
-
-#define senderr(e) do { rv = (e); goto _bad; } while (0)
-
-#ifdef __FreeBSD__
-VNET_DEFINE(uma_zone_t, pfr_ktable_pl);
-VNET_DEFINE(uma_zone_t, pfr_kentry_pl);
-VNET_DEFINE(uma_zone_t, pfr_kcounters_pl);
-VNET_DEFINE(struct sockaddr_in, pfr_sin);
-#define V_pfr_sin VNET(pfr_sin)
-VNET_DEFINE(struct sockaddr_in6, pfr_sin6);
-#define V_pfr_sin6 VNET(pfr_sin6)
-VNET_DEFINE(union sockaddr_union, pfr_mask);
-#define V_pfr_mask VNET(pfr_mask)
-VNET_DEFINE(struct pf_addr, pfr_ffaddr);
-#define V_pfr_ffaddr VNET(pfr_ffaddr)
-#else
-struct pool pfr_ktable_pl;
-struct pool pfr_kentry_pl;
-struct pool pfr_kcounters_pl;
-struct sockaddr_in pfr_sin;
-struct sockaddr_in6 pfr_sin6;
-union sockaddr_union pfr_mask;
-struct pf_addr pfr_ffaddr;
-#endif
-
-void pfr_copyout_addr(struct pfr_addr *,
- struct pfr_kentry *ke);
-int pfr_validate_addr(struct pfr_addr *);
-void pfr_enqueue_addrs(struct pfr_ktable *,
- struct pfr_kentryworkq *, int *, int);
-void pfr_mark_addrs(struct pfr_ktable *);
-struct pfr_kentry *pfr_lookup_addr(struct pfr_ktable *,
- struct pfr_addr *, int);
-struct pfr_kentry *pfr_create_kentry(struct pfr_addr *, int);
-void pfr_destroy_kentries(struct pfr_kentryworkq *);
-void pfr_destroy_kentry(struct pfr_kentry *);
-void pfr_insert_kentries(struct pfr_ktable *,
- struct pfr_kentryworkq *, long);
-void pfr_remove_kentries(struct pfr_ktable *,
- struct pfr_kentryworkq *);
-void pfr_clstats_kentries(struct pfr_kentryworkq *, long,
- int);
-void pfr_reset_feedback(struct pfr_addr *, int, int);
-void pfr_prepare_network(union sockaddr_union *, int, int);
-int pfr_route_kentry(struct pfr_ktable *,
- struct pfr_kentry *);
-int pfr_unroute_kentry(struct pfr_ktable *,
- struct pfr_kentry *);
-int pfr_walktree(struct radix_node *, void *);
-int pfr_validate_table(struct pfr_table *, int, int);
-int pfr_fix_anchor(char *);
-void pfr_commit_ktable(struct pfr_ktable *, long);
-void pfr_insert_ktables(struct pfr_ktableworkq *);
-void pfr_insert_ktable(struct pfr_ktable *);
-void pfr_setflags_ktables(struct pfr_ktableworkq *);
-void pfr_setflags_ktable(struct pfr_ktable *, int);
-void pfr_clstats_ktables(struct pfr_ktableworkq *, long,
- int);
-void pfr_clstats_ktable(struct pfr_ktable *, long, int);
-struct pfr_ktable *pfr_create_ktable(struct pfr_table *, long, int, int);
-void pfr_destroy_ktables(struct pfr_ktableworkq *, int);
-void pfr_destroy_ktable(struct pfr_ktable *, int);
-int pfr_ktable_compare(struct pfr_ktable *,
- struct pfr_ktable *);
-struct pfr_ktable *pfr_lookup_table(struct pfr_table *);
-void pfr_clean_node_mask(struct pfr_ktable *,
- struct pfr_kentryworkq *);
-int pfr_table_count(struct pfr_table *, int);
-int pfr_skip_table(struct pfr_table *,
- struct pfr_ktable *, int);
-struct pfr_kentry *pfr_kentry_byidx(struct pfr_ktable *, int, int);
-
-RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
-RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
-
-struct pfr_ktablehead pfr_ktables;
-struct pfr_table pfr_nulltable;
-int pfr_ktable_cnt;
-
-void
-pfr_initialize(void)
-{
-#ifndef __FreeBSD__
- pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0,
- "pfrktable", NULL);
- pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
- "pfrkentry", NULL);
- pool_init(&pfr_kcounters_pl, sizeof(struct pfr_kcounters), 0, 0, 0,
- "pfrkcounters", NULL);
-
- pfr_sin.sin_len = sizeof(pfr_sin);
- pfr_sin.sin_family = AF_INET;
- pfr_sin6.sin6_len = sizeof(pfr_sin6);
- pfr_sin6.sin6_family = AF_INET6;
-
- memset(&pfr_ffaddr, 0xff, sizeof(pfr_ffaddr));
-#else
- V_pfr_sin.sin_len = sizeof(V_pfr_sin);
- V_pfr_sin.sin_family = AF_INET;
- V_pfr_sin6.sin6_len = sizeof(V_pfr_sin6);
- V_pfr_sin6.sin6_family = AF_INET6;
-
- memset(&V_pfr_ffaddr, 0xff, sizeof(V_pfr_ffaddr));
-#endif
-}
-
-int
-pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
-{
- struct pfr_ktable *kt;
- struct pfr_kentryworkq workq;
- int s;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
- if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- if (kt->pfrkt_flags & PFR_TFLAG_CONST)
- return (EPERM);
- pfr_enqueue_addrs(kt, &workq, ndel, 0);
-
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_remove_kentries(kt, &workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- if (kt->pfrkt_cnt) {
- printf("pfr_clr_addrs: corruption detected (%d).\n",
- kt->pfrkt_cnt);
- kt->pfrkt_cnt = 0;
- }
- }
- return (0);
-}
-
-int
-pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *nadd, int flags)
-{
- struct pfr_ktable *kt, *tmpkt;
- struct pfr_kentryworkq workq;
- struct pfr_kentry *p, *q;
- struct pfr_addr ad;
- int i, rv, s, xadd = 0;
- long tzero = time_second;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
- if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- if (kt->pfrkt_flags & PFR_TFLAG_CONST)
- return (EPERM);
- tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
- !(flags & PFR_FLAG_USERIOCTL));
- if (tmpkt == NULL)
- return (ENOMEM);
- SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
- senderr(EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
- q = pfr_lookup_addr(tmpkt, &ad, 1);
- if (flags & PFR_FLAG_FEEDBACK) {
- if (q != NULL)
- ad.pfra_fback = PFR_FB_DUPLICATE;
- else if (p == NULL)
- ad.pfra_fback = PFR_FB_ADDED;
- else if (p->pfrke_not != ad.pfra_not)
- ad.pfra_fback = PFR_FB_CONFLICT;
- else
- ad.pfra_fback = PFR_FB_NONE;
- }
- if (p == NULL && q == NULL) {
- p = pfr_create_kentry(&ad,
- !(flags & PFR_FLAG_USERIOCTL));
- if (p == NULL)
- senderr(ENOMEM);
- if (pfr_route_kentry(tmpkt, p)) {
- pfr_destroy_kentry(p);
- ad.pfra_fback = PFR_FB_NONE;
- } else {
- SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
- xadd++;
- }
- }
- if (flags & PFR_FLAG_FEEDBACK)
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
- }
- pfr_clean_node_mask(tmpkt, &workq);
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_insert_kentries(kt, &workq, tzero);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- } else
- pfr_destroy_kentries(&workq);
- if (nadd != NULL)
- *nadd = xadd;
- pfr_destroy_ktable(tmpkt, 0);
- return (0);
-_bad:
- pfr_clean_node_mask(tmpkt, &workq);
- pfr_destroy_kentries(&workq);
- if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
- pfr_destroy_ktable(tmpkt, 0);
- return (rv);
-}
-
-int
-pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *ndel, int flags)
-{
- struct pfr_ktable *kt;
- struct pfr_kentryworkq workq;
- struct pfr_kentry *p;
- struct pfr_addr ad;
- int i, rv, s, xdel = 0, log = 1;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
- if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- if (kt->pfrkt_flags & PFR_TFLAG_CONST)
- return (EPERM);
- /*
- * there are two algorithms to choose from here.
- * with:
- * n: number of addresses to delete
- * N: number of addresses in the table
- *
- * one is O(N) and is better for large 'n'
- * one is O(n*LOG(N)) and is better for small 'n'
- *
- * following code try to decide which one is best.
- */
- for (i = kt->pfrkt_cnt; i > 0; i >>= 1)
- log++;
- if (size > kt->pfrkt_cnt/log) {
- /* full table scan */
- pfr_mark_addrs(kt);
- } else {
- /* iterate over addresses to delete */
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- return (EFAULT);
- if (pfr_validate_addr(&ad))
- return (EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
- if (p != NULL)
- p->pfrke_mark = 0;
- }
- }
- SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
- senderr(EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
- if (flags & PFR_FLAG_FEEDBACK) {
- if (p == NULL)
- ad.pfra_fback = PFR_FB_NONE;
- else if (p->pfrke_not != ad.pfra_not)
- ad.pfra_fback = PFR_FB_CONFLICT;
- else if (p->pfrke_mark)
- ad.pfra_fback = PFR_FB_DUPLICATE;
- else
- ad.pfra_fback = PFR_FB_DELETED;
- }
- if (p != NULL && p->pfrke_not == ad.pfra_not &&
- !p->pfrke_mark) {
- p->pfrke_mark = 1;
- SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
- xdel++;
- }
- if (flags & PFR_FLAG_FEEDBACK)
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_remove_kentries(kt, &workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
- if (ndel != NULL)
- *ndel = xdel;
- return (0);
-_bad:
- if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
- return (rv);
-}
-
-int
-pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *size2, int *nadd, int *ndel, int *nchange, int flags,
- u_int32_t ignore_pfrt_flags)
-{
- struct pfr_ktable *kt, *tmpkt;
- struct pfr_kentryworkq addq, delq, changeq;
- struct pfr_kentry *p, *q;
- struct pfr_addr ad;
- int i, rv, s, xadd = 0, xdel = 0, xchange = 0;
- long tzero = time_second;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
- if (pfr_validate_table(tbl, ignore_pfrt_flags, flags &
- PFR_FLAG_USERIOCTL))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- if (kt->pfrkt_flags & PFR_TFLAG_CONST)
- return (EPERM);
- tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
- !(flags & PFR_FLAG_USERIOCTL));
- if (tmpkt == NULL)
- return (ENOMEM);
- pfr_mark_addrs(kt);
- SLIST_INIT(&addq);
- SLIST_INIT(&delq);
- SLIST_INIT(&changeq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
- senderr(EINVAL);
- ad.pfra_fback = PFR_FB_NONE;
- p = pfr_lookup_addr(kt, &ad, 1);
- if (p != NULL) {
- if (p->pfrke_mark) {
- ad.pfra_fback = PFR_FB_DUPLICATE;
- goto _skip;
- }
- p->pfrke_mark = 1;
- if (p->pfrke_not != ad.pfra_not) {
- SLIST_INSERT_HEAD(&changeq, p, pfrke_workq);
- ad.pfra_fback = PFR_FB_CHANGED;
- xchange++;
- }
- } else {
- q = pfr_lookup_addr(tmpkt, &ad, 1);
- if (q != NULL) {
- ad.pfra_fback = PFR_FB_DUPLICATE;
- goto _skip;
- }
- p = pfr_create_kentry(&ad,
- !(flags & PFR_FLAG_USERIOCTL));
- if (p == NULL)
- senderr(ENOMEM);
- if (pfr_route_kentry(tmpkt, p)) {
- pfr_destroy_kentry(p);
- ad.pfra_fback = PFR_FB_NONE;
- } else {
- SLIST_INSERT_HEAD(&addq, p, pfrke_workq);
- ad.pfra_fback = PFR_FB_ADDED;
- xadd++;
- }
- }
-_skip:
- if (flags & PFR_FLAG_FEEDBACK)
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
- }
- pfr_enqueue_addrs(kt, &delq, &xdel, ENQUEUE_UNMARKED_ONLY);
- if ((flags & PFR_FLAG_FEEDBACK) && *size2) {
- if (*size2 < size+xdel) {
- *size2 = size+xdel;
- senderr(0);
- }
- i = 0;
- SLIST_FOREACH(p, &delq, pfrke_workq) {
- pfr_copyout_addr(&ad, p);
- ad.pfra_fback = PFR_FB_DELETED;
- if (COPYOUT(&ad, addr+size+i, sizeof(ad), flags))
- senderr(EFAULT);
- i++;
- }
- }
- pfr_clean_node_mask(tmpkt, &addq);
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_insert_kentries(kt, &addq, tzero);
- pfr_remove_kentries(kt, &delq);
- pfr_clstats_kentries(&changeq, tzero, INVERT_NEG_FLAG);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- } else
- pfr_destroy_kentries(&addq);
- if (nadd != NULL)
- *nadd = xadd;
- if (ndel != NULL)
- *ndel = xdel;
- if (nchange != NULL)
- *nchange = xchange;
- if ((flags & PFR_FLAG_FEEDBACK) && size2)
- *size2 = size+xdel;
- pfr_destroy_ktable(tmpkt, 0);
- return (0);
-_bad:
- pfr_clean_node_mask(tmpkt, &addq);
- pfr_destroy_kentries(&addq);
- if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
- pfr_destroy_ktable(tmpkt, 0);
- return (rv);
-}
-
-int
-pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *nmatch, int flags)
-{
- struct pfr_ktable *kt;
- struct pfr_kentry *p;
- struct pfr_addr ad;
- int i, xmatch = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_REPLACE);
- if (pfr_validate_table(tbl, 0, 0))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
-
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- return (EFAULT);
- if (pfr_validate_addr(&ad))
- return (EINVAL);
- if (ADDR_NETWORK(&ad))
- return (EINVAL);
- p = pfr_lookup_addr(kt, &ad, 0);
- if (flags & PFR_FLAG_REPLACE)
- pfr_copyout_addr(&ad, p);
- ad.pfra_fback = (p == NULL) ? PFR_FB_NONE :
- (p->pfrke_not ? PFR_FB_NOTMATCH : PFR_FB_MATCH);
- if (p != NULL && !p->pfrke_not)
- xmatch++;
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- return (EFAULT);
- }
- if (nmatch != NULL)
- *nmatch = xmatch;
- return (0);
-}
-
-int
-pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
- int flags)
-{
- struct pfr_ktable *kt;
- struct pfr_walktree w;
- int rv;
-
- ACCEPT_FLAGS(flags, 0);
- if (pfr_validate_table(tbl, 0, 0))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- if (kt->pfrkt_cnt > *size) {
- *size = kt->pfrkt_cnt;
- return (0);
- }
-
- bzero(&w, sizeof(w));
- w.pfrw_op = PFRW_GET_ADDRS;
- w.pfrw_addr = addr;
- w.pfrw_free = kt->pfrkt_cnt;
- w.pfrw_flags = flags;
-#ifdef __FreeBSD__
- rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
- if (!rv)
-#ifdef __FreeBSD__
- rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
- &w);
-#else
- rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
- if (rv)
- return (rv);
-
- if (w.pfrw_free) {
- printf("pfr_get_addrs: corruption detected (%d).\n",
- w.pfrw_free);
- return (ENOTTY);
- }
- *size = kt->pfrkt_cnt;
- return (0);
-}
-
-int
-pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
- int flags)
-{
- struct pfr_ktable *kt;
- struct pfr_walktree w;
- struct pfr_kentryworkq workq;
- int rv, s;
- long tzero = time_second;
-
- /* XXX PFR_FLAG_CLSTATS disabled */
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC);
- if (pfr_validate_table(tbl, 0, 0))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- if (kt->pfrkt_cnt > *size) {
- *size = kt->pfrkt_cnt;
- return (0);
- }
-
- bzero(&w, sizeof(w));
- w.pfrw_op = PFRW_GET_ASTATS;
- w.pfrw_astats = addr;
- w.pfrw_free = kt->pfrkt_cnt;
- w.pfrw_flags = flags;
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
-#ifdef __FreeBSD__
- rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rv = rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
- if (!rv)
-#ifdef __FreeBSD__
- rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
- &w);
-#else
- rv = rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
- if (!rv && (flags & PFR_FLAG_CLSTATS)) {
- pfr_enqueue_addrs(kt, &workq, NULL, 0);
- pfr_clstats_kentries(&workq, tzero, 0);
- }
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- if (rv)
- return (rv);
-
- if (w.pfrw_free) {
- printf("pfr_get_astats: corruption detected (%d).\n",
- w.pfrw_free);
- return (ENOTTY);
- }
- *size = kt->pfrkt_cnt;
- return (0);
-}
-
-int
-pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *nzero, int flags)
-{
- struct pfr_ktable *kt;
- struct pfr_kentryworkq workq;
- struct pfr_kentry *p;
- struct pfr_addr ad;
- int i, rv, s, xzero = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_FEEDBACK);
- if (pfr_validate_table(tbl, 0, 0))
- return (EINVAL);
- kt = pfr_lookup_table(tbl);
- if (kt == NULL || !(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (ESRCH);
- SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
- senderr(EINVAL);
- p = pfr_lookup_addr(kt, &ad, 1);
- if (flags & PFR_FLAG_FEEDBACK) {
- ad.pfra_fback = (p != NULL) ?
- PFR_FB_CLEARED : PFR_FB_NONE;
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- senderr(EFAULT);
- }
- if (p != NULL) {
- SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
- xzero++;
- }
- }
-
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_clstats_kentries(&workq, 0, 0);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
- if (nzero != NULL)
- *nzero = xzero;
- return (0);
-_bad:
- if (flags & PFR_FLAG_FEEDBACK)
- pfr_reset_feedback(addr, size, flags);
- return (rv);
-}
-
-int
-pfr_validate_addr(struct pfr_addr *ad)
-{
- int i;
-
- switch (ad->pfra_af) {
-#ifdef INET
- case AF_INET:
- if (ad->pfra_net > 32)
- return (-1);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- if (ad->pfra_net > 128)
- return (-1);
- break;
-#endif /* INET6 */
- default:
- return (-1);
- }
- if (ad->pfra_net < 128 &&
- (((caddr_t)ad)[ad->pfra_net/8] & (0xFF >> (ad->pfra_net%8))))
- return (-1);
- for (i = (ad->pfra_net+7)/8; i < sizeof(ad->pfra_u); i++)
- if (((caddr_t)ad)[i])
- return (-1);
- if (ad->pfra_not && ad->pfra_not != 1)
- return (-1);
- if (ad->pfra_fback)
- return (-1);
- return (0);
-}
-
-void
-pfr_enqueue_addrs(struct pfr_ktable *kt, struct pfr_kentryworkq *workq,
- int *naddr, int sweep)
-{
- struct pfr_walktree w;
-
- SLIST_INIT(workq);
- bzero(&w, sizeof(w));
- w.pfrw_op = sweep ? PFRW_SWEEP : PFRW_ENQUEUE;
- w.pfrw_workq = workq;
- if (kt->pfrkt_ip4 != NULL)
-#ifdef __FreeBSD__
- if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree,
- &w))
-#else
- if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
-#endif
- printf("pfr_enqueue_addrs: IPv4 walktree failed.\n");
- if (kt->pfrkt_ip6 != NULL)
-#ifdef __FreeBSD__
- if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
- &w))
-#else
- if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
-#endif
- printf("pfr_enqueue_addrs: IPv6 walktree failed.\n");
- if (naddr != NULL)
- *naddr = w.pfrw_cnt;
-}
-
-void
-pfr_mark_addrs(struct pfr_ktable *kt)
-{
- struct pfr_walktree w;
-
- bzero(&w, sizeof(w));
- w.pfrw_op = PFRW_MARK;
-#ifdef __FreeBSD__
- if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
-#else
- if (rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
-#endif
- printf("pfr_mark_addrs: IPv4 walktree failed.\n");
-#ifdef __FreeBSD__
- if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
-#else
- if (rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
-#endif
- printf("pfr_mark_addrs: IPv6 walktree failed.\n");
-}
-
-
-struct pfr_kentry *
-pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
-{
- union sockaddr_union sa, mask;
-#ifdef __FreeBSD__
- struct radix_node_head *head = NULL;
-#else
- struct radix_node_head *head;
-#endif
- struct pfr_kentry *ke;
- int s;
-
- bzero(&sa, sizeof(sa));
- if (ad->pfra_af == AF_INET) {
- FILLIN_SIN(sa.sin, ad->pfra_ip4addr);
- head = kt->pfrkt_ip4;
- } else if ( ad->pfra_af == AF_INET6 ) {
- FILLIN_SIN6(sa.sin6, ad->pfra_ip6addr);
- head = kt->pfrkt_ip6;
- }
- if (ADDR_NETWORK(ad)) {
- pfr_prepare_network(&mask, ad->pfra_af, ad->pfra_net);
- s = splsoftnet(); /* rn_lookup makes use of globals */
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#endif
- ke = (struct pfr_kentry *)rn_lookup(&sa, &mask, head);
- splx(s);
- if (ke && KENTRY_RNF_ROOT(ke))
- ke = NULL;
- } else {
- ke = (struct pfr_kentry *)rn_match(&sa, head);
- if (ke && KENTRY_RNF_ROOT(ke))
- ke = NULL;
- if (exact && ke && KENTRY_NETWORK(ke))
- ke = NULL;
- }
- return (ke);
-}
-
-struct pfr_kentry *
-pfr_create_kentry(struct pfr_addr *ad, int intr)
-{
- struct pfr_kentry *ke;
-
-#ifdef __FreeBSD__
- ke = pool_get(&V_pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
-#else
- if (intr)
- ke = pool_get(&pfr_kentry_pl, PR_NOWAIT | PR_ZERO);
- else
- ke = pool_get(&pfr_kentry_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
-#endif
- if (ke == NULL)
- return (NULL);
-
- if (ad->pfra_af == AF_INET)
- FILLIN_SIN(ke->pfrke_sa.sin, ad->pfra_ip4addr);
- else if (ad->pfra_af == AF_INET6)
- FILLIN_SIN6(ke->pfrke_sa.sin6, ad->pfra_ip6addr);
- ke->pfrke_af = ad->pfra_af;
- ke->pfrke_net = ad->pfra_net;
- ke->pfrke_not = ad->pfra_not;
- return (ke);
-}
-
-void
-pfr_destroy_kentries(struct pfr_kentryworkq *workq)
-{
- struct pfr_kentry *p, *q;
-
- for (p = SLIST_FIRST(workq); p != NULL; p = q) {
- q = SLIST_NEXT(p, pfrke_workq);
- pfr_destroy_kentry(p);
- }
-}
-
-void
-pfr_destroy_kentry(struct pfr_kentry *ke)
-{
- if (ke->pfrke_counters)
-#ifdef __FreeBSD__
- pool_put(&V_pfr_kcounters_pl, ke->pfrke_counters);
- pool_put(&V_pfr_kentry_pl, ke);
-#else
- pool_put(&pfr_kcounters_pl, ke->pfrke_counters);
- pool_put(&pfr_kentry_pl, ke);
-#endif
-}
-
-void
-pfr_insert_kentries(struct pfr_ktable *kt,
- struct pfr_kentryworkq *workq, long tzero)
-{
- struct pfr_kentry *p;
- int rv, n = 0;
-
- SLIST_FOREACH(p, workq, pfrke_workq) {
- rv = pfr_route_kentry(kt, p);
- if (rv) {
- printf("pfr_insert_kentries: cannot route entry "
- "(code=%d).\n", rv);
- break;
- }
- p->pfrke_tzero = tzero;
- n++;
- }
- kt->pfrkt_cnt += n;
-}
-
-int
-pfr_insert_kentry(struct pfr_ktable *kt, struct pfr_addr *ad, long tzero)
-{
- struct pfr_kentry *p;
- int rv;
-
- p = pfr_lookup_addr(kt, ad, 1);
- if (p != NULL)
- return (0);
- p = pfr_create_kentry(ad, 1);
- if (p == NULL)
- return (EINVAL);
-
- rv = pfr_route_kentry(kt, p);
- if (rv)
- return (rv);
-
- p->pfrke_tzero = tzero;
- kt->pfrkt_cnt++;
-
- return (0);
-}
-
-void
-pfr_remove_kentries(struct pfr_ktable *kt,
- struct pfr_kentryworkq *workq)
-{
- struct pfr_kentry *p;
- int n = 0;
-
- SLIST_FOREACH(p, workq, pfrke_workq) {
- pfr_unroute_kentry(kt, p);
- n++;
- }
- kt->pfrkt_cnt -= n;
- pfr_destroy_kentries(workq);
-}
-
-void
-pfr_clean_node_mask(struct pfr_ktable *kt,
- struct pfr_kentryworkq *workq)
-{
- struct pfr_kentry *p;
-
- SLIST_FOREACH(p, workq, pfrke_workq)
- pfr_unroute_kentry(kt, p);
-}
-
-void
-pfr_clstats_kentries(struct pfr_kentryworkq *workq, long tzero, int negchange)
-{
- struct pfr_kentry *p;
- int s;
-
- SLIST_FOREACH(p, workq, pfrke_workq) {
- s = splsoftnet();
- if (negchange)
- p->pfrke_not = !p->pfrke_not;
- if (p->pfrke_counters) {
-#ifdef __FreeBSD__
- pool_put(&V_pfr_kcounters_pl, p->pfrke_counters);
-#else
- pool_put(&pfr_kcounters_pl, p->pfrke_counters);
-#endif
- p->pfrke_counters = NULL;
- }
- splx(s);
- p->pfrke_tzero = tzero;
- }
-}
-
-void
-pfr_reset_feedback(struct pfr_addr *addr, int size, int flags)
-{
- struct pfr_addr ad;
- int i;
-
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- break;
- ad.pfra_fback = PFR_FB_NONE;
- if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
- break;
- }
-}
-
-void
-pfr_prepare_network(union sockaddr_union *sa, int af, int net)
-{
- int i;
-
- bzero(sa, sizeof(*sa));
- if (af == AF_INET) {
- sa->sin.sin_len = sizeof(sa->sin);
- sa->sin.sin_family = AF_INET;
- sa->sin.sin_addr.s_addr = net ? htonl(-1 << (32-net)) : 0;
- } else if (af == AF_INET6) {
- sa->sin6.sin6_len = sizeof(sa->sin6);
- sa->sin6.sin6_family = AF_INET6;
- for (i = 0; i < 4; i++) {
- if (net <= 32) {
- sa->sin6.sin6_addr.s6_addr32[i] =
- net ? htonl(-1 << (32-net)) : 0;
- break;
- }
- sa->sin6.sin6_addr.s6_addr32[i] = 0xFFFFFFFF;
- net -= 32;
- }
- }
-}
-
-int
-pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
-{
- union sockaddr_union mask;
- struct radix_node *rn;
-#ifdef __FreeBSD__
- struct radix_node_head *head = NULL;
-#else
- struct radix_node_head *head;
-#endif
- int s;
-
- bzero(ke->pfrke_node, sizeof(ke->pfrke_node));
- if (ke->pfrke_af == AF_INET)
- head = kt->pfrkt_ip4;
- else if (ke->pfrke_af == AF_INET6)
- head = kt->pfrkt_ip6;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#endif
- if (KENTRY_NETWORK(ke)) {
- pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
-#ifdef __FreeBSD__
- rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node);
-#else
- rn = rn_addroute(&ke->pfrke_sa, &mask, head, ke->pfrke_node, 0);
-#endif
- } else
-#ifdef __FreeBSD__
- rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node);
-#else
- rn = rn_addroute(&ke->pfrke_sa, NULL, head, ke->pfrke_node, 0);
-#endif
- splx(s);
-
- return (rn == NULL ? -1 : 0);
-}
-
-int
-pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
-{
- union sockaddr_union mask;
- struct radix_node *rn;
-#ifdef __FreeBSD__
- struct radix_node_head *head = NULL;
-#else
- struct radix_node_head *head;
-#endif
- int s;
-
- if (ke->pfrke_af == AF_INET)
- head = kt->pfrkt_ip4;
- else if (ke->pfrke_af == AF_INET6)
- head = kt->pfrkt_ip6;
-
- s = splsoftnet();
-#ifdef __FreeBSD__
- PF_LOCK_ASSERT();
-#endif
- if (KENTRY_NETWORK(ke)) {
- pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
-#ifdef __FreeBSD__
- rn = rn_delete(&ke->pfrke_sa, &mask, head);
-#else
- rn = rn_delete(&ke->pfrke_sa, &mask, head, NULL);
-#endif
- } else
-#ifdef __FreeBSD__
- rn = rn_delete(&ke->pfrke_sa, NULL, head);
-#else
- rn = rn_delete(&ke->pfrke_sa, NULL, head, NULL);
-#endif
- splx(s);
-
- if (rn == NULL) {
- printf("pfr_unroute_kentry: delete failed.\n");
- return (-1);
- }
- return (0);
-}
-
-void
-pfr_copyout_addr(struct pfr_addr *ad, struct pfr_kentry *ke)
-{
- bzero(ad, sizeof(*ad));
- if (ke == NULL)
- return;
- ad->pfra_af = ke->pfrke_af;
- ad->pfra_net = ke->pfrke_net;
- ad->pfra_not = ke->pfrke_not;
- if (ad->pfra_af == AF_INET)
- ad->pfra_ip4addr = ke->pfrke_sa.sin.sin_addr;
- else if (ad->pfra_af == AF_INET6)
- ad->pfra_ip6addr = ke->pfrke_sa.sin6.sin6_addr;
-}
-
-int
-pfr_walktree(struct radix_node *rn, void *arg)
-{
- struct pfr_kentry *ke = (struct pfr_kentry *)rn;
- struct pfr_walktree *w = arg;
- int s, flags = w->pfrw_flags;
-
- switch (w->pfrw_op) {
- case PFRW_MARK:
- ke->pfrke_mark = 0;
- break;
- case PFRW_SWEEP:
- if (ke->pfrke_mark)
- break;
- /* FALLTHROUGH */
- case PFRW_ENQUEUE:
- SLIST_INSERT_HEAD(w->pfrw_workq, ke, pfrke_workq);
- w->pfrw_cnt++;
- break;
- case PFRW_GET_ADDRS:
- if (w->pfrw_free-- > 0) {
- struct pfr_addr ad;
-
- pfr_copyout_addr(&ad, ke);
- if (copyout(&ad, w->pfrw_addr, sizeof(ad)))
- return (EFAULT);
- w->pfrw_addr++;
- }
- break;
- case PFRW_GET_ASTATS:
- if (w->pfrw_free-- > 0) {
- struct pfr_astats as;
-
- pfr_copyout_addr(&as.pfras_a, ke);
-
- s = splsoftnet();
- if (ke->pfrke_counters) {
- bcopy(ke->pfrke_counters->pfrkc_packets,
- as.pfras_packets, sizeof(as.pfras_packets));
- bcopy(ke->pfrke_counters->pfrkc_bytes,
- as.pfras_bytes, sizeof(as.pfras_bytes));
- } else {
- bzero(as.pfras_packets, sizeof(as.pfras_packets));
- bzero(as.pfras_bytes, sizeof(as.pfras_bytes));
- as.pfras_a.pfra_fback = PFR_FB_NOCOUNT;
- }
- splx(s);
- as.pfras_tzero = ke->pfrke_tzero;
-
- if (COPYOUT(&as, w->pfrw_astats, sizeof(as), flags))
- return (EFAULT);
- w->pfrw_astats++;
- }
- break;
- case PFRW_POOL_GET:
- if (ke->pfrke_not)
- break; /* negative entries are ignored */
- if (!w->pfrw_cnt--) {
- w->pfrw_kentry = ke;
- return (1); /* finish search */
- }
- break;
- case PFRW_DYNADDR_UPDATE:
- if (ke->pfrke_af == AF_INET) {
- if (w->pfrw_dyn->pfid_acnt4++ > 0)
- break;
-#ifdef __FreeBSD__
- pfr_prepare_network(&V_pfr_mask, AF_INET, ke->pfrke_net);
-#else
- pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
-#endif
- w->pfrw_dyn->pfid_addr4 = *SUNION2PF(
- &ke->pfrke_sa, AF_INET);
- w->pfrw_dyn->pfid_mask4 = *SUNION2PF(
-#ifdef __FreeBSD__
- &V_pfr_mask, AF_INET);
-#else
- &pfr_mask, AF_INET);
-#endif
- } else if (ke->pfrke_af == AF_INET6){
- if (w->pfrw_dyn->pfid_acnt6++ > 0)
- break;
-#ifdef __FreeBSD__
- pfr_prepare_network(&V_pfr_mask, AF_INET6, ke->pfrke_net);
-#else
- pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
-#endif
- w->pfrw_dyn->pfid_addr6 = *SUNION2PF(
- &ke->pfrke_sa, AF_INET6);
- w->pfrw_dyn->pfid_mask6 = *SUNION2PF(
-#ifdef __FreeBSD__
- &V_pfr_mask, AF_INET6);
-#else
- &pfr_mask, AF_INET6);
-#endif
- }
- break;
- }
- return (0);
-}
-
-int
-pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
-{
- struct pfr_ktableworkq workq;
- struct pfr_ktable *p;
- int s, xdel = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_ALLRSETS);
- if (pfr_fix_anchor(filter->pfrt_anchor))
- return (EINVAL);
- if (pfr_table_count(filter, flags) < 0)
- return (ENOENT);
-
- SLIST_INIT(&workq);
- RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (pfr_skip_table(filter, p, flags))
- continue;
- if (!strcmp(p->pfrkt_anchor, PF_RESERVED_ANCHOR))
- continue;
- if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE))
- continue;
- p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_ACTIVE;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- xdel++;
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_setflags_ktables(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
- if (ndel != NULL)
- *ndel = xdel;
- return (0);
-}
-
-int
-pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
-{
- struct pfr_ktableworkq addq, changeq;
- struct pfr_ktable *p, *q, *r, key;
- int i, rv, s, xadd = 0;
- long tzero = time_second;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
- SLIST_INIT(&addq);
- SLIST_INIT(&changeq);
- for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- senderr(EFAULT);
- if (pfr_validate_table(&key.pfrkt_t, PFR_TFLAG_USRMASK,
- flags & PFR_FLAG_USERIOCTL))
- senderr(EINVAL);
- key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
- p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
- if (p == NULL) {
- p = pfr_create_ktable(&key.pfrkt_t, tzero, 1,
- !(flags & PFR_FLAG_USERIOCTL));
- if (p == NULL)
- senderr(ENOMEM);
- SLIST_FOREACH(q, &addq, pfrkt_workq) {
- if (!pfr_ktable_compare(p, q))
- goto _skip;
- }
- SLIST_INSERT_HEAD(&addq, p, pfrkt_workq);
- xadd++;
- if (!key.pfrkt_anchor[0])
- goto _skip;
-
- /* find or create root table */
- bzero(key.pfrkt_anchor, sizeof(key.pfrkt_anchor));
- r = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
- if (r != NULL) {
- p->pfrkt_root = r;
- goto _skip;
- }
- SLIST_FOREACH(q, &addq, pfrkt_workq) {
- if (!pfr_ktable_compare(&key, q)) {
- p->pfrkt_root = q;
- goto _skip;
- }
- }
- key.pfrkt_flags = 0;
- r = pfr_create_ktable(&key.pfrkt_t, 0, 1,
- !(flags & PFR_FLAG_USERIOCTL));
- if (r == NULL)
- senderr(ENOMEM);
- SLIST_INSERT_HEAD(&addq, r, pfrkt_workq);
- p->pfrkt_root = r;
- } else if (!(p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
- SLIST_FOREACH(q, &changeq, pfrkt_workq)
- if (!pfr_ktable_compare(&key, q))
- goto _skip;
- p->pfrkt_nflags = (p->pfrkt_flags &
- ~PFR_TFLAG_USRMASK) | key.pfrkt_flags;
- SLIST_INSERT_HEAD(&changeq, p, pfrkt_workq);
- xadd++;
- }
-_skip:
- ;
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_insert_ktables(&addq);
- pfr_setflags_ktables(&changeq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- } else
- pfr_destroy_ktables(&addq, 0);
- if (nadd != NULL)
- *nadd = xadd;
- return (0);
-_bad:
- pfr_destroy_ktables(&addq, 0);
- return (rv);
-}
-
-int
-pfr_del_tables(struct pfr_table *tbl, int size, int *ndel, int flags)
-{
- struct pfr_ktableworkq workq;
- struct pfr_ktable *p, *q, key;
- int i, s, xdel = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
- SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- return (EFAULT);
- if (pfr_validate_table(&key.pfrkt_t, 0,
- flags & PFR_FLAG_USERIOCTL))
- return (EINVAL);
- p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
- if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
- SLIST_FOREACH(q, &workq, pfrkt_workq)
- if (!pfr_ktable_compare(p, q))
- goto _skip;
- p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_ACTIVE;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- xdel++;
- }
-_skip:
- ;
- }
-
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_setflags_ktables(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
- if (ndel != NULL)
- *ndel = xdel;
- return (0);
-}
-
-int
-pfr_get_tables(struct pfr_table *filter, struct pfr_table *tbl, int *size,
- int flags)
-{
- struct pfr_ktable *p;
- int n, nn;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ALLRSETS);
- if (pfr_fix_anchor(filter->pfrt_anchor))
- return (EINVAL);
- n = nn = pfr_table_count(filter, flags);
- if (n < 0)
- return (ENOENT);
- if (n > *size) {
- *size = n;
- return (0);
- }
- RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (pfr_skip_table(filter, p, flags))
- continue;
- if (n-- <= 0)
- continue;
- if (COPYOUT(&p->pfrkt_t, tbl++, sizeof(*tbl), flags))
- return (EFAULT);
- }
- if (n) {
- printf("pfr_get_tables: corruption detected (%d).\n", n);
- return (ENOTTY);
- }
- *size = nn;
- return (0);
-}
-
-int
-pfr_get_tstats(struct pfr_table *filter, struct pfr_tstats *tbl, int *size,
- int flags)
-{
- struct pfr_ktable *p;
- struct pfr_ktableworkq workq;
- int s, n, nn;
- long tzero = time_second;
-
- /* XXX PFR_FLAG_CLSTATS disabled */
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_ALLRSETS);
- if (pfr_fix_anchor(filter->pfrt_anchor))
- return (EINVAL);
- n = nn = pfr_table_count(filter, flags);
- if (n < 0)
- return (ENOENT);
- if (n > *size) {
- *size = n;
- return (0);
- }
- SLIST_INIT(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (pfr_skip_table(filter, p, flags))
- continue;
- if (n-- <= 0)
- continue;
- if (!(flags & PFR_FLAG_ATOMIC))
- s = splsoftnet();
- if (COPYOUT(&p->pfrkt_ts, tbl++, sizeof(*tbl), flags)) {
- splx(s);
- return (EFAULT);
- }
- if (!(flags & PFR_FLAG_ATOMIC))
- splx(s);
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- }
- if (flags & PFR_FLAG_CLSTATS)
- pfr_clstats_ktables(&workq, tzero,
- flags & PFR_FLAG_ADDRSTOO);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- if (n) {
- printf("pfr_get_tstats: corruption detected (%d).\n", n);
- return (ENOTTY);
- }
- *size = nn;
- return (0);
-}
-
-int
-pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
-{
- struct pfr_ktableworkq workq;
- struct pfr_ktable *p, key;
- int i, s, xzero = 0;
- long tzero = time_second;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY |
- PFR_FLAG_ADDRSTOO);
- SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- return (EFAULT);
- if (pfr_validate_table(&key.pfrkt_t, 0, 0))
- return (EINVAL);
- p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
- if (p != NULL) {
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- xzero++;
- }
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_clstats_ktables(&workq, tzero, flags & PFR_FLAG_ADDRSTOO);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
- if (nzero != NULL)
- *nzero = xzero;
- return (0);
-}
-
-int
-pfr_set_tflags(struct pfr_table *tbl, int size, int setflag, int clrflag,
- int *nchange, int *ndel, int flags)
-{
- struct pfr_ktableworkq workq;
- struct pfr_ktable *p, *q, key;
- int i, s, xchange = 0, xdel = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
- if ((setflag & ~PFR_TFLAG_USRMASK) ||
- (clrflag & ~PFR_TFLAG_USRMASK) ||
- (setflag & clrflag))
- return (EINVAL);
- SLIST_INIT(&workq);
- for (i = 0; i < size; i++) {
- if (COPYIN(tbl+i, &key.pfrkt_t, sizeof(key.pfrkt_t), flags))
- return (EFAULT);
- if (pfr_validate_table(&key.pfrkt_t, 0,
- flags & PFR_FLAG_USERIOCTL))
- return (EINVAL);
- p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
- if (p != NULL && (p->pfrkt_flags & PFR_TFLAG_ACTIVE)) {
- p->pfrkt_nflags = (p->pfrkt_flags | setflag) &
- ~clrflag;
- if (p->pfrkt_nflags == p->pfrkt_flags)
- goto _skip;
- SLIST_FOREACH(q, &workq, pfrkt_workq)
- if (!pfr_ktable_compare(p, q))
- goto _skip;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- if ((p->pfrkt_flags & PFR_TFLAG_PERSIST) &&
- (clrflag & PFR_TFLAG_PERSIST) &&
- !(p->pfrkt_flags & PFR_TFLAG_REFERENCED))
- xdel++;
- else
- xchange++;
- }
-_skip:
- ;
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- pfr_setflags_ktables(&workq);
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- }
- if (nchange != NULL)
- *nchange = xchange;
- if (ndel != NULL)
- *ndel = xdel;
- return (0);
-}
-
-int
-pfr_ina_begin(struct pfr_table *trs, u_int32_t *ticket, int *ndel, int flags)
-{
- struct pfr_ktableworkq workq;
- struct pfr_ktable *p;
- struct pf_ruleset *rs;
- int xdel = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
- rs = pf_find_or_create_ruleset(trs->pfrt_anchor);
- if (rs == NULL)
- return (ENOMEM);
- SLIST_INIT(&workq);
- RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
- pfr_skip_table(trs, p, 0))
- continue;
- p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- xdel++;
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- pfr_setflags_ktables(&workq);
- if (ticket != NULL)
- *ticket = ++rs->tticket;
- rs->topen = 1;
- } else
- pf_remove_if_empty_ruleset(rs);
- if (ndel != NULL)
- *ndel = xdel;
- return (0);
-}
-
-int
-pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
- int *nadd, int *naddr, u_int32_t ticket, int flags)
-{
- struct pfr_ktableworkq tableq;
- struct pfr_kentryworkq addrq;
- struct pfr_ktable *kt, *rt, *shadow, key;
- struct pfr_kentry *p;
- struct pfr_addr ad;
- struct pf_ruleset *rs;
- int i, rv, xadd = 0, xaddr = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_ADDRSTOO);
- if (size && !(flags & PFR_FLAG_ADDRSTOO))
- return (EINVAL);
- if (pfr_validate_table(tbl, PFR_TFLAG_USRMASK,
- flags & PFR_FLAG_USERIOCTL))
- return (EINVAL);
- rs = pf_find_ruleset(tbl->pfrt_anchor);
- if (rs == NULL || !rs->topen || ticket != rs->tticket)
- return (EBUSY);
- tbl->pfrt_flags |= PFR_TFLAG_INACTIVE;
- SLIST_INIT(&tableq);
- kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
- if (kt == NULL) {
- kt = pfr_create_ktable(tbl, 0, 1,
- !(flags & PFR_FLAG_USERIOCTL));
- if (kt == NULL)
- return (ENOMEM);
- SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq);
- xadd++;
- if (!tbl->pfrt_anchor[0])
- goto _skip;
-
- /* find or create root table */
- bzero(&key, sizeof(key));
- strlcpy(key.pfrkt_name, tbl->pfrt_name, sizeof(key.pfrkt_name));
- rt = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
- if (rt != NULL) {
- kt->pfrkt_root = rt;
- goto _skip;
- }
- rt = pfr_create_ktable(&key.pfrkt_t, 0, 1,
- !(flags & PFR_FLAG_USERIOCTL));
- if (rt == NULL) {
- pfr_destroy_ktables(&tableq, 0);
- return (ENOMEM);
- }
- SLIST_INSERT_HEAD(&tableq, rt, pfrkt_workq);
- kt->pfrkt_root = rt;
- } else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE))
- xadd++;
-_skip:
- shadow = pfr_create_ktable(tbl, 0, 0, !(flags & PFR_FLAG_USERIOCTL));
- if (shadow == NULL) {
- pfr_destroy_ktables(&tableq, 0);
- return (ENOMEM);
- }
- SLIST_INIT(&addrq);
- for (i = 0; i < size; i++) {
- if (COPYIN(addr+i, &ad, sizeof(ad), flags))
- senderr(EFAULT);
- if (pfr_validate_addr(&ad))
- senderr(EINVAL);
- if (pfr_lookup_addr(shadow, &ad, 1) != NULL)
- continue;
- p = pfr_create_kentry(&ad, 0);
- if (p == NULL)
- senderr(ENOMEM);
- if (pfr_route_kentry(shadow, p)) {
- pfr_destroy_kentry(p);
- continue;
- }
- SLIST_INSERT_HEAD(&addrq, p, pfrke_workq);
- xaddr++;
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (kt->pfrkt_shadow != NULL)
- pfr_destroy_ktable(kt->pfrkt_shadow, 1);
- kt->pfrkt_flags |= PFR_TFLAG_INACTIVE;
- pfr_insert_ktables(&tableq);
- shadow->pfrkt_cnt = (flags & PFR_FLAG_ADDRSTOO) ?
- xaddr : NO_ADDRESSES;
- kt->pfrkt_shadow = shadow;
- } else {
- pfr_clean_node_mask(shadow, &addrq);
- pfr_destroy_ktable(shadow, 0);
- pfr_destroy_ktables(&tableq, 0);
- pfr_destroy_kentries(&addrq);
- }
- if (nadd != NULL)
- *nadd = xadd;
- if (naddr != NULL)
- *naddr = xaddr;
- return (0);
-_bad:
- pfr_destroy_ktable(shadow, 0);
- pfr_destroy_ktables(&tableq, 0);
- pfr_destroy_kentries(&addrq);
- return (rv);
-}
-
-int
-pfr_ina_rollback(struct pfr_table *trs, u_int32_t ticket, int *ndel, int flags)
-{
- struct pfr_ktableworkq workq;
- struct pfr_ktable *p;
- struct pf_ruleset *rs;
- int xdel = 0;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
- rs = pf_find_ruleset(trs->pfrt_anchor);
- if (rs == NULL || !rs->topen || ticket != rs->tticket)
- return (0);
- SLIST_INIT(&workq);
- RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
- pfr_skip_table(trs, p, 0))
- continue;
- p->pfrkt_nflags = p->pfrkt_flags & ~PFR_TFLAG_INACTIVE;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- xdel++;
- }
- if (!(flags & PFR_FLAG_DUMMY)) {
- pfr_setflags_ktables(&workq);
- rs->topen = 0;
- pf_remove_if_empty_ruleset(rs);
- }
- if (ndel != NULL)
- *ndel = xdel;
- return (0);
-}
-
-int
-pfr_ina_commit(struct pfr_table *trs, u_int32_t ticket, int *nadd,
- int *nchange, int flags)
-{
- struct pfr_ktable *p, *q;
- struct pfr_ktableworkq workq;
- struct pf_ruleset *rs;
- int s, xadd = 0, xchange = 0;
- long tzero = time_second;
-
- ACCEPT_FLAGS(flags, PFR_FLAG_ATOMIC | PFR_FLAG_DUMMY);
- rs = pf_find_ruleset(trs->pfrt_anchor);
- if (rs == NULL || !rs->topen || ticket != rs->tticket)
- return (EBUSY);
-
- SLIST_INIT(&workq);
- RB_FOREACH(p, pfr_ktablehead, &pfr_ktables) {
- if (!(p->pfrkt_flags & PFR_TFLAG_INACTIVE) ||
- pfr_skip_table(trs, p, 0))
- continue;
- SLIST_INSERT_HEAD(&workq, p, pfrkt_workq);
- if (p->pfrkt_flags & PFR_TFLAG_ACTIVE)
- xchange++;
- else
- xadd++;
- }
-
- if (!(flags & PFR_FLAG_DUMMY)) {
- if (flags & PFR_FLAG_ATOMIC)
- s = splsoftnet();
- for (p = SLIST_FIRST(&workq); p != NULL; p = q) {
- q = SLIST_NEXT(p, pfrkt_workq);
- pfr_commit_ktable(p, tzero);
- }
- if (flags & PFR_FLAG_ATOMIC)
- splx(s);
- rs->topen = 0;
- pf_remove_if_empty_ruleset(rs);
- }
- if (nadd != NULL)
- *nadd = xadd;
- if (nchange != NULL)
- *nchange = xchange;
-
- return (0);
-}
-
-void
-pfr_commit_ktable(struct pfr_ktable *kt, long tzero)
-{
- struct pfr_ktable *shadow = kt->pfrkt_shadow;
- int nflags;
-
- if (shadow->pfrkt_cnt == NO_ADDRESSES) {
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- pfr_clstats_ktable(kt, tzero, 1);
- } else if (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) {
- /* kt might contain addresses */
- struct pfr_kentryworkq addrq, addq, changeq, delq, garbageq;
- struct pfr_kentry *p, *q, *next;
- struct pfr_addr ad;
-
- pfr_enqueue_addrs(shadow, &addrq, NULL, 0);
- pfr_mark_addrs(kt);
- SLIST_INIT(&addq);
- SLIST_INIT(&changeq);
- SLIST_INIT(&delq);
- SLIST_INIT(&garbageq);
- pfr_clean_node_mask(shadow, &addrq);
- for (p = SLIST_FIRST(&addrq); p != NULL; p = next) {
- next = SLIST_NEXT(p, pfrke_workq); /* XXX */
- pfr_copyout_addr(&ad, p);
- q = pfr_lookup_addr(kt, &ad, 1);
- if (q != NULL) {
- if (q->pfrke_not != p->pfrke_not)
- SLIST_INSERT_HEAD(&changeq, q,
- pfrke_workq);
- q->pfrke_mark = 1;
- SLIST_INSERT_HEAD(&garbageq, p, pfrke_workq);
- } else {
- p->pfrke_tzero = tzero;
- SLIST_INSERT_HEAD(&addq, p, pfrke_workq);
- }
- }
- pfr_enqueue_addrs(kt, &delq, NULL, ENQUEUE_UNMARKED_ONLY);
- pfr_insert_kentries(kt, &addq, tzero);
- pfr_remove_kentries(kt, &delq);
- pfr_clstats_kentries(&changeq, tzero, INVERT_NEG_FLAG);
- pfr_destroy_kentries(&garbageq);
- } else {
- /* kt cannot contain addresses */
- SWAP(struct radix_node_head *, kt->pfrkt_ip4,
- shadow->pfrkt_ip4);
- SWAP(struct radix_node_head *, kt->pfrkt_ip6,
- shadow->pfrkt_ip6);
- SWAP(int, kt->pfrkt_cnt, shadow->pfrkt_cnt);
- pfr_clstats_ktable(kt, tzero, 1);
- }
- nflags = ((shadow->pfrkt_flags & PFR_TFLAG_USRMASK) |
- (kt->pfrkt_flags & PFR_TFLAG_SETMASK) | PFR_TFLAG_ACTIVE)
- & ~PFR_TFLAG_INACTIVE;
- pfr_destroy_ktable(shadow, 0);
- kt->pfrkt_shadow = NULL;
- pfr_setflags_ktable(kt, nflags);
-}
-
-int
-pfr_validate_table(struct pfr_table *tbl, int allowedflags, int no_reserved)
-{
- int i;
-
- if (!tbl->pfrt_name[0])
- return (-1);
- if (no_reserved && !strcmp(tbl->pfrt_anchor, PF_RESERVED_ANCHOR))
- return (-1);
- if (tbl->pfrt_name[PF_TABLE_NAME_SIZE-1])
- return (-1);
- for (i = strlen(tbl->pfrt_name); i < PF_TABLE_NAME_SIZE; i++)
- if (tbl->pfrt_name[i])
- return (-1);
- if (pfr_fix_anchor(tbl->pfrt_anchor))
- return (-1);
- if (tbl->pfrt_flags & ~allowedflags)
- return (-1);
- return (0);
-}
-
-/*
- * Rewrite anchors referenced by tables to remove slashes
- * and check for validity.
- */
-int
-pfr_fix_anchor(char *anchor)
-{
- size_t siz = MAXPATHLEN;
- int i;
-
- if (anchor[0] == '/') {
- char *path;
- int off;
-
- path = anchor;
- off = 1;
- while (*++path == '/')
- off++;
- bcopy(path, anchor, siz - off);
- memset(anchor + siz - off, 0, off);
- }
- if (anchor[siz - 1])
- return (-1);
- for (i = strlen(anchor); i < siz; i++)
- if (anchor[i])
- return (-1);
- return (0);
-}
-
-int
-pfr_table_count(struct pfr_table *filter, int flags)
-{
- struct pf_ruleset *rs;
-
- if (flags & PFR_FLAG_ALLRSETS)
- return (pfr_ktable_cnt);
- if (filter->pfrt_anchor[0]) {
- rs = pf_find_ruleset(filter->pfrt_anchor);
- return ((rs != NULL) ? rs->tables : -1);
- }
- return (pf_main_ruleset.tables);
-}
-
-int
-pfr_skip_table(struct pfr_table *filter, struct pfr_ktable *kt, int flags)
-{
- if (flags & PFR_FLAG_ALLRSETS)
- return (0);
- if (strcmp(filter->pfrt_anchor, kt->pfrkt_anchor))
- return (1);
- return (0);
-}
-
-void
-pfr_insert_ktables(struct pfr_ktableworkq *workq)
-{
- struct pfr_ktable *p;
-
- SLIST_FOREACH(p, workq, pfrkt_workq)
- pfr_insert_ktable(p);
-}
-
-void
-pfr_insert_ktable(struct pfr_ktable *kt)
-{
- RB_INSERT(pfr_ktablehead, &pfr_ktables, kt);
- pfr_ktable_cnt++;
- if (kt->pfrkt_root != NULL)
- if (!kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR]++)
- pfr_setflags_ktable(kt->pfrkt_root,
- kt->pfrkt_root->pfrkt_flags|PFR_TFLAG_REFDANCHOR);
-}
-
-void
-pfr_setflags_ktables(struct pfr_ktableworkq *workq)
-{
- struct pfr_ktable *p, *q;
-
- for (p = SLIST_FIRST(workq); p; p = q) {
- q = SLIST_NEXT(p, pfrkt_workq);
- pfr_setflags_ktable(p, p->pfrkt_nflags);
- }
-}
-
-void
-pfr_setflags_ktable(struct pfr_ktable *kt, int newf)
-{
- struct pfr_kentryworkq addrq;
-
- if (!(newf & PFR_TFLAG_REFERENCED) &&
- !(newf & PFR_TFLAG_PERSIST))
- newf &= ~PFR_TFLAG_ACTIVE;
- if (!(newf & PFR_TFLAG_ACTIVE))
- newf &= ~PFR_TFLAG_USRMASK;
- if (!(newf & PFR_TFLAG_SETMASK)) {
- RB_REMOVE(pfr_ktablehead, &pfr_ktables, kt);
- if (kt->pfrkt_root != NULL)
- if (!--kt->pfrkt_root->pfrkt_refcnt[PFR_REFCNT_ANCHOR])
- pfr_setflags_ktable(kt->pfrkt_root,
- kt->pfrkt_root->pfrkt_flags &
- ~PFR_TFLAG_REFDANCHOR);
- pfr_destroy_ktable(kt, 1);
- pfr_ktable_cnt--;
- return;
- }
- if (!(newf & PFR_TFLAG_ACTIVE) && kt->pfrkt_cnt) {
- pfr_enqueue_addrs(kt, &addrq, NULL, 0);
- pfr_remove_kentries(kt, &addrq);
- }
- if (!(newf & PFR_TFLAG_INACTIVE) && kt->pfrkt_shadow != NULL) {
- pfr_destroy_ktable(kt->pfrkt_shadow, 1);
- kt->pfrkt_shadow = NULL;
- }
- kt->pfrkt_flags = newf;
-}
-
-void
-pfr_clstats_ktables(struct pfr_ktableworkq *workq, long tzero, int recurse)
-{
- struct pfr_ktable *p;
-
- SLIST_FOREACH(p, workq, pfrkt_workq)
- pfr_clstats_ktable(p, tzero, recurse);
-}
-
-void
-pfr_clstats_ktable(struct pfr_ktable *kt, long tzero, int recurse)
-{
- struct pfr_kentryworkq addrq;
- int s;
-
- if (recurse) {
- pfr_enqueue_addrs(kt, &addrq, NULL, 0);
- pfr_clstats_kentries(&addrq, tzero, 0);
- }
- s = splsoftnet();
- bzero(kt->pfrkt_packets, sizeof(kt->pfrkt_packets));
- bzero(kt->pfrkt_bytes, sizeof(kt->pfrkt_bytes));
- kt->pfrkt_match = kt->pfrkt_nomatch = 0;
- splx(s);
- kt->pfrkt_tzero = tzero;
-}
-
-struct pfr_ktable *
-pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
- int intr)
-{
- struct pfr_ktable *kt;
- struct pf_ruleset *rs;
-
-#ifdef __FreeBSD__
- kt = pool_get(&V_pfr_ktable_pl, PR_NOWAIT|PR_ZERO);
-#else
- if (intr)
- kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL);
- else
- kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
-#endif
- if (kt == NULL)
- return (NULL);
- kt->pfrkt_t = *tbl;
-
- if (attachruleset) {
- rs = pf_find_or_create_ruleset(tbl->pfrt_anchor);
- if (!rs) {
- pfr_destroy_ktable(kt, 0);
- return (NULL);
- }
- kt->pfrkt_rs = rs;
- rs->tables++;
- }
-
- if (!rn_inithead((void **)&kt->pfrkt_ip4,
- offsetof(struct sockaddr_in, sin_addr) * 8) ||
- !rn_inithead((void **)&kt->pfrkt_ip6,
- offsetof(struct sockaddr_in6, sin6_addr) * 8)) {
- pfr_destroy_ktable(kt, 0);
- return (NULL);
- }
- kt->pfrkt_tzero = tzero;
-
- return (kt);
-}
-
-void
-pfr_destroy_ktables(struct pfr_ktableworkq *workq, int flushaddr)
-{
- struct pfr_ktable *p, *q;
-
- for (p = SLIST_FIRST(workq); p; p = q) {
- q = SLIST_NEXT(p, pfrkt_workq);
- pfr_destroy_ktable(p, flushaddr);
- }
-}
-
-void
-pfr_destroy_ktable(struct pfr_ktable *kt, int flushaddr)
-{
- struct pfr_kentryworkq addrq;
-
- if (flushaddr) {
- pfr_enqueue_addrs(kt, &addrq, NULL, 0);
- pfr_clean_node_mask(kt, &addrq);
- pfr_destroy_kentries(&addrq);
- }
-#if defined(__FreeBSD__) && (__FreeBSD_version >= 500100)
- if (kt->pfrkt_ip4 != NULL) {
- RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip4);
- free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
- }
- if (kt->pfrkt_ip6 != NULL) {
- RADIX_NODE_HEAD_DESTROY(kt->pfrkt_ip6);
- free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
- }
-#else
- if (kt->pfrkt_ip4 != NULL)
- free((caddr_t)kt->pfrkt_ip4, M_RTABLE);
- if (kt->pfrkt_ip6 != NULL)
- free((caddr_t)kt->pfrkt_ip6, M_RTABLE);
-#endif
- if (kt->pfrkt_shadow != NULL)
- pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr);
- if (kt->pfrkt_rs != NULL) {
- kt->pfrkt_rs->tables--;
- pf_remove_if_empty_ruleset(kt->pfrkt_rs);
- }
-#ifdef __FreeBSD__
- pool_put(&V_pfr_ktable_pl, kt);
-#else
- pool_put(&pfr_ktable_pl, kt);
-#endif
-}
-
-int
-pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
-{
- int d;
-
- if ((d = strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE)))
- return (d);
- return (strcmp(p->pfrkt_anchor, q->pfrkt_anchor));
-}
-
-struct pfr_ktable *
-pfr_lookup_table(struct pfr_table *tbl)
-{
- /* struct pfr_ktable start like a struct pfr_table */
- return (RB_FIND(pfr_ktablehead, &pfr_ktables,
- (struct pfr_ktable *)tbl));
-}
-
-int
-pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
-{
- struct pfr_kentry *ke = NULL;
- int match;
-
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (0);
-
- switch (af) {
-#ifdef INET
- case AF_INET:
-#ifdef __FreeBSD__
- V_pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
-#else
- pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
-#endif
- if (ke && KENTRY_RNF_ROOT(ke))
- ke = NULL;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
-#ifdef __FreeBSD__
- bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
-#else
- bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
-#endif
- if (ke && KENTRY_RNF_ROOT(ke))
- ke = NULL;
- break;
-#endif /* INET6 */
- }
- match = (ke && !ke->pfrke_not);
- if (match)
- kt->pfrkt_match++;
- else
- kt->pfrkt_nomatch++;
- return (match);
-}
-
-void
-pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
- u_int64_t len, int dir_out, int op_pass, int notrule)
-{
- struct pfr_kentry *ke = NULL;
-
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return;
-
- switch (af) {
-#ifdef INET
- case AF_INET:
-#ifdef __FreeBSD__
- V_pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
-#else
- pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&pfr_sin, kt->pfrkt_ip4);
-#endif
- if (ke && KENTRY_RNF_ROOT(ke))
- ke = NULL;
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
-#ifdef __FreeBSD__
- bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
-#else
- bcopy(a, &pfr_sin6.sin6_addr, sizeof(pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&pfr_sin6, kt->pfrkt_ip6);
-#endif
- if (ke && KENTRY_RNF_ROOT(ke))
- ke = NULL;
- break;
-#endif /* INET6 */
- default:
- ;
- }
- if ((ke == NULL || ke->pfrke_not) != notrule) {
- if (op_pass != PFR_OP_PASS)
- printf("pfr_update_stats: assertion failed.\n");
- op_pass = PFR_OP_XPASS;
- }
- kt->pfrkt_packets[dir_out][op_pass]++;
- kt->pfrkt_bytes[dir_out][op_pass] += len;
- if (ke != NULL && op_pass != PFR_OP_XPASS &&
- (kt->pfrkt_flags & PFR_TFLAG_COUNTERS)) {
- if (ke->pfrke_counters == NULL)
-#ifdef __FreeBSD__
- ke->pfrke_counters = pool_get(&V_pfr_kcounters_pl,
-#else
- ke->pfrke_counters = pool_get(&pfr_kcounters_pl,
-#endif
- PR_NOWAIT | PR_ZERO);
- if (ke->pfrke_counters != NULL) {
- ke->pfrke_counters->pfrkc_packets[dir_out][op_pass]++;
- ke->pfrke_counters->pfrkc_bytes[dir_out][op_pass] += len;
- }
- }
-}
-
-struct pfr_ktable *
-pfr_attach_table(struct pf_ruleset *rs, char *name, int intr)
-{
- struct pfr_ktable *kt, *rt;
- struct pfr_table tbl;
- struct pf_anchor *ac = rs->anchor;
-
- bzero(&tbl, sizeof(tbl));
- strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name));
- if (ac != NULL)
- strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor));
- kt = pfr_lookup_table(&tbl);
- if (kt == NULL) {
- kt = pfr_create_ktable(&tbl, time_second, 1, intr);
- if (kt == NULL)
- return (NULL);
- if (ac != NULL) {
- bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
- rt = pfr_lookup_table(&tbl);
- if (rt == NULL) {
- rt = pfr_create_ktable(&tbl, 0, 1, intr);
- if (rt == NULL) {
- pfr_destroy_ktable(kt, 0);
- return (NULL);
- }
- pfr_insert_ktable(rt);
- }
- kt->pfrkt_root = rt;
- }
- pfr_insert_ktable(kt);
- }
- if (!kt->pfrkt_refcnt[PFR_REFCNT_RULE]++)
- pfr_setflags_ktable(kt, kt->pfrkt_flags|PFR_TFLAG_REFERENCED);
- return (kt);
-}
-
-void
-pfr_detach_table(struct pfr_ktable *kt)
-{
- if (kt->pfrkt_refcnt[PFR_REFCNT_RULE] <= 0)
- printf("pfr_detach_table: refcount = %d.\n",
- kt->pfrkt_refcnt[PFR_REFCNT_RULE]);
- else if (!--kt->pfrkt_refcnt[PFR_REFCNT_RULE])
- pfr_setflags_ktable(kt, kt->pfrkt_flags&~PFR_TFLAG_REFERENCED);
-}
-
-int
-pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
- struct pf_addr **raddr, struct pf_addr **rmask, sa_family_t af)
-{
-#ifdef __FreeBSD__
- struct pfr_kentry *ke, *ke2 = NULL;
- struct pf_addr *addr = NULL;
-#else
- struct pfr_kentry *ke, *ke2;
- struct pf_addr *addr;
-#endif
- union sockaddr_union mask;
- int idx = -1, use_counter = 0;
-
-#ifdef __FreeBSD__
- if (af == AF_INET)
- addr = (struct pf_addr *)&V_pfr_sin.sin_addr;
- else if (af == AF_INET6)
- addr = (struct pf_addr *)&V_pfr_sin6.sin6_addr;
-#else
- if (af == AF_INET)
- addr = (struct pf_addr *)&pfr_sin.sin_addr;
- else if (af == AF_INET6)
- addr = (struct pf_addr *)&pfr_sin6.sin6_addr;
-#endif
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
- kt = kt->pfrkt_root;
- if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
- return (-1);
-
- if (pidx != NULL)
- idx = *pidx;
- if (counter != NULL && idx >= 0)
- use_counter = 1;
- if (idx < 0)
- idx = 0;
-
-_next_block:
- ke = pfr_kentry_byidx(kt, idx, af);
- if (ke == NULL) {
- kt->pfrkt_nomatch++;
- return (1);
- }
-#ifdef __FreeBSD__
- pfr_prepare_network(&V_pfr_mask, af, ke->pfrke_net);
-#else
- pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
-#endif
- *raddr = SUNION2PF(&ke->pfrke_sa, af);
-#ifdef __FreeBSD__
- *rmask = SUNION2PF(&V_pfr_mask, af);
-#else
- *rmask = SUNION2PF(&pfr_mask, af);
-#endif
-
- if (use_counter) {
- /* is supplied address within block? */
- if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) {
- /* no, go to next block in table */
- idx++;
- use_counter = 0;
- goto _next_block;
- }
- PF_ACPY(addr, counter, af);
- } else {
- /* use first address of block */
- PF_ACPY(addr, *raddr, af);
- }
-
- if (!KENTRY_NETWORK(ke)) {
- /* this is a single IP address - no possible nested block */
- PF_ACPY(counter, addr, af);
- *pidx = idx;
- kt->pfrkt_match++;
- return (0);
- }
- for (;;) {
- /* we don't want to use a nested block */
-#ifdef __FreeBSD__
- if (af == AF_INET)
- ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin,
- kt->pfrkt_ip4);
- else if (af == AF_INET6)
- ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin6,
- kt->pfrkt_ip6);
-#else
- if (af == AF_INET)
- ke2 = (struct pfr_kentry *)rn_match(&pfr_sin,
- kt->pfrkt_ip4);
- else if (af == AF_INET6)
- ke2 = (struct pfr_kentry *)rn_match(&pfr_sin6,
- kt->pfrkt_ip6);
-#endif
- /* no need to check KENTRY_RNF_ROOT() here */
- if (ke2 == ke) {
- /* lookup return the same block - perfect */
- PF_ACPY(counter, addr, af);
- *pidx = idx;
- kt->pfrkt_match++;
- return (0);
- }
-
- /* we need to increase the counter past the nested block */
- pfr_prepare_network(&mask, AF_INET, ke2->pfrke_net);
-#ifdef __FreeBSD__
- PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &V_pfr_ffaddr, af);
-#else
- PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &pfr_ffaddr, af);
-#endif
- PF_AINC(addr, af);
- if (!PF_MATCHA(0, *raddr, *rmask, addr, af)) {
- /* ok, we reached the end of our main block */
- /* go to next block in table */
- idx++;
- use_counter = 0;
- goto _next_block;
- }
- }
-}
-
-struct pfr_kentry *
-pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
-{
- struct pfr_walktree w;
-
- bzero(&w, sizeof(w));
- w.pfrw_op = PFRW_POOL_GET;
- w.pfrw_cnt = idx;
-
- switch (af) {
-#ifdef INET
- case AF_INET:
-#ifdef __FreeBSD__
- kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
- return (w.pfrw_kentry);
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
-#ifdef __FreeBSD__
- kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
- return (w.pfrw_kentry);
-#endif /* INET6 */
- default:
- return (NULL);
- }
-}
-
-void
-pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
-{
- struct pfr_walktree w;
- int s;
-
- bzero(&w, sizeof(w));
- w.pfrw_op = PFRW_DYNADDR_UPDATE;
- w.pfrw_dyn = dyn;
-
- s = splsoftnet();
- dyn->pfid_acnt4 = 0;
- dyn->pfid_acnt6 = 0;
- if (!dyn->pfid_af || dyn->pfid_af == AF_INET)
-#ifdef __FreeBSD__
- kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
-#endif
- if (!dyn->pfid_af || dyn->pfid_af == AF_INET6)
-#ifdef __FreeBSD__
- kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#else
- rn_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
-#endif
- splx(s);
-}
diff --git a/sys/contrib/pf/net/pfvar.h b/sys/contrib/pf/net/pfvar.h
deleted file mode 100644
index dab70c5..0000000
--- a/sys/contrib/pf/net/pfvar.h
+++ /dev/null
@@ -1,2234 +0,0 @@
-/* $OpenBSD: pfvar.h,v 1.282 2009/01/29 15:12:28 pyr Exp $ */
-
-/*
- * Copyright (c) 2001 Daniel Hartmeier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * - 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
- * COPYRIGHT HOLDERS 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.
- *
- */
-
-#ifndef _NET_PFVAR_H_
-#define _NET_PFVAR_H_
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/tree.h>
-#ifdef __FreeBSD__
-#include <sys/lock.h>
-#include <sys/sx.h>
-#else
-#include <sys/rwlock.h>
-#endif
-
-#include <net/radix.h>
-#include <net/route.h>
-#ifdef __FreeBSD__
-#include <net/if_clone.h>
-#include <net/pf_mtag.h>
-#include <vm/uma.h>
-#else
-#include <netinet/ip_ipsp.h>
-#endif
-
-#ifdef __FreeBSD__
-#include <netinet/in.h>
-#endif
-
-#include <netinet/tcp_fsm.h>
-
-struct ip;
-struct ip6_hdr;
-#ifdef __FreeBSD__
-struct inpcb;
-#endif
-
-#define PF_TCPS_PROXY_SRC ((TCP_NSTATES)+0)
-#define PF_TCPS_PROXY_DST ((TCP_NSTATES)+1)
-
-#define PF_MD5_DIGEST_LENGTH 16
-#ifdef MD5_DIGEST_LENGTH
-#if PF_MD5_DIGEST_LENGTH != MD5_DIGEST_LENGTH
-#error
-#endif
-#endif
-
-enum { PF_INOUT, PF_IN, PF_OUT };
-enum { PF_PASS, PF_DROP, PF_SCRUB, PF_NOSCRUB, PF_NAT, PF_NONAT,
- PF_BINAT, PF_NOBINAT, PF_RDR, PF_NORDR, PF_SYNPROXY_DROP, PF_DEFER };
-enum { PF_RULESET_SCRUB, PF_RULESET_FILTER, PF_RULESET_NAT,
- PF_RULESET_BINAT, PF_RULESET_RDR, PF_RULESET_MAX };
-enum { PF_OP_NONE, PF_OP_IRG, PF_OP_EQ, PF_OP_NE, PF_OP_LT,
- PF_OP_LE, PF_OP_GT, PF_OP_GE, PF_OP_XRG, PF_OP_RRG };
-enum { PF_DEBUG_NONE, PF_DEBUG_URGENT, PF_DEBUG_MISC, PF_DEBUG_NOISY };
-enum { PF_CHANGE_NONE, PF_CHANGE_ADD_HEAD, PF_CHANGE_ADD_TAIL,
- PF_CHANGE_ADD_BEFORE, PF_CHANGE_ADD_AFTER,
- PF_CHANGE_REMOVE, PF_CHANGE_GET_TICKET };
-enum { PF_GET_NONE, PF_GET_CLR_CNTR };
-enum { PF_SK_WIRE, PF_SK_STACK, PF_SK_BOTH };
-
-/*
- * Note about PFTM_*: real indices into pf_rule.timeout[] come before
- * PFTM_MAX, special cases afterwards. See pf_state_expires().
- */
-enum { PFTM_TCP_FIRST_PACKET, PFTM_TCP_OPENING, PFTM_TCP_ESTABLISHED,
- PFTM_TCP_CLOSING, PFTM_TCP_FIN_WAIT, PFTM_TCP_CLOSED,
- PFTM_UDP_FIRST_PACKET, PFTM_UDP_SINGLE, PFTM_UDP_MULTIPLE,
- PFTM_ICMP_FIRST_PACKET, PFTM_ICMP_ERROR_REPLY,
- PFTM_OTHER_FIRST_PACKET, PFTM_OTHER_SINGLE,
- PFTM_OTHER_MULTIPLE, PFTM_FRAG, PFTM_INTERVAL,
- PFTM_ADAPTIVE_START, PFTM_ADAPTIVE_END, PFTM_SRC_NODE,
- PFTM_TS_DIFF, PFTM_MAX, PFTM_PURGE, PFTM_UNLINKED,
- PFTM_UNTIL_PACKET };
-
-/* PFTM default values */
-#define PFTM_TCP_FIRST_PACKET_VAL 120 /* First TCP packet */
-#define PFTM_TCP_OPENING_VAL 30 /* No response yet */
-#define PFTM_TCP_ESTABLISHED_VAL 24*60*60/* Established */
-#define PFTM_TCP_CLOSING_VAL 15 * 60 /* Half closed */
-#define PFTM_TCP_FIN_WAIT_VAL 45 /* Got both FINs */
-#define PFTM_TCP_CLOSED_VAL 90 /* Got a RST */
-#define PFTM_UDP_FIRST_PACKET_VAL 60 /* First UDP packet */
-#define PFTM_UDP_SINGLE_VAL 30 /* Unidirectional */
-#define PFTM_UDP_MULTIPLE_VAL 60 /* Bidirectional */
-#define PFTM_ICMP_FIRST_PACKET_VAL 20 /* First ICMP packet */
-#define PFTM_ICMP_ERROR_REPLY_VAL 10 /* Got error response */
-#define PFTM_OTHER_FIRST_PACKET_VAL 60 /* First packet */
-#define PFTM_OTHER_SINGLE_VAL 30 /* Unidirectional */
-#define PFTM_OTHER_MULTIPLE_VAL 60 /* Bidirectional */
-#define PFTM_FRAG_VAL 30 /* Fragment expire */
-#define PFTM_INTERVAL_VAL 10 /* Expire interval */
-#define PFTM_SRC_NODE_VAL 0 /* Source tracking */
-#define PFTM_TS_DIFF_VAL 30 /* Allowed TS diff */
-
-enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO };
-enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS,
- PF_LIMIT_TABLES, PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_MAX };
-#define PF_POOL_IDMASK 0x0f
-enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM,
- PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN };
-enum { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, PF_ADDR_DYNIFTL,
- PF_ADDR_TABLE, PF_ADDR_RTLABEL, PF_ADDR_URPFFAILED,
- PF_ADDR_RANGE };
-#define PF_POOL_TYPEMASK 0x0f
-#define PF_POOL_STICKYADDR 0x20
-#define PF_WSCALE_FLAG 0x80
-#define PF_WSCALE_MASK 0x0f
-
-#define PF_LOG 0x01
-#define PF_LOG_ALL 0x02
-#define PF_LOG_SOCKET_LOOKUP 0x04
-
-struct pf_addr {
- union {
- struct in_addr v4;
- struct in6_addr v6;
- u_int8_t addr8[16];
- u_int16_t addr16[8];
- u_int32_t addr32[4];
- } pfa; /* 128-bit address */
-#define v4 pfa.v4
-#define v6 pfa.v6
-#define addr8 pfa.addr8
-#define addr16 pfa.addr16
-#define addr32 pfa.addr32
-};
-
-#define PF_TABLE_NAME_SIZE 32
-
-#define PFI_AFLAG_NETWORK 0x01
-#define PFI_AFLAG_BROADCAST 0x02
-#define PFI_AFLAG_PEER 0x04
-#define PFI_AFLAG_MODEMASK 0x07
-#define PFI_AFLAG_NOALIAS 0x08
-
-struct pf_addr_wrap {
- union {
- struct {
- struct pf_addr addr;
- struct pf_addr mask;
- } a;
- char ifname[IFNAMSIZ];
- char tblname[PF_TABLE_NAME_SIZE];
-#ifdef __FreeBSD__
-#define RTLABEL_LEN 32
-#endif
- char rtlabelname[RTLABEL_LEN];
- u_int32_t rtlabel;
- } v;
- union {
- struct pfi_dynaddr *dyn;
- struct pfr_ktable *tbl;
- int dyncnt;
- int tblcnt;
- } p;
- u_int8_t type; /* PF_ADDR_* */
- u_int8_t iflags; /* PFI_AFLAG_* */
-};
-
-#ifdef _KERNEL
-
-struct pfi_dynaddr {
- TAILQ_ENTRY(pfi_dynaddr) entry;
- struct pf_addr pfid_addr4;
- struct pf_addr pfid_mask4;
- struct pf_addr pfid_addr6;
- struct pf_addr pfid_mask6;
- struct pfr_ktable *pfid_kt;
- struct pfi_kif *pfid_kif;
- void *pfid_hook_cookie;
- int pfid_net; /* mask or 128 */
- int pfid_acnt4; /* address count IPv4 */
- int pfid_acnt6; /* address count IPv6 */
- sa_family_t pfid_af; /* rule af */
- u_int8_t pfid_iflags; /* PFI_AFLAG_* */
-};
-
-/*
- * Address manipulation macros
- */
-
-#ifdef __FreeBSD__
-#define splsoftnet() splnet()
-
-#define HTONL(x) (x) = htonl((__uint32_t)(x))
-#define HTONS(x) (x) = htons((__uint16_t)(x))
-#define NTOHL(x) (x) = ntohl((__uint32_t)(x))
-#define NTOHS(x) (x) = ntohs((__uint16_t)(x))
-
-#define PF_NAME "pf"
-
-#define PR_NOWAIT M_NOWAIT
-#define PR_WAITOK M_WAITOK
-#define PR_ZERO M_ZERO
-#define pool_get(p, f) uma_zalloc(*(p), (f))
-#define pool_put(p, o) uma_zfree(*(p), (o))
-
-#define UMA_CREATE(var, type, desc) \
- var = uma_zcreate(desc, sizeof(type), \
- NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); \
- if (var == NULL) \
- break
-#define UMA_DESTROY(var) \
- if (var) \
- uma_zdestroy(var)
-
-#ifdef __FreeBSD__
-extern struct mtx pf_task_mtx;
-
-#define PF_LOCK_ASSERT() mtx_assert(&pf_task_mtx, MA_OWNED)
-#define PF_UNLOCK_ASSERT() mtx_assert(&pf_task_mtx, MA_NOTOWNED)
-#define PF_LOCK() mtx_lock(&pf_task_mtx)
-#define PF_UNLOCK() mtx_unlock(&pf_task_mtx)
-#else
-#define PF_LOCK_ASSERT()
-#define PF_UNLOCK_ASSERT()
-#define PF_LOCK()
-#define PF_UNLOCK()
-#endif /* __FreeBSD__ */
-
-#define PF_COPYIN(uaddr, kaddr, len, r) do { \
- PF_UNLOCK(); \
- r = copyin((uaddr), (kaddr), (len)); \
- PF_LOCK(); \
-} while(0)
-
-#define PF_COPYOUT(kaddr, uaddr, len, r) do { \
- PF_UNLOCK(); \
- r = copyout((kaddr), (uaddr), (len)); \
- PF_LOCK(); \
-} while(0)
-
-#define PF_MODVER 1
-#define PFLOG_MODVER 1
-#define PFSYNC_MODVER 1
-
-#define PFLOG_MINVER 1
-#define PFLOG_PREFVER PFLOG_MODVER
-#define PFLOG_MAXVER 1
-#define PFSYNC_MINVER 1
-#define PFSYNC_PREFVER PFSYNC_MODVER
-#define PFSYNC_MAXVER 1
-#endif /* __FreeBSD__ */
-#ifdef INET
-#ifndef INET6
-#define PF_INET_ONLY
-#endif /* ! INET6 */
-#endif /* INET */
-
-#ifdef INET6
-#ifndef INET
-#define PF_INET6_ONLY
-#endif /* ! INET */
-#endif /* INET6 */
-
-#ifdef INET
-#ifdef INET6
-#define PF_INET_INET6
-#endif /* INET6 */
-#endif /* INET */
-
-#else
-
-#define PF_INET_INET6
-
-#endif /* _KERNEL */
-
-/* Both IPv4 and IPv6 */
-#ifdef PF_INET_INET6
-
-#define PF_AEQ(a, b, c) \
- ((c == AF_INET && (a)->addr32[0] == (b)->addr32[0]) || \
- ((a)->addr32[3] == (b)->addr32[3] && \
- (a)->addr32[2] == (b)->addr32[2] && \
- (a)->addr32[1] == (b)->addr32[1] && \
- (a)->addr32[0] == (b)->addr32[0])) \
-
-#define PF_ANEQ(a, b, c) \
- ((c == AF_INET && (a)->addr32[0] != (b)->addr32[0]) || \
- ((a)->addr32[3] != (b)->addr32[3] || \
- (a)->addr32[2] != (b)->addr32[2] || \
- (a)->addr32[1] != (b)->addr32[1] || \
- (a)->addr32[0] != (b)->addr32[0])) \
-
-#define PF_AZERO(a, c) \
- ((c == AF_INET && !(a)->addr32[0]) || \
- (!(a)->addr32[0] && !(a)->addr32[1] && \
- !(a)->addr32[2] && !(a)->addr32[3] )) \
-
-#define PF_MATCHA(n, a, m, b, f) \
- pf_match_addr(n, a, m, b, f)
-
-#define PF_ACPY(a, b, f) \
- pf_addrcpy(a, b, f)
-
-#define PF_AINC(a, f) \
- pf_addr_inc(a, f)
-
-#define PF_POOLMASK(a, b, c, d, f) \
- pf_poolmask(a, b, c, d, f)
-
-#else
-
-/* Just IPv6 */
-
-#ifdef PF_INET6_ONLY
-
-#define PF_AEQ(a, b, c) \
- ((a)->addr32[3] == (b)->addr32[3] && \
- (a)->addr32[2] == (b)->addr32[2] && \
- (a)->addr32[1] == (b)->addr32[1] && \
- (a)->addr32[0] == (b)->addr32[0]) \
-
-#define PF_ANEQ(a, b, c) \
- ((a)->addr32[3] != (b)->addr32[3] || \
- (a)->addr32[2] != (b)->addr32[2] || \
- (a)->addr32[1] != (b)->addr32[1] || \
- (a)->addr32[0] != (b)->addr32[0]) \
-
-#define PF_AZERO(a, c) \
- (!(a)->addr32[0] && \
- !(a)->addr32[1] && \
- !(a)->addr32[2] && \
- !(a)->addr32[3] ) \
-
-#define PF_MATCHA(n, a, m, b, f) \
- pf_match_addr(n, a, m, b, f)
-
-#define PF_ACPY(a, b, f) \
- pf_addrcpy(a, b, f)
-
-#define PF_AINC(a, f) \
- pf_addr_inc(a, f)
-
-#define PF_POOLMASK(a, b, c, d, f) \
- pf_poolmask(a, b, c, d, f)
-
-#else
-
-/* Just IPv4 */
-#ifdef PF_INET_ONLY
-
-#define PF_AEQ(a, b, c) \
- ((a)->addr32[0] == (b)->addr32[0])
-
-#define PF_ANEQ(a, b, c) \
- ((a)->addr32[0] != (b)->addr32[0])
-
-#define PF_AZERO(a, c) \
- (!(a)->addr32[0])
-
-#define PF_MATCHA(n, a, m, b, f) \
- pf_match_addr(n, a, m, b, f)
-
-#define PF_ACPY(a, b, f) \
- (a)->v4.s_addr = (b)->v4.s_addr
-
-#define PF_AINC(a, f) \
- do { \
- (a)->addr32[0] = htonl(ntohl((a)->addr32[0]) + 1); \
- } while (0)
-
-#define PF_POOLMASK(a, b, c, d, f) \
- do { \
- (a)->addr32[0] = ((b)->addr32[0] & (c)->addr32[0]) | \
- (((c)->addr32[0] ^ 0xffffffff ) & (d)->addr32[0]); \
- } while (0)
-
-#endif /* PF_INET_ONLY */
-#endif /* PF_INET6_ONLY */
-#endif /* PF_INET_INET6 */
-
-/*
- * XXX callers not FIB-aware in our version of pf yet.
- * OpenBSD fixed it later it seems, 2010/05/07 13:33:16 claudio.
- */
-#define PF_MISMATCHAW(aw, x, af, neg, ifp, rtid) \
- ( \
- (((aw)->type == PF_ADDR_NOROUTE && \
- pf_routable((x), (af), NULL, (rtid))) || \
- (((aw)->type == PF_ADDR_URPFFAILED && (ifp) != NULL && \
- pf_routable((x), (af), (ifp), (rtid))) || \
- ((aw)->type == PF_ADDR_RTLABEL && \
- !pf_rtlabel_match((x), (af), (aw), (rtid))) || \
- ((aw)->type == PF_ADDR_TABLE && \
- !pfr_match_addr((aw)->p.tbl, (x), (af))) || \
- ((aw)->type == PF_ADDR_DYNIFTL && \
- !pfi_match_addr((aw)->p.dyn, (x), (af))) || \
- ((aw)->type == PF_ADDR_RANGE && \
- !pf_match_addr_range(&(aw)->v.a.addr, \
- &(aw)->v.a.mask, (x), (af))) || \
- ((aw)->type == PF_ADDR_ADDRMASK && \
- !PF_AZERO(&(aw)->v.a.mask, (af)) && \
- !PF_MATCHA(0, &(aw)->v.a.addr, \
- &(aw)->v.a.mask, (x), (af))))) != \
- (neg) \
- )
-
-
-struct pf_rule_uid {
- uid_t uid[2];
- u_int8_t op;
-};
-
-struct pf_rule_gid {
- uid_t gid[2];
- u_int8_t op;
-};
-
-struct pf_rule_addr {
- struct pf_addr_wrap addr;
- u_int16_t port[2];
- u_int8_t neg;
- u_int8_t port_op;
-};
-
-struct pf_pooladdr {
- struct pf_addr_wrap addr;
- TAILQ_ENTRY(pf_pooladdr) entries;
- char ifname[IFNAMSIZ];
- struct pfi_kif *kif;
-};
-
-TAILQ_HEAD(pf_palist, pf_pooladdr);
-
-struct pf_poolhashkey {
- union {
- u_int8_t key8[16];
- u_int16_t key16[8];
- u_int32_t key32[4];
- } pfk; /* 128-bit hash key */
-#define key8 pfk.key8
-#define key16 pfk.key16
-#define key32 pfk.key32
-};
-
-struct pf_pool {
- struct pf_palist list;
- struct pf_pooladdr *cur;
- struct pf_poolhashkey key;
- struct pf_addr counter;
- int tblidx;
- u_int16_t proxy_port[2];
- u_int8_t port_op;
- u_int8_t opts;
-};
-
-
-/* A packed Operating System description for fingerprinting */
-typedef u_int32_t pf_osfp_t;
-#define PF_OSFP_ANY ((pf_osfp_t)0)
-#define PF_OSFP_UNKNOWN ((pf_osfp_t)-1)
-#define PF_OSFP_NOMATCH ((pf_osfp_t)-2)
-
-struct pf_osfp_entry {
- SLIST_ENTRY(pf_osfp_entry) fp_entry;
- pf_osfp_t fp_os;
- int fp_enflags;
-#define PF_OSFP_EXPANDED 0x001 /* expanded entry */
-#define PF_OSFP_GENERIC 0x002 /* generic signature */
-#define PF_OSFP_NODETAIL 0x004 /* no p0f details */
-#define PF_OSFP_LEN 32
- char fp_class_nm[PF_OSFP_LEN];
- char fp_version_nm[PF_OSFP_LEN];
- char fp_subtype_nm[PF_OSFP_LEN];
-};
-#define PF_OSFP_ENTRY_EQ(a, b) \
- ((a)->fp_os == (b)->fp_os && \
- memcmp((a)->fp_class_nm, (b)->fp_class_nm, PF_OSFP_LEN) == 0 && \
- memcmp((a)->fp_version_nm, (b)->fp_version_nm, PF_OSFP_LEN) == 0 && \
- memcmp((a)->fp_subtype_nm, (b)->fp_subtype_nm, PF_OSFP_LEN) == 0)
-
-/* handle pf_osfp_t packing */
-#define _FP_RESERVED_BIT 1 /* For the special negative #defines */
-#define _FP_UNUSED_BITS 1
-#define _FP_CLASS_BITS 10 /* OS Class (Windows, Linux) */
-#define _FP_VERSION_BITS 10 /* OS version (95, 98, NT, 2.4.54, 3.2) */
-#define _FP_SUBTYPE_BITS 10 /* patch level (NT SP4, SP3, ECN patch) */
-#define PF_OSFP_UNPACK(osfp, class, version, subtype) do { \
- (class) = ((osfp) >> (_FP_VERSION_BITS+_FP_SUBTYPE_BITS)) & \
- ((1 << _FP_CLASS_BITS) - 1); \
- (version) = ((osfp) >> _FP_SUBTYPE_BITS) & \
- ((1 << _FP_VERSION_BITS) - 1);\
- (subtype) = (osfp) & ((1 << _FP_SUBTYPE_BITS) - 1); \
-} while(0)
-#define PF_OSFP_PACK(osfp, class, version, subtype) do { \
- (osfp) = ((class) & ((1 << _FP_CLASS_BITS) - 1)) << (_FP_VERSION_BITS \
- + _FP_SUBTYPE_BITS); \
- (osfp) |= ((version) & ((1 << _FP_VERSION_BITS) - 1)) << \
- _FP_SUBTYPE_BITS; \
- (osfp) |= (subtype) & ((1 << _FP_SUBTYPE_BITS) - 1); \
-} while(0)
-
-/* the fingerprint of an OSes TCP SYN packet */
-typedef u_int64_t pf_tcpopts_t;
-struct pf_os_fingerprint {
- SLIST_HEAD(pf_osfp_enlist, pf_osfp_entry) fp_oses; /* list of matches */
- pf_tcpopts_t fp_tcpopts; /* packed TCP options */
- u_int16_t fp_wsize; /* TCP window size */
- u_int16_t fp_psize; /* ip->ip_len */
- u_int16_t fp_mss; /* TCP MSS */
- u_int16_t fp_flags;
-#define PF_OSFP_WSIZE_MOD 0x0001 /* Window modulus */
-#define PF_OSFP_WSIZE_DC 0x0002 /* Window don't care */
-#define PF_OSFP_WSIZE_MSS 0x0004 /* Window multiple of MSS */
-#define PF_OSFP_WSIZE_MTU 0x0008 /* Window multiple of MTU */
-#define PF_OSFP_PSIZE_MOD 0x0010 /* packet size modulus */
-#define PF_OSFP_PSIZE_DC 0x0020 /* packet size don't care */
-#define PF_OSFP_WSCALE 0x0040 /* TCP window scaling */
-#define PF_OSFP_WSCALE_MOD 0x0080 /* TCP window scale modulus */
-#define PF_OSFP_WSCALE_DC 0x0100 /* TCP window scale dont-care */
-#define PF_OSFP_MSS 0x0200 /* TCP MSS */
-#define PF_OSFP_MSS_MOD 0x0400 /* TCP MSS modulus */
-#define PF_OSFP_MSS_DC 0x0800 /* TCP MSS dont-care */
-#define PF_OSFP_DF 0x1000 /* IPv4 don't fragment bit */
-#define PF_OSFP_TS0 0x2000 /* Zero timestamp */
-#define PF_OSFP_INET6 0x4000 /* IPv6 */
- u_int8_t fp_optcnt; /* TCP option count */
- u_int8_t fp_wscale; /* TCP window scaling */
- u_int8_t fp_ttl; /* IPv4 TTL */
-#define PF_OSFP_MAXTTL_OFFSET 40
-/* TCP options packing */
-#define PF_OSFP_TCPOPT_NOP 0x0 /* TCP NOP option */
-#define PF_OSFP_TCPOPT_WSCALE 0x1 /* TCP window scaling option */
-#define PF_OSFP_TCPOPT_MSS 0x2 /* TCP max segment size opt */
-#define PF_OSFP_TCPOPT_SACK 0x3 /* TCP SACK OK option */
-#define PF_OSFP_TCPOPT_TS 0x4 /* TCP timestamp option */
-#define PF_OSFP_TCPOPT_BITS 3 /* bits used by each option */
-#define PF_OSFP_MAX_OPTS \
- (sizeof(((struct pf_os_fingerprint *)0)->fp_tcpopts) * 8) \
- / PF_OSFP_TCPOPT_BITS
-
- SLIST_ENTRY(pf_os_fingerprint) fp_next;
-};
-
-struct pf_osfp_ioctl {
- struct pf_osfp_entry fp_os;
- pf_tcpopts_t fp_tcpopts; /* packed TCP options */
- u_int16_t fp_wsize; /* TCP window size */
- u_int16_t fp_psize; /* ip->ip_len */
- u_int16_t fp_mss; /* TCP MSS */
- u_int16_t fp_flags;
- u_int8_t fp_optcnt; /* TCP option count */
- u_int8_t fp_wscale; /* TCP window scaling */
- u_int8_t fp_ttl; /* IPv4 TTL */
-
- int fp_getnum; /* DIOCOSFPGET number */
-};
-
-
-union pf_rule_ptr {
- struct pf_rule *ptr;
- u_int32_t nr;
-};
-
-#define PF_ANCHOR_NAME_SIZE 64
-
-struct pf_rule {
- struct pf_rule_addr src;
- struct pf_rule_addr dst;
-#define PF_SKIP_IFP 0
-#define PF_SKIP_DIR 1
-#define PF_SKIP_AF 2
-#define PF_SKIP_PROTO 3
-#define PF_SKIP_SRC_ADDR 4
-#define PF_SKIP_SRC_PORT 5
-#define PF_SKIP_DST_ADDR 6
-#define PF_SKIP_DST_PORT 7
-#define PF_SKIP_COUNT 8
- union pf_rule_ptr skip[PF_SKIP_COUNT];
-#define PF_RULE_LABEL_SIZE 64
- char label[PF_RULE_LABEL_SIZE];
-#define PF_QNAME_SIZE 64
- char ifname[IFNAMSIZ];
- char qname[PF_QNAME_SIZE];
- char pqname[PF_QNAME_SIZE];
-#define PF_TAG_NAME_SIZE 64
- char tagname[PF_TAG_NAME_SIZE];
- char match_tagname[PF_TAG_NAME_SIZE];
-
- char overload_tblname[PF_TABLE_NAME_SIZE];
-
- TAILQ_ENTRY(pf_rule) entries;
- struct pf_pool rpool;
-
- u_int64_t evaluations;
- u_int64_t packets[2];
- u_int64_t bytes[2];
-
- struct pfi_kif *kif;
- struct pf_anchor *anchor;
- struct pfr_ktable *overload_tbl;
-
- pf_osfp_t os_fingerprint;
-
- int rtableid;
- u_int32_t timeout[PFTM_MAX];
- u_int32_t states_cur;
- u_int32_t states_tot;
- u_int32_t max_states;
- u_int32_t src_nodes;
- u_int32_t max_src_nodes;
- u_int32_t max_src_states;
- u_int32_t spare1; /* netgraph */
- u_int32_t max_src_conn;
- struct {
- u_int32_t limit;
- u_int32_t seconds;
- } max_src_conn_rate;
- u_int32_t qid;
- u_int32_t pqid;
- u_int32_t rt_listid;
- u_int32_t nr;
- u_int32_t prob;
- uid_t cuid;
- pid_t cpid;
-
- u_int16_t return_icmp;
- u_int16_t return_icmp6;
- u_int16_t max_mss;
- u_int16_t tag;
- u_int16_t match_tag;
- u_int16_t spare2; /* netgraph */
-
- struct pf_rule_uid uid;
- struct pf_rule_gid gid;
-
- u_int32_t rule_flag;
- u_int8_t action;
- u_int8_t direction;
- u_int8_t log;
- u_int8_t logif;
- u_int8_t quick;
- u_int8_t ifnot;
- u_int8_t match_tag_not;
- u_int8_t natpass;
-
-#define PF_STATE_NORMAL 0x1
-#define PF_STATE_MODULATE 0x2
-#define PF_STATE_SYNPROXY 0x3
- u_int8_t keep_state;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t type;
- u_int8_t code;
- u_int8_t flags;
- u_int8_t flagset;
- u_int8_t min_ttl;
- u_int8_t allow_opts;
- u_int8_t rt;
- u_int8_t return_ttl;
- u_int8_t tos;
- u_int8_t set_tos;
- u_int8_t anchor_relative;
- u_int8_t anchor_wildcard;
-
-#define PF_FLUSH 0x01
-#define PF_FLUSH_GLOBAL 0x02
- u_int8_t flush;
-
- struct {
- struct pf_addr addr;
- u_int16_t port;
- } divert;
-};
-
-/* rule flags */
-#define PFRULE_DROP 0x0000
-#define PFRULE_RETURNRST 0x0001
-#define PFRULE_FRAGMENT 0x0002
-#define PFRULE_RETURNICMP 0x0004
-#define PFRULE_RETURN 0x0008
-#define PFRULE_NOSYNC 0x0010
-#define PFRULE_SRCTRACK 0x0020 /* track source states */
-#define PFRULE_RULESRCTRACK 0x0040 /* per rule */
-
-/* scrub flags */
-#define PFRULE_NODF 0x0100
-#define PFRULE_FRAGCROP 0x0200 /* non-buffering frag cache */
-#define PFRULE_FRAGDROP 0x0400 /* drop funny fragments */
-#define PFRULE_RANDOMID 0x0800
-#define PFRULE_REASSEMBLE_TCP 0x1000
-#define PFRULE_SET_TOS 0x2000
-
-/* rule flags again */
-#define PFRULE_IFBOUND 0x00010000 /* if-bound */
-#define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */
-#define PFRULE_PFLOW 0x00040000
-
-#define PFSTATE_HIWAT 10000 /* default state table size */
-#define PFSTATE_ADAPT_START 6000 /* default adaptive timeout start */
-#define PFSTATE_ADAPT_END 12000 /* default adaptive timeout end */
-
-
-struct pf_threshold {
- u_int32_t limit;
-#define PF_THRESHOLD_MULT 1000
-#define PF_THRESHOLD_MAX 0xffffffff / PF_THRESHOLD_MULT
- u_int32_t seconds;
- u_int32_t count;
- u_int32_t last;
-};
-
-struct pf_src_node {
- RB_ENTRY(pf_src_node) entry;
- struct pf_addr addr;
- struct pf_addr raddr;
- union pf_rule_ptr rule;
- struct pfi_kif *kif;
- u_int64_t bytes[2];
- u_int64_t packets[2];
- u_int32_t states;
- u_int32_t conn;
- struct pf_threshold conn_rate;
- u_int32_t creation;
- u_int32_t expire;
- sa_family_t af;
- u_int8_t ruletype;
-};
-
-#define PFSNODE_HIWAT 10000 /* default source node table size */
-
-struct pf_state_scrub {
- struct timeval pfss_last; /* time received last packet */
- u_int32_t pfss_tsecr; /* last echoed timestamp */
- u_int32_t pfss_tsval; /* largest timestamp */
- u_int32_t pfss_tsval0; /* original timestamp */
- u_int16_t pfss_flags;
-#define PFSS_TIMESTAMP 0x0001 /* modulate timestamp */
-#define PFSS_PAWS 0x0010 /* stricter PAWS checks */
-#define PFSS_PAWS_IDLED 0x0020 /* was idle too long. no PAWS */
-#define PFSS_DATA_TS 0x0040 /* timestamp on data packets */
-#define PFSS_DATA_NOTS 0x0080 /* no timestamp on data packets */
- u_int8_t pfss_ttl; /* stashed TTL */
- u_int8_t pad;
- u_int32_t pfss_ts_mod; /* timestamp modulation */
-};
-
-struct pf_state_host {
- struct pf_addr addr;
- u_int16_t port;
- u_int16_t pad;
-};
-
-struct pf_state_peer {
- struct pf_state_scrub *scrub; /* state is scrubbed */
- u_int32_t seqlo; /* Max sequence number sent */
- u_int32_t seqhi; /* Max the other end ACKd + win */
- u_int32_t seqdiff; /* Sequence number modulator */
- u_int16_t max_win; /* largest window (pre scaling) */
- u_int16_t mss; /* Maximum segment size option */
- u_int8_t state; /* active state level */
- u_int8_t wscale; /* window scaling factor */
- u_int8_t tcp_est; /* Did we reach TCPS_ESTABLISHED */
- u_int8_t pad[1];
-};
-
-TAILQ_HEAD(pf_state_queue, pf_state);
-
-/* keep synced with struct pf_state_key, used in RB_FIND */
-struct pf_state_key_cmp {
- struct pf_addr addr[2];
- u_int16_t port[2];
- sa_family_t af;
- u_int8_t proto;
- u_int8_t pad[2];
-};
-
-struct pf_state_item {
- TAILQ_ENTRY(pf_state_item) entry;
- struct pf_state *s;
-};
-
-TAILQ_HEAD(pf_statelisthead, pf_state_item);
-
-struct pf_state_key {
- struct pf_addr addr[2];
- u_int16_t port[2];
- sa_family_t af;
- u_int8_t proto;
- u_int8_t pad[2];
-
- RB_ENTRY(pf_state_key) entry;
- struct pf_statelisthead states;
- struct pf_state_key *reverse;
- struct inpcb *inp;
-};
-
-/* keep synced with struct pf_state, used in RB_FIND */
-struct pf_state_cmp {
- u_int64_t id;
- u_int32_t creatorid;
- u_int8_t direction;
- u_int8_t pad[3];
-};
-
-struct pf_state {
- u_int64_t id;
- u_int32_t creatorid;
- u_int8_t direction;
-#ifdef __FreeBSD__
- u_int8_t pad[2];
- u_int8_t local_flags;
-#define PFSTATE_EXPIRING 0x01
-#else
- u_int8_t pad[3];
-#endif
-
- TAILQ_ENTRY(pf_state) sync_list;
- TAILQ_ENTRY(pf_state) entry_list;
- RB_ENTRY(pf_state) entry_id;
- struct pf_state_peer src;
- struct pf_state_peer dst;
- union pf_rule_ptr rule;
- union pf_rule_ptr anchor;
- union pf_rule_ptr nat_rule;
- struct pf_addr rt_addr;
- struct pf_state_key *key[2]; /* addresses stack and wire */
- struct pfi_kif *kif;
- struct pfi_kif *rt_kif;
- struct pf_src_node *src_node;
- struct pf_src_node *nat_src_node;
- u_int64_t packets[2];
- u_int64_t bytes[2];
- u_int32_t creation;
- u_int32_t expire;
- u_int32_t pfsync_time;
- u_int16_t tag;
- u_int8_t log;
- u_int8_t state_flags;
-#define PFSTATE_ALLOWOPTS 0x01
-#define PFSTATE_SLOPPY 0x02
-#define PFSTATE_PFLOW 0x04
-#define PFSTATE_NOSYNC 0x08
-#define PFSTATE_ACK 0x10
- u_int8_t timeout;
- u_int8_t sync_state; /* PFSYNC_S_x */
-
- /* XXX */
- u_int8_t sync_updates;
- u_int8_t _tail[3];
-};
-
-/*
- * Unified state structures for pulling states out of the kernel
- * used by pfsync(4) and the pf(4) ioctl.
- */
-struct pfsync_state_scrub {
- u_int16_t pfss_flags;
- u_int8_t pfss_ttl; /* stashed TTL */
-#define PFSYNC_SCRUB_FLAG_VALID 0x01
- u_int8_t scrub_flag;
- u_int32_t pfss_ts_mod; /* timestamp modulation */
-} __packed;
-
-struct pfsync_state_peer {
- struct pfsync_state_scrub scrub; /* state is scrubbed */
- u_int32_t seqlo; /* Max sequence number sent */
- u_int32_t seqhi; /* Max the other end ACKd + win */
- u_int32_t seqdiff; /* Sequence number modulator */
- u_int16_t max_win; /* largest window (pre scaling) */
- u_int16_t mss; /* Maximum segment size option */
- u_int8_t state; /* active state level */
- u_int8_t wscale; /* window scaling factor */
- u_int8_t pad[6];
-} __packed;
-
-struct pfsync_state_key {
- struct pf_addr addr[2];
- u_int16_t port[2];
-};
-
-struct pfsync_state {
- u_int32_t id[2];
- char ifname[IFNAMSIZ];
- struct pfsync_state_key key[2];
- struct pfsync_state_peer src;
- struct pfsync_state_peer dst;
- struct pf_addr rt_addr;
- u_int32_t rule;
- u_int32_t anchor;
- u_int32_t nat_rule;
- u_int32_t creation;
- u_int32_t expire;
- u_int32_t packets[2][2];
- u_int32_t bytes[2][2];
- u_int32_t creatorid;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t direction;
-#ifdef __FreeBSD__
- u_int8_t local_flags;
-#define PFSTATE_EXPIRING 0x01
- u_int8_t pad;
-#endif
- u_int8_t log;
- u_int8_t state_flags;
- u_int8_t timeout;
- u_int8_t sync_flags;
- u_int8_t updates;
-} __packed;
-
-#ifdef __FreeBSD__
-#ifdef _KERNEL
-/* pfsync */
-typedef int pfsync_state_import_t(struct pfsync_state *, u_int8_t);
-typedef void pfsync_insert_state_t(struct pf_state *);
-typedef void pfsync_update_state_t(struct pf_state *);
-typedef void pfsync_delete_state_t(struct pf_state *);
-typedef void pfsync_clear_states_t(u_int32_t, const char *);
-typedef int pfsync_state_in_use_t(struct pf_state *);
-typedef int pfsync_defer_t(struct pf_state *, struct mbuf *);
-typedef int pfsync_up_t(void);
-
-extern pfsync_state_import_t *pfsync_state_import_ptr;
-extern pfsync_insert_state_t *pfsync_insert_state_ptr;
-extern pfsync_update_state_t *pfsync_update_state_ptr;
-extern pfsync_delete_state_t *pfsync_delete_state_ptr;
-extern pfsync_clear_states_t *pfsync_clear_states_ptr;
-extern pfsync_state_in_use_t *pfsync_state_in_use_ptr;
-extern pfsync_defer_t *pfsync_defer_ptr;
-extern pfsync_up_t *pfsync_up_ptr;
-
-void pfsync_state_export(struct pfsync_state *,
- struct pf_state *);
-
-/* pflow */
-typedef int export_pflow_t(struct pf_state *);
-
-extern export_pflow_t *export_pflow_ptr;
-
-/* pflog */
-struct pf_ruleset;
-struct pf_pdesc;
-typedef int pflog_packet_t(struct pfi_kif *, struct mbuf *, sa_family_t,
- u_int8_t, u_int8_t, struct pf_rule *, struct pf_rule *,
- struct pf_ruleset *, struct pf_pdesc *);
-
-extern pflog_packet_t *pflog_packet_ptr;
-
-/* pf uid hack */
-VNET_DECLARE(int, debug_pfugidhack);
-#define V_debug_pfugidhack VNET(debug_pfugidhack)
-
-#define V_pf_end_threads VNET(pf_end_threads)
-#endif
-
-/* Macros to set/clear/test flags. */
-#ifdef _KERNEL
-#define SET(t, f) ((t) |= (f))
-#define CLR(t, f) ((t) &= ~(f))
-#define ISSET(t, f) ((t) & (f))
-#endif
-#endif
-
-#define PFSYNC_FLAG_SRCNODE 0x04
-#define PFSYNC_FLAG_NATSRCNODE 0x08
-
-/* for copies to/from network byte order */
-/* ioctl interface also uses network byte order */
-#define pf_state_peer_hton(s,d) do { \
- (d)->seqlo = htonl((s)->seqlo); \
- (d)->seqhi = htonl((s)->seqhi); \
- (d)->seqdiff = htonl((s)->seqdiff); \
- (d)->max_win = htons((s)->max_win); \
- (d)->mss = htons((s)->mss); \
- (d)->state = (s)->state; \
- (d)->wscale = (s)->wscale; \
- if ((s)->scrub) { \
- (d)->scrub.pfss_flags = \
- htons((s)->scrub->pfss_flags & PFSS_TIMESTAMP); \
- (d)->scrub.pfss_ttl = (s)->scrub->pfss_ttl; \
- (d)->scrub.pfss_ts_mod = htonl((s)->scrub->pfss_ts_mod);\
- (d)->scrub.scrub_flag = PFSYNC_SCRUB_FLAG_VALID; \
- } \
-} while (0)
-
-#define pf_state_peer_ntoh(s,d) do { \
- (d)->seqlo = ntohl((s)->seqlo); \
- (d)->seqhi = ntohl((s)->seqhi); \
- (d)->seqdiff = ntohl((s)->seqdiff); \
- (d)->max_win = ntohs((s)->max_win); \
- (d)->mss = ntohs((s)->mss); \
- (d)->state = (s)->state; \
- (d)->wscale = (s)->wscale; \
- if ((s)->scrub.scrub_flag == PFSYNC_SCRUB_FLAG_VALID && \
- (d)->scrub != NULL) { \
- (d)->scrub->pfss_flags = \
- ntohs((s)->scrub.pfss_flags) & PFSS_TIMESTAMP; \
- (d)->scrub->pfss_ttl = (s)->scrub.pfss_ttl; \
- (d)->scrub->pfss_ts_mod = ntohl((s)->scrub.pfss_ts_mod);\
- } \
-} while (0)
-
-#define pf_state_counter_hton(s,d) do { \
- d[0] = htonl((s>>32)&0xffffffff); \
- d[1] = htonl(s&0xffffffff); \
-} while (0)
-
-#define pf_state_counter_from_pfsync(s) \
- (((u_int64_t)(s[0])<<32) | (u_int64_t)(s[1]))
-
-#define pf_state_counter_ntoh(s,d) do { \
- d = ntohl(s[0]); \
- d = d<<32; \
- d += ntohl(s[1]); \
-} while (0)
-
-TAILQ_HEAD(pf_rulequeue, pf_rule);
-
-struct pf_anchor;
-
-struct pf_ruleset {
- struct {
- struct pf_rulequeue queues[2];
- struct {
- struct pf_rulequeue *ptr;
- struct pf_rule **ptr_array;
- u_int32_t rcount;
- u_int32_t ticket;
- int open;
- } active, inactive;
- } rules[PF_RULESET_MAX];
- struct pf_anchor *anchor;
- u_int32_t tticket;
- int tables;
- int topen;
-};
-
-RB_HEAD(pf_anchor_global, pf_anchor);
-RB_HEAD(pf_anchor_node, pf_anchor);
-struct pf_anchor {
- RB_ENTRY(pf_anchor) entry_global;
- RB_ENTRY(pf_anchor) entry_node;
- struct pf_anchor *parent;
- struct pf_anchor_node children;
- char name[PF_ANCHOR_NAME_SIZE];
- char path[MAXPATHLEN];
- struct pf_ruleset ruleset;
- int refcnt; /* anchor rules */
- int match;
-};
-RB_PROTOTYPE(pf_anchor_global, pf_anchor, entry_global, pf_anchor_compare);
-RB_PROTOTYPE(pf_anchor_node, pf_anchor, entry_node, pf_anchor_compare);
-
-#define PF_RESERVED_ANCHOR "_pf"
-
-#define PFR_TFLAG_PERSIST 0x00000001
-#define PFR_TFLAG_CONST 0x00000002
-#define PFR_TFLAG_ACTIVE 0x00000004
-#define PFR_TFLAG_INACTIVE 0x00000008
-#define PFR_TFLAG_REFERENCED 0x00000010
-#define PFR_TFLAG_REFDANCHOR 0x00000020
-#define PFR_TFLAG_COUNTERS 0x00000040
-/* Adjust masks below when adding flags. */
-#define PFR_TFLAG_USRMASK 0x00000043
-#define PFR_TFLAG_SETMASK 0x0000003C
-#define PFR_TFLAG_ALLMASK 0x0000007F
-
-struct pfr_table {
- char pfrt_anchor[MAXPATHLEN];
- char pfrt_name[PF_TABLE_NAME_SIZE];
- u_int32_t pfrt_flags;
- u_int8_t pfrt_fback;
-};
-
-enum { PFR_FB_NONE, PFR_FB_MATCH, PFR_FB_ADDED, PFR_FB_DELETED,
- PFR_FB_CHANGED, PFR_FB_CLEARED, PFR_FB_DUPLICATE,
- PFR_FB_NOTMATCH, PFR_FB_CONFLICT, PFR_FB_NOCOUNT, PFR_FB_MAX };
-
-struct pfr_addr {
- union {
- struct in_addr _pfra_ip4addr;
- struct in6_addr _pfra_ip6addr;
- } pfra_u;
- u_int8_t pfra_af;
- u_int8_t pfra_net;
- u_int8_t pfra_not;
- u_int8_t pfra_fback;
-};
-#define pfra_ip4addr pfra_u._pfra_ip4addr
-#define pfra_ip6addr pfra_u._pfra_ip6addr
-
-enum { PFR_DIR_IN, PFR_DIR_OUT, PFR_DIR_MAX };
-enum { PFR_OP_BLOCK, PFR_OP_PASS, PFR_OP_ADDR_MAX, PFR_OP_TABLE_MAX };
-#define PFR_OP_XPASS PFR_OP_ADDR_MAX
-
-struct pfr_astats {
- struct pfr_addr pfras_a;
- u_int64_t pfras_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
- u_int64_t pfras_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
- long pfras_tzero;
-};
-
-enum { PFR_REFCNT_RULE, PFR_REFCNT_ANCHOR, PFR_REFCNT_MAX };
-
-struct pfr_tstats {
- struct pfr_table pfrts_t;
- u_int64_t pfrts_packets[PFR_DIR_MAX][PFR_OP_TABLE_MAX];
- u_int64_t pfrts_bytes[PFR_DIR_MAX][PFR_OP_TABLE_MAX];
- u_int64_t pfrts_match;
- u_int64_t pfrts_nomatch;
- long pfrts_tzero;
- int pfrts_cnt;
- int pfrts_refcnt[PFR_REFCNT_MAX];
-};
-#define pfrts_name pfrts_t.pfrt_name
-#define pfrts_flags pfrts_t.pfrt_flags
-
-#ifndef _SOCKADDR_UNION_DEFINED
-#define _SOCKADDR_UNION_DEFINED
-union sockaddr_union {
- struct sockaddr sa;
- struct sockaddr_in sin;
- struct sockaddr_in6 sin6;
-};
-#endif /* _SOCKADDR_UNION_DEFINED */
-
-struct pfr_kcounters {
- u_int64_t pfrkc_packets[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
- u_int64_t pfrkc_bytes[PFR_DIR_MAX][PFR_OP_ADDR_MAX];
-};
-
-SLIST_HEAD(pfr_kentryworkq, pfr_kentry);
-struct pfr_kentry {
- struct radix_node pfrke_node[2];
- union sockaddr_union pfrke_sa;
- SLIST_ENTRY(pfr_kentry) pfrke_workq;
- union {
-
- struct pfr_kcounters *pfrke_counters;
-#if 0
- struct pfr_kroute *pfrke_route;
-#endif
- } u;
- long pfrke_tzero;
- u_int8_t pfrke_af;
- u_int8_t pfrke_net;
- u_int8_t pfrke_not;
- u_int8_t pfrke_mark;
-};
-#define pfrke_counters u.pfrke_counters
-#define pfrke_route u.pfrke_route
-
-
-SLIST_HEAD(pfr_ktableworkq, pfr_ktable);
-RB_HEAD(pfr_ktablehead, pfr_ktable);
-struct pfr_ktable {
- struct pfr_tstats pfrkt_ts;
- RB_ENTRY(pfr_ktable) pfrkt_tree;
- SLIST_ENTRY(pfr_ktable) pfrkt_workq;
- struct radix_node_head *pfrkt_ip4;
- struct radix_node_head *pfrkt_ip6;
- struct pfr_ktable *pfrkt_shadow;
- struct pfr_ktable *pfrkt_root;
- struct pf_ruleset *pfrkt_rs;
- long pfrkt_larg;
- int pfrkt_nflags;
-};
-#define pfrkt_t pfrkt_ts.pfrts_t
-#define pfrkt_name pfrkt_t.pfrt_name
-#define pfrkt_anchor pfrkt_t.pfrt_anchor
-#define pfrkt_ruleset pfrkt_t.pfrt_ruleset
-#define pfrkt_flags pfrkt_t.pfrt_flags
-#define pfrkt_cnt pfrkt_ts.pfrts_cnt
-#define pfrkt_refcnt pfrkt_ts.pfrts_refcnt
-#define pfrkt_packets pfrkt_ts.pfrts_packets
-#define pfrkt_bytes pfrkt_ts.pfrts_bytes
-#define pfrkt_match pfrkt_ts.pfrts_match
-#define pfrkt_nomatch pfrkt_ts.pfrts_nomatch
-#define pfrkt_tzero pfrkt_ts.pfrts_tzero
-
-RB_HEAD(pf_state_tree, pf_state_key);
-RB_PROTOTYPE(pf_state_tree, pf_state_key, entry, pf_state_compare_key);
-
-RB_HEAD(pf_state_tree_ext_gwy, pf_state_key);
-RB_PROTOTYPE(pf_state_tree_ext_gwy, pf_state_key,
- entry_ext_gwy, pf_state_compare_ext_gwy);
-
-RB_HEAD(pfi_ifhead, pfi_kif);
-
-/* state tables */
-#ifdef __FreeBSD__
-#ifdef _KERNEL
-VNET_DECLARE(struct pf_state_tree, pf_statetbl);
-#define V_pf_statetbl VNET(pf_statetbl)
-#endif
-#else
-extern struct pf_state_tree pf_statetbl;
-#endif
-
-/* keep synced with pfi_kif, used in RB_FIND */
-struct pfi_kif_cmp {
- char pfik_name[IFNAMSIZ];
-};
-
-struct pfi_kif {
- char pfik_name[IFNAMSIZ];
- RB_ENTRY(pfi_kif) pfik_tree;
- u_int64_t pfik_packets[2][2][2];
- u_int64_t pfik_bytes[2][2][2];
- u_int32_t pfik_tzero;
- int pfik_flags;
- void *pfik_ah_cookie;
- struct ifnet *pfik_ifp;
- struct ifg_group *pfik_group;
- int pfik_states;
- int pfik_rules;
- TAILQ_HEAD(, pfi_dynaddr) pfik_dynaddrs;
-};
-
-enum pfi_kif_refs {
- PFI_KIF_REF_NONE,
- PFI_KIF_REF_STATE,
- PFI_KIF_REF_RULE
-};
-
-#define PFI_IFLAG_SKIP 0x0100 /* skip filtering on interface */
-
-struct pf_pdesc {
- struct {
- int done;
- uid_t uid;
- gid_t gid;
- pid_t pid;
- } lookup;
- u_int64_t tot_len; /* Make Mickey money */
- union {
- struct tcphdr *tcp;
- struct udphdr *udp;
- struct icmp *icmp;
-#ifdef INET6
- struct icmp6_hdr *icmp6;
-#endif /* INET6 */
- void *any;
- } hdr;
-
- struct pf_rule *nat_rule; /* nat/rdr rule applied to packet */
- struct ether_header
- *eh;
- struct pf_addr *src; /* src address */
- struct pf_addr *dst; /* dst address */
- u_int16_t *sport;
- u_int16_t *dport;
-#ifdef __FreeBSD__
- struct pf_mtag *pf_mtag;
-#endif
-
- u_int32_t p_len; /* total length of payload */
-
- u_int16_t *ip_sum;
- u_int16_t *proto_sum;
- u_int16_t flags; /* Let SCRUB trigger behavior in
- * state code. Easier than tags */
-#define PFDESC_TCP_NORM 0x0001 /* TCP shall be statefully scrubbed */
-#define PFDESC_IP_REAS 0x0002 /* IP frags would've been reassembled */
- sa_family_t af;
- u_int8_t proto;
- u_int8_t tos;
- u_int8_t dir; /* direction */
- u_int8_t sidx; /* key index for source */
- u_int8_t didx; /* key index for destination */
-};
-
-/* flags for RDR options */
-#define PF_DPORT_RANGE 0x01 /* Dest port uses range */
-#define PF_RPORT_RANGE 0x02 /* RDR'ed port uses range */
-
-/* Reasons code for passing/dropping a packet */
-#define PFRES_MATCH 0 /* Explicit match of a rule */
-#define PFRES_BADOFF 1 /* Bad offset for pull_hdr */
-#define PFRES_FRAG 2 /* Dropping following fragment */
-#define PFRES_SHORT 3 /* Dropping short packet */
-#define PFRES_NORM 4 /* Dropping by normalizer */
-#define PFRES_MEMORY 5 /* Dropped due to lacking mem */
-#define PFRES_TS 6 /* Bad TCP Timestamp (RFC1323) */
-#define PFRES_CONGEST 7 /* Congestion (of ipintrq) */
-#define PFRES_IPOPTIONS 8 /* IP option */
-#define PFRES_PROTCKSUM 9 /* Protocol checksum invalid */
-#define PFRES_BADSTATE 10 /* State mismatch */
-#define PFRES_STATEINS 11 /* State insertion failure */
-#define PFRES_MAXSTATES 12 /* State limit */
-#define PFRES_SRCLIMIT 13 /* Source node/conn limit */
-#define PFRES_SYNPROXY 14 /* SYN proxy */
-#define PFRES_MAX 15 /* total+1 */
-
-#define PFRES_NAMES { \
- "match", \
- "bad-offset", \
- "fragment", \
- "short", \
- "normalize", \
- "memory", \
- "bad-timestamp", \
- "congestion", \
- "ip-option", \
- "proto-cksum", \
- "state-mismatch", \
- "state-insert", \
- "state-limit", \
- "src-limit", \
- "synproxy", \
- NULL \
-}
-
-/* Counters for other things we want to keep track of */
-#define LCNT_STATES 0 /* states */
-#define LCNT_SRCSTATES 1 /* max-src-states */
-#define LCNT_SRCNODES 2 /* max-src-nodes */
-#define LCNT_SRCCONN 3 /* max-src-conn */
-#define LCNT_SRCCONNRATE 4 /* max-src-conn-rate */
-#define LCNT_OVERLOAD_TABLE 5 /* entry added to overload table */
-#define LCNT_OVERLOAD_FLUSH 6 /* state entries flushed */
-#define LCNT_MAX 7 /* total+1 */
-
-#define LCNT_NAMES { \
- "max states per rule", \
- "max-src-states", \
- "max-src-nodes", \
- "max-src-conn", \
- "max-src-conn-rate", \
- "overload table insertion", \
- "overload flush states", \
- NULL \
-}
-
-/* UDP state enumeration */
-#define PFUDPS_NO_TRAFFIC 0
-#define PFUDPS_SINGLE 1
-#define PFUDPS_MULTIPLE 2
-
-#define PFUDPS_NSTATES 3 /* number of state levels */
-
-#define PFUDPS_NAMES { \
- "NO_TRAFFIC", \
- "SINGLE", \
- "MULTIPLE", \
- NULL \
-}
-
-/* Other protocol state enumeration */
-#define PFOTHERS_NO_TRAFFIC 0
-#define PFOTHERS_SINGLE 1
-#define PFOTHERS_MULTIPLE 2
-
-#define PFOTHERS_NSTATES 3 /* number of state levels */
-
-#define PFOTHERS_NAMES { \
- "NO_TRAFFIC", \
- "SINGLE", \
- "MULTIPLE", \
- NULL \
-}
-
-#define FCNT_STATE_SEARCH 0
-#define FCNT_STATE_INSERT 1
-#define FCNT_STATE_REMOVALS 2
-#define FCNT_MAX 3
-
-#define SCNT_SRC_NODE_SEARCH 0
-#define SCNT_SRC_NODE_INSERT 1
-#define SCNT_SRC_NODE_REMOVALS 2
-#define SCNT_MAX 3
-
-#define ACTION_SET(a, x) \
- do { \
- if ((a) != NULL) \
- *(a) = (x); \
- } while (0)
-
-#ifdef __FreeBSD__
-#define REASON_SET(a, x) \
- do { \
- if ((a) != NULL) \
- *(a) = (x); \
- if (x < PFRES_MAX) \
- V_pf_status.counters[x]++; \
- } while (0)
-#else
-#define REASON_SET(a, x) \
- do { \
- if ((a) != NULL) \
- *(a) = (x); \
- if (x < PFRES_MAX) \
- pf_status.counters[x]++; \
- } while (0)
-#endif
-
-struct pf_status {
- u_int64_t counters[PFRES_MAX];
- u_int64_t lcounters[LCNT_MAX]; /* limit counters */
- u_int64_t fcounters[FCNT_MAX];
- u_int64_t scounters[SCNT_MAX];
- u_int64_t pcounters[2][2][3];
- u_int64_t bcounters[2][2];
- u_int64_t stateid;
- u_int32_t running;
- u_int32_t states;
- u_int32_t src_nodes;
- u_int32_t since;
- u_int32_t debug;
- u_int32_t hostid;
- char ifname[IFNAMSIZ];
- u_int8_t pf_chksum[PF_MD5_DIGEST_LENGTH];
-};
-
-struct cbq_opts {
- u_int minburst;
- u_int maxburst;
- u_int pktsize;
- u_int maxpktsize;
- u_int ns_per_byte;
- u_int maxidle;
- int minidle;
- u_int offtime;
- int flags;
-};
-
-struct priq_opts {
- int flags;
-};
-
-struct hfsc_opts {
- /* real-time service curve */
- u_int rtsc_m1; /* slope of the 1st segment in bps */
- u_int rtsc_d; /* the x-projection of m1 in msec */
- u_int rtsc_m2; /* slope of the 2nd segment in bps */
- /* link-sharing service curve */
- u_int lssc_m1;
- u_int lssc_d;
- u_int lssc_m2;
- /* upper-limit service curve */
- u_int ulsc_m1;
- u_int ulsc_d;
- u_int ulsc_m2;
- int flags;
-};
-
-struct pf_altq {
- char ifname[IFNAMSIZ];
-
- void *altq_disc; /* discipline-specific state */
- TAILQ_ENTRY(pf_altq) entries;
-
- /* scheduler spec */
- u_int8_t scheduler; /* scheduler type */
- u_int16_t tbrsize; /* tokenbucket regulator size */
- u_int32_t ifbandwidth; /* interface bandwidth */
-
- /* queue spec */
- char qname[PF_QNAME_SIZE]; /* queue name */
- char parent[PF_QNAME_SIZE]; /* parent name */
- u_int32_t parent_qid; /* parent queue id */
- u_int32_t bandwidth; /* queue bandwidth */
- u_int8_t priority; /* priority */
-#ifdef __FreeBSD__
- u_int8_t local_flags; /* dynamic interface */
-#define PFALTQ_FLAG_IF_REMOVED 0x01
-#endif
- u_int16_t qlimit; /* queue size limit */
- u_int16_t flags; /* misc flags */
- union {
- struct cbq_opts cbq_opts;
- struct priq_opts priq_opts;
- struct hfsc_opts hfsc_opts;
- } pq_u;
-
- u_int32_t qid; /* return value */
-};
-
-struct pf_tagname {
- TAILQ_ENTRY(pf_tagname) entries;
- char name[PF_TAG_NAME_SIZE];
- u_int16_t tag;
- int ref;
-};
-
-struct pf_divert {
- union {
- struct in_addr ipv4;
- struct in6_addr ipv6;
- } addr;
- u_int16_t port;
-};
-
-#define PFFRAG_FRENT_HIWAT 5000 /* Number of fragment entries */
-#define PFFRAG_FRAG_HIWAT 1000 /* Number of fragmented packets */
-#define PFFRAG_FRCENT_HIWAT 50000 /* Number of fragment cache entries */
-#define PFFRAG_FRCACHE_HIWAT 10000 /* Number of fragment descriptors */
-
-#define PFR_KTABLE_HIWAT 1000 /* Number of tables */
-#define PFR_KENTRY_HIWAT 200000 /* Number of table entries */
-#define PFR_KENTRY_HIWAT_SMALL 100000 /* Number of table entries (tiny hosts) */
-
-/*
- * ioctl parameter structures
- */
-
-struct pfioc_pooladdr {
- u_int32_t action;
- u_int32_t ticket;
- u_int32_t nr;
- u_int32_t r_num;
- u_int8_t r_action;
- u_int8_t r_last;
- u_int8_t af;
- char anchor[MAXPATHLEN];
- struct pf_pooladdr addr;
-};
-
-struct pfioc_rule {
- u_int32_t action;
- u_int32_t ticket;
- u_int32_t pool_ticket;
- u_int32_t nr;
- char anchor[MAXPATHLEN];
- char anchor_call[MAXPATHLEN];
- struct pf_rule rule;
-};
-
-struct pfioc_natlook {
- struct pf_addr saddr;
- struct pf_addr daddr;
- struct pf_addr rsaddr;
- struct pf_addr rdaddr;
- u_int16_t sport;
- u_int16_t dport;
- u_int16_t rsport;
- u_int16_t rdport;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t direction;
-};
-
-struct pfioc_state {
- struct pfsync_state state;
-};
-
-struct pfioc_src_node_kill {
- sa_family_t psnk_af;
- struct pf_rule_addr psnk_src;
- struct pf_rule_addr psnk_dst;
- u_int psnk_killed;
-};
-
-struct pfioc_state_kill {
- struct pf_state_cmp psk_pfcmp;
- sa_family_t psk_af;
- int psk_proto;
- struct pf_rule_addr psk_src;
- struct pf_rule_addr psk_dst;
- char psk_ifname[IFNAMSIZ];
- char psk_label[PF_RULE_LABEL_SIZE];
- u_int psk_killed;
-};
-
-struct pfioc_states {
- int ps_len;
- union {
- caddr_t psu_buf;
- struct pfsync_state *psu_states;
- } ps_u;
-#define ps_buf ps_u.psu_buf
-#define ps_states ps_u.psu_states
-};
-
-struct pfioc_src_nodes {
- int psn_len;
- union {
- caddr_t psu_buf;
- struct pf_src_node *psu_src_nodes;
- } psn_u;
-#define psn_buf psn_u.psu_buf
-#define psn_src_nodes psn_u.psu_src_nodes
-};
-
-struct pfioc_if {
- char ifname[IFNAMSIZ];
-};
-
-struct pfioc_tm {
- int timeout;
- int seconds;
-};
-
-struct pfioc_limit {
- int index;
- unsigned limit;
-};
-
-struct pfioc_altq {
- u_int32_t action;
- u_int32_t ticket;
- u_int32_t nr;
- struct pf_altq altq;
-};
-
-struct pfioc_qstats {
- u_int32_t ticket;
- u_int32_t nr;
- void *buf;
- int nbytes;
- u_int8_t scheduler;
-};
-
-struct pfioc_ruleset {
- u_int32_t nr;
- char path[MAXPATHLEN];
- char name[PF_ANCHOR_NAME_SIZE];
-};
-
-#define PF_RULESET_ALTQ (PF_RULESET_MAX)
-#define PF_RULESET_TABLE (PF_RULESET_MAX+1)
-struct pfioc_trans {
- int size; /* number of elements */
- int esize; /* size of each element in bytes */
- struct pfioc_trans_e {
- int rs_num;
- char anchor[MAXPATHLEN];
- u_int32_t ticket;
- } *array;
-};
-
-#define PFR_FLAG_ATOMIC 0x00000001
-#define PFR_FLAG_DUMMY 0x00000002
-#define PFR_FLAG_FEEDBACK 0x00000004
-#define PFR_FLAG_CLSTATS 0x00000008
-#define PFR_FLAG_ADDRSTOO 0x00000010
-#define PFR_FLAG_REPLACE 0x00000020
-#define PFR_FLAG_ALLRSETS 0x00000040
-#define PFR_FLAG_ALLMASK 0x0000007F
-#ifdef _KERNEL
-#define PFR_FLAG_USERIOCTL 0x10000000
-#endif
-
-struct pfioc_table {
- struct pfr_table pfrio_table;
- void *pfrio_buffer;
- int pfrio_esize;
- int pfrio_size;
- int pfrio_size2;
- int pfrio_nadd;
- int pfrio_ndel;
- int pfrio_nchange;
- int pfrio_flags;
- u_int32_t pfrio_ticket;
-};
-#define pfrio_exists pfrio_nadd
-#define pfrio_nzero pfrio_nadd
-#define pfrio_nmatch pfrio_nadd
-#define pfrio_naddr pfrio_size2
-#define pfrio_setflag pfrio_size2
-#define pfrio_clrflag pfrio_nadd
-
-struct pfioc_iface {
- char pfiio_name[IFNAMSIZ];
- void *pfiio_buffer;
- int pfiio_esize;
- int pfiio_size;
- int pfiio_nzero;
- int pfiio_flags;
-};
-
-
-/*
- * ioctl operations
- */
-
-#define DIOCSTART _IO ('D', 1)
-#define DIOCSTOP _IO ('D', 2)
-#define DIOCADDRULE _IOWR('D', 4, struct pfioc_rule)
-#define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule)
-#define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule)
-/* XXX cut 8 - 17 */
-#define DIOCCLRSTATES _IOWR('D', 18, struct pfioc_state_kill)
-#define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state)
-#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
-#define DIOCGETSTATUS _IOWR('D', 21, struct pf_status)
-#define DIOCCLRSTATUS _IO ('D', 22)
-#define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook)
-#define DIOCSETDEBUG _IOWR('D', 24, u_int32_t)
-#define DIOCGETSTATES _IOWR('D', 25, struct pfioc_states)
-#define DIOCCHANGERULE _IOWR('D', 26, struct pfioc_rule)
-/* XXX cut 26 - 28 */
-#define DIOCSETTIMEOUT _IOWR('D', 29, struct pfioc_tm)
-#define DIOCGETTIMEOUT _IOWR('D', 30, struct pfioc_tm)
-#define DIOCADDSTATE _IOWR('D', 37, struct pfioc_state)
-#define DIOCCLRRULECTRS _IO ('D', 38)
-#define DIOCGETLIMIT _IOWR('D', 39, struct pfioc_limit)
-#define DIOCSETLIMIT _IOWR('D', 40, struct pfioc_limit)
-#define DIOCKILLSTATES _IOWR('D', 41, struct pfioc_state_kill)
-#define DIOCSTARTALTQ _IO ('D', 42)
-#define DIOCSTOPALTQ _IO ('D', 43)
-#define DIOCADDALTQ _IOWR('D', 45, struct pfioc_altq)
-#define DIOCGETALTQS _IOWR('D', 47, struct pfioc_altq)
-#define DIOCGETALTQ _IOWR('D', 48, struct pfioc_altq)
-#define DIOCCHANGEALTQ _IOWR('D', 49, struct pfioc_altq)
-#define DIOCGETQSTATS _IOWR('D', 50, struct pfioc_qstats)
-#define DIOCBEGINADDRS _IOWR('D', 51, struct pfioc_pooladdr)
-#define DIOCADDADDR _IOWR('D', 52, struct pfioc_pooladdr)
-#define DIOCGETADDRS _IOWR('D', 53, struct pfioc_pooladdr)
-#define DIOCGETADDR _IOWR('D', 54, struct pfioc_pooladdr)
-#define DIOCCHANGEADDR _IOWR('D', 55, struct pfioc_pooladdr)
-/* XXX cut 55 - 57 */
-#define DIOCGETRULESETS _IOWR('D', 58, struct pfioc_ruleset)
-#define DIOCGETRULESET _IOWR('D', 59, struct pfioc_ruleset)
-#define DIOCRCLRTABLES _IOWR('D', 60, struct pfioc_table)
-#define DIOCRADDTABLES _IOWR('D', 61, struct pfioc_table)
-#define DIOCRDELTABLES _IOWR('D', 62, struct pfioc_table)
-#define DIOCRGETTABLES _IOWR('D', 63, struct pfioc_table)
-#define DIOCRGETTSTATS _IOWR('D', 64, struct pfioc_table)
-#define DIOCRCLRTSTATS _IOWR('D', 65, struct pfioc_table)
-#define DIOCRCLRADDRS _IOWR('D', 66, struct pfioc_table)
-#define DIOCRADDADDRS _IOWR('D', 67, struct pfioc_table)
-#define DIOCRDELADDRS _IOWR('D', 68, struct pfioc_table)
-#define DIOCRSETADDRS _IOWR('D', 69, struct pfioc_table)
-#define DIOCRGETADDRS _IOWR('D', 70, struct pfioc_table)
-#define DIOCRGETASTATS _IOWR('D', 71, struct pfioc_table)
-#define DIOCRCLRASTATS _IOWR('D', 72, struct pfioc_table)
-#define DIOCRTSTADDRS _IOWR('D', 73, struct pfioc_table)
-#define DIOCRSETTFLAGS _IOWR('D', 74, struct pfioc_table)
-#define DIOCRINADEFINE _IOWR('D', 77, struct pfioc_table)
-#define DIOCOSFPFLUSH _IO('D', 78)
-#define DIOCOSFPADD _IOWR('D', 79, struct pf_osfp_ioctl)
-#define DIOCOSFPGET _IOWR('D', 80, struct pf_osfp_ioctl)
-#define DIOCXBEGIN _IOWR('D', 81, struct pfioc_trans)
-#define DIOCXCOMMIT _IOWR('D', 82, struct pfioc_trans)
-#define DIOCXROLLBACK _IOWR('D', 83, struct pfioc_trans)
-#define DIOCGETSRCNODES _IOWR('D', 84, struct pfioc_src_nodes)
-#define DIOCCLRSRCNODES _IO('D', 85)
-#define DIOCSETHOSTID _IOWR('D', 86, u_int32_t)
-#define DIOCIGETIFACES _IOWR('D', 87, struct pfioc_iface)
-#define DIOCSETIFFLAG _IOWR('D', 89, struct pfioc_iface)
-#define DIOCCLRIFFLAG _IOWR('D', 90, struct pfioc_iface)
-#define DIOCKILLSRCNODES _IOWR('D', 91, struct pfioc_src_node_kill)
-#ifdef __FreeBSD__
-struct pf_ifspeed {
- char ifname[IFNAMSIZ];
- u_int32_t baudrate;
-};
-#define DIOCGIFSPEED _IOWR('D', 92, struct pf_ifspeed)
-#endif
-
-#ifdef _KERNEL
-RB_HEAD(pf_src_tree, pf_src_node);
-RB_PROTOTYPE(pf_src_tree, pf_src_node, entry, pf_src_compare);
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pf_src_tree, tree_src_tracking);
-#define V_tree_src_tracking VNET(tree_src_tracking)
-#else
-extern struct pf_src_tree tree_src_tracking;
-#endif
-
-RB_HEAD(pf_state_tree_id, pf_state);
-RB_PROTOTYPE(pf_state_tree_id, pf_state,
- entry_id, pf_state_compare_id);
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pf_state_tree_id, tree_id);
-#define V_tree_id VNET(tree_id)
-VNET_DECLARE(struct pf_state_queue, state_list);
-#define V_state_list VNET(state_list)
-#else
-extern struct pf_state_tree_id tree_id;
-extern struct pf_state_queue state_list;
-#endif
-
-TAILQ_HEAD(pf_poolqueue, pf_pool);
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pf_poolqueue, pf_pools[2]);
-#define V_pf_pools VNET(pf_pools)
-#else
-extern struct pf_poolqueue pf_pools[2];
-#endif
-TAILQ_HEAD(pf_altqqueue, pf_altq);
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pf_altqqueue, pf_altqs[2]);
-#define V_pf_altqs VNET(pf_altqs)
-VNET_DECLARE(struct pf_palist, pf_pabuf);
-#define V_pf_pabuf VNET(pf_pabuf)
-#else
-extern struct pf_altqqueue pf_altqs[2];
-extern struct pf_palist pf_pabuf;
-#endif
-
-#ifdef __FreeBSD__
-VNET_DECLARE(u_int32_t, ticket_altqs_active);
-#define V_ticket_altqs_active VNET(ticket_altqs_active)
-VNET_DECLARE(u_int32_t, ticket_altqs_inactive);
-#define V_ticket_altqs_inactive VNET(ticket_altqs_inactive)
-VNET_DECLARE(int, altqs_inactive_open);
-#define V_altqs_inactive_open VNET(altqs_inactive_open)
-VNET_DECLARE(u_int32_t, ticket_pabuf);
-#define V_ticket_pabuf VNET(ticket_pabuf)
-VNET_DECLARE(struct pf_altqqueue *, pf_altqs_active);
-#define V_pf_altqs_active VNET(pf_altqs_active)
-VNET_DECLARE(struct pf_altqqueue *, pf_altqs_inactive);
-#define V_pf_altqs_inactive VNET(pf_altqs_inactive)
-VNET_DECLARE(struct pf_poolqueue *, pf_pools_active);
-#define V_pf_pools_active VNET(pf_pools_active)
-VNET_DECLARE(struct pf_poolqueue *, pf_pools_inactive);
-#define V_pf_pools_inactive VNET(pf_pools_inactive)
-#else
-extern u_int32_t ticket_altqs_active;
-extern u_int32_t ticket_altqs_inactive;
-extern int altqs_inactive_open;
-extern u_int32_t ticket_pabuf;
-extern struct pf_altqqueue *pf_altqs_active;
-extern struct pf_altqqueue *pf_altqs_inactive;
-extern struct pf_poolqueue *pf_pools_active;
-extern struct pf_poolqueue *pf_pools_inactive;
-#endif
-extern int pf_tbladdr_setup(struct pf_ruleset *,
- struct pf_addr_wrap *);
-extern void pf_tbladdr_remove(struct pf_addr_wrap *);
-extern void pf_tbladdr_copyout(struct pf_addr_wrap *);
-extern void pf_calc_skip_steps(struct pf_rulequeue *);
-#ifdef __FreeBSD__
-#ifdef ALTQ
-extern void pf_altq_ifnet_event(struct ifnet *, int);
-#endif
-VNET_DECLARE(uma_zone_t, pf_src_tree_pl);
-#define V_pf_src_tree_pl VNET(pf_src_tree_pl)
-VNET_DECLARE(uma_zone_t, pf_rule_pl);
-#define V_pf_rule_pl VNET(pf_rule_pl)
-VNET_DECLARE(uma_zone_t, pf_state_pl);
-#define V_pf_state_pl VNET(pf_state_pl)
-VNET_DECLARE(uma_zone_t, pf_state_key_pl);
-#define V_pf_state_key_pl VNET(pf_state_key_pl)
-VNET_DECLARE(uma_zone_t, pf_state_item_pl);
-#define V_pf_state_item_pl VNET(pf_state_item_pl)
-VNET_DECLARE(uma_zone_t, pf_altq_pl);
-#define V_pf_altq_pl VNET(pf_altq_pl)
-VNET_DECLARE(uma_zone_t, pf_pooladdr_pl);
-#define V_pf_pooladdr_pl VNET(pf_pooladdr_pl)
-VNET_DECLARE(uma_zone_t, pfr_ktable_pl);
-#define V_pfr_ktable_pl VNET(pfr_ktable_pl)
-VNET_DECLARE(uma_zone_t, pfr_kentry_pl);
-#define V_pfr_kentry_pl VNET(pfr_kentry_pl)
-VNET_DECLARE(uma_zone_t, pfr_kcounters_pl);
-#define V_pfr_kcounters_pl VNET(pfr_kcounters_pl)
-VNET_DECLARE(uma_zone_t, pf_cache_pl);
-#define V_pf_cache_pl VNET(pf_cache_pl)
-VNET_DECLARE(uma_zone_t, pf_cent_pl);
-#define V_pf_cent_pl VNET(pf_cent_pl)
-VNET_DECLARE(uma_zone_t, pf_state_scrub_pl);
-#define V_pf_state_scrub_pl VNET(pf_state_scrub_pl)
-VNET_DECLARE(uma_zone_t, pfi_addr_pl);
-#define V_pfi_addr_pl VNET(pfi_addr_pl)
-#else
-extern struct pool pf_src_tree_pl, pf_rule_pl;
-extern struct pool pf_state_pl, pf_state_key_pl, pf_state_item_pl,
- pf_altq_pl, pf_pooladdr_pl;
-extern struct pool pf_state_scrub_pl;
-#endif
-extern void pf_purge_thread(void *);
-#ifdef __FreeBSD__
-extern int pf_purge_expired_src_nodes(int);
-extern int pf_purge_expired_states(u_int32_t , int);
-#else
-extern void pf_purge_expired_src_nodes(int);
-extern void pf_purge_expired_states(u_int32_t);
-#endif
-extern void pf_unlink_state(struct pf_state *);
-extern void pf_free_state(struct pf_state *);
-extern int pf_state_insert(struct pfi_kif *,
- struct pf_state_key *,
- struct pf_state_key *,
- struct pf_state *);
-extern int pf_insert_src_node(struct pf_src_node **,
- struct pf_rule *, struct pf_addr *,
- sa_family_t);
-void pf_src_tree_remove_state(struct pf_state *);
-extern struct pf_state *pf_find_state_byid(struct pf_state_cmp *);
-extern struct pf_state *pf_find_state_all(struct pf_state_key_cmp *,
- u_int, int *);
-extern void pf_print_state(struct pf_state *);
-extern void pf_print_flags(u_int8_t);
-extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,
- u_int8_t);
-
-#ifdef __FreeBSD__
-VNET_DECLARE(struct ifnet *, sync_ifp);
-#define V_sync_ifp VNET(sync_ifp);
-VNET_DECLARE(struct pf_rule, pf_default_rule);
-#define V_pf_default_rule VNET(pf_default_rule)
-#else
-extern struct ifnet *sync_ifp;
-extern struct pf_rule pf_default_rule;
-#endif
-extern void pf_addrcpy(struct pf_addr *, struct pf_addr *,
- u_int8_t);
-void pf_rm_rule(struct pf_rulequeue *,
- struct pf_rule *);
-#ifndef __FreeBSD__
-struct pf_divert *pf_find_divert(struct mbuf *);
-#endif
-
-#ifdef INET
-#ifdef __FreeBSD__
-int pf_test(int, struct ifnet *, struct mbuf **, struct ether_header *,
- struct inpcb *);
-#else
-int pf_test(int, struct ifnet *, struct mbuf **, struct ether_header *);
-#endif
-#endif /* INET */
-
-#ifdef INET6
-#ifdef __FreeBSD__
-int pf_test6(int, struct ifnet *, struct mbuf **, struct ether_header *,
- struct inpcb *);
-#else
-int pf_test6(int, struct ifnet *, struct mbuf **, struct ether_header *);
-#endif
-void pf_poolmask(struct pf_addr *, struct pf_addr*,
- struct pf_addr *, struct pf_addr *, u_int8_t);
-void pf_addr_inc(struct pf_addr *, sa_family_t);
-#endif /* INET6 */
-
-#ifdef __FreeBSD__
-u_int32_t pf_new_isn(struct pf_state *);
-#endif
-void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *,
- sa_family_t);
-void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
-int pflog_packet(struct pfi_kif *, struct mbuf *, sa_family_t, u_int8_t,
- u_int8_t, struct pf_rule *, struct pf_rule *, struct pf_ruleset *,
- struct pf_pdesc *);
-void pf_send_deferred_syn(struct pf_state *);
-int pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t);
-int pf_match_addr_range(struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t);
-int pf_match(u_int8_t, u_int32_t, u_int32_t, u_int32_t);
-int pf_match_port(u_int8_t, u_int16_t, u_int16_t, u_int16_t);
-int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t);
-int pf_match_gid(u_int8_t, gid_t, gid_t, gid_t);
-
-void pf_normalize_init(void);
-int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *,
- struct pf_pdesc *);
-int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *,
- struct pf_pdesc *);
-int pf_normalize_tcp(int, struct pfi_kif *, struct mbuf *, int, int, void *,
- struct pf_pdesc *);
-void pf_normalize_tcp_cleanup(struct pf_state *);
-int pf_normalize_tcp_init(struct mbuf *, int, struct pf_pdesc *,
- struct tcphdr *, struct pf_state_peer *, struct pf_state_peer *);
-int pf_normalize_tcp_stateful(struct mbuf *, int, struct pf_pdesc *,
- u_short *, struct tcphdr *, struct pf_state *,
- struct pf_state_peer *, struct pf_state_peer *, int *);
-u_int32_t
- pf_state_expires(const struct pf_state *);
-void pf_purge_expired_fragments(void);
-int pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *,
- int);
-int pf_rtlabel_match(struct pf_addr *, sa_family_t, struct pf_addr_wrap *,
- int);
-#ifdef __FreeBSD__
-int pf_socket_lookup(int, struct pf_pdesc *, struct inpcb *);
-#else
-int pf_socket_lookup(int, struct pf_pdesc *);
-#endif
-struct pf_state_key *pf_alloc_state_key(int);
-void pf_pkt_addr_changed(struct mbuf *);
-int pf_state_key_attach(struct pf_state_key *, struct pf_state *, int);
-void pfr_initialize(void);
-int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
-void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
- u_int64_t, int, int, int);
-int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *,
- struct pf_addr **, struct pf_addr **, sa_family_t);
-void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
-struct pfr_ktable *
- pfr_attach_table(struct pf_ruleset *, char *, int);
-void pfr_detach_table(struct pfr_ktable *);
-int pfr_clr_tables(struct pfr_table *, int *, int);
-int pfr_add_tables(struct pfr_table *, int, int *, int);
-int pfr_del_tables(struct pfr_table *, int, int *, int);
-int pfr_get_tables(struct pfr_table *, struct pfr_table *, int *, int);
-int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int);
-int pfr_clr_tstats(struct pfr_table *, int, int *, int);
-int pfr_set_tflags(struct pfr_table *, int, int, int, int *, int *, int);
-int pfr_clr_addrs(struct pfr_table *, int *, int);
-int pfr_insert_kentry(struct pfr_ktable *, struct pfr_addr *, long);
-int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
- int);
-int pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
- int);
-int pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
- int *, int *, int *, int, u_int32_t);
-int pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
-int pfr_get_astats(struct pfr_table *, struct pfr_astats *, int *, int);
-int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *,
- int);
-int pfr_tst_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
- int);
-int pfr_ina_begin(struct pfr_table *, u_int32_t *, int *, int);
-int pfr_ina_rollback(struct pfr_table *, u_int32_t, int *, int);
-int pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
-int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
- int *, u_int32_t, int);
-
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pfi_kif *, pfi_all);
-#define V_pfi_all VNET(pfi_all)
-#else
-extern struct pfi_kif *pfi_all;
-#endif
-
-void pfi_initialize(void);
-#ifdef __FreeBSD__
-void pfi_cleanup(void);
-#endif
-struct pfi_kif *pfi_kif_get(const char *);
-void pfi_kif_ref(struct pfi_kif *, enum pfi_kif_refs);
-void pfi_kif_unref(struct pfi_kif *, enum pfi_kif_refs);
-int pfi_kif_match(struct pfi_kif *, struct pfi_kif *);
-void pfi_attach_ifnet(struct ifnet *);
-void pfi_detach_ifnet(struct ifnet *);
-void pfi_attach_ifgroup(struct ifg_group *);
-void pfi_detach_ifgroup(struct ifg_group *);
-void pfi_group_change(const char *);
-int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *,
- sa_family_t);
-int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t);
-void pfi_dynaddr_remove(struct pf_addr_wrap *);
-void pfi_dynaddr_copyout(struct pf_addr_wrap *);
-void pfi_update_status(const char *, struct pf_status *);
-int pfi_get_ifaces(const char *, struct pfi_kif *, int *);
-int pfi_set_flags(const char *, int);
-int pfi_clear_flags(const char *, int);
-
-#ifdef __FreeBSD__
-int pf_match_tag(struct mbuf *, struct pf_rule *, int *,
- struct pf_mtag *);
-#else
-int pf_match_tag(struct mbuf *, struct pf_rule *, int *);
-#endif
-u_int16_t pf_tagname2tag(char *);
-void pf_tag2tagname(u_int16_t, char *);
-void pf_tag_ref(u_int16_t);
-void pf_tag_unref(u_int16_t);
-#ifdef __FreeBSD__
-int pf_tag_packet(struct mbuf *, int, int, struct pf_mtag *);
-#else
-int pf_tag_packet(struct mbuf *, int, int);
-#endif
-u_int32_t pf_qname2qid(char *);
-void pf_qid2qname(u_int32_t, char *);
-void pf_qid_unref(u_int32_t);
-
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pf_status, pf_status);
-#define V_pf_status VNET(pf_status)
-#else
-extern struct pf_status pf_status;
-#endif
-
-#ifdef __FreeBSD__
-VNET_DECLARE(uma_zone_t, pf_frent_pl);
-#define V_pf_frent_pl VNET(pf_frent_pl)
-VNET_DECLARE(uma_zone_t, pf_frag_pl);
-#define V_pf_frag_pl VNET(pf_frag_pl)
-VNET_DECLARE(struct sx, pf_consistency_lock);
-#define V_pf_consistency_lock VNET(pf_consistency_lock)
-#else
-extern struct pool pf_frent_pl, pf_frag_pl;
-extern struct rwlock pf_consistency_lock;
-#endif
-
-struct pf_pool_limit {
- void *pp;
- unsigned limit;
-};
-#ifdef __FreeBSD__
-VNET_DECLARE(struct pf_pool_limit, pf_pool_limits[PF_LIMIT_MAX]);
-#define V_pf_pool_limits VNET(pf_pool_limits)
-#else
-extern struct pf_pool_limit pf_pool_limits[PF_LIMIT_MAX];
-#endif
-
-#ifdef __FreeBSD__
-struct pf_frent {
- LIST_ENTRY(pf_frent) fr_next;
- struct ip *fr_ip;
- struct mbuf *fr_m;
-};
-
-struct pf_frcache {
- LIST_ENTRY(pf_frcache) fr_next;
- uint16_t fr_off;
- uint16_t fr_end;
-};
-
-struct pf_fragment {
- RB_ENTRY(pf_fragment) fr_entry;
- TAILQ_ENTRY(pf_fragment) frag_next;
- struct in_addr fr_src;
- struct in_addr fr_dst;
- u_int8_t fr_p; /* protocol of this fragment */
- u_int8_t fr_flags; /* status flags */
- u_int16_t fr_id; /* fragment id for reassemble */
- u_int16_t fr_max; /* fragment data max */
- u_int32_t fr_timeout;
-#define fr_queue fr_u.fru_queue
-#define fr_cache fr_u.fru_cache
- union {
- LIST_HEAD(pf_fragq, pf_frent) fru_queue; /* buffering */
- LIST_HEAD(pf_cacheq, pf_frcache) fru_cache; /* non-buf */
- } fr_u;
-};
-#endif /* (__FreeBSD__) */
-
-#endif /* _KERNEL */
-
-#ifdef __FreeBSD__
-#ifdef _KERNEL
-VNET_DECLARE(struct pf_anchor_global, pf_anchors);
-#define V_pf_anchors VNET(pf_anchors)
-VNET_DECLARE(struct pf_anchor, pf_main_anchor);
-#define V_pf_main_anchor VNET(pf_main_anchor)
-#define pf_main_ruleset V_pf_main_anchor.ruleset
-#endif
-#else
-extern struct pf_anchor_global pf_anchors;
-extern struct pf_anchor pf_main_anchor;
-#define pf_main_ruleset pf_main_anchor.ruleset
-#endif
-
-/* these ruleset functions can be linked into userland programs (pfctl) */
-int pf_get_ruleset_number(u_int8_t);
-void pf_init_ruleset(struct pf_ruleset *);
-int pf_anchor_setup(struct pf_rule *,
- const struct pf_ruleset *, const char *);
-int pf_anchor_copyout(const struct pf_ruleset *,
- const struct pf_rule *, struct pfioc_rule *);
-void pf_anchor_remove(struct pf_rule *);
-void pf_remove_if_empty_ruleset(struct pf_ruleset *);
-struct pf_anchor *pf_find_anchor(const char *);
-struct pf_ruleset *pf_find_ruleset(const char *);
-struct pf_ruleset *pf_find_or_create_ruleset(const char *);
-void pf_rs_initialize(void);
-
-#ifndef __FreeBSD__
-#ifdef _KERNEL
-int pf_anchor_copyout(const struct pf_ruleset *,
- const struct pf_rule *, struct pfioc_rule *);
-void pf_anchor_remove(struct pf_rule *);
-
-#endif /* _KERNEL */
-#endif
-
-/* The fingerprint functions can be linked into userland programs (tcpdump) */
-int pf_osfp_add(struct pf_osfp_ioctl *);
-#ifdef _KERNEL
-struct pf_osfp_enlist *
- pf_osfp_fingerprint(struct pf_pdesc *, struct mbuf *, int,
- const struct tcphdr *);
-#endif /* _KERNEL */
-struct pf_osfp_enlist *
- pf_osfp_fingerprint_hdr(const struct ip *, const struct ip6_hdr *,
- const struct tcphdr *);
-void pf_osfp_flush(void);
-int pf_osfp_get(struct pf_osfp_ioctl *);
-#ifdef __FreeBSD__
-int pf_osfp_initialize(void);
-void pf_osfp_cleanup(void);
-#else
-void pf_osfp_initialize(void);
-#endif
-int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t);
-struct pf_os_fingerprint *
- pf_osfp_validate(void);
-
-#ifdef _KERNEL
-void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
-
-void pf_step_into_anchor(int *, struct pf_ruleset **, int,
- struct pf_rule **, struct pf_rule **, int *);
-int pf_step_out_of_anchor(int *, struct pf_ruleset **,
- int, struct pf_rule **, struct pf_rule **,
- int *);
-
-int pf_map_addr(u_int8_t, struct pf_rule *,
- struct pf_addr *, struct pf_addr *,
- struct pf_addr *, struct pf_src_node **);
-struct pf_rule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
- int, int, struct pfi_kif *, struct pf_src_node **,
- struct pf_state_key **, struct pf_state_key **,
- struct pf_state_key **, struct pf_state_key **,
- struct pf_addr *, struct pf_addr *,
- u_int16_t, u_int16_t);
-
-int pf_state_key_setup(struct pf_pdesc *, struct pf_rule *,
- struct pf_state_key **, struct pf_state_key **,
- struct pf_state_key **, struct pf_state_key **,
- struct pf_addr *, struct pf_addr *,
- u_int16_t, u_int16_t);
-#endif /* _KERNEL */
-
-
-#endif /* _NET_PFVAR_H_ */
diff --git a/sys/contrib/pf/netinet/in4_cksum.c b/sys/contrib/pf/netinet/in4_cksum.c
deleted file mode 100644
index bf25baf..0000000
--- a/sys/contrib/pf/netinet/in4_cksum.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* $FreeBSD$ */
-/* $OpenBSD: in4_cksum.c,v 1.7 2003/06/02 23:28:13 millert Exp $ */
-/* $KAME: in4_cksum.c,v 1.10 2001/11/30 10:06:15 itojun Exp $ */
-/* $NetBSD: in_cksum.c,v 1.13 1996/10/13 02:03:03 christos Exp $ */
-
-/*
- * Copyright (C) 1999 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. 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.
- */
-
-/*
- * Copyright (c) 1988, 1992, 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. 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.
- *
- * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-
-#include <machine/in_cksum.h>
-
-#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
-#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; (void)ADDCARRY(sum);}
-
-int in4_cksum(struct mbuf *, u_int8_t, int, int);
-
-int
-in4_cksum(struct mbuf *m, u_int8_t nxt, int off, int len)
-{
- union {
- struct ipovly ipov;
- u_int16_t w[10];
- } u;
- union {
- u_int16_t s[2];
- u_int32_t l;
- } l_util;
-
- u_int16_t *w;
- int psum;
- int sum = 0;
-
- if (nxt != 0) {
- /* pseudo header */
- if (off < sizeof(struct ipovly))
- panic("in4_cksum: offset too short");
- if (m->m_len < sizeof(struct ip))
- panic("in4_cksum: bad mbuf chain");
- bzero(&u.ipov, sizeof(u.ipov));
- u.ipov.ih_len = htons(len);
- u.ipov.ih_pr = nxt;
- u.ipov.ih_src = mtod(m, struct ip *)->ip_src;
- u.ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
- w = u.w;
- /* assumes sizeof(ipov) == 20 */
- sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3]; sum += w[4];
- sum += w[5]; sum += w[6]; sum += w[7]; sum += w[8]; sum += w[9];
- }
-
- psum = in_cksum_skip(m, len + off, off);
- psum = ~psum & 0xffff;
- sum += psum;
- REDUCE;
- return (~sum & 0xffff);
-}
diff --git a/sys/netinet/ipfw/dn_heap.c b/sys/netinet/ipfw/dn_heap.c
deleted file mode 100644
index 3bdfd9d..0000000
--- a/sys/netinet/ipfw/dn_heap.c
+++ /dev/null
@@ -1,552 +0,0 @@
-/*-
- * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * Binary heap and hash tables, used in dummynet
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#ifdef _KERNEL
-__FBSDID("$FreeBSD$");
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <netinet/ipfw/dn_heap.h>
-#ifndef log
-#define log(x, arg...)
-#endif
-
-#else /* !_KERNEL */
-
-#include <stdio.h>
-#include <dn_test.h>
-#include <strings.h>
-#include <stdlib.h>
-
-#include "dn_heap.h"
-#define log(x, arg...) fprintf(stderr, ## arg)
-#define panic(x...) fprintf(stderr, ## x), exit(1)
-#define MALLOC_DEFINE(a, b, c)
-static void *my_malloc(int s) { return malloc(s); }
-static void my_free(void *p) { free(p); }
-#define malloc(s, t, w) my_malloc(s)
-#define free(p, t) my_free(p)
-#endif /* !_KERNEL */
-
-static MALLOC_DEFINE(M_DN_HEAP, "dummynet", "dummynet heap");
-
-/*
- * Heap management functions.
- *
- * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
- * Some macros help finding parent/children so we can optimize them.
- *
- * heap_init() is called to expand the heap when needed.
- * Increment size in blocks of 16 entries.
- * Returns 1 on error, 0 on success
- */
-#define HEAP_FATHER(x) ( ( (x) - 1 ) / 2 )
-#define HEAP_LEFT(x) ( (x)+(x) + 1 )
-#define HEAP_SWAP(a, b, buffer) { buffer = a ; a = b ; b = buffer ; }
-#define HEAP_INCREMENT 15
-
-static int
-heap_resize(struct dn_heap *h, unsigned int new_size)
-{
- struct dn_heap_entry *p;
-
- if (h->size >= new_size ) /* have enough room */
- return 0;
-#if 1 /* round to the next power of 2 */
- new_size |= new_size >> 1;
- new_size |= new_size >> 2;
- new_size |= new_size >> 4;
- new_size |= new_size >> 8;
- new_size |= new_size >> 16;
-#else
- new_size = (new_size + HEAP_INCREMENT ) & ~HEAP_INCREMENT;
-#endif
- p = malloc(new_size * sizeof(*p), M_DN_HEAP, M_NOWAIT);
- if (p == NULL) {
- printf("--- %s, resize %d failed\n", __func__, new_size );
- return 1; /* error */
- }
- if (h->size > 0) {
- bcopy(h->p, p, h->size * sizeof(*p) );
- free(h->p, M_DN_HEAP);
- }
- h->p = p;
- h->size = new_size;
- return 0;
-}
-
-int
-heap_init(struct dn_heap *h, int size, int ofs)
-{
- if (heap_resize(h, size))
- return 1;
- h->elements = 0;
- h->ofs = ofs;
- return 0;
-}
-
-/*
- * Insert element in heap. Normally, p != NULL, we insert p in
- * a new position and bubble up. If p == NULL, then the element is
- * already in place, and key is the position where to start the
- * bubble-up.
- * Returns 1 on failure (cannot allocate new heap entry)
- *
- * If ofs > 0 the position (index, int) of the element in the heap is
- * also stored in the element itself at the given offset in bytes.
- */
-#define SET_OFFSET(h, i) do { \
- if (h->ofs > 0) \
- *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = i; \
- } while (0)
-/*
- * RESET_OFFSET is used for sanity checks. It sets ofs
- * to an invalid value.
- */
-#define RESET_OFFSET(h, i) do { \
- if (h->ofs > 0) \
- *((int32_t *)((char *)(h->p[i].object) + h->ofs)) = -16; \
- } while (0)
-
-int
-heap_insert(struct dn_heap *h, uint64_t key1, void *p)
-{
- int son = h->elements;
-
- //log("%s key %llu p %p\n", __FUNCTION__, key1, p);
- if (p == NULL) { /* data already there, set starting point */
- son = key1;
- } else { /* insert new element at the end, possibly resize */
- son = h->elements;
- if (son == h->size) /* need resize... */
- // XXX expand by 16 or so
- if (heap_resize(h, h->elements+16) )
- return 1; /* failure... */
- h->p[son].object = p;
- h->p[son].key = key1;
- h->elements++;
- }
- /* make sure that son >= father along the path */
- while (son > 0) {
- int father = HEAP_FATHER(son);
- struct dn_heap_entry tmp;
-
- if (DN_KEY_LT( h->p[father].key, h->p[son].key ) )
- break; /* found right position */
- /* son smaller than father, swap and repeat */
- HEAP_SWAP(h->p[son], h->p[father], tmp);
- SET_OFFSET(h, son);
- son = father;
- }
- SET_OFFSET(h, son);
- return 0;
-}
-
-/*
- * remove top element from heap, or obj if obj != NULL
- */
-void
-heap_extract(struct dn_heap *h, void *obj)
-{
- int child, father, max = h->elements - 1;
-
- if (max < 0) {
- printf("--- %s: empty heap 0x%p\n", __FUNCTION__, h);
- return;
- }
- if (obj == NULL)
- father = 0; /* default: move up smallest child */
- else { /* extract specific element, index is at offset */
- if (h->ofs <= 0)
- panic("%s: extract from middle not set on %p\n",
- __FUNCTION__, h);
- father = *((int *)((char *)obj + h->ofs));
- if (father < 0 || father >= h->elements) {
- panic("%s: father %d out of bound 0..%d\n",
- __FUNCTION__, father, h->elements);
- }
- }
- /*
- * below, father is the index of the empty element, which
- * we replace at each step with the smallest child until we
- * reach the bottom level.
- */
- // XXX why removing RESET_OFFSET increases runtime by 10% ?
- RESET_OFFSET(h, father);
- while ( (child = HEAP_LEFT(father)) <= max ) {
- if (child != max &&
- DN_KEY_LT(h->p[child+1].key, h->p[child].key) )
- child++; /* take right child, otherwise left */
- h->p[father] = h->p[child];
- SET_OFFSET(h, father);
- father = child;
- }
- h->elements--;
- if (father != max) {
- /*
- * Fill hole with last entry and bubble up,
- * reusing the insert code
- */
- h->p[father] = h->p[max];
- heap_insert(h, father, NULL);
- }
-}
-
-#if 0
-/*
- * change object position and update references
- * XXX this one is never used!
- */
-static void
-heap_move(struct dn_heap *h, uint64_t new_key, void *object)
-{
- int temp, i, max = h->elements-1;
- struct dn_heap_entry *p, buf;
-
- if (h->ofs <= 0)
- panic("cannot move items on this heap");
- p = h->p; /* shortcut */
-
- i = *((int *)((char *)object + h->ofs));
- if (DN_KEY_LT(new_key, p[i].key) ) { /* must move up */
- p[i].key = new_key;
- for (; i>0 &&
- DN_KEY_LT(new_key, p[(temp = HEAP_FATHER(i))].key);
- i = temp ) { /* bubble up */
- HEAP_SWAP(p[i], p[temp], buf);
- SET_OFFSET(h, i);
- }
- } else { /* must move down */
- p[i].key = new_key;
- while ( (temp = HEAP_LEFT(i)) <= max ) {
- /* found left child */
- if (temp != max &&
- DN_KEY_LT(p[temp+1].key, p[temp].key))
- temp++; /* select child with min key */
- if (DN_KEY_LT(>p[temp].key, new_key)) {
- /* go down */
- HEAP_SWAP(p[i], p[temp], buf);
- SET_OFFSET(h, i);
- } else
- break;
- i = temp;
- }
- }
- SET_OFFSET(h, i);
-}
-#endif /* heap_move, unused */
-
-/*
- * heapify() will reorganize data inside an array to maintain the
- * heap property. It is needed when we delete a bunch of entries.
- */
-static void
-heapify(struct dn_heap *h)
-{
- int i;
-
- for (i = 0; i < h->elements; i++ )
- heap_insert(h, i , NULL);
-}
-
-int
-heap_scan(struct dn_heap *h, int (*fn)(void *, uintptr_t),
- uintptr_t arg)
-{
- int i, ret, found;
-
- for (i = found = 0 ; i < h->elements ;) {
- ret = fn(h->p[i].object, arg);
- if (ret & HEAP_SCAN_DEL) {
- h->elements-- ;
- h->p[i] = h->p[h->elements] ;
- found++ ;
- } else
- i++ ;
- if (ret & HEAP_SCAN_END)
- break;
- }
- if (found)
- heapify(h);
- return found;
-}
-
-/*
- * cleanup the heap and free data structure
- */
-void
-heap_free(struct dn_heap *h)
-{
- if (h->size >0 )
- free(h->p, M_DN_HEAP);
- bzero(h, sizeof(*h) );
-}
-
-/*
- * hash table support.
- */
-
-struct dn_ht {
- int buckets; /* how many buckets, really buckets - 1*/
- int entries; /* how many entries */
- int ofs; /* offset of link field */
- uint32_t (*hash)(uintptr_t, int, void *arg);
- int (*match)(void *_el, uintptr_t key, int, void *);
- void *(*newh)(uintptr_t, int, void *);
- void **ht; /* bucket heads */
-};
-/*
- * Initialize, allocating bucket pointers inline.
- * Recycle previous record if possible.
- * If the 'newh' function is not supplied, we assume that the
- * key passed to ht_find is the same object to be stored in.
- */
-struct dn_ht *
-dn_ht_init(struct dn_ht *ht, int buckets, int ofs,
- uint32_t (*h)(uintptr_t, int, void *),
- int (*match)(void *, uintptr_t, int, void *),
- void *(*newh)(uintptr_t, int, void *))
-{
- int l;
-
- /*
- * Notes about rounding bucket size to a power of two.
- * Given the original bucket size, we compute the nearest lower and
- * higher power of two, minus 1 (respectively b_min and b_max) because
- * this value will be used to do an AND with the index returned
- * by hash function.
- * To choice between these two values, the original bucket size is
- * compared with b_min. If the original size is greater than 4/3 b_min,
- * we round the bucket size to b_max, else to b_min.
- * This ratio try to round to the nearest power of two, advantaging
- * the greater size if the different between two power is relatively
- * big.
- * Rounding the bucket size to a power of two avoid the use of
- * module when calculating the correct bucket.
- * The ht->buckets variable store the bucket size - 1 to simply
- * do an AND between the index returned by hash function and ht->bucket
- * instead of a module.
- */
- int b_min; /* min buckets */
- int b_max; /* max buckets */
- int b_ori; /* original buckets */
-
- if (h == NULL || match == NULL) {
- printf("--- missing hash or match function");
- return NULL;
- }
- if (buckets < 1 || buckets > 65536)
- return NULL;
-
- b_ori = buckets;
- /* calculate next power of 2, - 1*/
- buckets |= buckets >> 1;
- buckets |= buckets >> 2;
- buckets |= buckets >> 4;
- buckets |= buckets >> 8;
- buckets |= buckets >> 16;
-
- b_max = buckets; /* Next power */
- b_min = buckets >> 1; /* Previous power */
-
- /* Calculate the 'nearest' bucket size */
- if (b_min * 4000 / 3000 < b_ori)
- buckets = b_max;
- else
- buckets = b_min;
-
- if (ht) { /* see if we can reuse */
- if (buckets <= ht->buckets) {
- ht->buckets = buckets;
- } else {
- /* free pointers if not allocated inline */
- if (ht->ht != (void *)(ht + 1))
- free(ht->ht, M_DN_HEAP);
- free(ht, M_DN_HEAP);
- ht = NULL;
- }
- }
- if (ht == NULL) {
- /* Allocate buckets + 1 entries because buckets is use to
- * do the AND with the index returned by hash function
- */
- l = sizeof(*ht) + (buckets + 1) * sizeof(void **);
- ht = malloc(l, M_DN_HEAP, M_NOWAIT | M_ZERO);
- }
- if (ht) {
- ht->ht = (void **)(ht + 1);
- ht->buckets = buckets;
- ht->ofs = ofs;
- ht->hash = h;
- ht->match = match;
- ht->newh = newh;
- }
- return ht;
-}
-
-/* dummy callback for dn_ht_free to unlink all */
-static int
-do_del(void *obj, void *arg)
-{
- return DNHT_SCAN_DEL;
-}
-
-void
-dn_ht_free(struct dn_ht *ht, int flags)
-{
- if (ht == NULL)
- return;
- if (flags & DNHT_REMOVE) {
- (void)dn_ht_scan(ht, do_del, NULL);
- } else {
- if (ht->ht && ht->ht != (void *)(ht + 1))
- free(ht->ht, M_DN_HEAP);
- free(ht, M_DN_HEAP);
- }
-}
-
-int
-dn_ht_entries(struct dn_ht *ht)
-{
- return ht ? ht->entries : 0;
-}
-
-/* lookup and optionally create or delete element */
-void *
-dn_ht_find(struct dn_ht *ht, uintptr_t key, int flags, void *arg)
-{
- int i;
- void **pp, *p;
-
- if (ht == NULL) /* easy on an empty hash */
- return NULL;
- i = (ht->buckets == 1) ? 0 :
- (ht->hash(key, flags, arg) & ht->buckets);
-
- for (pp = &ht->ht[i]; (p = *pp); pp = (void **)((char *)p + ht->ofs)) {
- if (flags & DNHT_MATCH_PTR) {
- if (key == (uintptr_t)p)
- break;
- } else if (ht->match(p, key, flags, arg)) /* found match */
- break;
- }
- if (p) {
- if (flags & DNHT_REMOVE) {
- /* link in the next element */
- *pp = *(void **)((char *)p + ht->ofs);
- *(void **)((char *)p + ht->ofs) = NULL;
- ht->entries--;
- }
- } else if (flags & DNHT_INSERT) {
- // printf("%s before calling new, bucket %d ofs %d\n",
- // __FUNCTION__, i, ht->ofs);
- p = ht->newh ? ht->newh(key, flags, arg) : (void *)key;
- // printf("%s newh returns %p\n", __FUNCTION__, p);
- if (p) {
- ht->entries++;
- *(void **)((char *)p + ht->ofs) = ht->ht[i];
- ht->ht[i] = p;
- }
- }
- return p;
-}
-
-/*
- * do a scan with the option to delete the object. Extract next before
- * running the callback because the element may be destroyed there.
- */
-int
-dn_ht_scan(struct dn_ht *ht, int (*fn)(void *, void *), void *arg)
-{
- int i, ret, found = 0;
- void **curp, *cur, *next;
-
- if (ht == NULL || fn == NULL)
- return 0;
- for (i = 0; i <= ht->buckets; i++) {
- curp = &ht->ht[i];
- while ( (cur = *curp) != NULL) {
- next = *(void **)((char *)cur + ht->ofs);
- ret = fn(cur, arg);
- if (ret & DNHT_SCAN_DEL) {
- found++;
- ht->entries--;
- *curp = next;
- } else {
- curp = (void **)((char *)cur + ht->ofs);
- }
- if (ret & DNHT_SCAN_END)
- return found;
- }
- }
- return found;
-}
-
-/*
- * Similar to dn_ht_scan(), except that the scan is performed only
- * in the bucket 'bucket'. The function returns a correct bucket number if
- * the original is invalid.
- * If the callback returns DNHT_SCAN_END, the function move the ht->ht[i]
- * pointer to the last entry processed. Moreover, the bucket number passed
- * by caller is decremented, because usually the caller increment it.
- */
-int
-dn_ht_scan_bucket(struct dn_ht *ht, int *bucket, int (*fn)(void *, void *),
- void *arg)
-{
- int i, ret, found = 0;
- void **curp, *cur, *next;
-
- if (ht == NULL || fn == NULL)
- return 0;
- if (*bucket > ht->buckets)
- *bucket = 0;
- i = *bucket;
-
- curp = &ht->ht[i];
- while ( (cur = *curp) != NULL) {
- next = *(void **)((char *)cur + ht->ofs);
- ret = fn(cur, arg);
- if (ret & DNHT_SCAN_DEL) {
- found++;
- ht->entries--;
- *curp = next;
- } else {
- curp = (void **)((char *)cur + ht->ofs);
- }
- if (ret & DNHT_SCAN_END)
- return found;
- }
- return found;
-}
diff --git a/sys/netinet/ipfw/dn_heap.h b/sys/netinet/ipfw/dn_heap.h
deleted file mode 100644
index c95473a..0000000
--- a/sys/netinet/ipfw/dn_heap.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*-
- * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * Binary heap and hash tables, header file
- *
- * $FreeBSD$
- */
-
-#ifndef _IP_DN_HEAP_H
-#define _IP_DN_HEAP_H
-
-#define DN_KEY_LT(a,b) ((int64_t)((a)-(b)) < 0)
-#define DN_KEY_LEQ(a,b) ((int64_t)((a)-(b)) <= 0)
-
-/*
- * This module implements a binary heap supporting random extraction.
- *
- * A heap entry contains an uint64_t key and a pointer to object.
- * DN_KEY_LT(a,b) returns true if key 'a' is smaller than 'b'
- *
- * The heap is a struct dn_heap plus a dynamically allocated
- * array of dn_heap_entry entries. 'size' represents the size of
- * the array, 'elements' count entries in use. The topmost
- * element has the smallest key.
- * The heap supports ordered insert, and extract from the top.
- * To extract an object from the middle of the heap, we the object
- * must reserve an 'int32_t' to store the position of the object
- * in the heap itself, and the location of this field must be
- * passed as an argument to heap_init() -- use -1 if the feature
- * is not used.
- */
-struct dn_heap_entry {
- uint64_t key; /* sorting key, smallest comes first */
- void *object; /* object pointer */
-};
-
-struct dn_heap {
- int size; /* the size of the array */
- int elements; /* elements in use */
- int ofs; /* offset in the object of heap index */
- struct dn_heap_entry *p; /* array of "size" entries */
-};
-
-enum {
- HEAP_SCAN_DEL = 1,
- HEAP_SCAN_END = 2,
-};
-
-/*
- * heap_init() reinitializes the heap setting the size and the offset
- * of the index for random extraction (use -1 if not used).
- * The 'elements' counter is set to 0.
- *
- * SET_HEAP_OFS() indicates where, in the object, is stored the index
- * for random extractions from the heap.
- *
- * heap_free() frees the memory associated to a heap.
- *
- * heap_insert() adds a key-pointer pair to the heap
- *
- * HEAP_TOP() returns a pointer to the top element of the heap,
- * but makes no checks on its existance (XXX should we change ?)
- *
- * heap_extract() removes the entry at the top, returing the pointer.
- * (the key should have been read before).
- *
- * heap_scan() invokes a callback on each entry of the heap.
- * The callback can return a combination of HEAP_SCAN_DEL and
- * HEAP_SCAN_END. HEAP_SCAN_DEL means the current element must
- * be removed, and HEAP_SCAN_END means to terminate the scan.
- * heap_scan() returns the number of elements removed.
- * Because the order is not guaranteed, we should use heap_scan()
- * only as a last resort mechanism.
- */
-#define HEAP_TOP(h) ((h)->p)
-#define SET_HEAP_OFS(h, n) do { (h)->ofs = n; } while (0)
-int heap_init(struct dn_heap *h, int size, int ofs);
-int heap_insert(struct dn_heap *h, uint64_t key1, void *p);
-void heap_extract(struct dn_heap *h, void *obj);
-void heap_free(struct dn_heap *h);
-int heap_scan(struct dn_heap *, int (*)(void *, uintptr_t), uintptr_t);
-
-/*------------------------------------------------------
- * This module implements a generic hash table with support for
- * running callbacks on the entire table. To avoid allocating
- * memory during hash table operations, objects must reserve
- * space for a link field. XXX if the heap is moderately full,
- * an SLIST suffices, and we can tolerate the cost of a hash
- * computation on each removal.
- *
- * dn_ht_init() initializes the table, setting the number of
- * buckets, the offset of the link field, the main callbacks.
- * Callbacks are:
- *
- * hash(key, flags, arg) called to return a bucket index.
- * match(obj, key, flags, arg) called to determine if key
- * matches the current 'obj' in the heap
- * newh(key, flags, arg) optional, used to allocate a new
- * object during insertions.
- *
- * dn_ht_free() frees the heap or unlink elements.
- * DNHT_REMOVE unlink elements, 0 frees the heap.
- * You need two calls to do both.
- *
- * dn_ht_find() is the main lookup function, which can also be
- * used to insert or delete elements in the hash table.
- * The final 'arg' is passed to all callbacks.
- *
- * dn_ht_scan() is used to invoke a callback on all entries of
- * the heap, or possibly on just one bucket. The callback
- * is invoked with a pointer to the object, and must return
- * one of DNHT_SCAN_DEL or DNHT_SCAN_END to request the
- * removal of the object from the heap and the end of the
- * scan, respectively.
- *
- * dn_ht_scan_bucket() is similar to dn_ht_scan(), except that it scans
- * only the specific bucket of the table. The bucket is a in-out
- * parameter and return a valid bucket number if the original
- * is invalid.
- *
- * A combination of flags can be used to modify the operation
- * of the dn_ht_find(), and of the callbacks:
- *
- * DNHT_KEY_IS_OBJ means the key is the object pointer.
- * It is usally of interest for the hash and match functions.
- *
- * DNHT_MATCH_PTR during a lookup, match pointers instead
- * of calling match(). Normally used when removing specific
- * entries. Does not imply KEY_IS_OBJ as the latter _is_ used
- * by the match function.
- *
- * DNHT_INSERT insert the element if not found.
- * Calls new() to allocates a new object unless
- * DNHT_KEY_IS_OBJ is set.
- *
- * DNHT_UNIQUE only insert if object not found.
- * XXX should it imply DNHT_INSERT ?
- *
- * DNHT_REMOVE remove objects if we find them.
- */
-struct dn_ht; /* should be opaque */
-
-struct dn_ht *dn_ht_init(struct dn_ht *, int buckets, int ofs,
- uint32_t (*hash)(uintptr_t, int, void *),
- int (*match)(void *, uintptr_t, int, void *),
- void *(*newh)(uintptr_t, int, void *));
-void dn_ht_free(struct dn_ht *, int flags);
-
-void *dn_ht_find(struct dn_ht *, uintptr_t, int, void *);
-int dn_ht_scan(struct dn_ht *, int (*)(void *, void *), void *);
-int dn_ht_scan_bucket(struct dn_ht *, int * , int (*)(void *, void *), void *);
-int dn_ht_entries(struct dn_ht *);
-
-enum { /* flags values.
- * first two are returned by the scan callback to indicate
- * to delete the matching element or to end the scan
- */
- DNHT_SCAN_DEL = 0x0001,
- DNHT_SCAN_END = 0x0002,
- DNHT_KEY_IS_OBJ = 0x0004, /* key is the obj pointer */
- DNHT_MATCH_PTR = 0x0008, /* match by pointer, not match() */
- DNHT_INSERT = 0x0010, /* insert if not found */
- DNHT_UNIQUE = 0x0020, /* report error if already there */
- DNHT_REMOVE = 0x0040, /* remove on find or dn_ht_free */
-};
-
-#endif /* _IP_DN_HEAP_H */
diff --git a/sys/netinet/ipfw/dn_sched.h b/sys/netinet/ipfw/dn_sched.h
deleted file mode 100644
index ab823fe..0000000
--- a/sys/netinet/ipfw/dn_sched.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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 API to write a packet scheduling algorithm for dummynet.
- *
- * $FreeBSD$
- */
-
-#ifndef _DN_SCHED_H
-#define _DN_SCHED_H
-
-#define DN_MULTIQUEUE 0x01
-/*
- * Descriptor for a scheduling algorithm.
- * Contains all function pointers for a given scheduler
- * This is typically created when a module is loaded, and stored
- * in a global list of schedulers.
- */
-struct dn_alg {
- uint32_t type; /* the scheduler type */
- const char *name; /* scheduler name */
- uint32_t flags; /* DN_MULTIQUEUE if supports multiple queues */
-
- /*
- * The following define the size of 3 optional data structures
- * that may need to be allocated at runtime, and are appended
- * to each of the base data structures: scheduler, sched.inst,
- * and queue. We don't have a per-flowset structure.
- */
- /* + parameters attached to the template, e.g.
- * default queue sizes, weights, quantum size, and so on;
- */
- size_t schk_datalen;
-
- /* + per-instance parameters, such as timestamps,
- * containers for queues, etc;
- */
- size_t si_datalen;
-
- size_t q_datalen; /* per-queue parameters (e.g. S,F) */
-
- /*
- * Methods implemented by the scheduler:
- * enqueue enqueue packet 'm' on scheduler 's', queue 'q'.
- * q is NULL for !MULTIQUEUE.
- * Return 0 on success, 1 on drop (packet consumed anyways).
- * Note that q should be interpreted only as a hint
- * on the flow that the mbuf belongs to: while a
- * scheduler will normally enqueue m into q, it is ok
- * to leave q alone and put the mbuf elsewhere.
- * This function is called in two cases:
- * - when a new packet arrives to the scheduler;
- * - when a scheduler is reconfigured. In this case the
- * call is issued by the new_queue callback, with a
- * non empty queue (q) and m pointing to the first
- * mbuf in the queue. For this reason, the function
- * should internally check for (m != q->mq.head)
- * before calling dn_enqueue().
- *
- * dequeue Called when scheduler instance 's' can
- * dequeue a packet. Return NULL if none are available.
- * XXX what about non work-conserving ?
- *
- * config called on 'sched X config ...', normally writes
- * in the area of size sch_arg
- *
- * destroy called on 'sched delete', frees everything
- * in sch_arg (other parts are handled by more specific
- * functions)
- *
- * new_sched called when a new instance is created, e.g.
- * to create the local queue for !MULTIQUEUE, set V or
- * copy parameters for WFQ, and so on.
- *
- * free_sched called when deleting an instance, cleans
- * extra data in the per-instance area.
- *
- * new_fsk called when a flowset is linked to a scheduler,
- * e.g. to validate parameters such as weights etc.
- * free_fsk when a flowset is unlinked from a scheduler.
- * (probably unnecessary)
- *
- * new_queue called to set the per-queue parameters,
- * e.g. S and F, adjust sum of weights in the parent, etc.
- *
- * The new_queue callback is normally called from when
- * creating a new queue. In some cases (such as a
- * scheduler change or reconfiguration) it can be called
- * with a non empty queue. In this case, the queue
- * In case of non empty queue, the new_queue callback could
- * need to call the enqueue function. In this case,
- * the callback should eventually call enqueue() passing
- * as m the first element in the queue.
- *
- * free_queue actions related to a queue removal, e.g. undo
- * all the above. If the queue has data in it, also remove
- * from the scheduler. This can e.g. happen during a reconfigure.
- */
- int (*enqueue)(struct dn_sch_inst *, struct dn_queue *,
- struct mbuf *);
- struct mbuf * (*dequeue)(struct dn_sch_inst *);
-
- int (*config)(struct dn_schk *);
- int (*destroy)(struct dn_schk*);
- int (*new_sched)(struct dn_sch_inst *);
- int (*free_sched)(struct dn_sch_inst *);
- int (*new_fsk)(struct dn_fsk *f);
- int (*free_fsk)(struct dn_fsk *f);
- int (*new_queue)(struct dn_queue *q);
- int (*free_queue)(struct dn_queue *q);
-
- /* run-time fields */
- int ref_count; /* XXX number of instances in the system */
- SLIST_ENTRY(dn_alg) next; /* Next scheduler in the list */
-};
-
-/* MSVC does not support initializers so we need this ugly macro */
-#ifdef _WIN32
-#define _SI(fld)
-#else
-#define _SI(fld) fld
-#endif
-
-/*
- * Additionally, dummynet exports some functions and macros
- * to be used by schedulers:
- */
-
-void dn_free_pkts(struct mbuf *mnext);
-int dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop);
-/* bound a variable between min and max */
-int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg);
-
-/*
- * Extract the head of a queue, update stats. Must be the very last
- * thing done on a dequeue as the queue itself may go away.
- */
-static __inline struct mbuf*
-dn_dequeue(struct dn_queue *q)
-{
- struct mbuf *m = q->mq.head;
- if (m == NULL)
- return NULL;
- q->mq.head = m->m_nextpkt;
-
- /* Update stats for the queue */
- q->ni.length--;
- q->ni.len_bytes -= m->m_pkthdr.len;
- if (q->_si) {
- q->_si->ni.length--;
- q->_si->ni.len_bytes -= m->m_pkthdr.len;
- }
- if (q->ni.length == 0) /* queue is now idle */
- q->q_time = dn_cfg.curr_time;
- return m;
-}
-
-int dn_sched_modevent(module_t mod, int cmd, void *arg);
-
-#define DECLARE_DNSCHED_MODULE(name, dnsched) \
- static moduledata_t name##_mod = { \
- #name, dn_sched_modevent, dnsched \
- }; \
- DECLARE_MODULE(name, name##_mod, \
- SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \
- MODULE_DEPEND(name, dummynet, 3, 3, 3);
-#endif /* _DN_SCHED_H */
diff --git a/sys/netinet/ipfw/dn_sched_fifo.c b/sys/netinet/ipfw/dn_sched_fifo.c
deleted file mode 100644
index 0bb3800..0000000
--- a/sys/netinet/ipfw/dn_sched_fifo.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * $FreeBSD$
- */
-
-#ifdef _KERNEL
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <net/if.h> /* IFNAMSIZ */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ipfw_rule_ref */
-#include <netinet/ip_fw.h> /* flow_id */
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-#else
-#include <dn_test.h>
-#endif
-
-/*
- * This file implements a FIFO scheduler for a single queue.
- * The queue is allocated as part of the scheduler instance,
- * and there is a single flowset is in the template which stores
- * queue size and policy.
- * Enqueue and dequeue use the default library functions.
- */
-static int
-fifo_enqueue(struct dn_sch_inst *si, struct dn_queue *q, struct mbuf *m)
-{
- /* XXX if called with q != NULL and m=NULL, this is a
- * re-enqueue from an existing scheduler, which we should
- * handle.
- */
- return dn_enqueue((struct dn_queue *)(si+1), m, 0);
-}
-
-static struct mbuf *
-fifo_dequeue(struct dn_sch_inst *si)
-{
- return dn_dequeue((struct dn_queue *)(si + 1));
-}
-
-static int
-fifo_new_sched(struct dn_sch_inst *si)
-{
- /* This scheduler instance contains the queue */
- struct dn_queue *q = (struct dn_queue *)(si + 1);
-
- set_oid(&q->ni.oid, DN_QUEUE, sizeof(*q));
- q->_si = si;
- q->fs = si->sched->fs;
- return 0;
-}
-
-static int
-fifo_free_sched(struct dn_sch_inst *si)
-{
- struct dn_queue *q = (struct dn_queue *)(si + 1);
- dn_free_pkts(q->mq.head);
- bzero(q, sizeof(*q));
- return 0;
-}
-
-/*
- * FIFO scheduler descriptor
- * contains the type of the scheduler, the name, the size of extra
- * data structures, and function pointers.
- */
-static struct dn_alg fifo_desc = {
- _SI( .type = ) DN_SCHED_FIFO,
- _SI( .name = ) "FIFO",
- _SI( .flags = ) 0,
-
- _SI( .schk_datalen = ) 0,
- _SI( .si_datalen = ) sizeof(struct dn_queue),
- _SI( .q_datalen = ) 0,
-
- _SI( .enqueue = ) fifo_enqueue,
- _SI( .dequeue = ) fifo_dequeue,
- _SI( .config = ) NULL,
- _SI( .destroy = ) NULL,
- _SI( .new_sched = ) fifo_new_sched,
- _SI( .free_sched = ) fifo_free_sched,
- _SI( .new_fsk = ) NULL,
- _SI( .free_fsk = ) NULL,
- _SI( .new_queue = ) NULL,
- _SI( .free_queue = ) NULL,
-};
-
-DECLARE_DNSCHED_MODULE(dn_fifo, &fifo_desc);
diff --git a/sys/netinet/ipfw/dn_sched_prio.c b/sys/netinet/ipfw/dn_sched_prio.c
deleted file mode 100644
index 28f6006..0000000
--- a/sys/netinet/ipfw/dn_sched_prio.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * $FreeBSD$
- */
-#ifdef _KERNEL
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <net/if.h> /* IFNAMSIZ */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ipfw_rule_ref */
-#include <netinet/ip_fw.h> /* flow_id */
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-#else
-#include <dn_test.h>
-#endif
-
-#define DN_SCHED_PRIO 5 //XXX
-
-#if !defined(_KERNEL) || !defined(__linux__)
-#define test_bit(ix, pData) ((*pData) & (1<<(ix)))
-#define __set_bit(ix, pData) (*pData) |= (1<<(ix))
-#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
-#endif
-
-#ifdef __MIPSEL__
-#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
-#endif
-
-/* Size of the array of queues pointers. */
-#define BITMAP_T unsigned long
-#define MAXPRIO (sizeof(BITMAP_T) * 8)
-
-/*
- * The scheduler instance contains an array of pointers to queues,
- * one for each priority, and a bitmap listing backlogged queues.
- */
-struct prio_si {
- BITMAP_T bitmap; /* array bitmap */
- struct dn_queue *q_array[MAXPRIO]; /* Array of queues pointers */
-};
-
-/*
- * If a queue with the same priority is already backlogged, use
- * that one instead of the queue passed as argument.
- */
-static int
-prio_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
-{
- struct prio_si *si = (struct prio_si *)(_si + 1);
- int prio = q->fs->fs.par[0];
-
- if (test_bit(prio, &si->bitmap) == 0) {
- /* No queue with this priority, insert */
- __set_bit(prio, &si->bitmap);
- si->q_array[prio] = q;
- } else { /* use the existing queue */
- q = si->q_array[prio];
- }
- if (dn_enqueue(q, m, 0))
- return 1;
- return 0;
-}
-
-/*
- * Packets are dequeued only from the highest priority queue.
- * The function ffs() return the lowest bit in the bitmap that rapresent
- * the array index (-1) which contains the pointer to the highest priority
- * queue.
- * After the dequeue, if this queue become empty, it is index is removed
- * from the bitmap.
- * Scheduler is idle if the bitmap is empty
- *
- * NOTE: highest priority is 0, lowest is sched->max_prio_q
- */
-static struct mbuf *
-prio_dequeue(struct dn_sch_inst *_si)
-{
- struct prio_si *si = (struct prio_si *)(_si + 1);
- struct mbuf *m;
- struct dn_queue *q;
- int prio;
-
- if (si->bitmap == 0) /* scheduler idle */
- return NULL;
-
- prio = ffs(si->bitmap) - 1;
-
- /* Take the highest priority queue in the scheduler */
- q = si->q_array[prio];
- // assert(q)
-
- m = dn_dequeue(q);
- if (q->mq.head == NULL) {
- /* Queue is now empty, remove from scheduler
- * and mark it
- */
- si->q_array[prio] = NULL;
- __clear_bit(prio, &si->bitmap);
- }
- return m;
-}
-
-static int
-prio_new_sched(struct dn_sch_inst *_si)
-{
- struct prio_si *si = (struct prio_si *)(_si + 1);
-
- bzero(si->q_array, sizeof(si->q_array));
- si->bitmap = 0;
-
- return 0;
-}
-
-static int
-prio_new_fsk(struct dn_fsk *fs)
-{
- /* Check if the prioritiy is between 0 and MAXPRIO-1 */
- ipdn_bound_var(&fs->fs.par[0], 0, 0, MAXPRIO - 1, "PRIO priority");
- return 0;
-}
-
-static int
-prio_new_queue(struct dn_queue *q)
-{
- struct prio_si *si = (struct prio_si *)(q->_si + 1);
- int prio = q->fs->fs.par[0];
- struct dn_queue *oldq;
-
- q->ni.oid.subtype = DN_SCHED_PRIO;
-
- if (q->mq.head == NULL)
- return 0;
-
- /* Queue already full, must insert in the scheduler or append
- * mbufs to existing queue. This partly duplicates prio_enqueue
- */
- if (test_bit(prio, &si->bitmap) == 0) {
- /* No queue with this priority, insert */
- __set_bit(prio, &si->bitmap);
- si->q_array[prio] = q;
- } else if ( (oldq = si->q_array[prio]) != q) {
- /* must append to the existing queue.
- * can simply append q->mq.head to q2->...
- * and add the counters to those of q2
- */
- oldq->mq.tail->m_nextpkt = q->mq.head;
- oldq->mq.tail = q->mq.tail;
- oldq->ni.length += q->ni.length;
- q->ni.length = 0;
- oldq->ni.len_bytes += q->ni.len_bytes;
- q->ni.len_bytes = 0;
- q->mq.tail = q->mq.head = NULL;
- }
- return 0;
-}
-
-static int
-prio_free_queue(struct dn_queue *q)
-{
- int prio = q->fs->fs.par[0];
- struct prio_si *si = (struct prio_si *)(q->_si + 1);
-
- if (si->q_array[prio] == q) {
- si->q_array[prio] = NULL;
- __clear_bit(prio, &si->bitmap);
- }
- return 0;
-}
-
-
-static struct dn_alg prio_desc = {
- _SI( .type = ) DN_SCHED_PRIO,
- _SI( .name = ) "PRIO",
- _SI( .flags = ) DN_MULTIQUEUE,
-
- /* we need extra space in the si and the queue */
- _SI( .schk_datalen = ) 0,
- _SI( .si_datalen = ) sizeof(struct prio_si),
- _SI( .q_datalen = ) 0,
-
- _SI( .enqueue = ) prio_enqueue,
- _SI( .dequeue = ) prio_dequeue,
-
- _SI( .config = ) NULL,
- _SI( .destroy = ) NULL,
- _SI( .new_sched = ) prio_new_sched,
- _SI( .free_sched = ) NULL,
-
- _SI( .new_fsk = ) prio_new_fsk,
- _SI( .free_fsk = ) NULL,
-
- _SI( .new_queue = ) prio_new_queue,
- _SI( .free_queue = ) prio_free_queue,
-};
-
-
-DECLARE_DNSCHED_MODULE(dn_prio, &prio_desc);
diff --git a/sys/netinet/ipfw/dn_sched_qfq.c b/sys/netinet/ipfw/dn_sched_qfq.c
deleted file mode 100644
index be7fba3..0000000
--- a/sys/netinet/ipfw/dn_sched_qfq.c
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * Copyright (c) 2010 Fabio Checconi, Luigi Rizzo, Paolo Valente
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * $FreeBSD$
- */
-
-#ifdef _KERNEL
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <net/if.h> /* IFNAMSIZ */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ipfw_rule_ref */
-#include <netinet/ip_fw.h> /* flow_id */
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-#else
-#include <dn_test.h>
-#endif
-
-#ifdef QFQ_DEBUG
-struct qfq_sched;
-static void dump_sched(struct qfq_sched *q, const char *msg);
-#define NO(x) x
-#else
-#define NO(x)
-#endif
-#define DN_SCHED_QFQ 4 // XXX Where?
-typedef unsigned long bitmap;
-
-/*
- * bitmaps ops are critical. Some linux versions have __fls
- * and the bitmap ops. Some machines have ffs
- */
-#if defined(_WIN32) || (defined(__MIPSEL__) && defined(LINUX_24))
-int fls(unsigned int n)
-{
- int i = 0;
- for (i = 0; n > 0; n >>= 1, i++)
- ;
- return i;
-}
-#endif
-
-#if !defined(_KERNEL) || defined( __FreeBSD__ ) || defined(_WIN32) || (defined(__MIPSEL__) && defined(LINUX_24))
-static inline unsigned long __fls(unsigned long word)
-{
- return fls(word) - 1;
-}
-#endif
-
-#if !defined(_KERNEL) || !defined(__linux__)
-#ifdef QFQ_DEBUG
-int test_bit(int ix, bitmap *p)
-{
- if (ix < 0 || ix > 31)
- D("bad index %d", ix);
- return *p & (1<<ix);
-}
-void __set_bit(int ix, bitmap *p)
-{
- if (ix < 0 || ix > 31)
- D("bad index %d", ix);
- *p |= (1<<ix);
-}
-void __clear_bit(int ix, bitmap *p)
-{
- if (ix < 0 || ix > 31)
- D("bad index %d", ix);
- *p &= ~(1<<ix);
-}
-#else /* !QFQ_DEBUG */
-/* XXX do we have fast version, or leave it to the compiler ? */
-#define test_bit(ix, pData) ((*pData) & (1<<(ix)))
-#define __set_bit(ix, pData) (*pData) |= (1<<(ix))
-#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
-#endif /* !QFQ_DEBUG */
-#endif /* !__linux__ */
-
-#ifdef __MIPSEL__
-#define __clear_bit(ix, pData) (*pData) &= ~(1<<(ix))
-#endif
-
-/*-------------------------------------------*/
-/*
-
-Virtual time computations.
-
-S, F and V are all computed in fixed point arithmetic with
-FRAC_BITS decimal bits.
-
- QFQ_MAX_INDEX is the maximum index allowed for a group. We need
- one bit per index.
- QFQ_MAX_WSHIFT is the maximum power of two supported as a weight.
- The layout of the bits is as below:
-
- [ MTU_SHIFT ][ FRAC_BITS ]
- [ MAX_INDEX ][ MIN_SLOT_SHIFT ]
- ^.__grp->index = 0
- *.__grp->slot_shift
-
- where MIN_SLOT_SHIFT is derived by difference from the others.
-
-The max group index corresponds to Lmax/w_min, where
-Lmax=1<<MTU_SHIFT, w_min = 1 .
-From this, and knowing how many groups (MAX_INDEX) we want,
-we can derive the shift corresponding to each group.
-
-Because we often need to compute
- F = S + len/w_i and V = V + len/wsum
-instead of storing w_i store the value
- inv_w = (1<<FRAC_BITS)/w_i
-so we can do F = S + len * inv_w * wsum.
-We use W_TOT in the formulas so we can easily move between
-static and adaptive weight sum.
-
-The per-scheduler-instance data contain all the data structures
-for the scheduler: bitmaps and bucket lists.
-
- */
-/*
- * Maximum number of consecutive slots occupied by backlogged classes
- * inside a group. This is approx lmax/lmin + 5.
- * XXX check because it poses constraints on MAX_INDEX
- */
-#define QFQ_MAX_SLOTS 32
-/*
- * Shifts used for class<->group mapping. Class weights are
- * in the range [1, QFQ_MAX_WEIGHT], we to map each class i to the
- * group with the smallest index that can support the L_i / r_i
- * configured for the class.
- *
- * grp->index is the index of the group; and grp->slot_shift
- * is the shift for the corresponding (scaled) sigma_i.
- *
- * When computing the group index, we do (len<<FP_SHIFT)/weight,
- * then compute an FLS (which is like a log2()), and if the result
- * is below the MAX_INDEX region we use 0 (which is the same as
- * using a larger len).
- */
-#define QFQ_MAX_INDEX 19
-#define QFQ_MAX_WSHIFT 16 /* log2(max_weight) */
-
-#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
-#define QFQ_MAX_WSUM (2*QFQ_MAX_WEIGHT)
-//#define IWSUM (q->i_wsum)
-#define IWSUM ((1<<FRAC_BITS)/QFQ_MAX_WSUM)
-
-#define FRAC_BITS 30 /* fixed point arithmetic */
-#define ONE_FP (1UL << FRAC_BITS)
-
-#define QFQ_MTU_SHIFT 11 /* log2(max_len) */
-#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
-
-/*
- * Possible group states, also indexes for the bitmaps array in
- * struct qfq_queue. We rely on ER, IR, EB, IB being numbered 0..3
- */
-enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE };
-
-struct qfq_group;
-/*
- * additional queue info. Some of this info should come from
- * the flowset, we copy them here for faster processing.
- * This is an overlay of the struct dn_queue
- */
-struct qfq_class {
- struct dn_queue _q;
- uint64_t S, F; /* flow timestamps (exact) */
- struct qfq_class *next; /* Link for the slot list. */
-
- /* group we belong to. In principle we would need the index,
- * which is log_2(lmax/weight), but we never reference it
- * directly, only the group.
- */
- struct qfq_group *grp;
-
- /* these are copied from the flowset. */
- uint32_t inv_w; /* ONE_FP/weight */
- uint32_t lmax; /* Max packet size for this flow. */
-};
-
-/* Group descriptor, see the paper for details.
- * Basically this contains the bucket lists
- */
-struct qfq_group {
- uint64_t S, F; /* group timestamps (approx). */
- unsigned int slot_shift; /* Slot shift. */
- unsigned int index; /* Group index. */
- unsigned int front; /* Index of the front slot. */
- bitmap full_slots; /* non-empty slots */
-
- /* Array of lists of active classes. */
- struct qfq_class *slots[QFQ_MAX_SLOTS];
-};
-
-/* scheduler instance descriptor. */
-struct qfq_sched {
- uint64_t V; /* Precise virtual time. */
- uint32_t wsum; /* weight sum */
- NO(uint32_t i_wsum; /* ONE_FP/w_sum */
- uint32_t _queued; /* debugging */
- uint32_t loops; /* debugging */)
- bitmap bitmaps[QFQ_MAX_STATE]; /* Group bitmaps. */
- struct qfq_group groups[QFQ_MAX_INDEX + 1]; /* The groups. */
-};
-
-/*---- support functions ----------------------------*/
-
-/* Generic comparison function, handling wraparound. */
-static inline int qfq_gt(uint64_t a, uint64_t b)
-{
- return (int64_t)(a - b) > 0;
-}
-
-/* Round a precise timestamp to its slotted value. */
-static inline uint64_t qfq_round_down(uint64_t ts, unsigned int shift)
-{
- return ts & ~((1ULL << shift) - 1);
-}
-
-/* return the pointer to the group with lowest index in the bitmap */
-static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
- unsigned long bitmap)
-{
- int index = ffs(bitmap) - 1; // zero-based
- return &q->groups[index];
-}
-
-/*
- * Calculate a flow index, given its weight and maximum packet length.
- * index = log_2(maxlen/weight) but we need to apply the scaling.
- * This is used only once at flow creation.
- */
-static int qfq_calc_index(uint32_t inv_w, unsigned int maxlen)
-{
- uint64_t slot_size = (uint64_t)maxlen *inv_w;
- unsigned long size_map;
- int index = 0;
-
- size_map = (unsigned long)(slot_size >> QFQ_MIN_SLOT_SHIFT);
- if (!size_map)
- goto out;
-
- index = __fls(size_map) + 1; // basically a log_2()
- index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
-
- if (index < 0)
- index = 0;
-
-out:
- ND("W = %d, L = %d, I = %d\n", ONE_FP/inv_w, maxlen, index);
- return index;
-}
-/*---- end support functions ----*/
-
-/*-------- API calls --------------------------------*/
-/*
- * Validate and copy parameters from flowset.
- */
-static int
-qfq_new_queue(struct dn_queue *_q)
-{
- struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
- struct qfq_class *cl = (struct qfq_class *)_q;
- int i;
- uint32_t w; /* approximated weight */
-
- /* import parameters from the flowset. They should be correct
- * already.
- */
- w = _q->fs->fs.par[0];
- cl->lmax = _q->fs->fs.par[1];
- if (!w || w > QFQ_MAX_WEIGHT) {
- w = 1;
- D("rounding weight to 1");
- }
- cl->inv_w = ONE_FP/w;
- w = ONE_FP/cl->inv_w;
- if (q->wsum + w > QFQ_MAX_WSUM)
- return EINVAL;
-
- i = qfq_calc_index(cl->inv_w, cl->lmax);
- cl->grp = &q->groups[i];
- q->wsum += w;
- // XXX cl->S = q->V; ?
- // XXX compute q->i_wsum
- return 0;
-}
-
-/* remove an empty queue */
-static int
-qfq_free_queue(struct dn_queue *_q)
-{
- struct qfq_sched *q = (struct qfq_sched *)(_q->_si + 1);
- struct qfq_class *cl = (struct qfq_class *)_q;
- if (cl->inv_w) {
- q->wsum -= ONE_FP/cl->inv_w;
- cl->inv_w = 0; /* reset weight to avoid run twice */
- }
- return 0;
-}
-
-/* Calculate a mask to mimic what would be ffs_from(). */
-static inline unsigned long
-mask_from(unsigned long bitmap, int from)
-{
- return bitmap & ~((1UL << from) - 1);
-}
-
-/*
- * The state computation relies on ER=0, IR=1, EB=2, IB=3
- * First compute eligibility comparing grp->S, q->V,
- * then check if someone is blocking us and possibly add EB
- */
-static inline unsigned int
-qfq_calc_state(struct qfq_sched *q, struct qfq_group *grp)
-{
- /* if S > V we are not eligible */
- unsigned int state = qfq_gt(grp->S, q->V);
- unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
- struct qfq_group *next;
-
- if (mask) {
- next = qfq_ffs(q, mask);
- if (qfq_gt(grp->F, next->F))
- state |= EB;
- }
-
- return state;
-}
-
-/*
- * In principle
- * q->bitmaps[dst] |= q->bitmaps[src] & mask;
- * q->bitmaps[src] &= ~mask;
- * but we should make sure that src != dst
- */
-static inline void
-qfq_move_groups(struct qfq_sched *q, unsigned long mask, int src, int dst)
-{
- q->bitmaps[dst] |= q->bitmaps[src] & mask;
- q->bitmaps[src] &= ~mask;
-}
-
-static inline void
-qfq_unblock_groups(struct qfq_sched *q, int index, uint64_t old_finish)
-{
- unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
- struct qfq_group *next;
-
- if (mask) {
- next = qfq_ffs(q, mask);
- if (!qfq_gt(next->F, old_finish))
- return;
- }
-
- mask = (1UL << index) - 1;
- qfq_move_groups(q, mask, EB, ER);
- qfq_move_groups(q, mask, IB, IR);
-}
-
-/*
- * perhaps
- *
- old_V ^= q->V;
- old_V >>= QFQ_MIN_SLOT_SHIFT;
- if (old_V) {
- ...
- }
- *
- */
-static inline void
-qfq_make_eligible(struct qfq_sched *q, uint64_t old_V)
-{
- unsigned long mask, vslot, old_vslot;
-
- vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
- old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
-
- if (vslot != old_vslot) {
- mask = (2UL << (__fls(vslot ^ old_vslot))) - 1;
- qfq_move_groups(q, mask, IR, ER);
- qfq_move_groups(q, mask, IB, EB);
- }
-}
-
-/*
- * XXX we should make sure that slot becomes less than 32.
- * This is guaranteed by the input values.
- * roundedS is always cl->S rounded on grp->slot_shift bits.
- */
-static inline void
-qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl, uint64_t roundedS)
-{
- uint64_t slot = (roundedS - grp->S) >> grp->slot_shift;
- unsigned int i = (grp->front + slot) % QFQ_MAX_SLOTS;
-
- cl->next = grp->slots[i];
- grp->slots[i] = cl;
- __set_bit(slot, &grp->full_slots);
-}
-
-/*
- * remove the entry from the slot
- */
-static inline void
-qfq_front_slot_remove(struct qfq_group *grp)
-{
- struct qfq_class **h = &grp->slots[grp->front];
-
- *h = (*h)->next;
- if (!*h)
- __clear_bit(0, &grp->full_slots);
-}
-
-/*
- * Returns the first full queue in a group. As a side effect,
- * adjust the bucket list so the first non-empty bucket is at
- * position 0 in full_slots.
- */
-static inline struct qfq_class *
-qfq_slot_scan(struct qfq_group *grp)
-{
- int i;
-
- ND("grp %d full %x", grp->index, grp->full_slots);
- if (!grp->full_slots)
- return NULL;
-
- i = ffs(grp->full_slots) - 1; // zero-based
- if (i > 0) {
- grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
- grp->full_slots >>= i;
- }
-
- return grp->slots[grp->front];
-}
-
-/*
- * adjust the bucket list. When the start time of a group decreases,
- * we move the index down (modulo QFQ_MAX_SLOTS) so we don't need to
- * move the objects. The mask of occupied slots must be shifted
- * because we use ffs() to find the first non-empty slot.
- * This covers decreases in the group's start time, but what about
- * increases of the start time ?
- * Here too we should make sure that i is less than 32
- */
-static inline void
-qfq_slot_rotate(struct qfq_sched *q, struct qfq_group *grp, uint64_t roundedS)
-{
- unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
-
- grp->full_slots <<= i;
- grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
-}
-
-
-static inline void
-qfq_update_eligible(struct qfq_sched *q, uint64_t old_V)
-{
- bitmap ineligible;
-
- ineligible = q->bitmaps[IR] | q->bitmaps[IB];
- if (ineligible) {
- if (!q->bitmaps[ER]) {
- struct qfq_group *grp;
- grp = qfq_ffs(q, ineligible);
- if (qfq_gt(grp->S, q->V))
- q->V = grp->S;
- }
- qfq_make_eligible(q, old_V);
- }
-}
-
-/*
- * Updates the class, returns true if also the group needs to be updated.
- */
-static inline int
-qfq_update_class(struct qfq_sched *q, struct qfq_group *grp,
- struct qfq_class *cl)
-{
-
- cl->S = cl->F;
- if (cl->_q.mq.head == NULL) {
- qfq_front_slot_remove(grp);
- } else {
- unsigned int len;
- uint64_t roundedS;
-
- len = cl->_q.mq.head->m_pkthdr.len;
- cl->F = cl->S + (uint64_t)len * cl->inv_w;
- roundedS = qfq_round_down(cl->S, grp->slot_shift);
- if (roundedS == grp->S)
- return 0;
-
- qfq_front_slot_remove(grp);
- qfq_slot_insert(grp, cl, roundedS);
- }
- return 1;
-}
-
-static struct mbuf *
-qfq_dequeue(struct dn_sch_inst *si)
-{
- struct qfq_sched *q = (struct qfq_sched *)(si + 1);
- struct qfq_group *grp;
- struct qfq_class *cl;
- struct mbuf *m;
- uint64_t old_V;
-
- NO(q->loops++;)
- if (!q->bitmaps[ER]) {
- NO(if (q->queued)
- dump_sched(q, "start dequeue");)
- return NULL;
- }
-
- grp = qfq_ffs(q, q->bitmaps[ER]);
-
- cl = grp->slots[grp->front];
- /* extract from the first bucket in the bucket list */
- m = dn_dequeue(&cl->_q);
-
- if (!m) {
- D("BUG/* non-workconserving leaf */");
- return NULL;
- }
- NO(q->queued--;)
- old_V = q->V;
- q->V += (uint64_t)m->m_pkthdr.len * IWSUM;
- ND("m is %p F 0x%llx V now 0x%llx", m, cl->F, q->V);
-
- if (qfq_update_class(q, grp, cl)) {
- uint64_t old_F = grp->F;
- cl = qfq_slot_scan(grp);
- if (!cl) { /* group gone, remove from ER */
- __clear_bit(grp->index, &q->bitmaps[ER]);
- // grp->S = grp->F + 1; // XXX debugging only
- } else {
- uint64_t roundedS = qfq_round_down(cl->S, grp->slot_shift);
- unsigned int s;
-
- if (grp->S == roundedS)
- goto skip_unblock;
- grp->S = roundedS;
- grp->F = roundedS + (2ULL << grp->slot_shift);
- /* remove from ER and put in the new set */
- __clear_bit(grp->index, &q->bitmaps[ER]);
- s = qfq_calc_state(q, grp);
- __set_bit(grp->index, &q->bitmaps[s]);
- }
- /* we need to unblock even if the group has gone away */
- qfq_unblock_groups(q, grp->index, old_F);
- }
-
-skip_unblock:
- qfq_update_eligible(q, old_V);
- NO(if (!q->bitmaps[ER] && q->queued)
- dump_sched(q, "end dequeue");)
-
- return m;
-}
-
-/*
- * Assign a reasonable start time for a new flow k in group i.
- * Admissible values for \hat(F) are multiples of \sigma_i
- * no greater than V+\sigma_i . Larger values mean that
- * we had a wraparound so we consider the timestamp to be stale.
- *
- * If F is not stale and F >= V then we set S = F.
- * Otherwise we should assign S = V, but this may violate
- * the ordering in ER. So, if we have groups in ER, set S to
- * the F_j of the first group j which would be blocking us.
- * We are guaranteed not to move S backward because
- * otherwise our group i would still be blocked.
- */
-static inline void
-qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
-{
- unsigned long mask;
- uint64_t limit, roundedF;
- int slot_shift = cl->grp->slot_shift;
-
- roundedF = qfq_round_down(cl->F, slot_shift);
- limit = qfq_round_down(q->V, slot_shift) + (1UL << slot_shift);
-
- if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
- /* timestamp was stale */
- mask = mask_from(q->bitmaps[ER], cl->grp->index);
- if (mask) {
- struct qfq_group *next = qfq_ffs(q, mask);
- if (qfq_gt(roundedF, next->F)) {
- cl->S = next->F;
- return;
- }
- }
- cl->S = q->V;
- } else { /* timestamp is not stale */
- cl->S = cl->F;
- }
-}
-
-static int
-qfq_enqueue(struct dn_sch_inst *si, struct dn_queue *_q, struct mbuf *m)
-{
- struct qfq_sched *q = (struct qfq_sched *)(si + 1);
- struct qfq_group *grp;
- struct qfq_class *cl = (struct qfq_class *)_q;
- uint64_t roundedS;
- int s;
-
- NO(q->loops++;)
- DX(4, "len %d flow %p inv_w 0x%x grp %d", m->m_pkthdr.len,
- _q, cl->inv_w, cl->grp->index);
- /* XXX verify that the packet obeys the parameters */
- if (m != _q->mq.head) {
- if (dn_enqueue(_q, m, 0)) /* packet was dropped */
- return 1;
- NO(q->queued++;)
- if (m != _q->mq.head)
- return 0;
- }
- /* If reach this point, queue q was idle */
- grp = cl->grp;
- qfq_update_start(q, cl); /* adjust start time */
- /* compute new finish time and rounded start. */
- cl->F = cl->S + (uint64_t)(m->m_pkthdr.len) * cl->inv_w;
- roundedS = qfq_round_down(cl->S, grp->slot_shift);
-
- /*
- * insert cl in the correct bucket.
- * If cl->S >= grp->S we don't need to adjust the
- * bucket list and simply go to the insertion phase.
- * Otherwise grp->S is decreasing, we must make room
- * in the bucket list, and also recompute the group state.
- * Finally, if there were no flows in this group and nobody
- * was in ER make sure to adjust V.
- */
- if (grp->full_slots) {
- if (!qfq_gt(grp->S, cl->S))
- goto skip_update;
- /* create a slot for this cl->S */
- qfq_slot_rotate(q, grp, roundedS);
- /* group was surely ineligible, remove */
- __clear_bit(grp->index, &q->bitmaps[IR]);
- __clear_bit(grp->index, &q->bitmaps[IB]);
- } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
- q->V = roundedS;
-
- grp->S = roundedS;
- grp->F = roundedS + (2ULL << grp->slot_shift); // i.e. 2\sigma_i
- s = qfq_calc_state(q, grp);
- __set_bit(grp->index, &q->bitmaps[s]);
- ND("new state %d 0x%x", s, q->bitmaps[s]);
- ND("S %llx F %llx V %llx", cl->S, cl->F, q->V);
-skip_update:
- qfq_slot_insert(grp, cl, roundedS);
-
- return 0;
-}
-
-
-#if 0
-static inline void
-qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
- struct qfq_class *cl, struct qfq_class **pprev)
-{
- unsigned int i, offset;
- uint64_t roundedS;
-
- roundedS = qfq_round_down(cl->S, grp->slot_shift);
- offset = (roundedS - grp->S) >> grp->slot_shift;
- i = (grp->front + offset) % QFQ_MAX_SLOTS;
-
-#ifdef notyet
- if (!pprev) {
- pprev = &grp->slots[i];
- while (*pprev && *pprev != cl)
- pprev = &(*pprev)->next;
- }
-#endif
-
- *pprev = cl->next;
- if (!grp->slots[i])
- __clear_bit(offset, &grp->full_slots);
-}
-
-/*
- * called to forcibly destroy a queue.
- * If the queue is not in the front bucket, or if it has
- * other queues in the front bucket, we can simply remove
- * the queue with no other side effects.
- * Otherwise we must propagate the event up.
- * XXX description to be completed.
- */
-static void
-qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl,
- struct qfq_class **pprev)
-{
- struct qfq_group *grp = &q->groups[cl->index];
- unsigned long mask;
- uint64_t roundedS;
- int s;
-
- cl->F = cl->S; // not needed if the class goes away.
- qfq_slot_remove(q, grp, cl, pprev);
-
- if (!grp->full_slots) {
- /* nothing left in the group, remove from all sets.
- * Do ER last because if we were blocking other groups
- * we must unblock them.
- */
- __clear_bit(grp->index, &q->bitmaps[IR]);
- __clear_bit(grp->index, &q->bitmaps[EB]);
- __clear_bit(grp->index, &q->bitmaps[IB]);
-
- if (test_bit(grp->index, &q->bitmaps[ER]) &&
- !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
- mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
- if (mask)
- mask = ~((1UL << __fls(mask)) - 1);
- else
- mask = ~0UL;
- qfq_move_groups(q, mask, EB, ER);
- qfq_move_groups(q, mask, IB, IR);
- }
- __clear_bit(grp->index, &q->bitmaps[ER]);
- } else if (!grp->slots[grp->front]) {
- cl = qfq_slot_scan(grp);
- roundedS = qfq_round_down(cl->S, grp->slot_shift);
- if (grp->S != roundedS) {
- __clear_bit(grp->index, &q->bitmaps[ER]);
- __clear_bit(grp->index, &q->bitmaps[IR]);
- __clear_bit(grp->index, &q->bitmaps[EB]);
- __clear_bit(grp->index, &q->bitmaps[IB]);
- grp->S = roundedS;
- grp->F = roundedS + (2ULL << grp->slot_shift);
- s = qfq_calc_state(q, grp);
- __set_bit(grp->index, &q->bitmaps[s]);
- }
- }
- qfq_update_eligible(q, q->V);
-}
-#endif
-
-static int
-qfq_new_fsk(struct dn_fsk *f)
-{
- ipdn_bound_var(&f->fs.par[0], 1, 1, QFQ_MAX_WEIGHT, "qfq weight");
- ipdn_bound_var(&f->fs.par[1], 1500, 1, 2000, "qfq maxlen");
- ND("weight %d len %d\n", f->fs.par[0], f->fs.par[1]);
- return 0;
-}
-
-/*
- * initialize a new scheduler instance
- */
-static int
-qfq_new_sched(struct dn_sch_inst *si)
-{
- struct qfq_sched *q = (struct qfq_sched *)(si + 1);
- struct qfq_group *grp;
- int i;
-
- for (i = 0; i <= QFQ_MAX_INDEX; i++) {
- grp = &q->groups[i];
- grp->index = i;
- grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS -
- (QFQ_MAX_INDEX - i);
- }
- return 0;
-}
-
-/*
- * QFQ scheduler descriptor
- */
-static struct dn_alg qfq_desc = {
- _SI( .type = ) DN_SCHED_QFQ,
- _SI( .name = ) "QFQ",
- _SI( .flags = ) DN_MULTIQUEUE,
-
- _SI( .schk_datalen = ) 0,
- _SI( .si_datalen = ) sizeof(struct qfq_sched),
- _SI( .q_datalen = ) sizeof(struct qfq_class) - sizeof(struct dn_queue),
-
- _SI( .enqueue = ) qfq_enqueue,
- _SI( .dequeue = ) qfq_dequeue,
-
- _SI( .config = ) NULL,
- _SI( .destroy = ) NULL,
- _SI( .new_sched = ) qfq_new_sched,
- _SI( .free_sched = ) NULL,
- _SI( .new_fsk = ) qfq_new_fsk,
- _SI( .free_fsk = ) NULL,
- _SI( .new_queue = ) qfq_new_queue,
- _SI( .free_queue = ) qfq_free_queue,
-};
-
-DECLARE_DNSCHED_MODULE(dn_qfq, &qfq_desc);
-
-#ifdef QFQ_DEBUG
-static void
-dump_groups(struct qfq_sched *q, uint32_t mask)
-{
- int i, j;
-
- for (i = 0; i < QFQ_MAX_INDEX + 1; i++) {
- struct qfq_group *g = &q->groups[i];
-
- if (0 == (mask & (1<<i)))
- continue;
- for (j = 0; j < QFQ_MAX_SLOTS; j++) {
- if (g->slots[j])
- D(" bucket %d %p", j, g->slots[j]);
- }
- D("full_slots 0x%x", g->full_slots);
- D(" %2d S 0x%20llx F 0x%llx %c", i,
- g->S, g->F,
- mask & (1<<i) ? '1' : '0');
- }
-}
-
-static void
-dump_sched(struct qfq_sched *q, const char *msg)
-{
- D("--- in %s: ---", msg);
- ND("loops %d queued %d V 0x%llx", q->loops, q->queued, q->V);
- D(" ER 0x%08x", q->bitmaps[ER]);
- D(" EB 0x%08x", q->bitmaps[EB]);
- D(" IR 0x%08x", q->bitmaps[IR]);
- D(" IB 0x%08x", q->bitmaps[IB]);
- dump_groups(q, 0xffffffff);
-};
-#endif /* QFQ_DEBUG */
diff --git a/sys/netinet/ipfw/dn_sched_rr.c b/sys/netinet/ipfw/dn_sched_rr.c
deleted file mode 100644
index 1bbd800..0000000
--- a/sys/netinet/ipfw/dn_sched_rr.c
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * $FreeBSD$
- */
-
-#ifdef _KERNEL
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <net/if.h> /* IFNAMSIZ */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ipfw_rule_ref */
-#include <netinet/ip_fw.h> /* flow_id */
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-#else
-#include <dn_test.h>
-#endif
-
-#define DN_SCHED_RR 3 // XXX Where?
-
-struct rr_queue {
- struct dn_queue q; /* Standard queue */
- int status; /* 1: queue is in the list */
- int credit; /* Number of bytes to transmit */
- int quantum; /* quantum * C */
- struct rr_queue *qnext; /* */
-};
-
-/* struct rr_schk contains global config parameters
- * and is right after dn_schk
- */
-struct rr_schk {
- int min_q; /* Min quantum */
- int max_q; /* Max quantum */
- int q_bytes; /* Bytes per quantum */
-};
-
-/* per-instance round robin list, right after dn_sch_inst */
-struct rr_si {
- struct rr_queue *head, *tail; /* Pointer to current queue */
-};
-
-/* Append a queue to the rr list */
-static inline void
-rr_append(struct rr_queue *q, struct rr_si *si)
-{
- q->status = 1; /* mark as in-rr_list */
- q->credit = q->quantum; /* initialize credit */
-
- /* append to the tail */
- if (si->head == NULL)
- si->head = q;
- else
- si->tail->qnext = q;
- si->tail = q; /* advance the tail pointer */
- q->qnext = si->head; /* make it circular */
-}
-
-/* Remove the head queue from circular list. */
-static inline void
-rr_remove_head(struct rr_si *si)
-{
- if (si->head == NULL)
- return; /* empty queue */
- si->head->status = 0;
-
- if (si->head == si->tail) {
- si->head = si->tail = NULL;
- return;
- }
-
- si->head = si->head->qnext;
- si->tail->qnext = si->head;
-}
-
-/* Remove a queue from circular list.
- * XXX see if ti can be merge with remove_queue()
- */
-static inline void
-remove_queue_q(struct rr_queue *q, struct rr_si *si)
-{
- struct rr_queue *prev;
-
- if (q->status != 1)
- return;
- if (q == si->head) {
- rr_remove_head(si);
- return;
- }
-
- for (prev = si->head; prev; prev = prev->qnext) {
- if (prev->qnext != q)
- continue;
- prev->qnext = q->qnext;
- if (q == si->tail)
- si->tail = prev;
- q->status = 0;
- break;
- }
-}
-
-
-static inline void
-next_pointer(struct rr_si *si)
-{
- if (si->head == NULL)
- return; /* empty queue */
-
- si->head = si->head->qnext;
- si->tail = si->tail->qnext;
-}
-
-static int
-rr_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
-{
- struct rr_si *si;
- struct rr_queue *rrq;
-
- if (m != q->mq.head) {
- if (dn_enqueue(q, m, 0)) /* packet was dropped */
- return 1;
- if (m != q->mq.head)
- return 0;
- }
-
- /* If reach this point, queue q was idle */
- si = (struct rr_si *)(_si + 1);
- rrq = (struct rr_queue *)q;
-
- if (rrq->status == 1) /* Queue is already in the queue list */
- return 0;
-
- /* Insert the queue in the queue list */
- rr_append(rrq, si);
-
- return 0;
-}
-
-static struct mbuf *
-rr_dequeue(struct dn_sch_inst *_si)
-{
- /* Access scheduler instance private data */
- struct rr_si *si = (struct rr_si *)(_si + 1);
- struct rr_queue *rrq;
- uint64_t len;
-
- while ( (rrq = si->head) ) {
- struct mbuf *m = rrq->q.mq.head;
- if ( m == NULL) {
- /* empty queue, remove from list */
- rr_remove_head(si);
- continue;
- }
- len = m->m_pkthdr.len;
-
- if (len > rrq->credit) {
- /* Packet too big */
- rrq->credit += rrq->quantum;
- /* Try next queue */
- next_pointer(si);
- } else {
- rrq->credit -= len;
- return dn_dequeue(&rrq->q);
- }
- }
-
- /* no packet to dequeue*/
- return NULL;
-}
-
-static int
-rr_config(struct dn_schk *_schk)
-{
- struct rr_schk *schk = (struct rr_schk *)(_schk + 1);
- ND("called");
-
- /* use reasonable quantums (64..2k bytes, default 1500) */
- schk->min_q = 64;
- schk->max_q = 2048;
- schk->q_bytes = 1500; /* quantum */
-
- return 0;
-}
-
-static int
-rr_new_sched(struct dn_sch_inst *_si)
-{
- struct rr_si *si = (struct rr_si *)(_si + 1);
-
- ND("called");
- si->head = si->tail = NULL;
-
- return 0;
-}
-
-static int
-rr_free_sched(struct dn_sch_inst *_si)
-{
- ND("called");
- /* Nothing to do? */
- return 0;
-}
-
-static int
-rr_new_fsk(struct dn_fsk *fs)
-{
- struct rr_schk *schk = (struct rr_schk *)(fs->sched + 1);
- /* par[0] is the weight, par[1] is the quantum step */
- ipdn_bound_var(&fs->fs.par[0], 1,
- 1, 65536, "RR weight");
- ipdn_bound_var(&fs->fs.par[1], schk->q_bytes,
- schk->min_q, schk->max_q, "RR quantum");
- return 0;
-}
-
-static int
-rr_new_queue(struct dn_queue *_q)
-{
- struct rr_queue *q = (struct rr_queue *)_q;
-
- _q->ni.oid.subtype = DN_SCHED_RR;
-
- q->quantum = _q->fs->fs.par[0] * _q->fs->fs.par[1];
- ND("called, q->quantum %d", q->quantum);
- q->credit = q->quantum;
- q->status = 0;
-
- if (_q->mq.head != NULL) {
- /* Queue NOT empty, insert in the queue list */
- rr_append(q, (struct rr_si *)(_q->_si + 1));
- }
- return 0;
-}
-
-static int
-rr_free_queue(struct dn_queue *_q)
-{
- struct rr_queue *q = (struct rr_queue *)_q;
-
- ND("called");
- if (q->status == 1) {
- struct rr_si *si = (struct rr_si *)(_q->_si + 1);
- remove_queue_q(q, si);
- }
- return 0;
-}
-
-/*
- * RR scheduler descriptor
- * contains the type of the scheduler, the name, the size of the
- * structures and function pointers.
- */
-static struct dn_alg rr_desc = {
- _SI( .type = ) DN_SCHED_RR,
- _SI( .name = ) "RR",
- _SI( .flags = ) DN_MULTIQUEUE,
-
- _SI( .schk_datalen = ) 0,
- _SI( .si_datalen = ) sizeof(struct rr_si),
- _SI( .q_datalen = ) sizeof(struct rr_queue) - sizeof(struct dn_queue),
-
- _SI( .enqueue = ) rr_enqueue,
- _SI( .dequeue = ) rr_dequeue,
-
- _SI( .config = ) rr_config,
- _SI( .destroy = ) NULL,
- _SI( .new_sched = ) rr_new_sched,
- _SI( .free_sched = ) rr_free_sched,
- _SI( .new_fsk = ) rr_new_fsk,
- _SI( .free_fsk = ) NULL,
- _SI( .new_queue = ) rr_new_queue,
- _SI( .free_queue = ) rr_free_queue,
-};
-
-
-DECLARE_DNSCHED_MODULE(dn_rr, &rr_desc);
diff --git a/sys/netinet/ipfw/dn_sched_wf2q.c b/sys/netinet/ipfw/dn_sched_wf2q.c
deleted file mode 100644
index 7f16719..0000000
--- a/sys/netinet/ipfw/dn_sched_wf2q.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
- * Copyright (c) 2000-2002 Luigi Rizzo, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * $FreeBSD$
- */
-
-#ifdef _KERNEL
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <net/if.h> /* IFNAMSIZ */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ipfw_rule_ref */
-#include <netinet/ip_fw.h> /* flow_id */
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-#else
-#include <dn_test.h>
-#endif
-
-#ifndef MAX64
-#define MAX64(x,y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x)
-#endif
-
-/*
- * timestamps are computed on 64 bit using fixed point arithmetic.
- * LMAX_BITS, WMAX_BITS are the max number of bits for the packet len
- * and sum of weights, respectively. FRAC_BITS is the number of
- * fractional bits. We want FRAC_BITS >> WMAX_BITS to avoid too large
- * errors when computing the inverse, FRAC_BITS < 32 so we can do 1/w
- * using an unsigned 32-bit division, and to avoid wraparounds we need
- * LMAX_BITS + WMAX_BITS + FRAC_BITS << 64
- * As an example
- * FRAC_BITS = 26, LMAX_BITS=14, WMAX_BITS = 19
- */
-#ifndef FRAC_BITS
-#define FRAC_BITS 28 /* shift for fixed point arithmetic */
-#define ONE_FP (1UL << FRAC_BITS)
-#endif
-
-/*
- * Private information for the scheduler instance:
- * sch_heap (key is Finish time) returns the next queue to serve
- * ne_heap (key is Start time) stores not-eligible queues
- * idle_heap (key=start/finish time) stores idle flows. It must
- * support extract-from-middle.
- * A flow is only in 1 of the three heaps.
- * XXX todo: use a more efficient data structure, e.g. a tree sorted
- * by F with min_subtree(S) in each node
- */
-struct wf2qp_si {
- struct dn_heap sch_heap; /* top extract - key Finish time */
- struct dn_heap ne_heap; /* top extract - key Start time */
- struct dn_heap idle_heap; /* random extract - key Start=Finish time */
- uint64_t V; /* virtual time */
- uint32_t inv_wsum; /* inverse of sum of weights */
- uint32_t wsum; /* sum of weights */
-};
-
-struct wf2qp_queue {
- struct dn_queue _q;
- uint64_t S, F; /* start time, finish time */
- uint32_t inv_w; /* ONE_FP / weight */
- int32_t heap_pos; /* position (index) of struct in heap */
-};
-
-/*
- * This file implements a WF2Q+ scheduler as it has been in dummynet
- * since 2000.
- * The scheduler supports per-flow queues and has O(log N) complexity.
- *
- * WF2Q+ needs to drain entries from the idle heap so that we
- * can keep the sum of weights up to date. We can do it whenever
- * we get a chance, or periodically, or following some other
- * strategy. The function idle_check() drains at most N elements
- * from the idle heap.
- */
-static void
-idle_check(struct wf2qp_si *si, int n, int force)
-{
- struct dn_heap *h = &si->idle_heap;
- while (n-- > 0 && h->elements > 0 &&
- (force || DN_KEY_LT(HEAP_TOP(h)->key, si->V))) {
- struct dn_queue *q = HEAP_TOP(h)->object;
- struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
-
- heap_extract(h, NULL);
- /* XXX to let the flowset delete the queue we should
- * mark it as 'unused' by the scheduler.
- */
- alg_fq->S = alg_fq->F + 1; /* Mark timestamp as invalid. */
- si->wsum -= q->fs->fs.par[0]; /* adjust sum of weights */
- if (si->wsum > 0)
- si->inv_wsum = ONE_FP/si->wsum;
- }
-}
-
-static int
-wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m)
-{
- struct dn_fsk *fs = q->fs;
- struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
- struct wf2qp_queue *alg_fq;
- uint64_t len = m->m_pkthdr.len;
-
- if (m != q->mq.head) {
- if (dn_enqueue(q, m, 0)) /* packet was dropped */
- return 1;
- if (m != q->mq.head) /* queue was already busy */
- return 0;
- }
-
- /* If reach this point, queue q was idle */
- alg_fq = (struct wf2qp_queue *)q;
-
- if (DN_KEY_LT(alg_fq->F, alg_fq->S)) {
- /* F<S means timestamps are invalid ->brand new queue. */
- alg_fq->S = si->V; /* init start time */
- si->wsum += fs->fs.par[0]; /* add weight of new queue. */
- si->inv_wsum = ONE_FP/si->wsum;
- } else { /* if it was idle then it was in the idle heap */
- heap_extract(&si->idle_heap, q);
- alg_fq->S = MAX64(alg_fq->F, si->V); /* compute new S */
- }
- alg_fq->F = alg_fq->S + len * alg_fq->inv_w;
-
- /* if nothing is backlogged, make sure this flow is eligible */
- if (si->ne_heap.elements == 0 && si->sch_heap.elements == 0)
- si->V = MAX64(alg_fq->S, si->V);
-
- /*
- * Look at eligibility. A flow is not eligibile if S>V (when
- * this happens, it means that there is some other flow already
- * scheduled for the same pipe, so the sch_heap cannot be
- * empty). If the flow is not eligible we just store it in the
- * ne_heap. Otherwise, we store in the sch_heap.
- * Note that for all flows in sch_heap (SCH), S_i <= V,
- * and for all flows in ne_heap (NEH), S_i > V.
- * So when we need to compute max(V, min(S_i)) forall i in
- * SCH+NEH, we only need to look into NEH.
- */
- if (DN_KEY_LT(si->V, alg_fq->S)) {
- /* S>V means flow Not eligible. */
- if (si->sch_heap.elements == 0)
- D("++ ouch! not eligible but empty scheduler!");
- heap_insert(&si->ne_heap, alg_fq->S, q);
- } else {
- heap_insert(&si->sch_heap, alg_fq->F, q);
- }
- return 0;
-}
-
-/* XXX invariant: sch > 0 || V >= min(S in neh) */
-static struct mbuf *
-wf2qp_dequeue(struct dn_sch_inst *_si)
-{
- /* Access scheduler instance private data */
- struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
- struct mbuf *m;
- struct dn_queue *q;
- struct dn_heap *sch = &si->sch_heap;
- struct dn_heap *neh = &si->ne_heap;
- struct wf2qp_queue *alg_fq;
-
- if (sch->elements == 0 && neh->elements == 0) {
- /* we have nothing to do. We could kill the idle heap
- * altogether and reset V
- */
- idle_check(si, 0x7fffffff, 1);
- si->V = 0;
- si->wsum = 0; /* should be set already */
- return NULL; /* quick return if nothing to do */
- }
- idle_check(si, 1, 0); /* drain something from the idle heap */
-
- /* make sure at least one element is eligible, bumping V
- * and moving entries that have become eligible.
- * We need to repeat the first part twice, before and
- * after extracting the candidate, or enqueue() will
- * find the data structure in a wrong state.
- */
- m = NULL;
- for(;;) {
- /*
- * Compute V = max(V, min(S_i)). Remember that all elements
- * in sch have by definition S_i <= V so if sch is not empty,
- * V is surely the max and we must not update it. Conversely,
- * if sch is empty we only need to look at neh.
- * We don't need to move the queues, as it will be done at the
- * next enqueue
- */
- if (sch->elements == 0 && neh->elements > 0) {
- si->V = MAX64(si->V, HEAP_TOP(neh)->key);
- }
- while (neh->elements > 0 &&
- DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) {
- q = HEAP_TOP(neh)->object;
- alg_fq = (struct wf2qp_queue *)q;
- heap_extract(neh, NULL);
- heap_insert(sch, alg_fq->F, q);
- }
- if (m) /* pkt found in previous iteration */
- break;
- /* ok we have at least one eligible pkt */
- q = HEAP_TOP(sch)->object;
- alg_fq = (struct wf2qp_queue *)q;
- m = dn_dequeue(q);
- heap_extract(sch, NULL); /* Remove queue from heap. */
- si->V += (uint64_t)(m->m_pkthdr.len) * si->inv_wsum;
- alg_fq->S = alg_fq->F; /* Update start time. */
- if (q->mq.head == 0) { /* not backlogged any more. */
- heap_insert(&si->idle_heap, alg_fq->F, q);
- } else { /* Still backlogged. */
- /* Update F, store in neh or sch */
- uint64_t len = q->mq.head->m_pkthdr.len;
- alg_fq->F += len * alg_fq->inv_w;
- if (DN_KEY_LEQ(alg_fq->S, si->V)) {
- heap_insert(sch, alg_fq->F, q);
- } else {
- heap_insert(neh, alg_fq->S, q);
- }
- }
- }
- return m;
-}
-
-static int
-wf2qp_new_sched(struct dn_sch_inst *_si)
-{
- struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
- int ofs = offsetof(struct wf2qp_queue, heap_pos);
-
- /* all heaps support extract from middle */
- if (heap_init(&si->idle_heap, 16, ofs) ||
- heap_init(&si->sch_heap, 16, ofs) ||
- heap_init(&si->ne_heap, 16, ofs)) {
- heap_free(&si->ne_heap);
- heap_free(&si->sch_heap);
- heap_free(&si->idle_heap);
- return ENOMEM;
- }
- return 0;
-}
-
-static int
-wf2qp_free_sched(struct dn_sch_inst *_si)
-{
- struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1);
-
- heap_free(&si->sch_heap);
- heap_free(&si->ne_heap);
- heap_free(&si->idle_heap);
-
- return 0;
-}
-
-static int
-wf2qp_new_fsk(struct dn_fsk *fs)
-{
- ipdn_bound_var(&fs->fs.par[0], 1,
- 1, 100, "WF2Q+ weight");
- return 0;
-}
-
-static int
-wf2qp_new_queue(struct dn_queue *_q)
-{
- struct wf2qp_queue *q = (struct wf2qp_queue *)_q;
-
- _q->ni.oid.subtype = DN_SCHED_WF2QP;
- q->F = 0; /* not strictly necessary */
- q->S = q->F + 1; /* mark timestamp as invalid. */
- q->inv_w = ONE_FP / _q->fs->fs.par[0];
- if (_q->mq.head != NULL) {
- wf2qp_enqueue(_q->_si, _q, _q->mq.head);
- }
- return 0;
-}
-
-/*
- * Called when the infrastructure removes a queue (e.g. flowset
- * is reconfigured). Nothing to do if we did not 'own' the queue,
- * otherwise remove it from the right heap and adjust the sum
- * of weights.
- */
-static int
-wf2qp_free_queue(struct dn_queue *q)
-{
- struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q;
- struct wf2qp_si *si = (struct wf2qp_si *)(q->_si + 1);
-
- if (alg_fq->S >= alg_fq->F + 1)
- return 0; /* nothing to do, not in any heap */
- si->wsum -= q->fs->fs.par[0];
- if (si->wsum > 0)
- si->inv_wsum = ONE_FP/si->wsum;
-
- /* extract from the heap. XXX TODO we may need to adjust V
- * to make sure the invariants hold.
- */
- if (q->mq.head == NULL) {
- heap_extract(&si->idle_heap, q);
- } else if (DN_KEY_LT(si->V, alg_fq->S)) {
- heap_extract(&si->ne_heap, q);
- } else {
- heap_extract(&si->sch_heap, q);
- }
- return 0;
-}
-
-/*
- * WF2Q+ scheduler descriptor
- * contains the type of the scheduler, the name, the size of the
- * structures and function pointers.
- */
-static struct dn_alg wf2qp_desc = {
- _SI( .type = ) DN_SCHED_WF2QP,
- _SI( .name = ) "WF2Q+",
- _SI( .flags = ) DN_MULTIQUEUE,
-
- /* we need extra space in the si and the queue */
- _SI( .schk_datalen = ) 0,
- _SI( .si_datalen = ) sizeof(struct wf2qp_si),
- _SI( .q_datalen = ) sizeof(struct wf2qp_queue) -
- sizeof(struct dn_queue),
-
- _SI( .enqueue = ) wf2qp_enqueue,
- _SI( .dequeue = ) wf2qp_dequeue,
-
- _SI( .config = ) NULL,
- _SI( .destroy = ) NULL,
- _SI( .new_sched = ) wf2qp_new_sched,
- _SI( .free_sched = ) wf2qp_free_sched,
-
- _SI( .new_fsk = ) wf2qp_new_fsk,
- _SI( .free_fsk = ) NULL,
-
- _SI( .new_queue = ) wf2qp_new_queue,
- _SI( .free_queue = ) wf2qp_free_queue,
-};
-
-
-DECLARE_DNSCHED_MODULE(dn_wf2qp, &wf2qp_desc);
diff --git a/sys/netinet/ipfw/dummynet.txt b/sys/netinet/ipfw/dummynet.txt
deleted file mode 100644
index e4f3075..0000000
--- a/sys/netinet/ipfw/dummynet.txt
+++ /dev/null
@@ -1,860 +0,0 @@
-#
-# $FreeBSD$
-#
-
-Notes on the internal structure of dummynet (2010 version)
-by Riccardo Panicucci and Luigi Rizzo
-Work supported by the EC project ONELAB2
-
-
-*********
-* INDEX *
-*********
-Implementation of new dummynet
- Internal structure
- Files
-Packet arrival
- The reconfiguration routine
-dummynet_task()
-Configuration
- Add a pipe
- Add a scheduler
- Add a flowset
-Listing object
-Delete of object
- Delete a pipe
- Delete a flowset
- Delete a scheduler
-Compatibility with FreeBSD7.2 and FreeBSD 8 ipfw binary
- ip_dummynet_glue.c
- ip_fw_glue.c
-How to configure dummynet
-How to implement a new scheduler
-
-
-
-OPEN ISSUES
-------------------------------
-20100131 deleting RR causes infinite loop
- presumably in the rr_free_queue() call -- seems to hang
- forever when deleting a live flow
-------------------------------
-
-Dummynet is a traffic shaper and network emulator. Packets are
-selected by an external filter such as ipfw, and passed to the emulator
-with a tag such as "pipe 10" or "queue 5" which tells what to
-do with the packet. As an example
-
- ipfw add queue 5 icmp from 10.0.0.2 to all
-
-All packets with the same tag belong to a "flowset", or a set
-of flows which can be further partitioned according to a mask.
-Flowsets are then passed to a scheduler for processing. The
-association of flowsets and schedulers is configurable e.g.
-
- ipfw queue 5 config sched 10 weight 3 flow_mask xxxx
- ipfw queue 8 config sched 10 weight 1 ...
- ipfw queue 3 config sched 20 weight 1 ...
-
-"sched 10" represents one or more scheduler instances,
-selected through a mask on the 5-tuple itself.
-
- ipfw sched 20 config type FIFO sched_mask yyy ...
-
-There are in fact two masks applied to each packet:
-+ the "sched_mask" sends packets arriving to a scheduler_id to
- one of many instances.
-+ the "flow_mask" together with the flowset_id is used to
- collect packets into independent flows on each scheduler.
-
-As an example, we can have
- ipfw queue 5 config sched 10 flow_mask src-ip 0x000000ff
- ipfw sched 10 config type WF2Q+ sched_mask src-ip 0xffffff00
-
-means that sched 10 will have one instance per /24 source subnet,
-and within that, each individual source will be a flow.
-
-Internal structure
------------------
-Dummynet-related data is split into several data structures,
-part of them constituting the userland-kernel API, and others
-specific to the kernel.
-NOTE: for up-to-date details please look at the relevant source
- headers (ip_dummynet.h, ip_dn_private.h, dn_sched.h)
-
-USERLAND-KERNEL API (ip_dummynet.h)
-
- struct dn_link:
- contains data about the physical link such as
- bandwith, delay, burst size;
-
- struct dn_fs:
- describes a flowset, i.e. a template for queues.
- Main parameters are the scheduler we attach to, a flow_mask,
- buckets, queue size, plr, weight, and other scheduler-specific
- parameters.
-
- struct dn_flow
- contains information on a flow, including masks and
- statistics
-
- struct dn_sch:
- defines a scheduler (and a link attached to it).
- Parameters include scheduler type, sched_mask, number of
- buckets, and possibly other scheduler-specific parameters,
-
- struct dn_profile:
- fields to simulate a delay profile
-
-
-KERNEL REPRESENTATION (ip_dn_private.h)
-
- struct mq
- a queue of mbufs with head and tail.
-
- struct dn_queue
- individual queue of packets, created by a flowset using
- flow_mask and attached to a scheduler instance selected
- through sched_mask.
- A dn_queue has a pointer to the dn_fsk (which in turn counts
- how many queues point to it), a pointer to the
- dn_sch_inst it attaches to, and is in a hash table in the
- flowset. scheduler instances also should store queues in
- their own containers used for scheduling (lists, trees, etc.)
- CREATE: done on packet arrivals when a flow matches a flowset.
- DELETE: done only when deleting the parent dn_sch_inst
- or draining memory.
-
- struct dn_fsk
- includes a dn_fs; a pointer to the dn_schk; a link field
- for the list of dn_fsk attached to the same scheduler,
- or for the unlinked list;
- a refcount for the number of queues pointing to it;
- The dn_fsk is in a hash table, fshash.
- CREATE: done on configuration commands.
- DELETE: on configuration commands.
-
- struct dn_sch_inst
- a scheduler instance, created from a dn_schk applying sched_mask.
- Contains a delay line, a reference to the parent, and scheduler-
- specific info. Both dn_sch_inst and its delay line can be in the
- evheap if they have events to be processed.
- CREATE: created from a dn_schk applying sched_mask
- DELETE: configuration command delete a scheduler which in turn
- sweeps the hash table of instances deleting them
-
- struct dn_schk
- includes dn_sch, dn_link, a pointer to dn_profile,
- a hash table of dn_sch_inst, a list of dn_fsk
- attached to it.
- CREATE: configuration command. If there are flowsets that
- refer to this number, they are attached and moved
- to the hash table
- DELETE: manual, see dn_sch_inst
-
-
- fshash schedhash
- +---------------+ sched +--------------+
- | sched-------------------->| NEW_SCHK|
- -<----*sch_chain |<-----------------*fsk_list |
- |NEW_FSK |<----. | [dn_link] |
- +---------------+ | +--------------+
- |qht (hash) | | | siht(hash) |
- | [dn_queue] | | | [dn_si] |
- | [dn_queue] | | | [dn_si] |
- | ... | | | ... |
- | +--------+ | | | +---------+ |
- | |dn_queue| | | | |dn_si | |
- | | fs *----------' | | | |
- | | si *---------------------->| | |
- | +---------+ | | +---------+ |
- +---------------+ +--------------+
-
-The following global data structures contain all
-schedulers and flowsets.
-
-- schedhash[x]: contains all scheduler templates in the system.
- Looked up only on manual configurations, where flowsets
- are attached to matching schedulers.
- We have one entry per 'sched X config' command
- (plus one for each 'pipe X config').
-
-- fshash[x]: contains all flowsets.
- We do a lookup on this for each packet.
- We have one entry for each 'queue X config'
- (plus one for each 'pipe X config').
-
-Additionally, a list that contains all unlinked flowset:
-- fsu: contains flowset that are not linked with any scheduler.
- Flowset are put in this list when they refer to a non
- existing scheduler.
- We don't need an efficient data structure as we never search
- here on a packet arrivals.
-
-Scheduler instances and the delay lines associated with each scheduler
-instance need to be woken up at certain times. Because we have many
-such objects, we keep them in a priority heap (system_heap).
-
-Almost all objects in this implementation are preceded by a structure
-(struct dn_id) which makes it easier to identify them.
-
-
-Files
------
-The dummynet code is split in several files.
-All kernel code is in sys/netinet/ipfw except ip_dummynet.h
-All userland code is in sbin/ipfw.
-Files are
-- sys/netinet/ip_dummynet.h defines the kernel-userland API
-- ip_dn_private.h contains the kernel-specific APIs
- and data structures
-- dn_sched.h defines the scheduler API
-- ip_dummynet.c cointains module glue and sockopt handlers, with all
- functions to configure and list objects.
-- ip_dn_io.c contains the functions directly related to packet processing,
- and run in the critical path. It also contains some functions
- exported to the schedulers.
-- dn_heap.[ch] implement a binary heap and a generic hash table
-- dn_sched_* implement the various scheduler modules
-
-- dummynet.c is the file used to implement the user side of dummynet.
- It contains the function to parsing command line, and functions to
- show the output of dummynet objects.
-Moreover, there are two new file (ip_dummynet_glue.c and ip_fw_glue.c) that
-are used to allow compatibility with the "ipfw" binary from FreeBSD 7.2 and
-FreeBSD 8.
-
-LOCKING
-=======
-At the moment the entire processing occurs under a single lock
-which is expected to be acquired in exclusive mode
-DN_BH_WLOCK() / DN_BH_WUNLOCK().
-
-In perspective we aim at the following:
-- the 'busy' flag, 'pending' list and all structures modified by packet
- arrivals and departures are protected by the BH_WLOCK.
- This is normally acquired in exclusive mode by the packet processing
- functions for short sections of code (exception -- the timer).
- If 'busy' is not set, we can do regular packet processing.
- If 'busy' is set, no pieces can be accessed.
- We must enqueue the packet on 'pending' and return immediately.
-
-- the 'busy' flag is set/cleared by long sections of code as follows:
- UH_WLOCK(); KASSERT(busy == 0);
- BH_WLOCK(); busy=1; BH_WUNLOCK();
- ... do processing ...
- BH_WLOCK(); busy=0; drain_queue(pending); BH_WUNLOCK();
- UH_WUNLOCK();
- this normally happens when the upper half has something heavy
- to do. The prologue and epilogue are not in the critical path.
-
-- the main containers (fshash, schedhash, ...) are protected by
- UH_WLOCK.
-
-Packet processing
-=================
-A packet enters dummynet through dummynet_io(). We first lookup
-the flowset number in fshash using dn_ht_find(), then find the scheduler
-instance using ipdn_si_find(), then possibly identify the correct
-queue with ipdn_q_find().
-If successful, we call the scheduler's enqueue function(), and
-if needed start I/O on the link calling serve_sched().
-If the packet can be returned immediately, this is done by
-leaving *m0 set. Otherwise, the packet is absorbed by dummynet
-and we simply return, possibly with some appropriate error code.
-
-Reconfiguration
----------------
-Reconfiguration is the complex part of the system because we need to
-keep track of the various objects and containers.
-At the moment we do not use reference counts for objects so all
-processing must be done under a lock.
-
-The main entry points for configuration is the ip_dn_ctl() handler
-for the IP_DUMMYNET3 sockopt (others are provided only for backward
-compatibility). Modifications to the configuration call do_config().
-The argument is a sequence of blocks each starting with a struct dn_id
-which specifies its content.
-The first dn_id must contain as obj.id the DN_API_VERSION
-The obj.type is DN_CMD_CONFIG (followed by actual objects),
-DN_CMD_DELETE (with the correct subtype and list of objects), or
-DN_CMD_FLUSH.
-
-DN_CMD_CONFIG is followed by objects to add/reconfigure. In general,
-if an object already exists it is reconfigured, otherwise it is
-created in a way that keeps the structure consistent.
-We have the following objects in the system, normally numbered with
-an identifier N between 1 and 65535. For certain objects we have
-"shadow" copies numbered I+NMAX and I+ 2*NMAX which are used to
-implement certain backward compatibility features.
-
-In general we have the following linking
-
- TRADITIONAL DUMMYNET QUEUES "queue N config ... pipe M ..."
- corresponds to a dn_fs object numbered N
-
- TRADITIONAL DUMMYNET PIPES "pipe N config ..."
- dn_fs N+2*NMAX --> dn_sch N+NMAX type FIFO --> dn_link N+NMAX
-
- GENERIC SCHEDULER "sched N config ... "
- [dn_fs N+NMAX] --> dn_sch N --> dn_link N
- The flowset N+NMAX is created only if the scheduler is not
- of type MULTIQUEUE.
-
- DELAY PROFILE "pipe N config profile ..."
- it is always attached to an existing dn_link N
-
-Because traditional dummynet pipes actually configure both a
-'standalone' instance and one that can be used by queues,
-we do the following:
-
- "pipe N config ..." configures:
- dn_sched N type WF2Q+
- dn_sched N+NMAX type FIFO
- dn_fs N+2NMAX attached to dn_sched N+NMAX
- dn_pipe N
- dn_pipe N+NMAX
-
- "queue N config" configures
- dn_fs N
-
- "sched N config" configures
- dn_sched N type as desired
- dn_fs N+NMAX attached to dn_sched N
-
-
-dummynet_task()
-===============
-The dummynet_task() function is the main dummynet processing function and is
-called every tick. This function first calculate the new current time, then
-it checks if it is the time to wake up object from the system_heap comparing
-the current time and the key of the heap. Two types of object (really the
-heap contains pointer to objects) are in the
-system_heap:
-
-- scheduler instance: if a scheduler instance is waked up, the dequeue()
- function is called until it has credit. If the dequeue() returns packets,
- the scheduler instance is inserted in the heap with a new key depending of
- the data that will be send out. If the scheduler instance remains with
- some credit, it means that is hasn't other packet to send and so the
- instance is no longer inserted in the heap.
-
- If the scheduler instance extracted from the heap has the DELETE flag set,
- the dequeue() is not called and the instance is destroyed now.
-
-- delay line: when extracting a delay line, the function transmit_event() is
- called to send out packet from delay line.
-
- If the scheduler instance associated with this delay line doesn't exists,
- the delay line will be delete now.
-
-Configuration
-=============
-To create a pipe, queue or scheduler, the user should type commands like:
-"ipfw pipe x config"
-"ipfw queue y config pipe x"
-"ipfw pipe x config sched <type>"
-
-The userland side of dummynet will prepare a buffer contains data to pass to
-kernel side.
-The buffer contains all struct needed to configure an object. In more detail,
-to configure a pipe all three structs (dn_link, dn_sch, dn_fs) are needed,
-plus the delay profile struct if the pipe has a delay profile.
-
-If configuring a scheduler only the struct dn_sch is wrote in the buffer,
-while if configuring a flowset only the dn_fs struct is wrote.
-
-The first struct in the buffer contains the type of command request, that is
-if it is configuring a pipe, a queue, or a scheduler. Then there are structs
-need to configure the object, and finally there is the struct that mark
-the end of the buffer.
-
-To support the insertion of pipe and queue using the old syntax, when adding
-a pipe it's necessary to create a FIFO flowset and a FIFO scheduler, which
-have a number x + DN_PIPEOFFSET.
-
-Add a pipe
-----------
-A pipe is only a template for a link.
-If the pipe already exists, parameters are updated. If a delay profile exists
-it is deleted and a new one is created.
-If the pipe doesn't exist a new one is created. After the creation, the
-flowset unlinked list is scanned to see if there are some flowset that would
-be linked with this pipe. If so, these flowset will be of wf2q+ type (for
-compatibility) and a new wf2q+ scheduler is created now.
-
-Add a scheduler
----------------
-If the scheduler already exists, and the type and the mask are the same, the
-scheduler is simply reconfigured calling the config_scheduler() scheduler
-function with the RECONFIGURE flag active.
-If the type or the mask differ, it is necessary to delete the old scheduler
-and create a new one.
-If the scheduler doesn't exists, a new one is created. If the scheduler has
-a mask, the hash table is created to store pointers to scheduler instances.
-When a new scheduler is created, it is necessary to scan the unlinked
-flowset list to search eventually flowset that would be linked with this
-scheduler number. If some are found, flowsets became of the type of this
-scheduler and they are configured properly.
-
-Add a flowset
--------------
-Flowset pointers are store in the system in two list. The unlinked flowset list
-contains all flowset that aren't linked with a scheduler, the flowset list
-contains flowset linked to a scheduler, and so they have a type.
-When adding a new flowset, first it is checked if the flowset exists (that is,
-it is in the flowset list) and if it doesn't exists a new flowset is created
-and added to unlinked flowset list if the scheduler which the flowset would be
-linked doesn't exists, or added in the flowset list and configured properly if
-the scheduler exists. If the flowset (before to be created) was in the
-unlinked flowset list, it is removed and deleted, and then recreated.
-If the flowset exists, to allow reconfiguration of this flowset, the
-scheduler number and types must match with the one in memory. If this isn't
-so, the flowset is deleted and a new one will be created. Really, the flowset
-it isn't deleted now, but it is removed from flowset list and it will be
-deleted later because there could be some queues that are using it.
-
-Listing of object
-=================
-The user can request a list of object present in dummynet through the command
-"ipfw [-v] pipe|queue [x] list|show"
-The kernel side of dummynet send a buffer to user side that contains all
-pipe, all scheduler, all flowset, plus all scheduler instances and all queues.
-The dummynet user land will format the output and show only the relevant
-information.
-The buffer sent start with all pipe from the system. The entire struct dn_link
-is passed, except the delay_profile struct that is useless in user space.
-After pipes, all flowset are wrote in the buffer. The struct contains
-scheduler flowset specific data is linked with the flowset writing the
-'obj' id of the extension into the 'alg_fs' pointer.
-Then schedulers are wrote. If a scheduler has one or more scheduler instance,
-these are linked to the parent scheduler writing the id of the parent in the
-'ptr_sched' pointer. If a scheduler instance has queues, there are wrote in
-the buffer and linked thorugh the 'obj' and 'sched_inst' pointer.
-Finally, flowsets in the unlinked flowset list are write in the buffer, and
-then a struct gen in saved in the buffer to mark the last struct in the buffer.
-
-
-Delete of object
-================
-An object is usually removed by user through a command like
-"ipfw pipe|queue x delete". XXX sched?
-ipfw pass to the kernel a struct gen that contains the type and the number
-of the object to remove
-
-Delete of pipe x
-----------------
-A pipe can be deleted by the user throught the command 'ipfw pipe x delete'.
-To delete a pipe, the pipe is removed from the pipe list, and then deleted.
-Also the scheduler associated with this pipe should be deleted.
-For compatibility with old dummynet syntax, the associated FIFO scheduler and
-FIFO flowset must be deleted.
-
-Delete of flowset x
--------------------
-To remove a flowset, we must be sure that is no loger referenced by any object.
-If the flowset to remove is in the unlinked flowset list, there is not any
-issue, the flowset can be safely removed calling a free() (the flowset
-extension is not yet created if the flowset is in this list).
-If the flowset is in the flowset list, first we remove from it so new packet
-are discarded when arrive. Next, the flowset is marked as delete.
-Now we must check if some queue is using this flowset.
-To do this, a counter (active_f) is provided. This counter indicate how many
-queues exist using this flowset.
-The active_f counter is automatically incremented when a queue is created
-and decremented when a queue is deleted.
-If the counter is 0, the flowset can be safely deleted, and the delete_alg_fs()
-scheduler function is called before deallocate memory.
-If the counter is not 0, the flowset remain in memory until the counter become
-zero. When a queue is delete (by dn_delete_queue() function) it is checked if
-the linked flowset is deleting and if so the counter is decrementing. If the
-counter reaches 0, the flowset is deleted.
-The deletion of a queue can be done only by the scheduler, or when the scheduler
-is destroyed.
-
-Delete of scheduler x
----------------------
-To delete a scheduler we must be sure that any scheduler instance of this type
-are in the system_heap. To do so, a counter (inst_counter) is provided.
-This counter is managed by the system: it is incremented every time it is
-inserted in the system_heap, and decremented every time it is extracted from it.
-To delete the scheduler, first we remove it from the scheduler list, so new
-packet are discarded when they arrive, and mark the scheduler as deleting.
-
-If the counter is 0, we can remove the scheduler safely calling the
-really_deletescheduler() function. This function will scan all scheduler
-instances and call the delete_scheduler_instance() function that will delete
-the instance. When all instance are deleted, the scheduler template is
-deleted calling the delete_scheduler_template(). If the delay line associate
-with the scheduler is empty, it is deleted now, else it will be deleted when
-it will became empy.
-If the counter was not 0, we wait for it. Every time the dummynet_task()
-function extract a scheduler from the system_heap, the counter is decremented.
-If the scheduler has the delete flag enabled the dequeue() is not called and
-delete_scheduler_instance() is called to delete the instance.
-Obviously this scheduler instance is no loger inserted in the system_heap.
-If the counter reaches 0, the delete_scheduler_template() function is called
-all memory is released.
-NOTE: Flowsets that belong to this scheduler are not deleted, so if a new
- scheduler with the same number is inserted will use these flowsets.
- To do so, the best approach would be insert these flowset in the
- unlinked flowset list, but doing this now will be very expensive.
- So flowsets will remain in memory and linked with a scheduler that no
- longer exists until a packet belonging to this flowset arrives. When
- this packet arrives, the reconfigure() function is called because the
- generation number mismatch with one contains in the flowset and so
- the flowset will be moved into the flowset unlinked list, or will be
- linked with the new scheduler if a new one was created.
-
-
-COMPATIBILITY WITH FREEBSD 7.2 AND FREEBSD 8 'IPFW' BINARY
-==========================================================
-Dummynet is not compatible with old ipfw binary because internal structs are
-changed. Moreover, the old ipfw binary is not compatible with new kernels
-because the struct that represents a firewall rule has changed. So, if a user
-install a new kernel on a FreeBSD 7.2, the ipfw (and possibly many other
-commands) will not work.
-New dummynet uses a new socket option: IP_DUMMYNET3, used for both set and get.
-The old option can be used to allow compatibility with the 'ipfw' binary of
-older version (tested with 7.2 and 8.0) of FreeBSD.
-Two file are provided for this purpose:
-- ip_dummynet_glue.c translates old dummynet requests to the new ones,
-- ip_fw_glue.c converts the rule format between 7.2 and 8 versions.
-Let see in detail these two files.
-
-IP_DUMMYNET_GLUE.C
-------------------
-The internal structs of new dummynet are very different from the original.
-Because of there are some difference from between dummynet in FreeBSD 7.2 and
-dummynet in FreeBSD 8 (the FreeBSD 8 version includes support to pipe delay
-profile and burst option), I have to include both header files. I copied
-the revision 191715 (for version 7.2) and the revision 196045 (for version 8)
-and I appended a number to each struct to mark them.
-
-The main function of this file is ip_dummynet_compat() that is called by
-ip_dn_ctl() when it receive a request of old socket option.
-
-A global variabile ('is7') store the version of 'ipfw' that FreeBSD is using.
-This variable is set every time a request of configuration is done, because
-with this request we receive a buffer of which size depending of ipfw version.
-Because of in general the first action is a configuration, this variable is
-usually set accordly. If the first action is a request of listing of pipes
-or queues, the system cannot know the version of ipfw, and we suppose that
-version 7.2 is used. If version is wrong, the output can be senseless, but
-the application should not crash.
-
-There are four request for old dummynet:
-- IP_DUMMYNET_FLUSH: the flush options have no parameter, so simply the
- dummynet_flush() function is called;
-- IP_DUMMYNET_DEL: the delete option need to be translate.
- It is only necessary to extract the number and the type of the object
- (pipe or queue) to delete from the buffer received and build a new struct
- gen contains the right parameters, then call the delete_object() function;
-- IP_DUMMYNET_CONFIGURE: the configure command receive a buffer depending of
- the ipfw version. After the properly extraction of all data, that depends
- by the ipfw version used, new structures are filled and then the dummynet
- config_link() function is properly called. Note that the 7.2 version does
- not support some parameter as burst or delay profile.
-- IP_DUMMYNET_GET: The get command should send to the ipfw the correct buffer
- depending of its version. There are two function that build the
- corrected buffer, ip_dummynet_get7() and ip_dummynet_get8(). These
- functions reproduce the buffer exactly as 'ipfw' expect. The only difference
- is that the weight parameter for a queue is no loger sent by dummynet and so
- it is set to 0.
- Moreover, because of the internal structure has changed, the bucket size
- of a queue could not be correct, because now all flowset share the hash
- table.
- If the version of ipfw is wrong, the output could be senseless or truncated,
- but the application should not crash.
-
-IP_FW_GLUE.C
-------------
-The ipfw binary also is used to add rules to FreeBSD firewall. Because of the
-struct ip_fw is changed from FreeBsd 7.2 to FreeBSD 8, it is necessary
-to write some glue code to allow use ipfw from FreeBSD 7.2 with the kernel
-provided with FreeBSD 8.
-This file contains two functions to convert a rule from FreeBSD 7.2 format to
-FreeBSD 8 format, and viceversa.
-The conversion should be done when a rule passes from userspace to kernel space
-and viceversa.
-I have to modify the ip_fw2.c file to manage these two case, and added a
-variable (is7) to store the ipfw version used, using an approach like the
-previous file:
-- when a new rule is added (option IP_FW_ADD) the is7 variable is set if the
- size of the rule received corrispond to FreeBSD 7.2 ipfw version. If so, the
- rule is converted to version 8 calling the function convert_rule_to_8().
- Moreover, after the insertion of the rule, the rule is now reconverted to
- version 7 because the ipfw binary will print it.
-- when the user request a list of rules (option IP_FW_GET) the is7 variable
- should be set correctly because we suppose that a configure command was done,
- else we suppose that the FreeBSD version is 8. The function ipfw_getrules()
- in ip_fw2.c file return all rules, eventually converted to version 7 (if
- the is7 is set) to the ipfw binary.
-The conversion of a rule is quite simple. The only difference between the
-two structures (struct ip_fw) is that in the new there is a new field
-(uint32_t id). So, I copy the entire rule in a buffer and the copy the rule in
-the right position in the new (or old) struct. The size of commands are not
-changed, and the copy is done into a cicle.
-
-How to configure dummynet
-=========================
-It is possible to configure dummynet through two main commands:
-'ipfw pipe' and 'ipfw queue'.
-To allow compatibility with old version, it is possible configure dummynet
-using the old command syntax. Doing so, obviously, it is only possible to
-configure a FIFO scheduler or a wf2q+ scheduler.
-A new command, 'ipfw pipe x config sched <type>' is supported to add a new
-scheduler to the system.
-
-- ipfw pipe x config ...
- create a new pipe with the link parameters
- create a new scheduler fifo (x + offset)
- create a new flowset fifo (x + offset)
- the mask is eventually stored in the FIFO scheduler
-
-- ipfw queue y config pipe x ...
- create a new flowset y linked to sched x.
- The type of flowset depends by the specified scheduler.
- If the scheduler does not exist, this flowset is inserted in a special
- list and will be not active.
- If pipe x exists and sched does not exist, a new wf2q+ scheduler is
- created and the flowset will be linked to this new scheduler (this is
- done for compatibility with old syntax).
-
-- ipfw pipe x config sched <type> ...
- create a new scheduler x of type <type>.
- Search into the flowset unlinked list if there are some flowset that
- should be linked with this new scheduler.
-
-- ipfw pipe x delete
- delete the pipe x
- delete the scheduler fifo (x + offset)
- delete the scheduler x
- delete the flowset fifo (x + offset)
-
-- ipfw queue x delete
- delete the flowset x
-
-- ipfw sched x delete ///XXX
- delete the scheduler x
-
-Follow now some examples to how configure dummynet:
-- Ex1:
- ipfw pipe 10 config bw 1M delay 15 // create a pipe with band and delay
- A FIFO flowset and scheduler is
- also created
- ipfw queue 5 config pipe 10 weight 56 // create a flowset. This flowset
- will be of wf2q+ because a pipe 10
- exists. Moreover, the wf2q+
- scheduler is created now.
-- Ex2:
- ipfw queue 5 config pipe 10 weight 56 // Create a flowset. Scheduler 10
- does not exist, so this flowset
- is inserted in the unlinked
- flowset list.
- ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
- Because of a flowset with 'pipe 10' exists,
- a wf2q+ scheduler is created now and that
- flowset is linked with this sceduler.
-
-- Ex3:
- ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
- ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
- pipe 10
- ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5. This flowset
- will belong to scheduler 10 and
- it is of type RR
-
-- Ex4:
- ipfw pipe 10 config sched rr // Create a scheduler of type RR, linked to
- pipe 10 (not exist yet)
- ipfw pipe 10 config bw... // Create a pipe, a FIFO flowset and scheduler.
- ipfw queue 5 config pipe 10 weight 56 // Create a flowset 5.This flowset
- will belong to scheduler 10 and
- it is of type RR
- ipfw pipe 10 config sched wf2q+ // Modify the type of scheduler 10. It
- becomes a wf2q+ scheduler.
- When a new packet of flowset 5 arrives,
- the flowset 5 becomes to wf2q+ type.
-
-How to implement a new scheduler
-================================
-In dummynet, a scheduler algorithm is represented by two main structs, some
-functions and other minor structs.
-- A struct dn_sch_xyz (where xyz is the 'type' of scheduler algorithm
- implemented) contains data relative to scheduler, as global parameter that
- are common to all instances of the scheduler
-- A struct dn_sch_inst_xyz contains data relative to a single scheduler
- instance, as local status variable depending for example by flows that
- are linked with the scheduler, and so on.
-To add a scheduler to dummynet, the user should type a command like:
-'ipfw pipe x config sched <type> [mask ... ...]'
-This command creates a new struct dn_sch_xyz of type <type>, and
-store the optional parameter in that struct.
-
-The parameter mask determines how many scheduler instance of this
-scheduler may exist. For example, it is possible to divide traffic
-depending on the source port (or destination, or ip address...),
-so that every scheduler instance act as an independent scheduler.
-If the mask is not set, all traffic goes to the same instance.
-
-When a packet arrives to a scheduler, the system search the corrected
-scheduler instance, and if it does not exist it is created now (the
-struct dn_sch_inst_xyz is allocated by the system, and the scheduler
-fills the field correctly). It is a task of the scheduler to create
-the struct that contains all queues for a scheduler instance.
-Dummynet provides some function to create an hash table to store
-queues, but the schedule algorithm can choice the own struct.
-
-To link a flow to a scheduler, the user should type a command like:
-'ipfw queue z config pipe x [mask... ...]'
-
-This command creates a new 'dn_fs' struct that will be inserted
-in the system. If the scheduler x exists, this flowset will be
-linked to that scheduler and the flowset type become the same as
-the scheduler type. At this point, the function create_alg_fs_xyz()
-is called to allow store eventually parameter for the flowset that
-depend by scheduler (for example the 'weight' parameter for a wf2q+
-scheduler, or some priority...). A parameter mask can be used for
-a flowset. If the mask parameter is set, the scheduler instance can
-separate packet according to its flow id (src and dst ip, ports...)
-and assign it to a separate queue. This is done by the scheduler,
-so it can ignore the mask if it wants.
-
-See now the two main structs:
-struct dn_sch_xyz {
- struct gen g; /* important the name g */
- /* global params */
-};
-struct dn_sch_inst_xyz {
- struct gen g; /* important the name g */
- /* params of the instance */
-};
-It is important to embed the struct gen as first parameter. The struct gen
-contains some values that the scheduler instance must fill (the 'type' of
-scheduler, the 'len' of the struct...)
-The function create_scheduler_xyz() should be implemented to initialize global
-parameters in the first struct, and if memory allocation is done it is
-mandatory to implement the delete_scheduler_template() function to free that
-memory.
-The function create_scheduler_instance_xyz() must be implemented even if the
-scheduler instance does not use extra parameters. In this function the struct
-gen fields must be filled with corrected infos. The
-delete_scheduler_instance_xyz() function must bu implemented if the instance
-has allocated some memory in the previous function.
-
-To store data belonging to a flowset the follow struct is used:
-struct alg_fs_xyz {
- struct gen g;
- /* fill correctly the gen struct
- g.subtype = DN_XYZ;
- g.len = sizeof(struct alg_fs_xyz)
- ...
- */
- /* params for the flow */
-};
-The create_alg_fs_xyz() function is mandatory, because it must fill the struct
-gen, but the delete_alg_fs_xyz() is mandatory only if the previous function
-has allocated some memory.
-
-A struct dn_queue contains packets belonging to a queue and some statistical
-data. The scheduler could have to store data in this struct, so it must define
-a dn_queue_xyz struct:
-struct dn_queue_xyz {
- struct dn_queue q;
- /* parameter for a queue */
-}
-
-All structures are allocated by the system. To do so, the scheduler must
-set the size of its structs in the scheduler descriptor:
-scheduler_size: sizeof(dn_sch_xyz)
-scheduler_i_size: sizeof(dn_sch_inst_xyz)
-flowset_size: sizeof(alg_fs_xyz)
-queue_size: sizeof(dn_queue_xyz);
-The scheduler_size could be 0, but other struct must have at least a struct gen.
-
-
-After the definition of structs, it is necessary to implement the
-scheduler functions.
-
-- int (*config_scheduler)(char *command, void *sch, int reconfigure);
- Configure a scheduler, or reconfigure if 'reconfigure' == 1.
- This function performs additional allocation and initialization of global
- parameter for this scheduler.
- If memory is allocated here, the delete_scheduler_template() function
- should be implemented to remove this memory.
-- int (*delete_scheduler_template)(void* sch);
- Delete a scheduler template. This function is mandatory if the scheduler
- uses extra data respect the struct dn_sch.
-- int (*create_scheduler_instance)(void *s);
- Create a new scheduler instance. The system allocate the necessary memory
- and the schedulet can access it using the 's' pointer.
- The scheduler instance stores all queues, and to do this can use the
- hash table provided by the system.
-- int (*delete_scheduler_instance)(void *s);
- Delete a scheduler instance. It is important to free memory allocated
- by create_scheduler_instance() function. The memory allocated by system
- is freed by the system itself. The struct contains all queue also has
- to be deleted.
-- int (*enqueue)(void *s, struct gen *f, struct mbuf *m,
- struct ipfw_flow_id *id);
- Called when a packet arrives. The packet 'm' belongs to the scheduler
- instance 's', has a flowset 'f' and the flowid 'id' has already been
- masked. The enqueue() must call dn_queue_packet(q, m) function to really
- enqueue packet in the queue q. The queue 'q' is chosen by the scheduler
- and if it does not exist should be created calling the dn_create_queue()
- function. If the schedule want to drop the packet, it must call the
- dn_drop_packet() function and then return 1.
-- struct mbuf * (*dequeue)(void *s);
- Called when the timer expires (or when a packet arrives and the scheduler
- instance is idle).
- This function is called when at least a packet can be send out. The
- scheduler choices the packet and returns it; if no packet are in the
- schedulerinstance, the function must return NULL.
- Before return a packet, it is important to call the function
- dn_return_packet() to update some statistic of the queue and update the
- queue counters.
-- int (*drain_queue)(void *s, int flag);
- The system request to scheduler to delete all queues that is not using
- to free memory. The flag parameter indicate if a queue must be deleted
- even if it is active.
-
-- int (*create_alg_fs)(char *command, struct gen *g, int reconfigure);
- It is called when a flowset is linked with a scheduler. This is done
- when the scheduler is defined, so we can know the type of flowset.
- The function initialize the flowset paramenter parsing the command
- line. The parameter will be stored in the g struct that have the right
- size allocated by the system. If the reconfigure flag is set, it means
- that the flowset is reconfiguring
-- int (*delete_alg_fs)(struct gen *f);
- It is called when a flowset is deleting. Must remove the memory allocate
- by the create_alg_fs() function.
-
-- int (*create_queue_alg)(struct dn_queue *q, struct gen *f);
- Called when a queue is created. The function should link the queue
- to the struct used by the scheduler instance to store all queues.
-- int (*delete_queue_alg)(struct dn_queue *q);
- Called when a queue is deleting. The function should remove extra data
- and update the struct contains all queues in the scheduler instance.
-
-The struct scheduler represent the scheduler descriptor that is passed to
-dummynet when a scheduler module is loaded.
-This struct contains the type of scheduler, the lenght of all structs and
-all function pointers.
-If a function is not implemented should be initialize to NULL. Some functions
-are mandatory, other are mandatory if some memory should be freed.
-Mandatory functions:
-- create_scheduler_instance()
-- enqueue()
-- dequeue()
-- create_alg_fs()
-- drain_queue()
-Optional functions:
-- config_scheduler()
-- create_queue_alg()
-Mandatory functions if the corresponding create...() has allocated memory:
-- delete_scheduler_template()
-- delete_scheduler_instance()
-- delete_alg_fs()
-- delete_queue_alg()
-
diff --git a/sys/netinet/ipfw/ip_dn_glue.c b/sys/netinet/ipfw/ip_dn_glue.c
deleted file mode 100644
index 9fc6b23..0000000
--- a/sys/netinet/ipfw/ip_dn_glue.c
+++ /dev/null
@@ -1,845 +0,0 @@
-/*-
- * Copyright (c) 2010 Riccardo Panicucci, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * $FreeBSD$
- *
- * Binary compatibility support for /sbin/ipfw RELENG_7 and RELENG_8
- */
-
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/time.h>
-#include <sys/taskqueue.h>
-#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-
-/* FREEBSD7.2 ip_dummynet.h r191715*/
-
-struct dn_heap_entry7 {
- int64_t key; /* sorting key. Topmost element is smallest one */
- void *object; /* object pointer */
-};
-
-struct dn_heap7 {
- int size;
- int elements;
- int offset; /* XXX if > 0 this is the offset of direct ptr to obj */
- struct dn_heap_entry7 *p; /* really an array of "size" entries */
-};
-
-/* Common to 7.2 and 8 */
-struct dn_flow_set {
- SLIST_ENTRY(dn_flow_set) next; /* linked list in a hash slot */
-
- u_short fs_nr ; /* flow_set number */
- u_short flags_fs;
-#define DNOLD_HAVE_FLOW_MASK 0x0001
-#define DNOLD_IS_RED 0x0002
-#define DNOLD_IS_GENTLE_RED 0x0004
-#define DNOLD_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */
-#define DNOLD_NOERROR 0x0010 /* do not report ENOBUFS on drops */
-#define DNOLD_HAS_PROFILE 0x0020 /* the pipe has a delay profile. */
-#define DNOLD_IS_PIPE 0x4000
-#define DNOLD_IS_QUEUE 0x8000
-
- struct dn_pipe7 *pipe ; /* pointer to parent pipe */
- u_short parent_nr ; /* parent pipe#, 0 if local to a pipe */
-
- int weight ; /* WFQ queue weight */
- int qsize ; /* queue size in slots or bytes */
- int plr ; /* pkt loss rate (2^31-1 means 100%) */
-
- struct ipfw_flow_id flow_mask ;
-
- /* hash table of queues onto this flow_set */
- int rq_size ; /* number of slots */
- int rq_elements ; /* active elements */
- struct dn_flow_queue7 **rq; /* array of rq_size entries */
-
- u_int32_t last_expired ; /* do not expire too frequently */
- int backlogged ; /* #active queues for this flowset */
-
- /* RED parameters */
-#define SCALE_RED 16
-#define SCALE(x) ( (x) << SCALE_RED )
-#define SCALE_VAL(x) ( (x) >> SCALE_RED )
-#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED )
- int w_q ; /* queue weight (scaled) */
- int max_th ; /* maximum threshold for queue (scaled) */
- int min_th ; /* minimum threshold for queue (scaled) */
- int max_p ; /* maximum value for p_b (scaled) */
- u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
- u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
- u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
- u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
- u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
- u_int lookup_depth ; /* depth of lookup table */
- int lookup_step ; /* granularity inside the lookup table */
- int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
- int avg_pkt_size ; /* medium packet size */
- int max_pkt_size ; /* max packet size */
-};
-SLIST_HEAD(dn_flow_set_head, dn_flow_set);
-
-#define DN_IS_PIPE 0x4000
-#define DN_IS_QUEUE 0x8000
-struct dn_flow_queue7 {
- struct dn_flow_queue7 *next ;
- struct ipfw_flow_id id ;
-
- struct mbuf *head, *tail ; /* queue of packets */
- u_int len ;
- u_int len_bytes ;
-
- u_long numbytes;
-
- u_int64_t tot_pkts ; /* statistics counters */
- u_int64_t tot_bytes ;
- u_int32_t drops ;
-
- int hash_slot ; /* debugging/diagnostic */
-
- /* RED parameters */
- int avg ; /* average queue length est. (scaled) */
- int count ; /* arrivals since last RED drop */
- int random ; /* random value (scaled) */
- u_int32_t q_time; /* start of queue idle time */
-
- /* WF2Q+ support */
- struct dn_flow_set *fs ; /* parent flow set */
- int heap_pos ; /* position (index) of struct in heap */
- int64_t sched_time ; /* current time when queue enters ready_heap */
-
- int64_t S,F ; /* start time, finish time */
-};
-
-struct dn_pipe7 { /* a pipe */
- SLIST_ENTRY(dn_pipe7) next; /* linked list in a hash slot */
-
- int pipe_nr ; /* number */
- int bandwidth; /* really, bytes/tick. */
- int delay ; /* really, ticks */
-
- struct mbuf *head, *tail ; /* packets in delay line */
-
- /* WF2Q+ */
- struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
- struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
- struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
-
- int64_t V ; /* virtual time */
- int sum; /* sum of weights of all active sessions */
-
- int numbytes;
-
- int64_t sched_time ; /* time pipe was scheduled in ready_heap */
-
- /*
- * When the tx clock come from an interface (if_name[0] != '\0'), its name
- * is stored below, whereas the ifp is filled when the rule is configured.
- */
- char if_name[IFNAMSIZ];
- struct ifnet *ifp ;
- int ready ; /* set if ifp != NULL and we got a signal from it */
-
- struct dn_flow_set fs ; /* used with fixed-rate flows */
-};
-SLIST_HEAD(dn_pipe_head7, dn_pipe7);
-
-
-/* FREEBSD8 ip_dummynet.h r196045 */
-struct dn_flow_queue8 {
- struct dn_flow_queue8 *next ;
- struct ipfw_flow_id id ;
-
- struct mbuf *head, *tail ; /* queue of packets */
- u_int len ;
- u_int len_bytes ;
-
- uint64_t numbytes ; /* credit for transmission (dynamic queues) */
- int64_t extra_bits; /* extra bits simulating unavailable channel */
-
- u_int64_t tot_pkts ; /* statistics counters */
- u_int64_t tot_bytes ;
- u_int32_t drops ;
-
- int hash_slot ; /* debugging/diagnostic */
-
- /* RED parameters */
- int avg ; /* average queue length est. (scaled) */
- int count ; /* arrivals since last RED drop */
- int random ; /* random value (scaled) */
- int64_t idle_time; /* start of queue idle time */
-
- /* WF2Q+ support */
- struct dn_flow_set *fs ; /* parent flow set */
- int heap_pos ; /* position (index) of struct in heap */
- int64_t sched_time ; /* current time when queue enters ready_heap */
-
- int64_t S,F ; /* start time, finish time */
-};
-
-struct dn_pipe8 { /* a pipe */
- SLIST_ENTRY(dn_pipe8) next; /* linked list in a hash slot */
-
- int pipe_nr ; /* number */
- int bandwidth; /* really, bytes/tick. */
- int delay ; /* really, ticks */
-
- struct mbuf *head, *tail ; /* packets in delay line */
-
- /* WF2Q+ */
- struct dn_heap7 scheduler_heap ; /* top extract - key Finish time*/
- struct dn_heap7 not_eligible_heap; /* top extract- key Start time */
- struct dn_heap7 idle_heap ; /* random extract - key Start=Finish time */
-
- int64_t V ; /* virtual time */
- int sum; /* sum of weights of all active sessions */
-
- /* Same as in dn_flow_queue, numbytes can become large */
- int64_t numbytes; /* bits I can transmit (more or less). */
- uint64_t burst; /* burst size, scaled: bits * hz */
-
- int64_t sched_time ; /* time pipe was scheduled in ready_heap */
- int64_t idle_time; /* start of pipe idle time */
-
- char if_name[IFNAMSIZ];
- struct ifnet *ifp ;
- int ready ; /* set if ifp != NULL and we got a signal from it */
-
- struct dn_flow_set fs ; /* used with fixed-rate flows */
-
- /* fields to simulate a delay profile */
-#define ED_MAX_NAME_LEN 32
- char name[ED_MAX_NAME_LEN];
- int loss_level;
- int samples_no;
- int *samples;
-};
-
-#define ED_MAX_SAMPLES_NO 1024
-struct dn_pipe_max8 {
- struct dn_pipe8 pipe;
- int samples[ED_MAX_SAMPLES_NO];
-};
-SLIST_HEAD(dn_pipe_head8, dn_pipe8);
-
-/*
- * Changes from 7.2 to 8:
- * dn_pipe:
- * numbytes from int to int64_t
- * add burst (int64_t)
- * add idle_time (int64_t)
- * add profile
- * add struct dn_pipe_max
- * add flag DN_HAS_PROFILE
- *
- * dn_flow_queue
- * numbytes from u_long to int64_t
- * add extra_bits (int64_t)
- * q_time from u_int32_t to int64_t and name idle_time
- *
- * dn_flow_set unchanged
- *
- */
-
-/* NOTE:XXX copied from dummynet.c */
-#define O_NEXT(p, len) ((void *)((char *)p + len))
-static void
-oid_fill(struct dn_id *oid, int len, int type, uintptr_t id)
-{
- oid->len = len;
- oid->type = type;
- oid->subtype = 0;
- oid->id = id;
-}
-/* make room in the buffer and move the pointer forward */
-static void *
-o_next(struct dn_id **o, int len, int type)
-{
- struct dn_id *ret = *o;
- oid_fill(ret, len, type, 0);
- *o = O_NEXT(*o, len);
- return ret;
-}
-
-
-static size_t pipesize7 = sizeof(struct dn_pipe7);
-static size_t pipesize8 = sizeof(struct dn_pipe8);
-static size_t pipesizemax8 = sizeof(struct dn_pipe_max8);
-
-/* Indicate 'ipfw' version
- * 1: from FreeBSD 7.2
- * 0: from FreeBSD 8
- * -1: unknow (for now is unused)
- *
- * It is update when a IP_DUMMYNET_DEL or IP_DUMMYNET_CONFIGURE request arrives
- * NOTE: if a IP_DUMMYNET_GET arrives and the 'ipfw' version is unknow,
- * it is suppose to be the FreeBSD 8 version.
- */
-static int is7 = 0;
-
-static int
-convertflags2new(int src)
-{
- int dst = 0;
-
- if (src & DNOLD_HAVE_FLOW_MASK)
- dst |= DN_HAVE_MASK;
- if (src & DNOLD_QSIZE_IS_BYTES)
- dst |= DN_QSIZE_BYTES;
- if (src & DNOLD_NOERROR)
- dst |= DN_NOERROR;
- if (src & DNOLD_IS_RED)
- dst |= DN_IS_RED;
- if (src & DNOLD_IS_GENTLE_RED)
- dst |= DN_IS_GENTLE_RED;
- if (src & DNOLD_HAS_PROFILE)
- dst |= DN_HAS_PROFILE;
-
- return dst;
-}
-
-static int
-convertflags2old(int src)
-{
- int dst = 0;
-
- if (src & DN_HAVE_MASK)
- dst |= DNOLD_HAVE_FLOW_MASK;
- if (src & DN_IS_RED)
- dst |= DNOLD_IS_RED;
- if (src & DN_IS_GENTLE_RED)
- dst |= DNOLD_IS_GENTLE_RED;
- if (src & DN_NOERROR)
- dst |= DNOLD_NOERROR;
- if (src & DN_HAS_PROFILE)
- dst |= DNOLD_HAS_PROFILE;
- if (src & DN_QSIZE_BYTES)
- dst |= DNOLD_QSIZE_IS_BYTES;
-
- return dst;
-}
-
-static int
-dn_compat_del(void *v)
-{
- struct dn_pipe7 *p = (struct dn_pipe7 *) v;
- struct dn_pipe8 *p8 = (struct dn_pipe8 *) v;
- struct {
- struct dn_id oid;
- uintptr_t a[1]; /* add more if we want a list */
- } cmd;
-
- /* XXX DN_API_VERSION ??? */
- oid_fill((void *)&cmd, sizeof(cmd), DN_CMD_DELETE, DN_API_VERSION);
-
- if (is7) {
- if (p->pipe_nr == 0 && p->fs.fs_nr == 0)
- return EINVAL;
- if (p->pipe_nr != 0 && p->fs.fs_nr != 0)
- return EINVAL;
- } else {
- if (p8->pipe_nr == 0 && p8->fs.fs_nr == 0)
- return EINVAL;
- if (p8->pipe_nr != 0 && p8->fs.fs_nr != 0)
- return EINVAL;
- }
-
- if (p->pipe_nr != 0) { /* pipe x delete */
- cmd.a[0] = p->pipe_nr;
- cmd.oid.subtype = DN_LINK;
- } else { /* queue x delete */
- cmd.oid.subtype = DN_FS;
- cmd.a[0] = (is7) ? p->fs.fs_nr : p8->fs.fs_nr;
- }
-
- return do_config(&cmd, cmd.oid.len);
-}
-
-static int
-dn_compat_config_queue(struct dn_fs *fs, void* v)
-{
- struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
- struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
- struct dn_flow_set *f;
-
- if (is7)
- f = &p7->fs;
- else
- f = &p8->fs;
-
- fs->fs_nr = f->fs_nr;
- fs->sched_nr = f->parent_nr;
- fs->flow_mask = f->flow_mask;
- fs->buckets = f->rq_size;
- fs->qsize = f->qsize;
- fs->plr = f->plr;
- fs->par[0] = f->weight;
- fs->flags = convertflags2new(f->flags_fs);
- if (fs->flags & DN_IS_GENTLE_RED || fs->flags & DN_IS_RED) {
- fs->w_q = f->w_q;
- fs->max_th = f->max_th;
- fs->min_th = f->min_th;
- fs->max_p = f->max_p;
- }
-
- return 0;
-}
-
-static int
-dn_compat_config_pipe(struct dn_sch *sch, struct dn_link *p,
- struct dn_fs *fs, void* v)
-{
- struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
- struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
- int i = p7->pipe_nr;
-
- sch->sched_nr = i;
- sch->oid.subtype = 0;
- p->link_nr = i;
- fs->fs_nr = i + 2*DN_MAX_ID;
- fs->sched_nr = i + DN_MAX_ID;
-
- /* Common to 7 and 8 */
- p->bandwidth = p7->bandwidth;
- p->delay = p7->delay;
- if (!is7) {
- /* FreeBSD 8 has burst */
- p->burst = p8->burst;
- }
-
- /* fill the fifo flowset */
- dn_compat_config_queue(fs, v);
- fs->fs_nr = i + 2*DN_MAX_ID;
- fs->sched_nr = i + DN_MAX_ID;
-
- /* Move scheduler related parameter from fs to sch */
- sch->buckets = fs->buckets; /*XXX*/
- fs->buckets = 0;
- if (fs->flags & DN_HAVE_MASK) {
- sch->flags |= DN_HAVE_MASK;
- fs->flags &= ~DN_HAVE_MASK;
- sch->sched_mask = fs->flow_mask;
- bzero(&fs->flow_mask, sizeof(struct ipfw_flow_id));
- }
-
- return 0;
-}
-
-static int
-dn_compat_config_profile(struct dn_profile *pf, struct dn_link *p,
- void *v)
-{
- struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
-
- p8->samples = &(((struct dn_pipe_max8 *)p8)->samples[0]);
-
- pf->link_nr = p->link_nr;
- pf->loss_level = p8->loss_level;
-// pf->bandwidth = p->bandwidth; //XXX bandwidth redundant?
- pf->samples_no = p8->samples_no;
- strncpy(pf->name, p8->name,sizeof(pf->name));
- bcopy(p8->samples, pf->samples, sizeof(pf->samples));
-
- return 0;
-}
-
-/*
- * If p->pipe_nr != 0 the command is 'pipe x config', so need to create
- * the three main struct, else only a flowset is created
- */
-static int
-dn_compat_configure(void *v)
-{
- struct dn_id *buf = NULL, *base;
- struct dn_sch *sch = NULL;
- struct dn_link *p = NULL;
- struct dn_fs *fs = NULL;
- struct dn_profile *pf = NULL;
- int lmax;
- int error;
-
- struct dn_pipe7 *p7 = (struct dn_pipe7 *)v;
- struct dn_pipe8 *p8 = (struct dn_pipe8 *)v;
-
- int i; /* number of object to configure */
-
- lmax = sizeof(struct dn_id); /* command header */
- lmax += sizeof(struct dn_sch) + sizeof(struct dn_link) +
- sizeof(struct dn_fs) + sizeof(struct dn_profile);
-
- base = buf = malloc(lmax, M_DUMMYNET, M_WAIT|M_ZERO);
- o_next(&buf, sizeof(struct dn_id), DN_CMD_CONFIG);
- base->id = DN_API_VERSION;
-
- /* pipe_nr is the same in p7 and p8 */
- i = p7->pipe_nr;
- if (i != 0) { /* pipe config */
- sch = o_next(&buf, sizeof(*sch), DN_SCH);
- p = o_next(&buf, sizeof(*p), DN_LINK);
- fs = o_next(&buf, sizeof(*fs), DN_FS);
-
- error = dn_compat_config_pipe(sch, p, fs, v);
- if (error) {
- free(buf, M_DUMMYNET);
- return error;
- }
- if (!is7 && p8->samples_no > 0) {
- /* Add profiles*/
- pf = o_next(&buf, sizeof(*pf), DN_PROFILE);
- error = dn_compat_config_profile(pf, p, v);
- if (error) {
- free(buf, M_DUMMYNET);
- return error;
- }
- }
- } else { /* queue config */
- fs = o_next(&buf, sizeof(*fs), DN_FS);
- error = dn_compat_config_queue(fs, v);
- if (error) {
- free(buf, M_DUMMYNET);
- return error;
- }
- }
- error = do_config(base, (char *)buf - (char *)base);
-
- if (buf)
- free(buf, M_DUMMYNET);
- return error;
-}
-
-int
-dn_compat_calc_size(void)
-{
- int need = 0;
- /* XXX use FreeBSD 8 struct size */
- /* NOTE:
- * - half scheduler: schk_count/2
- * - all flowset: fsk_count
- * - all flowset queues: queue_count
- * - all pipe queue: si_count
- */
- need += dn_cfg.schk_count * sizeof(struct dn_pipe8) / 2;
- need += dn_cfg.fsk_count * sizeof(struct dn_flow_set);
- need += dn_cfg.si_count * sizeof(struct dn_flow_queue8);
- need += dn_cfg.queue_count * sizeof(struct dn_flow_queue8);
-
- return need;
-}
-
-int
-dn_c_copy_q (void *_ni, void *arg)
-{
- struct copy_args *a = arg;
- struct dn_flow_queue7 *fq7 = (struct dn_flow_queue7 *)*a->start;
- struct dn_flow_queue8 *fq8 = (struct dn_flow_queue8 *)*a->start;
- struct dn_flow *ni = (struct dn_flow *)_ni;
- int size = 0;
-
- /* XXX hash slot not set */
- /* No difference between 7.2/8 */
- fq7->len = ni->length;
- fq7->len_bytes = ni->len_bytes;
- fq7->id = ni->fid;
-
- if (is7) {
- size = sizeof(struct dn_flow_queue7);
- fq7->tot_pkts = ni->tot_pkts;
- fq7->tot_bytes = ni->tot_bytes;
- fq7->drops = ni->drops;
- } else {
- size = sizeof(struct dn_flow_queue8);
- fq8->tot_pkts = ni->tot_pkts;
- fq8->tot_bytes = ni->tot_bytes;
- fq8->drops = ni->drops;
- }
-
- *a->start += size;
- return 0;
-}
-
-int
-dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq)
-{
- struct dn_link *l = &s->link;
- struct dn_fsk *f = s->fs;
-
- struct dn_pipe7 *pipe7 = (struct dn_pipe7 *)*a->start;
- struct dn_pipe8 *pipe8 = (struct dn_pipe8 *)*a->start;
- struct dn_flow_set *fs;
- int size = 0;
-
- if (is7) {
- fs = &pipe7->fs;
- size = sizeof(struct dn_pipe7);
- } else {
- fs = &pipe8->fs;
- size = sizeof(struct dn_pipe8);
- }
-
- /* These 4 field are the same in pipe7 and pipe8 */
- pipe7->next.sle_next = (struct dn_pipe7 *)DN_IS_PIPE;
- pipe7->bandwidth = l->bandwidth;
- pipe7->delay = l->delay * 1000 / hz;
- pipe7->pipe_nr = l->link_nr - DN_MAX_ID;
-
- if (!is7) {
- if (s->profile) {
- struct dn_profile *pf = s->profile;
- strncpy(pipe8->name, pf->name, sizeof(pf->name));
- pipe8->loss_level = pf->loss_level;
- pipe8->samples_no = pf->samples_no;
- }
- pipe8->burst = div64(l->burst , 8 * hz);
- }
-
- fs->flow_mask = s->sch.sched_mask;
- fs->rq_size = s->sch.buckets ? s->sch.buckets : 1;
-
- fs->parent_nr = l->link_nr - DN_MAX_ID;
- fs->qsize = f->fs.qsize;
- fs->plr = f->fs.plr;
- fs->w_q = f->fs.w_q;
- fs->max_th = f->max_th;
- fs->min_th = f->min_th;
- fs->max_p = f->fs.max_p;
- fs->rq_elements = nq;
-
- fs->flags_fs = convertflags2old(f->fs.flags);
-
- *a->start += size;
- return 0;
-}
-
-
-int
-dn_compat_copy_pipe(struct copy_args *a, void *_o)
-{
- int have = a->end - *a->start;
- int need = 0;
- int pipe_size = sizeof(struct dn_pipe8);
- int queue_size = sizeof(struct dn_flow_queue8);
- int n_queue = 0; /* number of queues */
-
- struct dn_schk *s = (struct dn_schk *)_o;
- /* calculate needed space:
- * - struct dn_pipe
- * - if there are instances, dn_queue * n_instances
- */
- n_queue = (s->sch.flags & DN_HAVE_MASK ? dn_ht_entries(s->siht) :
- (s->siht ? 1 : 0));
- need = pipe_size + queue_size * n_queue;
- if (have < need) {
- D("have %d < need %d", have, need);
- return 1;
- }
- /* copy pipe */
- dn_c_copy_pipe(s, a, n_queue);
-
- /* copy queues */
- if (s->sch.flags & DN_HAVE_MASK)
- dn_ht_scan(s->siht, dn_c_copy_q, a);
- else if (s->siht)
- dn_c_copy_q(s->siht, a);
- return 0;
-}
-
-int
-dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq)
-{
- struct dn_flow_set *fs = (struct dn_flow_set *)*a->start;
-
- fs->next.sle_next = (struct dn_flow_set *)DN_IS_QUEUE;
- fs->fs_nr = f->fs.fs_nr;
- fs->qsize = f->fs.qsize;
- fs->plr = f->fs.plr;
- fs->w_q = f->fs.w_q;
- fs->max_th = f->max_th;
- fs->min_th = f->min_th;
- fs->max_p = f->fs.max_p;
- fs->flow_mask = f->fs.flow_mask;
- fs->rq_elements = nq;
- fs->rq_size = (f->fs.buckets ? f->fs.buckets : 1);
- fs->parent_nr = f->fs.sched_nr;
- fs->weight = f->fs.par[0];
-
- fs->flags_fs = convertflags2old(f->fs.flags);
- *a->start += sizeof(struct dn_flow_set);
- return 0;
-}
-
-int
-dn_compat_copy_queue(struct copy_args *a, void *_o)
-{
- int have = a->end - *a->start;
- int need = 0;
- int fs_size = sizeof(struct dn_flow_set);
- int queue_size = sizeof(struct dn_flow_queue8);
-
- struct dn_fsk *fs = (struct dn_fsk *)_o;
- int n_queue = 0; /* number of queues */
-
- n_queue = (fs->fs.flags & DN_HAVE_MASK ? dn_ht_entries(fs->qht) :
- (fs->qht ? 1 : 0));
-
- need = fs_size + queue_size * n_queue;
- if (have < need) {
- D("have < need");
- return 1;
- }
-
- /* copy flowset */
- dn_c_copy_fs(fs, a, n_queue);
-
- /* copy queues */
- if (fs->fs.flags & DN_HAVE_MASK)
- dn_ht_scan(fs->qht, dn_c_copy_q, a);
- else if (fs->qht)
- dn_c_copy_q(fs->qht, a);
-
- return 0;
-}
-
-int
-copy_data_helper_compat(void *_o, void *_arg)
-{
- struct copy_args *a = _arg;
-
- if (a->type == DN_COMPAT_PIPE) {
- struct dn_schk *s = _o;
- if (s->sch.oid.subtype != 1 || s->sch.sched_nr <= DN_MAX_ID) {
- return 0; /* not old type */
- }
- /* copy pipe parameters, and if instance exists, copy
- * other parameters and eventually queues.
- */
- if(dn_compat_copy_pipe(a, _o))
- return DNHT_SCAN_END;
- } else if (a->type == DN_COMPAT_QUEUE) {
- struct dn_fsk *fs = _o;
- if (fs->fs.fs_nr >= DN_MAX_ID)
- return 0;
- if (dn_compat_copy_queue(a, _o))
- return DNHT_SCAN_END;
- }
- return 0;
-}
-
-/* Main function to manage old requests */
-int
-ip_dummynet_compat(struct sockopt *sopt)
-{
- int error=0;
- void *v = NULL;
- struct dn_id oid;
-
- /* Lenght of data, used to found ipfw version... */
- int len = sopt->sopt_valsize;
-
- /* len can be 0 if command was dummynet_flush */
- if (len == pipesize7) {
- D("setting compatibility with FreeBSD 7.2");
- is7 = 1;
- }
- else if (len == pipesize8 || len == pipesizemax8) {
- D("setting compatibility with FreeBSD 8");
- is7 = 0;
- }
-
- switch (sopt->sopt_name) {
- default:
- printf("dummynet: -- unknown option %d", sopt->sopt_name);
- error = EINVAL;
- break;
-
- case IP_DUMMYNET_FLUSH:
- oid_fill(&oid, sizeof(oid), DN_CMD_FLUSH, DN_API_VERSION);
- do_config(&oid, oid.len);
- break;
-
- case IP_DUMMYNET_DEL:
- v = malloc(len, M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, v, len, len);
- if (error)
- break;
- error = dn_compat_del(v);
- free(v, M_TEMP);
- break;
-
- case IP_DUMMYNET_CONFIGURE:
- v = malloc(len, M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, v, len, len);
- if (error)
- break;
- error = dn_compat_configure(v);
- free(v, M_TEMP);
- break;
-
- case IP_DUMMYNET_GET: {
- void *buf;
- int ret;
- int original_size = sopt->sopt_valsize;
- int size;
-
- ret = dummynet_get(sopt, &buf);
- if (ret)
- return 0;//XXX ?
- size = sopt->sopt_valsize;
- sopt->sopt_valsize = original_size;
- D("size=%d, buf=%p", size, buf);
- ret = sooptcopyout(sopt, buf, size);
- if (ret)
- printf(" %s ERROR sooptcopyout\n", __FUNCTION__);
- if (buf)
- free(buf, M_DUMMYNET);
- }
- }
-
- return error;
-}
-
-
diff --git a/sys/netinet/ipfw/ip_dn_io.c b/sys/netinet/ipfw/ip_dn_io.c
deleted file mode 100644
index a39f169..0000000
--- a/sys/netinet/ipfw/ip_dn_io.c
+++ /dev/null
@@ -1,851 +0,0 @@
-/*-
- * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * Dummynet portions related to packet handling.
- */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
-#include <net/netisr.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h> /* ip_len, ip_off */
-#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-
-#include <netinet/if_ether.h> /* various ether_* routines */
-
-#include <netinet/ip6.h> /* for ip6_input, ip6_output prototypes */
-#include <netinet6/ip6_var.h>
-
-/*
- * We keep a private variable for the simulation time, but we could
- * probably use an existing one ("softticks" in sys/kern/kern_timeout.c)
- * instead of dn_cfg.curr_time
- */
-
-struct dn_parms dn_cfg;
-//VNET_DEFINE(struct dn_parms, _base_dn_cfg);
-
-static long tick_last; /* Last tick duration (usec). */
-static long tick_delta; /* Last vs standard tick diff (usec). */
-static long tick_delta_sum; /* Accumulated tick difference (usec).*/
-static long tick_adjustment; /* Tick adjustments done. */
-static long tick_lost; /* Lost(coalesced) ticks number. */
-/* Adjusted vs non-adjusted curr_time difference (ticks). */
-static long tick_diff;
-
-static unsigned long io_pkt;
-static unsigned long io_pkt_fast;
-static unsigned long io_pkt_drop;
-
-/*
- * We use a heap to store entities for which we have pending timer events.
- * The heap is checked at every tick and all entities with expired events
- * are extracted.
- */
-
-MALLOC_DEFINE(M_DUMMYNET, "dummynet", "dummynet heap");
-
-extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
-
-#ifdef SYSCTL_NODE
-
-SYSBEGIN(f4)
-
-SYSCTL_DECL(_net_inet);
-SYSCTL_DECL(_net_inet_ip);
-static SYSCTL_NODE(_net_inet_ip, OID_AUTO, dummynet, CTLFLAG_RW, 0, "Dummynet");
-
-/* wrapper to pass dn_cfg fields to SYSCTL_* */
-//#define DC(x) (&(VNET_NAME(_base_dn_cfg).x))
-#define DC(x) (&(dn_cfg.x))
-/* parameters */
-
-static int
-sysctl_hash_size(SYSCTL_HANDLER_ARGS)
-{
- int error, value;
-
- value = dn_cfg.hash_size;
- error = sysctl_handle_int(oidp, &value, 0, req);
- if (error != 0 || req->newptr == NULL)
- return (error);
- if (value < 16 || value > 65536)
- return (EINVAL);
- dn_cfg.hash_size = value;
- return (0);
-}
-
-SYSCTL_PROC(_net_inet_ip_dummynet, OID_AUTO, hash_size,
- CTLTYPE_INT | CTLFLAG_RW, 0, 0, sysctl_hash_size,
- "I", "Default hash table size");
-
-static int
-sysctl_limits(SYSCTL_HANDLER_ARGS)
-{
- int error;
- long value;
-
- if (arg2 != 0)
- value = dn_cfg.slot_limit;
- else
- value = dn_cfg.byte_limit;
- error = sysctl_handle_long(oidp, &value, 0, req);
-
- if (error != 0 || req->newptr == NULL)
- return (error);
- if (arg2 != 0) {
- if (value < 1)
- return (EINVAL);
- dn_cfg.slot_limit = value;
- } else {
- if (value < 1500)
- return (EINVAL);
- dn_cfg.byte_limit = value;
- }
- return (0);
-}
-
-SYSCTL_PROC(_net_inet_ip_dummynet, OID_AUTO, pipe_slot_limit,
- CTLTYPE_LONG | CTLFLAG_RW, 0, 1, sysctl_limits,
- "L", "Upper limit in slots for pipe queue.");
-SYSCTL_PROC(_net_inet_ip_dummynet, OID_AUTO, pipe_byte_limit,
- CTLTYPE_LONG | CTLFLAG_RW, 0, 0, sysctl_limits,
- "L", "Upper limit in bytes for pipe queue.");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast,
- CTLFLAG_RW, DC(io_fast), 0, "Enable fast dummynet io.");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, debug,
- CTLFLAG_RW, DC(debug), 0, "Dummynet debug level");
-
-/* RED parameters */
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_lookup_depth,
- CTLFLAG_RD, DC(red_lookup_depth), 0, "Depth of RED lookup table");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_avg_pkt_size,
- CTLFLAG_RD, DC(red_avg_pkt_size), 0, "RED Medium packet size");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, red_max_pkt_size,
- CTLFLAG_RD, DC(red_max_pkt_size), 0, "RED Max packet size");
-
-/* time adjustment */
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta,
- CTLFLAG_RD, &tick_delta, 0, "Last vs standard tick difference (usec).");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_delta_sum,
- CTLFLAG_RD, &tick_delta_sum, 0, "Accumulated tick difference (usec).");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_adjustment,
- CTLFLAG_RD, &tick_adjustment, 0, "Tick adjustments done.");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff,
- CTLFLAG_RD, &tick_diff, 0,
- "Adjusted vs non-adjusted curr_time difference (ticks).");
-SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost,
- CTLFLAG_RD, &tick_lost, 0,
- "Number of ticks coalesced by dummynet taskqueue.");
-
-/* Drain parameters */
-SYSCTL_UINT(_net_inet_ip_dummynet, OID_AUTO, expire,
- CTLFLAG_RW, DC(expire), 0, "Expire empty queues/pipes");
-SYSCTL_UINT(_net_inet_ip_dummynet, OID_AUTO, expire_cycle,
- CTLFLAG_RD, DC(expire_cycle), 0, "Expire cycle for queues/pipes");
-
-/* statistics */
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, schk_count,
- CTLFLAG_RD, DC(schk_count), 0, "Number of schedulers");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, si_count,
- CTLFLAG_RD, DC(si_count), 0, "Number of scheduler instances");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, fsk_count,
- CTLFLAG_RD, DC(fsk_count), 0, "Number of flowsets");
-SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, queue_count,
- CTLFLAG_RD, DC(queue_count), 0, "Number of queues");
-SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt,
- CTLFLAG_RD, &io_pkt, 0,
- "Number of packets passed to dummynet.");
-SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_fast,
- CTLFLAG_RD, &io_pkt_fast, 0,
- "Number of packets bypassed dummynet scheduler.");
-SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt_drop,
- CTLFLAG_RD, &io_pkt_drop, 0,
- "Number of packets dropped by dummynet.");
-#undef DC
-SYSEND
-
-#endif
-
-static void dummynet_send(struct mbuf *);
-
-/*
- * Packets processed by dummynet have an mbuf tag associated with
- * them that carries their dummynet state.
- * Outside dummynet, only the 'rule' field is relevant, and it must
- * be at the beginning of the structure.
- */
-struct dn_pkt_tag {
- struct ipfw_rule_ref rule; /* matching rule */
-
- /* second part, dummynet specific */
- int dn_dir; /* action when packet comes out.*/
- /* see ip_fw_private.h */
- uint64_t output_time; /* when the pkt is due for delivery*/
- struct ifnet *ifp; /* interface, for ip_output */
- struct _ip6dn_args ip6opt; /* XXX ipv6 options */
-};
-
-/*
- * Return the mbuf tag holding the dummynet state (it should
- * be the first one on the list).
- */
-static struct dn_pkt_tag *
-dn_tag_get(struct mbuf *m)
-{
- struct m_tag *mtag = m_tag_first(m);
- KASSERT(mtag != NULL &&
- mtag->m_tag_cookie == MTAG_ABI_COMPAT &&
- mtag->m_tag_id == PACKET_TAG_DUMMYNET,
- ("packet on dummynet queue w/o dummynet tag!"));
- return (struct dn_pkt_tag *)(mtag+1);
-}
-
-static inline void
-mq_append(struct mq *q, struct mbuf *m)
-{
- if (q->head == NULL)
- q->head = m;
- else
- q->tail->m_nextpkt = m;
- q->tail = m;
- m->m_nextpkt = NULL;
-}
-
-/*
- * Dispose a list of packet. Use a functions so if we need to do
- * more work, this is a central point to do it.
- */
-void dn_free_pkts(struct mbuf *mnext)
-{
- struct mbuf *m;
-
- while ((m = mnext) != NULL) {
- mnext = m->m_nextpkt;
- FREE_PKT(m);
- }
-}
-
-static int
-red_drops (struct dn_queue *q, int len)
-{
- /*
- * RED algorithm
- *
- * RED calculates the average queue size (avg) using a low-pass filter
- * with an exponential weighted (w_q) moving average:
- * avg <- (1-w_q) * avg + w_q * q_size
- * where q_size is the queue length (measured in bytes or * packets).
- *
- * If q_size == 0, we compute the idle time for the link, and set
- * avg = (1 - w_q)^(idle/s)
- * where s is the time needed for transmitting a medium-sized packet.
- *
- * Now, if avg < min_th the packet is enqueued.
- * If avg > max_th the packet is dropped. Otherwise, the packet is
- * dropped with probability P function of avg.
- */
-
- struct dn_fsk *fs = q->fs;
- int64_t p_b = 0;
-
- /* Queue in bytes or packets? */
- uint32_t q_size = (fs->fs.flags & DN_QSIZE_BYTES) ?
- q->ni.len_bytes : q->ni.length;
-
- /* Average queue size estimation. */
- if (q_size != 0) {
- /* Queue is not empty, avg <- avg + (q_size - avg) * w_q */
- int diff = SCALE(q_size) - q->avg;
- int64_t v = SCALE_MUL((int64_t)diff, (int64_t)fs->w_q);
-
- q->avg += (int)v;
- } else {
- /*
- * Queue is empty, find for how long the queue has been
- * empty and use a lookup table for computing
- * (1 - * w_q)^(idle_time/s) where s is the time to send a
- * (small) packet.
- * XXX check wraps...
- */
- if (q->avg) {
- u_int t = div64((dn_cfg.curr_time - q->q_time), fs->lookup_step);
-
- q->avg = (t < fs->lookup_depth) ?
- SCALE_MUL(q->avg, fs->w_q_lookup[t]) : 0;
- }
- }
-
- /* Should i drop? */
- if (q->avg < fs->min_th) {
- q->count = -1;
- return (0); /* accept packet */
- }
- if (q->avg >= fs->max_th) { /* average queue >= max threshold */
- if (fs->fs.flags & DN_IS_GENTLE_RED) {
- /*
- * According to Gentle-RED, if avg is greater than
- * max_th the packet is dropped with a probability
- * p_b = c_3 * avg - c_4
- * where c_3 = (1 - max_p) / max_th
- * c_4 = 1 - 2 * max_p
- */
- p_b = SCALE_MUL((int64_t)fs->c_3, (int64_t)q->avg) -
- fs->c_4;
- } else {
- q->count = -1;
- return (1);
- }
- } else if (q->avg > fs->min_th) {
- /*
- * We compute p_b using the linear dropping function
- * p_b = c_1 * avg - c_2
- * where c_1 = max_p / (max_th - min_th)
- * c_2 = max_p * min_th / (max_th - min_th)
- */
- p_b = SCALE_MUL((int64_t)fs->c_1, (int64_t)q->avg) - fs->c_2;
- }
-
- if (fs->fs.flags & DN_QSIZE_BYTES)
- p_b = div64((p_b * len) , fs->max_pkt_size);
- if (++q->count == 0)
- q->random = random() & 0xffff;
- else {
- /*
- * q->count counts packets arrived since last drop, so a greater
- * value of q->count means a greater packet drop probability.
- */
- if (SCALE_MUL(p_b, SCALE((int64_t)q->count)) > q->random) {
- q->count = 0;
- /* After a drop we calculate a new random value. */
- q->random = random() & 0xffff;
- return (1); /* drop */
- }
- }
- /* End of RED algorithm. */
-
- return (0); /* accept */
-
-}
-
-/*
- * Enqueue a packet in q, subject to space and queue management policy
- * (whose parameters are in q->fs).
- * Update stats for the queue and the scheduler.
- * Return 0 on success, 1 on drop. The packet is consumed anyways.
- */
-int
-dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
-{
- struct dn_fs *f;
- struct dn_flow *ni; /* stats for scheduler instance */
- uint64_t len;
-
- if (q->fs == NULL || q->_si == NULL) {
- printf("%s fs %p si %p, dropping\n",
- __FUNCTION__, q->fs, q->_si);
- FREE_PKT(m);
- return 1;
- }
- f = &(q->fs->fs);
- ni = &q->_si->ni;
- len = m->m_pkthdr.len;
- /* Update statistics, then check reasons to drop pkt. */
- q->ni.tot_bytes += len;
- q->ni.tot_pkts++;
- ni->tot_bytes += len;
- ni->tot_pkts++;
- if (drop)
- goto drop;
- if (f->plr && random() < f->plr)
- goto drop;
- if (f->flags & DN_IS_RED && red_drops(q, m->m_pkthdr.len))
- goto drop;
- if (f->flags & DN_QSIZE_BYTES) {
- if (q->ni.len_bytes > f->qsize)
- goto drop;
- } else if (q->ni.length >= f->qsize) {
- goto drop;
- }
- mq_append(&q->mq, m);
- q->ni.length++;
- q->ni.len_bytes += len;
- ni->length++;
- ni->len_bytes += len;
- return 0;
-
-drop:
- io_pkt_drop++;
- q->ni.drops++;
- ni->drops++;
- FREE_PKT(m);
- return 1;
-}
-
-/*
- * Fetch packets from the delay line which are due now. If there are
- * leftover packets, reinsert the delay line in the heap.
- * Runs under scheduler lock.
- */
-static void
-transmit_event(struct mq *q, struct delay_line *dline, uint64_t now)
-{
- struct mbuf *m;
- struct dn_pkt_tag *pkt = NULL;
-
- dline->oid.subtype = 0; /* not in heap */
- while ((m = dline->mq.head) != NULL) {
- pkt = dn_tag_get(m);
- if (!DN_KEY_LEQ(pkt->output_time, now))
- break;
- dline->mq.head = m->m_nextpkt;
- mq_append(q, m);
- }
- if (m != NULL) {
- dline->oid.subtype = 1; /* in heap */
- heap_insert(&dn_cfg.evheap, pkt->output_time, dline);
- }
-}
-
-/*
- * Convert the additional MAC overheads/delays into an equivalent
- * number of bits for the given data rate. The samples are
- * in milliseconds so we need to divide by 1000.
- */
-static uint64_t
-extra_bits(struct mbuf *m, struct dn_schk *s)
-{
- int index;
- uint64_t bits;
- struct dn_profile *pf = s->profile;
-
- if (!pf || pf->samples_no == 0)
- return 0;
- index = random() % pf->samples_no;
- bits = div64((uint64_t)pf->samples[index] * s->link.bandwidth, 1000);
- if (index >= pf->loss_level) {
- struct dn_pkt_tag *dt = dn_tag_get(m);
- if (dt)
- dt->dn_dir = DIR_DROP;
- }
- return bits;
-}
-
-/*
- * Send traffic from a scheduler instance due by 'now'.
- * Return a pointer to the head of the queue.
- */
-static struct mbuf *
-serve_sched(struct mq *q, struct dn_sch_inst *si, uint64_t now)
-{
- struct mq def_q;
- struct dn_schk *s = si->sched;
- struct mbuf *m = NULL;
- int delay_line_idle = (si->dline.mq.head == NULL);
- int done, bw;
-
- if (q == NULL) {
- q = &def_q;
- q->head = NULL;
- }
-
- bw = s->link.bandwidth;
- si->kflags &= ~DN_ACTIVE;
-
- if (bw > 0)
- si->credit += (now - si->sched_time) * bw;
- else
- si->credit = 0;
- si->sched_time = now;
- done = 0;
- while (si->credit >= 0 && (m = s->fp->dequeue(si)) != NULL) {
- uint64_t len_scaled;
-
- done++;
- len_scaled = (bw == 0) ? 0 : hz *
- (m->m_pkthdr.len * 8 + extra_bits(m, s));
- si->credit -= len_scaled;
- /* Move packet in the delay line */
- dn_tag_get(m)->output_time = dn_cfg.curr_time + s->link.delay ;
- mq_append(&si->dline.mq, m);
- }
-
- /*
- * If credit >= 0 the instance is idle, mark time.
- * Otherwise put back in the heap, and adjust the output
- * time of the last inserted packet, m, which was too early.
- */
- if (si->credit >= 0) {
- si->idle_time = now;
- } else {
- uint64_t t;
- KASSERT (bw > 0, ("bw=0 and credit<0 ?"));
- t = div64(bw - 1 - si->credit, bw);
- if (m)
- dn_tag_get(m)->output_time += t;
- si->kflags |= DN_ACTIVE;
- heap_insert(&dn_cfg.evheap, now + t, si);
- }
- if (delay_line_idle && done)
- transmit_event(q, &si->dline, now);
- return q->head;
-}
-
-/*
- * The timer handler for dummynet. Time is computed in ticks, but
- * but the code is tolerant to the actual rate at which this is called.
- * Once complete, the function reschedules itself for the next tick.
- */
-void
-dummynet_task(void *context, int pending)
-{
- struct timeval t;
- struct mq q = { NULL, NULL }; /* queue to accumulate results */
-
- CURVNET_SET((struct vnet *)context);
-
- DN_BH_WLOCK();
-
- /* Update number of lost(coalesced) ticks. */
- tick_lost += pending - 1;
-
- getmicrouptime(&t);
- /* Last tick duration (usec). */
- tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 +
- (t.tv_usec - dn_cfg.prev_t.tv_usec);
- /* Last tick vs standard tick difference (usec). */
- tick_delta = (tick_last * hz - 1000000) / hz;
- /* Accumulated tick difference (usec). */
- tick_delta_sum += tick_delta;
-
- dn_cfg.prev_t = t;
-
- /*
- * Adjust curr_time if the accumulated tick difference is
- * greater than the 'standard' tick. Since curr_time should
- * be monotonically increasing, we do positive adjustments
- * as required, and throttle curr_time in case of negative
- * adjustment.
- */
- dn_cfg.curr_time++;
- if (tick_delta_sum - tick >= 0) {
- int diff = tick_delta_sum / tick;
-
- dn_cfg.curr_time += diff;
- tick_diff += diff;
- tick_delta_sum %= tick;
- tick_adjustment++;
- } else if (tick_delta_sum + tick <= 0) {
- dn_cfg.curr_time--;
- tick_diff--;
- tick_delta_sum += tick;
- tick_adjustment++;
- }
-
- /* serve pending events, accumulate in q */
- for (;;) {
- struct dn_id *p; /* generic parameter to handler */
-
- if (dn_cfg.evheap.elements == 0 ||
- DN_KEY_LT(dn_cfg.curr_time, HEAP_TOP(&dn_cfg.evheap)->key))
- break;
- p = HEAP_TOP(&dn_cfg.evheap)->object;
- heap_extract(&dn_cfg.evheap, NULL);
-
- if (p->type == DN_SCH_I) {
- serve_sched(&q, (struct dn_sch_inst *)p, dn_cfg.curr_time);
- } else { /* extracted a delay line */
- transmit_event(&q, (struct delay_line *)p, dn_cfg.curr_time);
- }
- }
- if (dn_cfg.expire && ++dn_cfg.expire_cycle >= dn_cfg.expire) {
- dn_cfg.expire_cycle = 0;
- dn_drain_scheduler();
- dn_drain_queue();
- }
-
- DN_BH_WUNLOCK();
- dn_reschedule();
- if (q.head != NULL)
- dummynet_send(q.head);
- CURVNET_RESTORE();
-}
-
-/*
- * forward a chain of packets to the proper destination.
- * This runs outside the dummynet lock.
- */
-static void
-dummynet_send(struct mbuf *m)
-{
- struct mbuf *n;
-
- for (; m != NULL; m = n) {
- struct ifnet *ifp = NULL; /* gcc 3.4.6 complains */
- struct m_tag *tag;
- int dst;
-
- n = m->m_nextpkt;
- m->m_nextpkt = NULL;
- tag = m_tag_first(m);
- if (tag == NULL) { /* should not happen */
- dst = DIR_DROP;
- } else {
- struct dn_pkt_tag *pkt = dn_tag_get(m);
- /* extract the dummynet info, rename the tag
- * to carry reinject info.
- */
- dst = pkt->dn_dir;
- ifp = pkt->ifp;
- tag->m_tag_cookie = MTAG_IPFW_RULE;
- tag->m_tag_id = 0;
- }
-
- switch (dst) {
- case DIR_OUT:
- SET_HOST_IPLEN(mtod(m, struct ip *));
- ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL);
- break ;
-
- case DIR_IN :
- /* put header in network format for ip_input() */
- //SET_NET_IPLEN(mtod(m, struct ip *));
- netisr_dispatch(NETISR_IP, m);
- break;
-
-#ifdef INET6
- case DIR_IN | PROTO_IPV6:
- netisr_dispatch(NETISR_IPV6, m);
- break;
-
- case DIR_OUT | PROTO_IPV6:
- ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL);
- break;
-#endif
-
- case DIR_FWD | PROTO_IFB: /* DN_TO_IFB_FWD: */
- if (bridge_dn_p != NULL)
- ((*bridge_dn_p)(m, ifp));
- else
- printf("dummynet: if_bridge not loaded\n");
-
- break;
-
- case DIR_IN | PROTO_LAYER2: /* DN_TO_ETH_DEMUX: */
- /*
- * The Ethernet code assumes the Ethernet header is
- * contiguous in the first mbuf header.
- * Insure this is true.
- */
- if (m->m_len < ETHER_HDR_LEN &&
- (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) {
- printf("dummynet/ether: pullup failed, "
- "dropping packet\n");
- break;
- }
- ether_demux(m->m_pkthdr.rcvif, m);
- break;
-
- case DIR_OUT | PROTO_LAYER2: /* N_TO_ETH_OUT: */
- ether_output_frame(ifp, m);
- break;
-
- case DIR_DROP:
- /* drop the packet after some time */
- FREE_PKT(m);
- break;
-
- default:
- printf("dummynet: bad switch %d!\n", dst);
- FREE_PKT(m);
- break;
- }
- }
-}
-
-static inline int
-tag_mbuf(struct mbuf *m, int dir, struct ip_fw_args *fwa)
-{
- struct dn_pkt_tag *dt;
- struct m_tag *mtag;
-
- mtag = m_tag_get(PACKET_TAG_DUMMYNET,
- sizeof(*dt), M_NOWAIT | M_ZERO);
- if (mtag == NULL)
- return 1; /* Cannot allocate packet header. */
- m_tag_prepend(m, mtag); /* Attach to mbuf chain. */
- dt = (struct dn_pkt_tag *)(mtag + 1);
- dt->rule = fwa->rule;
- dt->rule.info &= IPFW_ONEPASS; /* only keep this info */
- dt->dn_dir = dir;
- dt->ifp = fwa->oif;
- /* dt->output tame is updated as we move through */
- dt->output_time = dn_cfg.curr_time;
- return 0;
-}
-
-
-/*
- * dummynet hook for packets.
- * We use the argument to locate the flowset fs and the sched_set sch
- * associated to it. The we apply flow_mask and sched_mask to
- * determine the queue and scheduler instances.
- *
- * dir where shall we send the packet after dummynet.
- * *m0 the mbuf with the packet
- * ifp the 'ifp' parameter from the caller.
- * NULL in ip_input, destination interface in ip_output,
- */
-int
-dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa)
-{
- struct mbuf *m = *m0;
- struct dn_fsk *fs = NULL;
- struct dn_sch_inst *si;
- struct dn_queue *q = NULL; /* default */
-
- int fs_id = (fwa->rule.info & IPFW_INFO_MASK) +
- ((fwa->rule.info & IPFW_IS_PIPE) ? 2*DN_MAX_ID : 0);
- DN_BH_WLOCK();
- io_pkt++;
- /* we could actually tag outside the lock, but who cares... */
- if (tag_mbuf(m, dir, fwa))
- goto dropit;
- if (dn_cfg.busy) {
- /* if the upper half is busy doing something expensive,
- * lets queue the packet and move forward
- */
- mq_append(&dn_cfg.pending, m);
- m = *m0 = NULL; /* consumed */
- goto done; /* already active, nothing to do */
- }
- /* XXX locate_flowset could be optimised with a direct ref. */
- fs = dn_ht_find(dn_cfg.fshash, fs_id, 0, NULL);
- if (fs == NULL)
- goto dropit; /* This queue/pipe does not exist! */
- if (fs->sched == NULL) /* should not happen */
- goto dropit;
- /* find scheduler instance, possibly applying sched_mask */
- si = ipdn_si_find(fs->sched, &(fwa->f_id));
- if (si == NULL)
- goto dropit;
- /*
- * If the scheduler supports multiple queues, find the right one
- * (otherwise it will be ignored by enqueue).
- */
- if (fs->sched->fp->flags & DN_MULTIQUEUE) {
- q = ipdn_q_find(fs, si, &(fwa->f_id));
- if (q == NULL)
- goto dropit;
- }
- if (fs->sched->fp->enqueue(si, q, m)) {
- /* packet was dropped by enqueue() */
- m = *m0 = NULL;
- goto dropit;
- }
-
- if (si->kflags & DN_ACTIVE) {
- m = *m0 = NULL; /* consumed */
- goto done; /* already active, nothing to do */
- }
-
- /* compute the initial allowance */
- if (si->idle_time < dn_cfg.curr_time) {
- /* Do this only on the first packet on an idle pipe */
- struct dn_link *p = &fs->sched->link;
-
- si->sched_time = dn_cfg.curr_time;
- si->credit = dn_cfg.io_fast ? p->bandwidth : 0;
- if (p->burst) {
- uint64_t burst = (dn_cfg.curr_time - si->idle_time) * p->bandwidth;
- if (burst > p->burst)
- burst = p->burst;
- si->credit += burst;
- }
- }
- /* pass through scheduler and delay line */
- m = serve_sched(NULL, si, dn_cfg.curr_time);
-
- /* optimization -- pass it back to ipfw for immediate send */
- /* XXX Don't call dummynet_send() if scheduler return the packet
- * just enqueued. This avoid a lock order reversal.
- *
- */
- if (/*dn_cfg.io_fast &&*/ m == *m0 && (dir & PROTO_LAYER2) == 0 ) {
- /* fast io, rename the tag * to carry reinject info. */
- struct m_tag *tag = m_tag_first(m);
-
- tag->m_tag_cookie = MTAG_IPFW_RULE;
- tag->m_tag_id = 0;
- io_pkt_fast++;
- if (m->m_nextpkt != NULL) {
- printf("dummynet: fast io: pkt chain detected!\n");
- m->m_nextpkt = NULL;
- }
- m = NULL;
- } else {
- *m0 = NULL;
- }
-done:
- DN_BH_WUNLOCK();
- if (m)
- dummynet_send(m);
- return 0;
-
-dropit:
- io_pkt_drop++;
- DN_BH_WUNLOCK();
- if (m)
- FREE_PKT(m);
- *m0 = NULL;
- return (fs && (fs->fs.flags & DN_NOERROR)) ? 0 : ENOBUFS;
-}
diff --git a/sys/netinet/ipfw/ip_dn_private.h b/sys/netinet/ipfw/ip_dn_private.h
deleted file mode 100644
index 159ddc9..0000000
--- a/sys/netinet/ipfw/ip_dn_private.h
+++ /dev/null
@@ -1,403 +0,0 @@
-/*-
- * Copyright (c) 2010 Luigi Rizzo, Riccardo Panicucci, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * internal dummynet APIs.
- *
- * $FreeBSD$
- */
-
-#ifndef _IP_DN_PRIVATE_H
-#define _IP_DN_PRIVATE_H
-
-/* debugging support
- * use ND() to remove debugging, D() to print a line,
- * DX(level, ...) to print above a certain level
- * If you redefine D() you are expected to redefine all.
- */
-#ifndef D
-#define ND(fmt, ...) do {} while (0)
-#define D1(fmt, ...) do {} while (0)
-#define D(fmt, ...) printf("%-10s " fmt "\n", \
- __FUNCTION__, ## __VA_ARGS__)
-#define DX(lev, fmt, ...) do { \
- if (dn_cfg.debug > lev) D(fmt, ## __VA_ARGS__); } while (0)
-#endif
-
-MALLOC_DECLARE(M_DUMMYNET);
-
-#ifndef __linux__
-#define div64(a, b) ((int64_t)(a) / (int64_t)(b))
-#endif
-
-#define DN_LOCK_INIT() do { \
- mtx_init(&dn_cfg.uh_mtx, "dn_uh", NULL, MTX_DEF); \
- mtx_init(&dn_cfg.bh_mtx, "dn_bh", NULL, MTX_DEF); \
- } while (0)
-#define DN_LOCK_DESTROY() do { \
- mtx_destroy(&dn_cfg.uh_mtx); \
- mtx_destroy(&dn_cfg.bh_mtx); \
- } while (0)
-#if 0 /* not used yet */
-#define DN_UH_RLOCK() mtx_lock(&dn_cfg.uh_mtx)
-#define DN_UH_RUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
-#define DN_UH_WLOCK() mtx_lock(&dn_cfg.uh_mtx)
-#define DN_UH_WUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
-#define DN_UH_LOCK_ASSERT() mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
-#endif
-
-#define DN_BH_RLOCK() mtx_lock(&dn_cfg.uh_mtx)
-#define DN_BH_RUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
-#define DN_BH_WLOCK() mtx_lock(&dn_cfg.uh_mtx)
-#define DN_BH_WUNLOCK() mtx_unlock(&dn_cfg.uh_mtx)
-#define DN_BH_LOCK_ASSERT() mtx_assert(&dn_cfg.uh_mtx, MA_OWNED)
-
-SLIST_HEAD(dn_schk_head, dn_schk);
-SLIST_HEAD(dn_sch_inst_head, dn_sch_inst);
-SLIST_HEAD(dn_fsk_head, dn_fsk);
-SLIST_HEAD(dn_queue_head, dn_queue);
-SLIST_HEAD(dn_alg_head, dn_alg);
-
-struct mq { /* a basic queue of packets*/
- struct mbuf *head, *tail;
-};
-
-static inline void
-set_oid(struct dn_id *o, int type, int len)
-{
- o->type = type;
- o->len = len;
- o->subtype = 0;
-};
-
-/*
- * configuration and global data for a dummynet instance
- *
- * When a configuration is modified from userland, 'id' is incremented
- * so we can use the value to check for stale pointers.
- */
-struct dn_parms {
- uint32_t id; /* configuration version */
-
- /* defaults (sysctl-accessible) */
- int red_lookup_depth;
- int red_avg_pkt_size;
- int red_max_pkt_size;
- int hash_size;
- int max_hash_size;
- long byte_limit; /* max queue sizes */
- long slot_limit;
-
- int io_fast;
- int debug;
-
- /* timekeeping */
- struct timeval prev_t; /* last time dummynet_tick ran */
- struct dn_heap evheap; /* scheduled events */
-
- /* counters of objects -- used for reporting space */
- int schk_count;
- int si_count;
- int fsk_count;
- int queue_count;
-
- /* ticks and other stuff */
- uint64_t curr_time;
- /* flowsets and schedulers are in hash tables, with 'hash_size'
- * buckets. fshash is looked up at every packet arrival
- * so better be generous if we expect many entries.
- */
- struct dn_ht *fshash;
- struct dn_ht *schedhash;
- /* list of flowsets without a scheduler -- use sch_chain */
- struct dn_fsk_head fsu; /* list of unlinked flowsets */
- struct dn_alg_head schedlist; /* list of algorithms */
-
- /* Store the fs/sch to scan when draining. The value is the
- * bucket number of the hash table. Expire can be disabled
- * with net.inet.ip.dummynet.expire=0, or it happens every
- * expire ticks.
- **/
- int drain_fs;
- int drain_sch;
- uint32_t expire;
- uint32_t expire_cycle; /* tick count */
-
- int init_done;
-
- /* if the upper half is busy doing something long,
- * can set the busy flag and we will enqueue packets in
- * a queue for later processing.
- */
- int busy;
- struct mq pending;
-
-#ifdef _KERNEL
- /*
- * This file is normally used in the kernel, unless we do
- * some userland tests, in which case we do not need a mtx.
- * uh_mtx arbitrates between system calls and also
- * protects fshash, schedhash and fsunlinked.
- * These structures are readonly for the lower half.
- * bh_mtx protects all other structures which may be
- * modified upon packet arrivals
- */
-#if defined( __linux__ ) || defined( _WIN32 )
- spinlock_t uh_mtx;
- spinlock_t bh_mtx;
-#else
- struct mtx uh_mtx;
- struct mtx bh_mtx;
-#endif
-
-#endif /* _KERNEL */
-};
-
-/*
- * Delay line, contains all packets on output from a link.
- * Every scheduler instance has one.
- */
-struct delay_line {
- struct dn_id oid;
- struct dn_sch_inst *si;
- struct mq mq;
-};
-
-/*
- * The kernel side of a flowset. It is linked in a hash table
- * of flowsets, and in a list of children of their parent scheduler.
- * qht is either the queue or (if HAVE_MASK) a hash table queues.
- * Note that the mask to use is the (flow_mask|sched_mask), which
- * changes as we attach/detach schedulers. So we store it here.
- *
- * XXX If we want to add scheduler-specific parameters, we need to
- * put them in external storage because the scheduler may not be
- * available when the fsk is created.
- */
-struct dn_fsk { /* kernel side of a flowset */
- struct dn_fs fs;
- SLIST_ENTRY(dn_fsk) fsk_next; /* hash chain for fshash */
-
- struct ipfw_flow_id fsk_mask;
-
- /* qht is a hash table of queues, or just a single queue
- * a bit in fs.flags tells us which one
- */
- struct dn_ht *qht;
- struct dn_schk *sched; /* Sched we are linked to */
- SLIST_ENTRY(dn_fsk) sch_chain; /* list of fsk attached to sched */
-
- /* bucket index used by drain routine to drain queues for this
- * flowset
- */
- int drain_bucket;
- /* Parameter realted to RED / GRED */
- /* original values are in dn_fs*/
- int w_q ; /* queue weight (scaled) */
- int max_th ; /* maximum threshold for queue (scaled) */
- int min_th ; /* minimum threshold for queue (scaled) */
- int max_p ; /* maximum value for p_b (scaled) */
-
- u_int c_1 ; /* max_p/(max_th-min_th) (scaled) */
- u_int c_2 ; /* max_p*min_th/(max_th-min_th) (scaled) */
- u_int c_3 ; /* for GRED, (1-max_p)/max_th (scaled) */
- u_int c_4 ; /* for GRED, 1 - 2*max_p (scaled) */
- u_int * w_q_lookup ; /* lookup table for computing (1-w_q)^t */
- u_int lookup_depth ; /* depth of lookup table */
- int lookup_step ; /* granularity inside the lookup table */
- int lookup_weight ; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */
- int avg_pkt_size ; /* medium packet size */
- int max_pkt_size ; /* max packet size */
-};
-
-/*
- * A queue is created as a child of a flowset unless it belongs to
- * a !MULTIQUEUE scheduler. It is normally in a hash table in the
- * flowset. fs always points to the parent flowset.
- * si normally points to the sch_inst, unless the flowset has been
- * detached from the scheduler -- in this case si == NULL and we
- * should not enqueue.
- */
-struct dn_queue {
- struct dn_flow ni; /* oid, flow_id, stats */
- struct mq mq; /* packets queue */
- struct dn_sch_inst *_si; /* owner scheduler instance */
- SLIST_ENTRY(dn_queue) q_next; /* hash chain list for qht */
- struct dn_fsk *fs; /* parent flowset. */
-
- /* RED parameters */
- int avg; /* average queue length est. (scaled) */
- int count; /* arrivals since last RED drop */
- int random; /* random value (scaled) */
- uint64_t q_time; /* start of queue idle time */
-
-};
-
-/*
- * The kernel side of a scheduler. Contains the userland config,
- * a link, pointer to extra config arguments from command line,
- * kernel flags, and a pointer to the scheduler methods.
- * It is stored in a hash table, and holds a list of all
- * flowsets and scheduler instances.
- * XXX sch must be at the beginning, see schk_hash().
- */
-struct dn_schk {
- struct dn_sch sch;
- struct dn_alg *fp; /* Pointer to scheduler functions */
- struct dn_link link; /* The link, embedded */
- struct dn_profile *profile; /* delay profile, if any */
- struct dn_id *cfg; /* extra config arguments */
-
- SLIST_ENTRY(dn_schk) schk_next; /* hash chain for schedhash */
-
- struct dn_fsk_head fsk_list; /* all fsk linked to me */
- struct dn_fsk *fs; /* Flowset for !MULTIQUEUE */
-
- /* bucket index used by the drain routine to drain the scheduler
- * instance for this flowset.
- */
- int drain_bucket;
-
- /* Hash table of all instances (through sch.sched_mask)
- * or single instance if no mask. Always valid.
- */
- struct dn_ht *siht;
-};
-
-
-/*
- * Scheduler instance.
- * Contains variables and all queues relative to a this instance.
- * This struct is created a runtime.
- */
-struct dn_sch_inst {
- struct dn_flow ni; /* oid, flowid and stats */
- SLIST_ENTRY(dn_sch_inst) si_next; /* hash chain for siht */
- struct delay_line dline;
- struct dn_schk *sched; /* the template */
- int kflags; /* DN_ACTIVE */
-
- int64_t credit; /* bits I can transmit (more or less). */
- uint64_t sched_time; /* time link was scheduled in ready_heap */
- uint64_t idle_time; /* start of scheduler instance idle time */
-
- /* q_count is the number of queues that this instance is using.
- * The counter is incremented or decremented when
- * a reference from the queue is created or deleted.
- * It is used to make sure that a scheduler instance can be safely
- * deleted by the drain routine. See notes below.
- */
- int q_count;
-
-};
-
-/*
- * NOTE about object drain.
- * The system will automatically (XXX check when) drain queues and
- * scheduler instances when they are idle.
- * A queue is idle when it has no packets; an instance is idle when
- * it is not in the evheap heap, and the corresponding delay line is empty.
- * A queue can be safely deleted when it is idle because of the scheduler
- * function xxx_free_queue() will remove any references to it.
- * An instance can be only deleted when no queues reference it. To be sure
- * of that, a counter (q_count) stores the number of queues that are pointing
- * to the instance.
- *
- * XXX
- * Order of scan:
- * - take all flowset in a bucket for the flowset hash table
- * - take all queues in a bucket for the flowset
- * - increment the queue bucket
- * - scan next flowset bucket
- * Nothing is done if a bucket contains no entries.
- *
- * The same schema is used for sceduler instances
- */
-
-
-/* kernel-side flags. Linux has DN_DELETE in fcntl.h
- */
-enum {
- /* 1 and 2 are reserved for the SCAN flags */
- DN_DESTROY = 0x0004, /* destroy */
- DN_DELETE_FS = 0x0008, /* destroy flowset */
- DN_DETACH = 0x0010,
- DN_ACTIVE = 0x0020, /* object is in evheap */
- DN_F_DLINE = 0x0040, /* object is a delay line */
- DN_DEL_SAFE = 0x0080, /* delete a queue only if no longer needed
- * by scheduler */
- DN_QHT_IS_Q = 0x0100, /* in flowset, qht is a single queue */
-};
-
-extern struct dn_parms dn_cfg;
-//VNET_DECLARE(struct dn_parms, _base_dn_cfg);
-//#define dn_cfg VNET(_base_dn_cfg)
-
-int dummynet_io(struct mbuf **, int , struct ip_fw_args *);
-void dummynet_task(void *context, int pending);
-void dn_reschedule(void);
-
-struct dn_queue *ipdn_q_find(struct dn_fsk *, struct dn_sch_inst *,
- struct ipfw_flow_id *);
-struct dn_sch_inst *ipdn_si_find(struct dn_schk *, struct ipfw_flow_id *);
-
-/*
- * copy_range is a template for requests for ranges of pipes/queues/scheds.
- * The number of ranges is variable and can be derived by o.len.
- * As a default, we use a small number of entries so that the struct
- * fits easily on the stack and is sufficient for most common requests.
- */
-#define DEFAULT_RANGES 5
-struct copy_range {
- struct dn_id o;
- uint32_t r[ 2 * DEFAULT_RANGES ];
-};
-
-struct copy_args {
- char **start;
- char *end;
- int flags;
- int type;
- struct copy_range *extra; /* extra filtering */
-};
-
-struct sockopt;
-int ip_dummynet_compat(struct sockopt *sopt);
-int dummynet_get(struct sockopt *sopt, void **compat);
-int dn_c_copy_q (void *_ni, void *arg);
-int dn_c_copy_pipe(struct dn_schk *s, struct copy_args *a, int nq);
-int dn_c_copy_fs(struct dn_fsk *f, struct copy_args *a, int nq);
-int dn_compat_copy_queue(struct copy_args *a, void *_o);
-int dn_compat_copy_pipe(struct copy_args *a, void *_o);
-int copy_data_helper_compat(void *_o, void *_arg);
-int dn_compat_calc_size(void);
-int do_config(void *p, int l);
-
-/* function to drain idle object */
-void dn_drain_scheduler(void);
-void dn_drain_queue(void);
-
-#endif /* _IP_DN_PRIVATE_H */
diff --git a/sys/netinet/ipfw/ip_dummynet.c b/sys/netinet/ipfw/ip_dummynet.c
deleted file mode 100644
index 928176e..0000000
--- a/sys/netinet/ipfw/ip_dummynet.c
+++ /dev/null
@@ -1,2313 +0,0 @@
-/*-
- * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
- * Portions Copyright (c) 2000 Akamba Corp.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Configuration and internal object management for dummynet.
- */
-
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/time.h>
-#include <sys/taskqueue.h>
-#include <net/if.h> /* IFNAMSIZ, struct ifaddr, ifq head, lock.h mutex.h */
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/ipfw/dn_heap.h>
-#include <netinet/ip_dummynet.h>
-#include <netinet/ipfw/ip_dn_private.h>
-#include <netinet/ipfw/dn_sched.h>
-
-/* which objects to copy */
-#define DN_C_LINK 0x01
-#define DN_C_SCH 0x02
-#define DN_C_FLOW 0x04
-#define DN_C_FS 0x08
-#define DN_C_QUEUE 0x10
-
-/* we use this argument in case of a schk_new */
-struct schk_new_arg {
- struct dn_alg *fp;
- struct dn_sch *sch;
-};
-
-/*---- callout hooks. ----*/
-static struct callout dn_timeout;
-static struct task dn_task;
-static struct taskqueue *dn_tq = NULL;
-
-static void
-dummynet(void * __unused unused)
-{
-
- taskqueue_enqueue(dn_tq, &dn_task);
-}
-
-void
-dn_reschedule(void)
-{
- callout_reset(&dn_timeout, 1, dummynet, NULL);
-}
-/*----- end of callout hooks -----*/
-
-/* Return a scheduler descriptor given the type or name. */
-static struct dn_alg *
-find_sched_type(int type, char *name)
-{
- struct dn_alg *d;
-
- SLIST_FOREACH(d, &dn_cfg.schedlist, next) {
- if (d->type == type || (name && !strcasecmp(d->name, name)))
- return d;
- }
- return NULL; /* not found */
-}
-
-int
-ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
-{
- int oldv = *v;
- const char *op = NULL;
- if (dflt < lo)
- dflt = lo;
- if (dflt > hi)
- dflt = hi;
- if (oldv < lo) {
- *v = dflt;
- op = "Bump";
- } else if (oldv > hi) {
- *v = hi;
- op = "Clamp";
- } else
- return *v;
- if (op && msg)
- printf("%s %s to %d (was %d)\n", op, msg, *v, oldv);
- return *v;
-}
-
-/*---- flow_id mask, hash and compare functions ---*/
-/*
- * The flow_id includes the 5-tuple, the queue/pipe number
- * which we store in the extra area in host order,
- * and for ipv6 also the flow_id6.
- * XXX see if we want the tos byte (can store in 'flags')
- */
-static struct ipfw_flow_id *
-flow_id_mask(struct ipfw_flow_id *mask, struct ipfw_flow_id *id)
-{
- int is_v6 = IS_IP6_FLOW_ID(id);
-
- id->dst_port &= mask->dst_port;
- id->src_port &= mask->src_port;
- id->proto &= mask->proto;
- id->extra &= mask->extra;
- if (is_v6) {
- APPLY_MASK(&id->dst_ip6, &mask->dst_ip6);
- APPLY_MASK(&id->src_ip6, &mask->src_ip6);
- id->flow_id6 &= mask->flow_id6;
- } else {
- id->dst_ip &= mask->dst_ip;
- id->src_ip &= mask->src_ip;
- }
- return id;
-}
-
-/* computes an OR of two masks, result in dst and also returned */
-static struct ipfw_flow_id *
-flow_id_or(struct ipfw_flow_id *src, struct ipfw_flow_id *dst)
-{
- int is_v6 = IS_IP6_FLOW_ID(dst);
-
- dst->dst_port |= src->dst_port;
- dst->src_port |= src->src_port;
- dst->proto |= src->proto;
- dst->extra |= src->extra;
- if (is_v6) {
-#define OR_MASK(_d, _s) \
- (_d)->__u6_addr.__u6_addr32[0] |= (_s)->__u6_addr.__u6_addr32[0]; \
- (_d)->__u6_addr.__u6_addr32[1] |= (_s)->__u6_addr.__u6_addr32[1]; \
- (_d)->__u6_addr.__u6_addr32[2] |= (_s)->__u6_addr.__u6_addr32[2]; \
- (_d)->__u6_addr.__u6_addr32[3] |= (_s)->__u6_addr.__u6_addr32[3];
- OR_MASK(&dst->dst_ip6, &src->dst_ip6);
- OR_MASK(&dst->src_ip6, &src->src_ip6);
-#undef OR_MASK
- dst->flow_id6 |= src->flow_id6;
- } else {
- dst->dst_ip |= src->dst_ip;
- dst->src_ip |= src->src_ip;
- }
- return dst;
-}
-
-static int
-nonzero_mask(struct ipfw_flow_id *m)
-{
- if (m->dst_port || m->src_port || m->proto || m->extra)
- return 1;
- if (IS_IP6_FLOW_ID(m)) {
- return
- m->dst_ip6.__u6_addr.__u6_addr32[0] ||
- m->dst_ip6.__u6_addr.__u6_addr32[1] ||
- m->dst_ip6.__u6_addr.__u6_addr32[2] ||
- m->dst_ip6.__u6_addr.__u6_addr32[3] ||
- m->src_ip6.__u6_addr.__u6_addr32[0] ||
- m->src_ip6.__u6_addr.__u6_addr32[1] ||
- m->src_ip6.__u6_addr.__u6_addr32[2] ||
- m->src_ip6.__u6_addr.__u6_addr32[3] ||
- m->flow_id6;
- } else {
- return m->dst_ip || m->src_ip;
- }
-}
-
-/* XXX we may want a better hash function */
-static uint32_t
-flow_id_hash(struct ipfw_flow_id *id)
-{
- uint32_t i;
-
- if (IS_IP6_FLOW_ID(id)) {
- uint32_t *d = (uint32_t *)&id->dst_ip6;
- uint32_t *s = (uint32_t *)&id->src_ip6;
- i = (d[0] ) ^ (d[1]) ^
- (d[2] ) ^ (d[3]) ^
- (d[0] >> 15) ^ (d[1] >> 15) ^
- (d[2] >> 15) ^ (d[3] >> 15) ^
- (s[0] << 1) ^ (s[1] << 1) ^
- (s[2] << 1) ^ (s[3] << 1) ^
- (s[0] << 16) ^ (s[1] << 16) ^
- (s[2] << 16) ^ (s[3] << 16) ^
- (id->dst_port << 1) ^ (id->src_port) ^
- (id->extra) ^
- (id->proto ) ^ (id->flow_id6);
- } else {
- i = (id->dst_ip) ^ (id->dst_ip >> 15) ^
- (id->src_ip << 1) ^ (id->src_ip >> 16) ^
- (id->extra) ^
- (id->dst_port << 1) ^ (id->src_port) ^ (id->proto);
- }
- return i;
-}
-
-/* Like bcmp, returns 0 if ids match, 1 otherwise. */
-static int
-flow_id_cmp(struct ipfw_flow_id *id1, struct ipfw_flow_id *id2)
-{
- int is_v6 = IS_IP6_FLOW_ID(id1);
-
- if (!is_v6) {
- if (IS_IP6_FLOW_ID(id2))
- return 1; /* different address families */
-
- return (id1->dst_ip == id2->dst_ip &&
- id1->src_ip == id2->src_ip &&
- id1->dst_port == id2->dst_port &&
- id1->src_port == id2->src_port &&
- id1->proto == id2->proto &&
- id1->extra == id2->extra) ? 0 : 1;
- }
- /* the ipv6 case */
- return (
- !bcmp(&id1->dst_ip6,&id2->dst_ip6, sizeof(id1->dst_ip6)) &&
- !bcmp(&id1->src_ip6,&id2->src_ip6, sizeof(id1->src_ip6)) &&
- id1->dst_port == id2->dst_port &&
- id1->src_port == id2->src_port &&
- id1->proto == id2->proto &&
- id1->extra == id2->extra &&
- id1->flow_id6 == id2->flow_id6) ? 0 : 1;
-}
-/*--------- end of flow-id mask, hash and compare ---------*/
-
-/*--- support functions for the qht hashtable ----
- * Entries are hashed by flow-id
- */
-static uint32_t
-q_hash(uintptr_t key, int flags, void *arg)
-{
- /* compute the hash slot from the flow id */
- struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
- &((struct dn_queue *)key)->ni.fid :
- (struct ipfw_flow_id *)key;
-
- return flow_id_hash(id);
-}
-
-static int
-q_match(void *obj, uintptr_t key, int flags, void *arg)
-{
- struct dn_queue *o = (struct dn_queue *)obj;
- struct ipfw_flow_id *id2;
-
- if (flags & DNHT_KEY_IS_OBJ) {
- /* compare pointers */
- id2 = &((struct dn_queue *)key)->ni.fid;
- } else {
- id2 = (struct ipfw_flow_id *)key;
- }
- return (0 == flow_id_cmp(&o->ni.fid, id2));
-}
-
-/*
- * create a new queue instance for the given 'key'.
- */
-static void *
-q_new(uintptr_t key, int flags, void *arg)
-{
- struct dn_queue *q, *template = arg;
- struct dn_fsk *fs = template->fs;
- int size = sizeof(*q) + fs->sched->fp->q_datalen;
-
- q = malloc(size, M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (q == NULL) {
- D("no memory for new queue");
- return NULL;
- }
-
- set_oid(&q->ni.oid, DN_QUEUE, size);
- if (fs->fs.flags & DN_QHT_HASH)
- q->ni.fid = *(struct ipfw_flow_id *)key;
- q->fs = fs;
- q->_si = template->_si;
- q->_si->q_count++;
-
- if (fs->sched->fp->new_queue)
- fs->sched->fp->new_queue(q);
- dn_cfg.queue_count++;
- return q;
-}
-
-/*
- * Notify schedulers that a queue is going away.
- * If (flags & DN_DESTROY), also free the packets.
- * The version for callbacks is called q_delete_cb().
- */
-static void
-dn_delete_queue(struct dn_queue *q, int flags)
-{
- struct dn_fsk *fs = q->fs;
-
- // D("fs %p si %p\n", fs, q->_si);
- /* notify the parent scheduler that the queue is going away */
- if (fs && fs->sched->fp->free_queue)
- fs->sched->fp->free_queue(q);
- q->_si->q_count--;
- q->_si = NULL;
- if (flags & DN_DESTROY) {
- if (q->mq.head)
- dn_free_pkts(q->mq.head);
- bzero(q, sizeof(*q)); // safety
- free(q, M_DUMMYNET);
- dn_cfg.queue_count--;
- }
-}
-
-static int
-q_delete_cb(void *q, void *arg)
-{
- int flags = (int)(uintptr_t)arg;
- dn_delete_queue(q, flags);
- return (flags & DN_DESTROY) ? DNHT_SCAN_DEL : 0;
-}
-
-/*
- * calls dn_delete_queue/q_delete_cb on all queues,
- * which notifies the parent scheduler and possibly drains packets.
- * flags & DN_DESTROY: drains queues and destroy qht;
- */
-static void
-qht_delete(struct dn_fsk *fs, int flags)
-{
- ND("fs %d start flags %d qht %p",
- fs->fs.fs_nr, flags, fs->qht);
- if (!fs->qht)
- return;
- if (fs->fs.flags & DN_QHT_HASH) {
- dn_ht_scan(fs->qht, q_delete_cb, (void *)(uintptr_t)flags);
- if (flags & DN_DESTROY) {
- dn_ht_free(fs->qht, 0);
- fs->qht = NULL;
- }
- } else {
- dn_delete_queue((struct dn_queue *)(fs->qht), flags);
- if (flags & DN_DESTROY)
- fs->qht = NULL;
- }
-}
-
-/*
- * Find and possibly create the queue for a MULTIQUEUE scheduler.
- * We never call it for !MULTIQUEUE (the queue is in the sch_inst).
- */
-struct dn_queue *
-ipdn_q_find(struct dn_fsk *fs, struct dn_sch_inst *si,
- struct ipfw_flow_id *id)
-{
- struct dn_queue template;
-
- template._si = si;
- template.fs = fs;
-
- if (fs->fs.flags & DN_QHT_HASH) {
- struct ipfw_flow_id masked_id;
- if (fs->qht == NULL) {
- fs->qht = dn_ht_init(NULL, fs->fs.buckets,
- offsetof(struct dn_queue, q_next),
- q_hash, q_match, q_new);
- if (fs->qht == NULL)
- return NULL;
- }
- masked_id = *id;
- flow_id_mask(&fs->fsk_mask, &masked_id);
- return dn_ht_find(fs->qht, (uintptr_t)&masked_id,
- DNHT_INSERT, &template);
- } else {
- if (fs->qht == NULL)
- fs->qht = q_new(0, 0, &template);
- return (struct dn_queue *)fs->qht;
- }
-}
-/*--- end of queue hash table ---*/
-
-/*--- support functions for the sch_inst hashtable ----
- *
- * These are hashed by flow-id
- */
-static uint32_t
-si_hash(uintptr_t key, int flags, void *arg)
-{
- /* compute the hash slot from the flow id */
- struct ipfw_flow_id *id = (flags & DNHT_KEY_IS_OBJ) ?
- &((struct dn_sch_inst *)key)->ni.fid :
- (struct ipfw_flow_id *)key;
-
- return flow_id_hash(id);
-}
-
-static int
-si_match(void *obj, uintptr_t key, int flags, void *arg)
-{
- struct dn_sch_inst *o = obj;
- struct ipfw_flow_id *id2;
-
- id2 = (flags & DNHT_KEY_IS_OBJ) ?
- &((struct dn_sch_inst *)key)->ni.fid :
- (struct ipfw_flow_id *)key;
- return flow_id_cmp(&o->ni.fid, id2) == 0;
-}
-
-/*
- * create a new instance for the given 'key'
- * Allocate memory for instance, delay line and scheduler private data.
- */
-static void *
-si_new(uintptr_t key, int flags, void *arg)
-{
- struct dn_schk *s = arg;
- struct dn_sch_inst *si;
- int l = sizeof(*si) + s->fp->si_datalen;
-
- si = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (si == NULL)
- goto error;
-
- /* Set length only for the part passed up to userland. */
- set_oid(&si->ni.oid, DN_SCH_I, sizeof(struct dn_flow));
- set_oid(&(si->dline.oid), DN_DELAY_LINE,
- sizeof(struct delay_line));
- /* mark si and dline as outside the event queue */
- si->ni.oid.id = si->dline.oid.id = -1;
-
- si->sched = s;
- si->dline.si = si;
-
- if (s->fp->new_sched && s->fp->new_sched(si)) {
- D("new_sched error");
- goto error;
- }
- if (s->sch.flags & DN_HAVE_MASK)
- si->ni.fid = *(struct ipfw_flow_id *)key;
-
- dn_cfg.si_count++;
- return si;
-
-error:
- if (si) {
- bzero(si, sizeof(*si)); // safety
- free(si, M_DUMMYNET);
- }
- return NULL;
-}
-
-/*
- * Callback from siht to delete all scheduler instances. Remove
- * si and delay line from the system heap, destroy all queues.
- * We assume that all flowset have been notified and do not
- * point to us anymore.
- */
-static int
-si_destroy(void *_si, void *arg)
-{
- struct dn_sch_inst *si = _si;
- struct dn_schk *s = si->sched;
- struct delay_line *dl = &si->dline;
-
- if (dl->oid.subtype) /* remove delay line from event heap */
- heap_extract(&dn_cfg.evheap, dl);
- dn_free_pkts(dl->mq.head); /* drain delay line */
- if (si->kflags & DN_ACTIVE) /* remove si from event heap */
- heap_extract(&dn_cfg.evheap, si);
- if (s->fp->free_sched)
- s->fp->free_sched(si);
- bzero(si, sizeof(*si)); /* safety */
- free(si, M_DUMMYNET);
- dn_cfg.si_count--;
- return DNHT_SCAN_DEL;
-}
-
-/*
- * Find the scheduler instance for this packet. If we need to apply
- * a mask, do on a local copy of the flow_id to preserve the original.
- * Assume siht is always initialized if we have a mask.
- */
-struct dn_sch_inst *
-ipdn_si_find(struct dn_schk *s, struct ipfw_flow_id *id)
-{
-
- if (s->sch.flags & DN_HAVE_MASK) {
- struct ipfw_flow_id id_t = *id;
- flow_id_mask(&s->sch.sched_mask, &id_t);
- return dn_ht_find(s->siht, (uintptr_t)&id_t,
- DNHT_INSERT, s);
- }
- if (!s->siht)
- s->siht = si_new(0, 0, s);
- return (struct dn_sch_inst *)s->siht;
-}
-
-/* callback to flush credit for the scheduler instance */
-static int
-si_reset_credit(void *_si, void *arg)
-{
- struct dn_sch_inst *si = _si;
- struct dn_link *p = &si->sched->link;
-
- si->credit = p->burst + (dn_cfg.io_fast ? p->bandwidth : 0);
- return 0;
-}
-
-static void
-schk_reset_credit(struct dn_schk *s)
-{
- if (s->sch.flags & DN_HAVE_MASK)
- dn_ht_scan(s->siht, si_reset_credit, NULL);
- else if (s->siht)
- si_reset_credit(s->siht, NULL);
-}
-/*---- end of sch_inst hashtable ---------------------*/
-
-/*-------------------------------------------------------
- * flowset hash (fshash) support. Entries are hashed by fs_nr.
- * New allocations are put in the fsunlinked list, from which
- * they are removed when they point to a specific scheduler.
- */
-static uint32_t
-fsk_hash(uintptr_t key, int flags, void *arg)
-{
- uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
- ((struct dn_fsk *)key)->fs.fs_nr;
-
- return ( (i>>8)^(i>>4)^i );
-}
-
-static int
-fsk_match(void *obj, uintptr_t key, int flags, void *arg)
-{
- struct dn_fsk *fs = obj;
- int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
- ((struct dn_fsk *)key)->fs.fs_nr;
-
- return (fs->fs.fs_nr == i);
-}
-
-static void *
-fsk_new(uintptr_t key, int flags, void *arg)
-{
- struct dn_fsk *fs;
-
- fs = malloc(sizeof(*fs), M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (fs) {
- set_oid(&fs->fs.oid, DN_FS, sizeof(fs->fs));
- dn_cfg.fsk_count++;
- fs->drain_bucket = 0;
- SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
- }
- return fs;
-}
-
-/*
- * detach flowset from its current scheduler. Flags as follows:
- * DN_DETACH removes from the fsk_list
- * DN_DESTROY deletes individual queues
- * DN_DELETE_FS destroys the flowset (otherwise goes in unlinked).
- */
-static void
-fsk_detach(struct dn_fsk *fs, int flags)
-{
- if (flags & DN_DELETE_FS)
- flags |= DN_DESTROY;
- ND("fs %d from sched %d flags %s %s %s",
- fs->fs.fs_nr, fs->fs.sched_nr,
- (flags & DN_DELETE_FS) ? "DEL_FS":"",
- (flags & DN_DESTROY) ? "DEL":"",
- (flags & DN_DETACH) ? "DET":"");
- if (flags & DN_DETACH) { /* detach from the list */
- struct dn_fsk_head *h;
- h = fs->sched ? &fs->sched->fsk_list : &dn_cfg.fsu;
- SLIST_REMOVE(h, fs, dn_fsk, sch_chain);
- }
- /* Free the RED parameters, they will be recomputed on
- * subsequent attach if needed.
- */
- if (fs->w_q_lookup)
- free(fs->w_q_lookup, M_DUMMYNET);
- fs->w_q_lookup = NULL;
- qht_delete(fs, flags);
- if (fs->sched && fs->sched->fp->free_fsk)
- fs->sched->fp->free_fsk(fs);
- fs->sched = NULL;
- if (flags & DN_DELETE_FS) {
- bzero(fs, sizeof(fs)); /* safety */
- free(fs, M_DUMMYNET);
- dn_cfg.fsk_count--;
- } else {
- SLIST_INSERT_HEAD(&dn_cfg.fsu, fs, sch_chain);
- }
-}
-
-/*
- * Detach or destroy all flowsets in a list.
- * flags specifies what to do:
- * DN_DESTROY: flush all queues
- * DN_DELETE_FS: DN_DESTROY + destroy flowset
- * DN_DELETE_FS implies DN_DESTROY
- */
-static void
-fsk_detach_list(struct dn_fsk_head *h, int flags)
-{
- struct dn_fsk *fs;
- int n = 0; /* only for stats */
-
- ND("head %p flags %x", h, flags);
- while ((fs = SLIST_FIRST(h))) {
- SLIST_REMOVE_HEAD(h, sch_chain);
- n++;
- fsk_detach(fs, flags);
- }
- ND("done %d flowsets", n);
-}
-
-/*
- * called on 'queue X delete' -- removes the flowset from fshash,
- * deletes all queues for the flowset, and removes the flowset.
- */
-static int
-delete_fs(int i, int locked)
-{
- struct dn_fsk *fs;
- int err = 0;
-
- if (!locked)
- DN_BH_WLOCK();
- fs = dn_ht_find(dn_cfg.fshash, i, DNHT_REMOVE, NULL);
- ND("fs %d found %p", i, fs);
- if (fs) {
- fsk_detach(fs, DN_DETACH | DN_DELETE_FS);
- err = 0;
- } else
- err = EINVAL;
- if (!locked)
- DN_BH_WUNLOCK();
- return err;
-}
-
-/*----- end of flowset hashtable support -------------*/
-
-/*------------------------------------------------------------
- * Scheduler hash. When searching by index we pass sched_nr,
- * otherwise we pass struct dn_sch * which is the first field in
- * struct dn_schk so we can cast between the two. We use this trick
- * because in the create phase (but it should be fixed).
- */
-static uint32_t
-schk_hash(uintptr_t key, int flags, void *_arg)
-{
- uint32_t i = !(flags & DNHT_KEY_IS_OBJ) ? key :
- ((struct dn_schk *)key)->sch.sched_nr;
- return ( (i>>8)^(i>>4)^i );
-}
-
-static int
-schk_match(void *obj, uintptr_t key, int flags, void *_arg)
-{
- struct dn_schk *s = (struct dn_schk *)obj;
- int i = !(flags & DNHT_KEY_IS_OBJ) ? key :
- ((struct dn_schk *)key)->sch.sched_nr;
- return (s->sch.sched_nr == i);
-}
-
-/*
- * Create the entry and intialize with the sched hash if needed.
- * Leave s->fp unset so we can tell whether a dn_ht_find() returns
- * a new object or a previously existing one.
- */
-static void *
-schk_new(uintptr_t key, int flags, void *arg)
-{
- struct schk_new_arg *a = arg;
- struct dn_schk *s;
- int l = sizeof(*s) +a->fp->schk_datalen;
-
- s = malloc(l, M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (s == NULL)
- return NULL;
- set_oid(&s->link.oid, DN_LINK, sizeof(s->link));
- s->sch = *a->sch; // copy initial values
- s->link.link_nr = s->sch.sched_nr;
- SLIST_INIT(&s->fsk_list);
- /* initialize the hash table or create the single instance */
- s->fp = a->fp; /* si_new needs this */
- s->drain_bucket = 0;
- if (s->sch.flags & DN_HAVE_MASK) {
- s->siht = dn_ht_init(NULL, s->sch.buckets,
- offsetof(struct dn_sch_inst, si_next),
- si_hash, si_match, si_new);
- if (s->siht == NULL) {
- free(s, M_DUMMYNET);
- return NULL;
- }
- }
- s->fp = NULL; /* mark as a new scheduler */
- dn_cfg.schk_count++;
- return s;
-}
-
-/*
- * Callback for sched delete. Notify all attached flowsets to
- * detach from the scheduler, destroy the internal flowset, and
- * all instances. The scheduler goes away too.
- * arg is 0 (only detach flowsets and destroy instances)
- * DN_DESTROY (detach & delete queues, delete schk)
- * or DN_DELETE_FS (delete queues and flowsets, delete schk)
- */
-static int
-schk_delete_cb(void *obj, void *arg)
-{
- struct dn_schk *s = obj;
-#if 0
- int a = (int)arg;
- ND("sched %d arg %s%s",
- s->sch.sched_nr,
- a&DN_DESTROY ? "DEL ":"",
- a&DN_DELETE_FS ? "DEL_FS":"");
-#endif
- fsk_detach_list(&s->fsk_list, arg ? DN_DESTROY : 0);
- /* no more flowset pointing to us now */
- if (s->sch.flags & DN_HAVE_MASK) {
- dn_ht_scan(s->siht, si_destroy, NULL);
- dn_ht_free(s->siht, 0);
- } else if (s->siht)
- si_destroy(s->siht, NULL);
- if (s->profile) {
- free(s->profile, M_DUMMYNET);
- s->profile = NULL;
- }
- s->siht = NULL;
- if (s->fp->destroy)
- s->fp->destroy(s);
- bzero(s, sizeof(*s)); // safety
- free(obj, M_DUMMYNET);
- dn_cfg.schk_count--;
- return DNHT_SCAN_DEL;
-}
-
-/*
- * called on a 'sched X delete' command. Deletes a single scheduler.
- * This is done by removing from the schedhash, unlinking all
- * flowsets and deleting their traffic.
- */
-static int
-delete_schk(int i)
-{
- struct dn_schk *s;
-
- s = dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
- ND("%d %p", i, s);
- if (!s)
- return EINVAL;
- delete_fs(i + DN_MAX_ID, 1); /* first delete internal fs */
- /* then detach flowsets, delete traffic */
- schk_delete_cb(s, (void*)(uintptr_t)DN_DESTROY);
- return 0;
-}
-/*--- end of schk hashtable support ---*/
-
-static int
-copy_obj(char **start, char *end, void *_o, const char *msg, int i)
-{
- struct dn_id *o = _o;
- int have = end - *start;
-
- if (have < o->len || o->len == 0 || o->type == 0) {
- D("(WARN) type %d %s %d have %d need %d",
- o->type, msg, i, have, o->len);
- return 1;
- }
- ND("type %d %s %d len %d", o->type, msg, i, o->len);
- bcopy(_o, *start, o->len);
- if (o->type == DN_LINK) {
- /* Adjust burst parameter for link */
- struct dn_link *l = (struct dn_link *)*start;
- l->burst = div64(l->burst, 8 * hz);
- l->delay = l->delay * 1000 / hz;
- } else if (o->type == DN_SCH) {
- /* Set id->id to the number of instances */
- struct dn_schk *s = _o;
- struct dn_id *id = (struct dn_id *)(*start);
- id->id = (s->sch.flags & DN_HAVE_MASK) ?
- dn_ht_entries(s->siht) : (s->siht ? 1 : 0);
- }
- *start += o->len;
- return 0;
-}
-
-/* Specific function to copy a queue.
- * Copies only the user-visible part of a queue (which is in
- * a struct dn_flow), and sets len accordingly.
- */
-static int
-copy_obj_q(char **start, char *end, void *_o, const char *msg, int i)
-{
- struct dn_id *o = _o;
- int have = end - *start;
- int len = sizeof(struct dn_flow); /* see above comment */
-
- if (have < len || o->len == 0 || o->type != DN_QUEUE) {
- D("ERROR type %d %s %d have %d need %d",
- o->type, msg, i, have, len);
- return 1;
- }
- ND("type %d %s %d len %d", o->type, msg, i, len);
- bcopy(_o, *start, len);
- ((struct dn_id*)(*start))->len = len;
- *start += len;
- return 0;
-}
-
-static int
-copy_q_cb(void *obj, void *arg)
-{
- struct dn_queue *q = obj;
- struct copy_args *a = arg;
- struct dn_flow *ni = (struct dn_flow *)(*a->start);
- if (copy_obj_q(a->start, a->end, &q->ni, "queue", -1))
- return DNHT_SCAN_END;
- ni->oid.type = DN_FLOW; /* override the DN_QUEUE */
- ni->oid.id = si_hash((uintptr_t)&ni->fid, 0, NULL);
- return 0;
-}
-
-static int
-copy_q(struct copy_args *a, struct dn_fsk *fs, int flags)
-{
- if (!fs->qht)
- return 0;
- if (fs->fs.flags & DN_QHT_HASH)
- dn_ht_scan(fs->qht, copy_q_cb, a);
- else
- copy_q_cb(fs->qht, a);
- return 0;
-}
-
-/*
- * This routine only copies the initial part of a profile ? XXX
- */
-static int
-copy_profile(struct copy_args *a, struct dn_profile *p)
-{
- int have = a->end - *a->start;
- /* XXX here we check for max length */
- int profile_len = sizeof(struct dn_profile) -
- ED_MAX_SAMPLES_NO*sizeof(int);
-
- if (p == NULL)
- return 0;
- if (have < profile_len) {
- D("error have %d need %d", have, profile_len);
- return 1;
- }
- bcopy(p, *a->start, profile_len);
- ((struct dn_id *)(*a->start))->len = profile_len;
- *a->start += profile_len;
- return 0;
-}
-
-static int
-copy_flowset(struct copy_args *a, struct dn_fsk *fs, int flags)
-{
- struct dn_fs *ufs = (struct dn_fs *)(*a->start);
- if (!fs)
- return 0;
- ND("flowset %d", fs->fs.fs_nr);
- if (copy_obj(a->start, a->end, &fs->fs, "flowset", fs->fs.fs_nr))
- return DNHT_SCAN_END;
- ufs->oid.id = (fs->fs.flags & DN_QHT_HASH) ?
- dn_ht_entries(fs->qht) : (fs->qht ? 1 : 0);
- if (flags) { /* copy queues */
- copy_q(a, fs, 0);
- }
- return 0;
-}
-
-static int
-copy_si_cb(void *obj, void *arg)
-{
- struct dn_sch_inst *si = obj;
- struct copy_args *a = arg;
- struct dn_flow *ni = (struct dn_flow *)(*a->start);
- if (copy_obj(a->start, a->end, &si->ni, "inst",
- si->sched->sch.sched_nr))
- return DNHT_SCAN_END;
- ni->oid.type = DN_FLOW; /* override the DN_SCH_I */
- ni->oid.id = si_hash((uintptr_t)si, DNHT_KEY_IS_OBJ, NULL);
- return 0;
-}
-
-static int
-copy_si(struct copy_args *a, struct dn_schk *s, int flags)
-{
- if (s->sch.flags & DN_HAVE_MASK)
- dn_ht_scan(s->siht, copy_si_cb, a);
- else if (s->siht)
- copy_si_cb(s->siht, a);
- return 0;
-}
-
-/*
- * compute a list of children of a scheduler and copy up
- */
-static int
-copy_fsk_list(struct copy_args *a, struct dn_schk *s, int flags)
-{
- struct dn_fsk *fs;
- struct dn_id *o;
- uint32_t *p;
-
- int n = 0, space = sizeof(*o);
- SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
- if (fs->fs.fs_nr < DN_MAX_ID)
- n++;
- }
- space += n * sizeof(uint32_t);
- DX(3, "sched %d has %d flowsets", s->sch.sched_nr, n);
- if (a->end - *(a->start) < space)
- return DNHT_SCAN_END;
- o = (struct dn_id *)(*(a->start));
- o->len = space;
- *a->start += o->len;
- o->type = DN_TEXT;
- p = (uint32_t *)(o+1);
- SLIST_FOREACH(fs, &s->fsk_list, sch_chain)
- if (fs->fs.fs_nr < DN_MAX_ID)
- *p++ = fs->fs.fs_nr;
- return 0;
-}
-
-static int
-copy_data_helper(void *_o, void *_arg)
-{
- struct copy_args *a = _arg;
- uint32_t *r = a->extra->r; /* start of first range */
- uint32_t *lim; /* first invalid pointer */
- int n;
-
- lim = (uint32_t *)((char *)(a->extra) + a->extra->o.len);
-
- if (a->type == DN_LINK || a->type == DN_SCH) {
- /* pipe|sched show, we receive a dn_schk */
- struct dn_schk *s = _o;
-
- n = s->sch.sched_nr;
- if (a->type == DN_SCH && n >= DN_MAX_ID)
- return 0; /* not a scheduler */
- if (a->type == DN_LINK && n <= DN_MAX_ID)
- return 0; /* not a pipe */
-
- /* see if the object is within one of our ranges */
- for (;r < lim; r += 2) {
- if (n < r[0] || n > r[1])
- continue;
- /* Found a valid entry, copy and we are done */
- if (a->flags & DN_C_LINK) {
- if (copy_obj(a->start, a->end,
- &s->link, "link", n))
- return DNHT_SCAN_END;
- if (copy_profile(a, s->profile))
- return DNHT_SCAN_END;
- if (copy_flowset(a, s->fs, 0))
- return DNHT_SCAN_END;
- }
- if (a->flags & DN_C_SCH) {
- if (copy_obj(a->start, a->end,
- &s->sch, "sched", n))
- return DNHT_SCAN_END;
- /* list all attached flowsets */
- if (copy_fsk_list(a, s, 0))
- return DNHT_SCAN_END;
- }
- if (a->flags & DN_C_FLOW)
- copy_si(a, s, 0);
- break;
- }
- } else if (a->type == DN_FS) {
- /* queue show, skip internal flowsets */
- struct dn_fsk *fs = _o;
-
- n = fs->fs.fs_nr;
- if (n >= DN_MAX_ID)
- return 0;
- /* see if the object is within one of our ranges */
- for (;r < lim; r += 2) {
- if (n < r[0] || n > r[1])
- continue;
- if (copy_flowset(a, fs, 0))
- return DNHT_SCAN_END;
- copy_q(a, fs, 0);
- break; /* we are done */
- }
- }
- return 0;
-}
-
-static inline struct dn_schk *
-locate_scheduler(int i)
-{
- return dn_ht_find(dn_cfg.schedhash, i, 0, NULL);
-}
-
-/*
- * red parameters are in fixed point arithmetic.
- */
-static int
-config_red(struct dn_fsk *fs)
-{
- int64_t s, idle, weight, w0;
- int t, i;
-
- fs->w_q = fs->fs.w_q;
- fs->max_p = fs->fs.max_p;
- ND("called");
- /* Doing stuff that was in userland */
- i = fs->sched->link.bandwidth;
- s = (i <= 0) ? 0 :
- hz * dn_cfg.red_avg_pkt_size * 8 * SCALE(1) / i;
-
- idle = div64((s * 3) , fs->w_q); /* s, fs->w_q scaled; idle not scaled */
- fs->lookup_step = div64(idle , dn_cfg.red_lookup_depth);
- /* fs->lookup_step not scaled, */
- if (!fs->lookup_step)
- fs->lookup_step = 1;
- w0 = weight = SCALE(1) - fs->w_q; //fs->w_q scaled
-
- for (t = fs->lookup_step; t > 1; --t)
- weight = SCALE_MUL(weight, w0);
- fs->lookup_weight = (int)(weight); // scaled
-
- /* Now doing stuff that was in kerneland */
- fs->min_th = SCALE(fs->fs.min_th);
- fs->max_th = SCALE(fs->fs.max_th);
-
- fs->c_1 = fs->max_p / (fs->fs.max_th - fs->fs.min_th);
- fs->c_2 = SCALE_MUL(fs->c_1, SCALE(fs->fs.min_th));
-
- if (fs->fs.flags & DN_IS_GENTLE_RED) {
- fs->c_3 = (SCALE(1) - fs->max_p) / fs->fs.max_th;
- fs->c_4 = SCALE(1) - 2 * fs->max_p;
- }
-
- /* If the lookup table already exist, free and create it again. */
- if (fs->w_q_lookup) {
- free(fs->w_q_lookup, M_DUMMYNET);
- fs->w_q_lookup = NULL;
- }
- if (dn_cfg.red_lookup_depth == 0) {
- printf("\ndummynet: net.inet.ip.dummynet.red_lookup_depth"
- "must be > 0\n");
- fs->fs.flags &= ~DN_IS_RED;
- fs->fs.flags &= ~DN_IS_GENTLE_RED;
- return (EINVAL);
- }
- fs->lookup_depth = dn_cfg.red_lookup_depth;
- fs->w_q_lookup = (u_int *)malloc(fs->lookup_depth * sizeof(int),
- M_DUMMYNET, M_NOWAIT);
- if (fs->w_q_lookup == NULL) {
- printf("dummynet: sorry, cannot allocate red lookup table\n");
- fs->fs.flags &= ~DN_IS_RED;
- fs->fs.flags &= ~DN_IS_GENTLE_RED;
- return(ENOSPC);
- }
-
- /* Fill the lookup table with (1 - w_q)^x */
- fs->w_q_lookup[0] = SCALE(1) - fs->w_q;
-
- for (i = 1; i < fs->lookup_depth; i++)
- fs->w_q_lookup[i] =
- SCALE_MUL(fs->w_q_lookup[i - 1], fs->lookup_weight);
-
- if (dn_cfg.red_avg_pkt_size < 1)
- dn_cfg.red_avg_pkt_size = 512;
- fs->avg_pkt_size = dn_cfg.red_avg_pkt_size;
- if (dn_cfg.red_max_pkt_size < 1)
- dn_cfg.red_max_pkt_size = 1500;
- fs->max_pkt_size = dn_cfg.red_max_pkt_size;
- ND("exit");
- return 0;
-}
-
-/* Scan all flowset attached to this scheduler and update red */
-static void
-update_red(struct dn_schk *s)
-{
- struct dn_fsk *fs;
- SLIST_FOREACH(fs, &s->fsk_list, sch_chain) {
- if (fs && (fs->fs.flags & DN_IS_RED))
- config_red(fs);
- }
-}
-
-/* attach flowset to scheduler s, possibly requeue */
-static void
-fsk_attach(struct dn_fsk *fs, struct dn_schk *s)
-{
- ND("remove fs %d from fsunlinked, link to sched %d",
- fs->fs.fs_nr, s->sch.sched_nr);
- SLIST_REMOVE(&dn_cfg.fsu, fs, dn_fsk, sch_chain);
- fs->sched = s;
- SLIST_INSERT_HEAD(&s->fsk_list, fs, sch_chain);
- if (s->fp->new_fsk)
- s->fp->new_fsk(fs);
- /* XXX compute fsk_mask */
- fs->fsk_mask = fs->fs.flow_mask;
- if (fs->sched->sch.flags & DN_HAVE_MASK)
- flow_id_or(&fs->sched->sch.sched_mask, &fs->fsk_mask);
- if (fs->qht) {
- /*
- * we must drain qht according to the old
- * type, and reinsert according to the new one.
- * The requeue is complex -- in general we need to
- * reclassify every single packet.
- * For the time being, let's hope qht is never set
- * when we reach this point.
- */
- D("XXX TODO requeue from fs %d to sch %d",
- fs->fs.fs_nr, s->sch.sched_nr);
- fs->qht = NULL;
- }
- /* set the new type for qht */
- if (nonzero_mask(&fs->fsk_mask))
- fs->fs.flags |= DN_QHT_HASH;
- else
- fs->fs.flags &= ~DN_QHT_HASH;
-
- /* XXX config_red() can fail... */
- if (fs->fs.flags & DN_IS_RED)
- config_red(fs);
-}
-
-/* update all flowsets which may refer to this scheduler */
-static void
-update_fs(struct dn_schk *s)
-{
- struct dn_fsk *fs, *tmp;
-
- SLIST_FOREACH_SAFE(fs, &dn_cfg.fsu, sch_chain, tmp) {
- if (s->sch.sched_nr != fs->fs.sched_nr) {
- D("fs %d for sch %d not %d still unlinked",
- fs->fs.fs_nr, fs->fs.sched_nr,
- s->sch.sched_nr);
- continue;
- }
- fsk_attach(fs, s);
- }
-}
-
-/*
- * Configuration -- to preserve backward compatibility we use
- * the following scheme (N is 65536)
- * NUMBER SCHED LINK FLOWSET
- * 1 .. N-1 (1)WFQ (2)WFQ (3)queue
- * N+1 .. 2N-1 (4)FIFO (5)FIFO (6)FIFO for sched 1..N-1
- * 2N+1 .. 3N-1 -- -- (7)FIFO for sched N+1..2N-1
- *
- * "pipe i config" configures #1, #2 and #3
- * "sched i config" configures #1 and possibly #6
- * "queue i config" configures #3
- * #1 is configured with 'pipe i config' or 'sched i config'
- * #2 is configured with 'pipe i config', and created if not
- * existing with 'sched i config'
- * #3 is configured with 'queue i config'
- * #4 is automatically configured after #1, can only be FIFO
- * #5 is automatically configured after #2
- * #6 is automatically created when #1 is !MULTIQUEUE,
- * and can be updated.
- * #7 is automatically configured after #2
- */
-
-/*
- * configure a link (and its FIFO instance)
- */
-static int
-config_link(struct dn_link *p, struct dn_id *arg)
-{
- int i;
-
- if (p->oid.len != sizeof(*p)) {
- D("invalid pipe len %d", p->oid.len);
- return EINVAL;
- }
- i = p->link_nr;
- if (i <= 0 || i >= DN_MAX_ID)
- return EINVAL;
- /*
- * The config program passes parameters as follows:
- * bw = bits/second (0 means no limits),
- * delay = ms, must be translated into ticks.
- * qsize = slots/bytes
- * burst ???
- */
- p->delay = (p->delay * hz) / 1000;
- /* Scale burst size: bytes -> bits * hz */
- p->burst *= 8 * hz;
-
- DN_BH_WLOCK();
- /* do it twice, base link and FIFO link */
- for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
- struct dn_schk *s = locate_scheduler(i);
- if (s == NULL) {
- DN_BH_WUNLOCK();
- D("sched %d not found", i);
- return EINVAL;
- }
- /* remove profile if exists */
- if (s->profile) {
- free(s->profile, M_DUMMYNET);
- s->profile = NULL;
- }
- /* copy all parameters */
- s->link.oid = p->oid;
- s->link.link_nr = i;
- s->link.delay = p->delay;
- if (s->link.bandwidth != p->bandwidth) {
- /* XXX bandwidth changes, need to update red params */
- s->link.bandwidth = p->bandwidth;
- update_red(s);
- }
- s->link.burst = p->burst;
- schk_reset_credit(s);
- }
- dn_cfg.id++;
- DN_BH_WUNLOCK();
- return 0;
-}
-
-/*
- * configure a flowset. Can be called from inside with locked=1,
- */
-static struct dn_fsk *
-config_fs(struct dn_fs *nfs, struct dn_id *arg, int locked)
-{
- int i;
- struct dn_fsk *fs;
-
- if (nfs->oid.len != sizeof(*nfs)) {
- D("invalid flowset len %d", nfs->oid.len);
- return NULL;
- }
- i = nfs->fs_nr;
- if (i <= 0 || i >= 3*DN_MAX_ID)
- return NULL;
- ND("flowset %d", i);
- /* XXX other sanity checks */
- if (nfs->flags & DN_QSIZE_BYTES) {
- ipdn_bound_var(&nfs->qsize, 16384,
- 1500, dn_cfg.byte_limit, NULL); // "queue byte size");
- } else {
- ipdn_bound_var(&nfs->qsize, 50,
- 1, dn_cfg.slot_limit, NULL); // "queue slot size");
- }
- if (nfs->flags & DN_HAVE_MASK) {
- /* make sure we have some buckets */
- ipdn_bound_var(&nfs->buckets, dn_cfg.hash_size,
- 1, dn_cfg.max_hash_size, "flowset buckets");
- } else {
- nfs->buckets = 1; /* we only need 1 */
- }
- if (!locked)
- DN_BH_WLOCK();
- do { /* exit with break when done */
- struct dn_schk *s;
- int flags = nfs->sched_nr ? DNHT_INSERT : 0;
- int j;
- int oldc = dn_cfg.fsk_count;
- fs = dn_ht_find(dn_cfg.fshash, i, flags, NULL);
- if (fs == NULL) {
- D("missing sched for flowset %d", i);
- break;
- }
- /* grab some defaults from the existing one */
- if (nfs->sched_nr == 0) /* reuse */
- nfs->sched_nr = fs->fs.sched_nr;
- for (j = 0; j < sizeof(nfs->par)/sizeof(nfs->par[0]); j++) {
- if (nfs->par[j] == -1) /* reuse */
- nfs->par[j] = fs->fs.par[j];
- }
- if (bcmp(&fs->fs, nfs, sizeof(*nfs)) == 0) {
- ND("flowset %d unchanged", i);
- break; /* no change, nothing to do */
- }
- if (oldc != dn_cfg.fsk_count) /* new item */
- dn_cfg.id++;
- s = locate_scheduler(nfs->sched_nr);
- /* detach from old scheduler if needed, preserving
- * queues if we need to reattach. Then update the
- * configuration, and possibly attach to the new sched.
- */
- DX(2, "fs %d changed sched %d@%p to %d@%p",
- fs->fs.fs_nr,
- fs->fs.sched_nr, fs->sched, nfs->sched_nr, s);
- if (fs->sched) {
- int flags = s ? DN_DETACH : (DN_DETACH | DN_DESTROY);
- flags |= DN_DESTROY; /* XXX temporary */
- fsk_detach(fs, flags);
- }
- fs->fs = *nfs; /* copy configuration */
- if (s != NULL)
- fsk_attach(fs, s);
- } while (0);
- if (!locked)
- DN_BH_WUNLOCK();
- return fs;
-}
-
-/*
- * config/reconfig a scheduler and its FIFO variant.
- * For !MULTIQUEUE schedulers, also set up the flowset.
- *
- * On reconfigurations (detected because s->fp is set),
- * detach existing flowsets preserving traffic, preserve link,
- * and delete the old scheduler creating a new one.
- */
-static int
-config_sched(struct dn_sch *_nsch, struct dn_id *arg)
-{
- struct dn_schk *s;
- struct schk_new_arg a; /* argument for schk_new */
- int i;
- struct dn_link p; /* copy of oldlink */
- struct dn_profile *pf = NULL; /* copy of old link profile */
- /* Used to preserv mask parameter */
- struct ipfw_flow_id new_mask;
- int new_buckets = 0;
- int new_flags = 0;
- int pipe_cmd;
- int err = ENOMEM;
-
- a.sch = _nsch;
- if (a.sch->oid.len != sizeof(*a.sch)) {
- D("bad sched len %d", a.sch->oid.len);
- return EINVAL;
- }
- i = a.sch->sched_nr;
- if (i <= 0 || i >= DN_MAX_ID)
- return EINVAL;
- /* make sure we have some buckets */
- if (a.sch->flags & DN_HAVE_MASK)
- ipdn_bound_var(&a.sch->buckets, dn_cfg.hash_size,
- 1, dn_cfg.max_hash_size, "sched buckets");
- /* XXX other sanity checks */
- bzero(&p, sizeof(p));
-
- pipe_cmd = a.sch->flags & DN_PIPE_CMD;
- a.sch->flags &= ~DN_PIPE_CMD; //XXX do it even if is not set?
- if (pipe_cmd) {
- /* Copy mask parameter */
- new_mask = a.sch->sched_mask;
- new_buckets = a.sch->buckets;
- new_flags = a.sch->flags;
- }
- DN_BH_WLOCK();
-again: /* run twice, for wfq and fifo */
- /*
- * lookup the type. If not supplied, use the previous one
- * or default to WF2Q+. Otherwise, return an error.
- */
- dn_cfg.id++;
- a.fp = find_sched_type(a.sch->oid.subtype, a.sch->name);
- if (a.fp != NULL) {
- /* found. Lookup or create entry */
- s = dn_ht_find(dn_cfg.schedhash, i, DNHT_INSERT, &a);
- } else if (a.sch->oid.subtype == 0 && !a.sch->name[0]) {
- /* No type. search existing s* or retry with WF2Q+ */
- s = dn_ht_find(dn_cfg.schedhash, i, 0, &a);
- if (s != NULL) {
- a.fp = s->fp;
- /* Scheduler exists, skip to FIFO scheduler
- * if command was pipe config...
- */
- if (pipe_cmd)
- goto next;
- } else {
- /* New scheduler, create a wf2q+ with no mask
- * if command was pipe config...
- */
- if (pipe_cmd) {
- /* clear mask parameter */
- bzero(&a.sch->sched_mask, sizeof(new_mask));
- a.sch->buckets = 0;
- a.sch->flags &= ~DN_HAVE_MASK;
- }
- a.sch->oid.subtype = DN_SCHED_WF2QP;
- goto again;
- }
- } else {
- D("invalid scheduler type %d %s",
- a.sch->oid.subtype, a.sch->name);
- err = EINVAL;
- goto error;
- }
- /* normalize name and subtype */
- a.sch->oid.subtype = a.fp->type;
- bzero(a.sch->name, sizeof(a.sch->name));
- strlcpy(a.sch->name, a.fp->name, sizeof(a.sch->name));
- if (s == NULL) {
- D("cannot allocate scheduler %d", i);
- goto error;
- }
- /* restore existing link if any */
- if (p.link_nr) {
- s->link = p;
- if (!pf || pf->link_nr != p.link_nr) { /* no saved value */
- s->profile = NULL; /* XXX maybe not needed */
- } else {
- s->profile = malloc(sizeof(struct dn_profile),
- M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (s->profile == NULL) {
- D("cannot allocate profile");
- goto error; //XXX
- }
- bcopy(pf, s->profile, sizeof(*pf));
- }
- }
- p.link_nr = 0;
- if (s->fp == NULL) {
- DX(2, "sched %d new type %s", i, a.fp->name);
- } else if (s->fp != a.fp ||
- bcmp(a.sch, &s->sch, sizeof(*a.sch)) ) {
- /* already existing. */
- DX(2, "sched %d type changed from %s to %s",
- i, s->fp->name, a.fp->name);
- DX(4, " type/sub %d/%d -> %d/%d",
- s->sch.oid.type, s->sch.oid.subtype,
- a.sch->oid.type, a.sch->oid.subtype);
- if (s->link.link_nr == 0)
- D("XXX WARNING link 0 for sched %d", i);
- p = s->link; /* preserve link */
- if (s->profile) {/* preserve profile */
- if (!pf)
- pf = malloc(sizeof(*pf),
- M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (pf) /* XXX should issue a warning otherwise */
- bcopy(s->profile, pf, sizeof(*pf));
- }
- /* remove from the hash */
- dn_ht_find(dn_cfg.schedhash, i, DNHT_REMOVE, NULL);
- /* Detach flowsets, preserve queues. */
- // schk_delete_cb(s, NULL);
- // XXX temporarily, kill queues
- schk_delete_cb(s, (void *)DN_DESTROY);
- goto again;
- } else {
- DX(4, "sched %d unchanged type %s", i, a.fp->name);
- }
- /* complete initialization */
- s->sch = *a.sch;
- s->fp = a.fp;
- s->cfg = arg;
- // XXX schk_reset_credit(s);
- /* create the internal flowset if needed,
- * trying to reuse existing ones if available
- */
- if (!(s->fp->flags & DN_MULTIQUEUE) && !s->fs) {
- s->fs = dn_ht_find(dn_cfg.fshash, i, 0, NULL);
- if (!s->fs) {
- struct dn_fs fs;
- bzero(&fs, sizeof(fs));
- set_oid(&fs.oid, DN_FS, sizeof(fs));
- fs.fs_nr = i + DN_MAX_ID;
- fs.sched_nr = i;
- s->fs = config_fs(&fs, NULL, 1 /* locked */);
- }
- if (!s->fs) {
- schk_delete_cb(s, (void *)DN_DESTROY);
- D("error creating internal fs for %d", i);
- goto error;
- }
- }
- /* call init function after the flowset is created */
- if (s->fp->config)
- s->fp->config(s);
- update_fs(s);
-next:
- if (i < DN_MAX_ID) { /* now configure the FIFO instance */
- i += DN_MAX_ID;
- if (pipe_cmd) {
- /* Restore mask parameter for FIFO */
- a.sch->sched_mask = new_mask;
- a.sch->buckets = new_buckets;
- a.sch->flags = new_flags;
- } else {
- /* sched config shouldn't modify the FIFO scheduler */
- if (dn_ht_find(dn_cfg.schedhash, i, 0, &a) != NULL) {
- /* FIFO already exist, don't touch it */
- err = 0; /* and this is not an error */
- goto error;
- }
- }
- a.sch->sched_nr = i;
- a.sch->oid.subtype = DN_SCHED_FIFO;
- bzero(a.sch->name, sizeof(a.sch->name));
- goto again;
- }
- err = 0;
-error:
- DN_BH_WUNLOCK();
- if (pf)
- free(pf, M_DUMMYNET);
- return err;
-}
-
-/*
- * attach a profile to a link
- */
-static int
-config_profile(struct dn_profile *pf, struct dn_id *arg)
-{
- struct dn_schk *s;
- int i, olen, err = 0;
-
- if (pf->oid.len < sizeof(*pf)) {
- D("short profile len %d", pf->oid.len);
- return EINVAL;
- }
- i = pf->link_nr;
- if (i <= 0 || i >= DN_MAX_ID)
- return EINVAL;
- /* XXX other sanity checks */
- DN_BH_WLOCK();
- for (; i < 2*DN_MAX_ID; i += DN_MAX_ID) {
- s = locate_scheduler(i);
-
- if (s == NULL) {
- err = EINVAL;
- break;
- }
- dn_cfg.id++;
- /*
- * If we had a profile and the new one does not fit,
- * or it is deleted, then we need to free memory.
- */
- if (s->profile && (pf->samples_no == 0 ||
- s->profile->oid.len < pf->oid.len)) {
- free(s->profile, M_DUMMYNET);
- s->profile = NULL;
- }
- if (pf->samples_no == 0)
- continue;
- /*
- * new profile, possibly allocate memory
- * and copy data.
- */
- if (s->profile == NULL)
- s->profile = malloc(pf->oid.len,
- M_DUMMYNET, M_NOWAIT | M_ZERO);
- if (s->profile == NULL) {
- D("no memory for profile %d", i);
- err = ENOMEM;
- break;
- }
- /* preserve larger length XXX double check */
- olen = s->profile->oid.len;
- if (olen < pf->oid.len)
- olen = pf->oid.len;
- bcopy(pf, s->profile, pf->oid.len);
- s->profile->oid.len = olen;
- }
- DN_BH_WUNLOCK();
- return err;
-}
-
-/*
- * Delete all objects:
- */
-static void
-dummynet_flush(void)
-{
-
- /* delete all schedulers and related links/queues/flowsets */
- dn_ht_scan(dn_cfg.schedhash, schk_delete_cb,
- (void *)(uintptr_t)DN_DELETE_FS);
- /* delete all remaining (unlinked) flowsets */
- DX(4, "still %d unlinked fs", dn_cfg.fsk_count);
- dn_ht_free(dn_cfg.fshash, DNHT_REMOVE);
- fsk_detach_list(&dn_cfg.fsu, DN_DELETE_FS);
- /* Reinitialize system heap... */
- heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
-}
-
-/*
- * Main handler for configuration. We are guaranteed to be called
- * with an oid which is at least a dn_id.
- * - the first object is the command (config, delete, flush, ...)
- * - config_link must be issued after the corresponding config_sched
- * - parameters (DN_TXT) for an object must preceed the object
- * processed on a config_sched.
- */
-int
-do_config(void *p, int l)
-{
- struct dn_id *next, *o;
- int err = 0, err2 = 0;
- struct dn_id *arg = NULL;
- uintptr_t *a;
-
- o = p;
- if (o->id != DN_API_VERSION) {
- D("invalid api version got %d need %d",
- o->id, DN_API_VERSION);
- return EINVAL;
- }
- for (; l >= sizeof(*o); o = next) {
- struct dn_id *prev = arg;
- if (o->len < sizeof(*o) || l < o->len) {
- D("bad len o->len %d len %d", o->len, l);
- err = EINVAL;
- break;
- }
- l -= o->len;
- next = (struct dn_id *)((char *)o + o->len);
- err = 0;
- switch (o->type) {
- default:
- D("cmd %d not implemented", o->type);
- break;
-
-#ifdef EMULATE_SYSCTL
- /* sysctl emulation.
- * if we recognize the command, jump to the correct
- * handler and return
- */
- case DN_SYSCTL_SET:
- err = kesysctl_emu_set(p, l);
- return err;
-#endif
-
- case DN_CMD_CONFIG: /* simply a header */
- break;
-
- case DN_CMD_DELETE:
- /* the argument is in the first uintptr_t after o */
- a = (uintptr_t *)(o+1);
- if (o->len < sizeof(*o) + sizeof(*a)) {
- err = EINVAL;
- break;
- }
- switch (o->subtype) {
- case DN_LINK:
- /* delete base and derived schedulers */
- DN_BH_WLOCK();
- err = delete_schk(*a);
- err2 = delete_schk(*a + DN_MAX_ID);
- DN_BH_WUNLOCK();
- if (!err)
- err = err2;
- break;
-
- default:
- D("invalid delete type %d",
- o->subtype);
- err = EINVAL;
- break;
-
- case DN_FS:
- err = (*a <1 || *a >= DN_MAX_ID) ?
- EINVAL : delete_fs(*a, 0) ;
- break;
- }
- break;
-
- case DN_CMD_FLUSH:
- DN_BH_WLOCK();
- dummynet_flush();
- DN_BH_WUNLOCK();
- break;
- case DN_TEXT: /* store argument the next block */
- prev = NULL;
- arg = o;
- break;
- case DN_LINK:
- err = config_link((struct dn_link *)o, arg);
- break;
- case DN_PROFILE:
- err = config_profile((struct dn_profile *)o, arg);
- break;
- case DN_SCH:
- err = config_sched((struct dn_sch *)o, arg);
- break;
- case DN_FS:
- err = (NULL==config_fs((struct dn_fs *)o, arg, 0));
- break;
- }
- if (prev)
- arg = NULL;
- if (err != 0)
- break;
- }
- return err;
-}
-
-static int
-compute_space(struct dn_id *cmd, struct copy_args *a)
-{
- int x = 0, need = 0;
- int profile_size = sizeof(struct dn_profile) -
- ED_MAX_SAMPLES_NO*sizeof(int);
-
- /* NOTE about compute space:
- * NP = dn_cfg.schk_count
- * NSI = dn_cfg.si_count
- * NF = dn_cfg.fsk_count
- * NQ = dn_cfg.queue_count
- * - ipfw pipe show
- * (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
- * link, scheduler template, flowset
- * integrated in scheduler and header
- * for flowset list
- * (NSI)*(dn_flow) all scheduler instance (includes
- * the queue instance)
- * - ipfw sched show
- * (NP/2)*(dn_link + dn_sch + dn_id + dn_fs) only half scheduler
- * link, scheduler template, flowset
- * integrated in scheduler and header
- * for flowset list
- * (NSI * dn_flow) all scheduler instances
- * (NF * sizeof(uint_32)) space for flowset list linked to scheduler
- * (NQ * dn_queue) all queue [XXXfor now not listed]
- * - ipfw queue show
- * (NF * dn_fs) all flowset
- * (NQ * dn_queue) all queues
- */
- switch (cmd->subtype) {
- default:
- return -1;
- /* XXX where do LINK and SCH differ ? */
- /* 'ipfw sched show' could list all queues associated to
- * a scheduler. This feature for now is disabled
- */
- case DN_LINK: /* pipe show */
- x = DN_C_LINK | DN_C_SCH | DN_C_FLOW;
- need += dn_cfg.schk_count *
- (sizeof(struct dn_fs) + profile_size) / 2;
- need += dn_cfg.fsk_count * sizeof(uint32_t);
- break;
- case DN_SCH: /* sched show */
- need += dn_cfg.schk_count *
- (sizeof(struct dn_fs) + profile_size) / 2;
- need += dn_cfg.fsk_count * sizeof(uint32_t);
- x = DN_C_SCH | DN_C_LINK | DN_C_FLOW;
- break;
- case DN_FS: /* queue show */
- x = DN_C_FS | DN_C_QUEUE;
- break;
- case DN_GET_COMPAT: /* compatibility mode */
- need = dn_compat_calc_size();
- break;
- }
- a->flags = x;
- if (x & DN_C_SCH) {
- need += dn_cfg.schk_count * sizeof(struct dn_sch) / 2;
- /* NOT also, each fs might be attached to a sched */
- need += dn_cfg.schk_count * sizeof(struct dn_id) / 2;
- }
- if (x & DN_C_FS)
- need += dn_cfg.fsk_count * sizeof(struct dn_fs);
- if (x & DN_C_LINK) {
- need += dn_cfg.schk_count * sizeof(struct dn_link) / 2;
- }
- /*
- * When exporting a queue to userland, only pass up the
- * struct dn_flow, which is the only visible part.
- */
-
- if (x & DN_C_QUEUE)
- need += dn_cfg.queue_count * sizeof(struct dn_flow);
- if (x & DN_C_FLOW)
- need += dn_cfg.si_count * (sizeof(struct dn_flow));
- return need;
-}
-
-/*
- * If compat != NULL dummynet_get is called in compatibility mode.
- * *compat will be the pointer to the buffer to pass to ipfw
- */
-int
-dummynet_get(struct sockopt *sopt, void **compat)
-{
- int have, i, need, error;
- char *start = NULL, *buf;
- size_t sopt_valsize;
- struct dn_id *cmd;
- struct copy_args a;
- struct copy_range r;
- int l = sizeof(struct dn_id);
-
- bzero(&a, sizeof(a));
- bzero(&r, sizeof(r));
-
- /* save and restore original sopt_valsize around copyin */
- sopt_valsize = sopt->sopt_valsize;
-
- cmd = &r.o;
-
- if (!compat) {
- /* copy at least an oid, and possibly a full object */
- error = sooptcopyin(sopt, cmd, sizeof(r), sizeof(*cmd));
- sopt->sopt_valsize = sopt_valsize;
- if (error)
- goto done;
- l = cmd->len;
-#ifdef EMULATE_SYSCTL
- /* sysctl emulation. */
- if (cmd->type == DN_SYSCTL_GET)
- return kesysctl_emu_get(sopt);
-#endif
- if (l > sizeof(r)) {
- /* request larger than default, allocate buffer */
- cmd = malloc(l, M_DUMMYNET, M_WAITOK);
- error = sooptcopyin(sopt, cmd, l, l);
- sopt->sopt_valsize = sopt_valsize;
- if (error)
- goto done;
- }
- } else { /* compatibility */
- error = 0;
- cmd->type = DN_CMD_GET;
- cmd->len = sizeof(struct dn_id);
- cmd->subtype = DN_GET_COMPAT;
- // cmd->id = sopt_valsize;
- D("compatibility mode");
- }
- a.extra = (struct copy_range *)cmd;
- if (cmd->len == sizeof(*cmd)) { /* no range, create a default */
- uint32_t *rp = (uint32_t *)(cmd + 1);
- cmd->len += 2* sizeof(uint32_t);
- rp[0] = 1;
- rp[1] = DN_MAX_ID - 1;
- if (cmd->subtype == DN_LINK) {
- rp[0] += DN_MAX_ID;
- rp[1] += DN_MAX_ID;
- }
- }
- /* Count space (under lock) and allocate (outside lock).
- * Exit with lock held if we manage to get enough buffer.
- * Try a few times then give up.
- */
- for (have = 0, i = 0; i < 10; i++) {
- DN_BH_WLOCK();
- need = compute_space(cmd, &a);
-
- /* if there is a range, ignore value from compute_space() */
- if (l > sizeof(*cmd))
- need = sopt_valsize - sizeof(*cmd);
-
- if (need < 0) {
- DN_BH_WUNLOCK();
- error = EINVAL;
- goto done;
- }
- need += sizeof(*cmd);
- cmd->id = need;
- if (have >= need)
- break;
-
- DN_BH_WUNLOCK();
- if (start)
- free(start, M_DUMMYNET);
- start = NULL;
- if (need > sopt_valsize)
- break;
-
- have = need;
- start = malloc(have, M_DUMMYNET, M_WAITOK | M_ZERO);
- }
-
- if (start == NULL) {
- if (compat) {
- *compat = NULL;
- error = 1; // XXX
- } else {
- error = sooptcopyout(sopt, cmd, sizeof(*cmd));
- }
- goto done;
- }
- ND("have %d:%d sched %d, %d:%d links %d, %d:%d flowsets %d, "
- "%d:%d si %d, %d:%d queues %d",
- dn_cfg.schk_count, sizeof(struct dn_sch), DN_SCH,
- dn_cfg.schk_count, sizeof(struct dn_link), DN_LINK,
- dn_cfg.fsk_count, sizeof(struct dn_fs), DN_FS,
- dn_cfg.si_count, sizeof(struct dn_flow), DN_SCH_I,
- dn_cfg.queue_count, sizeof(struct dn_queue), DN_QUEUE);
- sopt->sopt_valsize = sopt_valsize;
- a.type = cmd->subtype;
-
- if (compat == NULL) {
- bcopy(cmd, start, sizeof(*cmd));
- ((struct dn_id*)(start))->len = sizeof(struct dn_id);
- buf = start + sizeof(*cmd);
- } else
- buf = start;
- a.start = &buf;
- a.end = start + have;
- /* start copying other objects */
- if (compat) {
- a.type = DN_COMPAT_PIPE;
- dn_ht_scan(dn_cfg.schedhash, copy_data_helper_compat, &a);
- a.type = DN_COMPAT_QUEUE;
- dn_ht_scan(dn_cfg.fshash, copy_data_helper_compat, &a);
- } else if (a.type == DN_FS) {
- dn_ht_scan(dn_cfg.fshash, copy_data_helper, &a);
- } else {
- dn_ht_scan(dn_cfg.schedhash, copy_data_helper, &a);
- }
- DN_BH_WUNLOCK();
-
- if (compat) {
- *compat = start;
- sopt->sopt_valsize = buf - start;
- /* free() is done by ip_dummynet_compat() */
- start = NULL; //XXX hack
- } else {
- error = sooptcopyout(sopt, start, buf - start);
- }
-done:
- if (cmd && cmd != &r.o)
- free(cmd, M_DUMMYNET);
- if (start)
- free(start, M_DUMMYNET);
- return error;
-}
-
-/* Callback called on scheduler instance to delete it if idle */
-static int
-drain_scheduler_cb(void *_si, void *arg)
-{
- struct dn_sch_inst *si = _si;
-
- if ((si->kflags & DN_ACTIVE) || si->dline.mq.head != NULL)
- return 0;
-
- if (si->sched->fp->flags & DN_MULTIQUEUE) {
- if (si->q_count == 0)
- return si_destroy(si, NULL);
- else
- return 0;
- } else { /* !DN_MULTIQUEUE */
- if ((si+1)->ni.length == 0)
- return si_destroy(si, NULL);
- else
- return 0;
- }
- return 0; /* unreachable */
-}
-
-/* Callback called on scheduler to check if it has instances */
-static int
-drain_scheduler_sch_cb(void *_s, void *arg)
-{
- struct dn_schk *s = _s;
-
- if (s->sch.flags & DN_HAVE_MASK) {
- dn_ht_scan_bucket(s->siht, &s->drain_bucket,
- drain_scheduler_cb, NULL);
- s->drain_bucket++;
- } else {
- if (s->siht) {
- if (drain_scheduler_cb(s->siht, NULL) == DNHT_SCAN_DEL)
- s->siht = NULL;
- }
- }
- return 0;
-}
-
-/* Called every tick, try to delete a 'bucket' of scheduler */
-void
-dn_drain_scheduler(void)
-{
- dn_ht_scan_bucket(dn_cfg.schedhash, &dn_cfg.drain_sch,
- drain_scheduler_sch_cb, NULL);
- dn_cfg.drain_sch++;
-}
-
-/* Callback called on queue to delete if it is idle */
-static int
-drain_queue_cb(void *_q, void *arg)
-{
- struct dn_queue *q = _q;
-
- if (q->ni.length == 0) {
- dn_delete_queue(q, DN_DESTROY);
- return DNHT_SCAN_DEL; /* queue is deleted */
- }
-
- return 0; /* queue isn't deleted */
-}
-
-/* Callback called on flowset used to check if it has queues */
-static int
-drain_queue_fs_cb(void *_fs, void *arg)
-{
- struct dn_fsk *fs = _fs;
-
- if (fs->fs.flags & DN_QHT_HASH) {
- /* Flowset has a hash table for queues */
- dn_ht_scan_bucket(fs->qht, &fs->drain_bucket,
- drain_queue_cb, NULL);
- fs->drain_bucket++;
- } else {
- /* No hash table for this flowset, null the pointer
- * if the queue is deleted
- */
- if (fs->qht) {
- if (drain_queue_cb(fs->qht, NULL) == DNHT_SCAN_DEL)
- fs->qht = NULL;
- }
- }
- return 0;
-}
-
-/* Called every tick, try to delete a 'bucket' of queue */
-void
-dn_drain_queue(void)
-{
- /* scan a bucket of flowset */
- dn_ht_scan_bucket(dn_cfg.fshash, &dn_cfg.drain_fs,
- drain_queue_fs_cb, NULL);
- dn_cfg.drain_fs++;
-}
-
-/*
- * Handler for the various dummynet socket options
- */
-static int
-ip_dn_ctl(struct sockopt *sopt)
-{
- void *p = NULL;
- int error, l;
-
- error = priv_check(sopt->sopt_td, PRIV_NETINET_DUMMYNET);
- if (error)
- return (error);
-
- /* Disallow sets in really-really secure mode. */
- if (sopt->sopt_dir == SOPT_SET) {
- error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
- if (error)
- return (error);
- }
-
- switch (sopt->sopt_name) {
- default :
- D("dummynet: unknown option %d", sopt->sopt_name);
- error = EINVAL;
- break;
-
- case IP_DUMMYNET_FLUSH:
- case IP_DUMMYNET_CONFIGURE:
- case IP_DUMMYNET_DEL: /* remove a pipe or queue */
- case IP_DUMMYNET_GET:
- D("dummynet: compat option %d", sopt->sopt_name);
- error = ip_dummynet_compat(sopt);
- break;
-
- case IP_DUMMYNET3 :
- if (sopt->sopt_dir == SOPT_GET) {
- error = dummynet_get(sopt, NULL);
- break;
- }
- l = sopt->sopt_valsize;
- if (l < sizeof(struct dn_id) || l > 12000) {
- D("argument len %d invalid", l);
- break;
- }
- p = malloc(l, M_TEMP, M_WAITOK); // XXX can it fail ?
- error = sooptcopyin(sopt, p, l, l);
- if (error)
- break ;
- error = do_config(p, l);
- break;
- }
-
- if (p != NULL)
- free(p, M_TEMP);
-
- return error ;
-}
-
-
-static void
-ip_dn_init(void)
-{
- if (dn_cfg.init_done)
- return;
- printf("DUMMYNET %p with IPv6 initialized (100409)\n", curvnet);
- dn_cfg.init_done = 1;
- /* Set defaults here. MSVC does not accept initializers,
- * and this is also useful for vimages
- */
- /* queue limits */
- dn_cfg.slot_limit = 100; /* Foot shooting limit for queues. */
- dn_cfg.byte_limit = 1024 * 1024;
- dn_cfg.expire = 1;
-
- /* RED parameters */
- dn_cfg.red_lookup_depth = 256; /* default lookup table depth */
- dn_cfg.red_avg_pkt_size = 512; /* default medium packet size */
- dn_cfg.red_max_pkt_size = 1500; /* default max packet size */
-
- /* hash tables */
- dn_cfg.max_hash_size = 65536; /* max in the hash tables */
- dn_cfg.hash_size = 64; /* default hash size */
-
- /* create hash tables for schedulers and flowsets.
- * In both we search by key and by pointer.
- */
- dn_cfg.schedhash = dn_ht_init(NULL, dn_cfg.hash_size,
- offsetof(struct dn_schk, schk_next),
- schk_hash, schk_match, schk_new);
- dn_cfg.fshash = dn_ht_init(NULL, dn_cfg.hash_size,
- offsetof(struct dn_fsk, fsk_next),
- fsk_hash, fsk_match, fsk_new);
-
- /* bucket index to drain object */
- dn_cfg.drain_fs = 0;
- dn_cfg.drain_sch = 0;
-
- heap_init(&dn_cfg.evheap, 16, offsetof(struct dn_id, id));
- SLIST_INIT(&dn_cfg.fsu);
- SLIST_INIT(&dn_cfg.schedlist);
-
- DN_LOCK_INIT();
-
- TASK_INIT(&dn_task, 0, dummynet_task, curvnet);
- dn_tq = taskqueue_create("dummynet", M_WAITOK,
- taskqueue_thread_enqueue, &dn_tq);
- taskqueue_start_threads(&dn_tq, 1, PI_NET, "dummynet");
-
- callout_init(&dn_timeout, CALLOUT_MPSAFE);
- callout_reset(&dn_timeout, 1, dummynet, NULL);
-
- /* Initialize curr_time adjustment mechanics. */
- getmicrouptime(&dn_cfg.prev_t);
-}
-
-#ifdef KLD_MODULE
-static void
-ip_dn_destroy(int last)
-{
- callout_drain(&dn_timeout);
-
- DN_BH_WLOCK();
- if (last) {
- ND("removing last instance\n");
- ip_dn_ctl_ptr = NULL;
- ip_dn_io_ptr = NULL;
- }
-
- dummynet_flush();
- DN_BH_WUNLOCK();
- taskqueue_drain(dn_tq, &dn_task);
- taskqueue_free(dn_tq);
-
- dn_ht_free(dn_cfg.schedhash, 0);
- dn_ht_free(dn_cfg.fshash, 0);
- heap_free(&dn_cfg.evheap);
-
- DN_LOCK_DESTROY();
-}
-#endif /* KLD_MODULE */
-
-static int
-dummynet_modevent(module_t mod, int type, void *data)
-{
-
- if (type == MOD_LOAD) {
- if (ip_dn_io_ptr) {
- printf("DUMMYNET already loaded\n");
- return EEXIST ;
- }
- ip_dn_init();
- ip_dn_ctl_ptr = ip_dn_ctl;
- ip_dn_io_ptr = dummynet_io;
- return 0;
- } else if (type == MOD_UNLOAD) {
-#if !defined(KLD_MODULE)
- printf("dummynet statically compiled, cannot unload\n");
- return EINVAL ;
-#else
- ip_dn_destroy(1 /* last */);
- return 0;
-#endif
- } else
- return EOPNOTSUPP;
-}
-
-/* modevent helpers for the modules */
-static int
-load_dn_sched(struct dn_alg *d)
-{
- struct dn_alg *s;
-
- if (d == NULL)
- return 1; /* error */
- ip_dn_init(); /* just in case, we need the lock */
-
- /* Check that mandatory funcs exists */
- if (d->enqueue == NULL || d->dequeue == NULL) {
- D("missing enqueue or dequeue for %s", d->name);
- return 1;
- }
-
- /* Search if scheduler already exists */
- DN_BH_WLOCK();
- SLIST_FOREACH(s, &dn_cfg.schedlist, next) {
- if (strcmp(s->name, d->name) == 0) {
- D("%s already loaded", d->name);
- break; /* scheduler already exists */
- }
- }
- if (s == NULL)
- SLIST_INSERT_HEAD(&dn_cfg.schedlist, d, next);
- DN_BH_WUNLOCK();
- D("dn_sched %s %sloaded", d->name, s ? "not ":"");
- return s ? 1 : 0;
-}
-
-static int
-unload_dn_sched(struct dn_alg *s)
-{
- struct dn_alg *tmp, *r;
- int err = EINVAL;
-
- ND("called for %s", s->name);
-
- DN_BH_WLOCK();
- SLIST_FOREACH_SAFE(r, &dn_cfg.schedlist, next, tmp) {
- if (strcmp(s->name, r->name) != 0)
- continue;
- ND("ref_count = %d", r->ref_count);
- err = (r->ref_count != 0) ? EBUSY : 0;
- if (err == 0)
- SLIST_REMOVE(&dn_cfg.schedlist, r, dn_alg, next);
- break;
- }
- DN_BH_WUNLOCK();
- D("dn_sched %s %sunloaded", s->name, err ? "not ":"");
- return err;
-}
-
-int
-dn_sched_modevent(module_t mod, int cmd, void *arg)
-{
- struct dn_alg *sch = arg;
-
- if (cmd == MOD_LOAD)
- return load_dn_sched(sch);
- else if (cmd == MOD_UNLOAD)
- return unload_dn_sched(sch);
- else
- return EINVAL;
-}
-
-static moduledata_t dummynet_mod = {
- "dummynet", dummynet_modevent, NULL
-};
-
-#define DN_SI_SUB SI_SUB_PROTO_IFATTACHDOMAIN
-#define DN_MODEV_ORD (SI_ORDER_ANY - 128) /* after ipfw */
-DECLARE_MODULE(dummynet, dummynet_mod, DN_SI_SUB, DN_MODEV_ORD);
-MODULE_DEPEND(dummynet, ipfw, 2, 2, 2);
-MODULE_VERSION(dummynet, 3);
-
-/*
- * Starting up. Done in order after dummynet_modevent() has been called.
- * VNET_SYSINIT is also called for each existing vnet and each new vnet.
- */
-//VNET_SYSINIT(vnet_dn_init, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_init, NULL);
-
-/*
- * Shutdown handlers up shop. These are done in REVERSE ORDER, but still
- * after dummynet_modevent() has been called. Not called on reboot.
- * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
- * or when the module is unloaded.
- */
-//VNET_SYSUNINIT(vnet_dn_uninit, DN_SI_SUB, DN_MODEV_ORD+2, ip_dn_destroy, NULL);
-
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw2.c b/sys/netinet/ipfw/ip_fw2.c
deleted file mode 100644
index 21a00bb..0000000
--- a/sys/netinet/ipfw/ip_fw2.c
+++ /dev/null
@@ -1,2783 +0,0 @@
-/*-
- * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * The FreeBSD IP packet firewall, main file
- */
-
-#include "opt_ipfw.h"
-#include "opt_ipdivert.h"
-#include "opt_inet.h"
-#ifndef INET
-#error "IPFIREWALL requires INET"
-#endif /* INET */
-#include "opt_inet6.h"
-#include "opt_ipsec.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/condvar.h>
-#include <sys/eventhandler.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/jail.h>
-#include <sys/module.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <sys/ucred.h>
-#include <net/ethernet.h> /* for ETHERTYPE_IP */
-#include <net/if.h>
-#include <net/route.h>
-#include <net/pf_mtag.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-#include <netinet/in_pcb.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/ip_carp.h>
-#include <netinet/pim.h>
-#include <netinet/tcp_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/sctp.h>
-
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#ifdef INET6
-#include <netinet6/in6_pcb.h>
-#include <netinet6/scope6_var.h>
-#include <netinet6/ip6_var.h>
-#endif
-
-#include <machine/in_cksum.h> /* XXX for in_cksum */
-
-#ifdef MAC
-#include <security/mac/mac_framework.h>
-#endif
-
-/*
- * static variables followed by global ones.
- * All ipfw global variables are here.
- */
-
-/* ipfw_vnet_ready controls when we are open for business */
-static VNET_DEFINE(int, ipfw_vnet_ready) = 0;
-#define V_ipfw_vnet_ready VNET(ipfw_vnet_ready)
-
-static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
-#define V_fw_deny_unknown_exthdrs VNET(fw_deny_unknown_exthdrs)
-
-static VNET_DEFINE(int, fw_permit_single_frag6) = 1;
-#define V_fw_permit_single_frag6 VNET(fw_permit_single_frag6)
-
-#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
-static int default_to_accept = 1;
-#else
-static int default_to_accept;
-#endif
-
-VNET_DEFINE(int, autoinc_step);
-VNET_DEFINE(int, fw_one_pass) = 1;
-
-VNET_DEFINE(unsigned int, fw_tables_max);
-/* Use 128 tables by default */
-static unsigned int default_fw_tables = IPFW_TABLES_DEFAULT;
-
-/*
- * Each rule belongs to one of 32 different sets (0..31).
- * The variable set_disable contains one bit per set.
- * If the bit is set, all rules in the corresponding set
- * are disabled. Set RESVD_SET(31) is reserved for the default rule
- * and rules that are not deleted by the flush command,
- * and CANNOT be disabled.
- * Rules in set RESVD_SET can only be deleted individually.
- */
-VNET_DEFINE(u_int32_t, set_disable);
-#define V_set_disable VNET(set_disable)
-
-VNET_DEFINE(int, fw_verbose);
-/* counter for ipfw_log(NULL...) */
-VNET_DEFINE(u_int64_t, norule_counter);
-VNET_DEFINE(int, verbose_limit);
-
-/* layer3_chain contains the list of rules for layer 3 */
-VNET_DEFINE(struct ip_fw_chain, layer3_chain);
-
-ipfw_nat_t *ipfw_nat_ptr = NULL;
-struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
-ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
-ipfw_nat_cfg_t *ipfw_nat_del_ptr;
-ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
-ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
-
-#ifdef SYSCTL_NODE
-uint32_t dummy_def = IPFW_DEFAULT_RULE;
-static int sysctl_ipfw_table_num(SYSCTL_HANDLER_ARGS);
-
-SYSBEGIN(f3)
-
-SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
-SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
- CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
- "Only do a single pass through ipfw when using dummynet(4)");
-SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
- CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
- "Rule number auto-increment step");
-SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
- CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
- "Log matches to ipfw rules");
-SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
- CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
- "Set upper limit of matches of ipfw rules logged");
-SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
- &dummy_def, 0,
- "The default/max possible rule number.");
-SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, tables_max,
- CTLTYPE_UINT|CTLFLAG_RW, 0, 0, sysctl_ipfw_table_num, "IU",
- "Maximum number of tables");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
- &default_to_accept, 0,
- "Make the default rule accept all packets.");
-TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
-TUNABLE_INT("net.inet.ip.fw.tables_max", &default_fw_tables);
-SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
- CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0,
- "Number of static rules");
-
-#ifdef INET6
-SYSCTL_DECL(_net_inet6_ip6);
-SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
-SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
- CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
- "Deny packets with unknown IPv6 Extension Headers");
-SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, permit_single_frag6,
- CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_permit_single_frag6), 0,
- "Permit single packet IPv6 fragments");
-#endif /* INET6 */
-
-SYSEND
-
-#endif /* SYSCTL_NODE */
-
-
-/*
- * Some macros used in the various matching options.
- * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
- * Other macros just cast void * into the appropriate type
- */
-#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
-#define TCP(p) ((struct tcphdr *)(p))
-#define SCTP(p) ((struct sctphdr *)(p))
-#define UDP(p) ((struct udphdr *)(p))
-#define ICMP(p) ((struct icmphdr *)(p))
-#define ICMP6(p) ((struct icmp6_hdr *)(p))
-
-static __inline int
-icmptype_match(struct icmphdr *icmp, ipfw_insn_u32 *cmd)
-{
- int type = icmp->icmp_type;
-
- return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) );
-}
-
-#define TT ( (1 << ICMP_ECHO) | (1 << ICMP_ROUTERSOLICIT) | \
- (1 << ICMP_TSTAMP) | (1 << ICMP_IREQ) | (1 << ICMP_MASKREQ) )
-
-static int
-is_icmp_query(struct icmphdr *icmp)
-{
- int type = icmp->icmp_type;
-
- return (type <= ICMP_MAXTYPE && (TT & (1<<type)) );
-}
-#undef TT
-
-/*
- * The following checks use two arrays of 8 or 16 bits to store the
- * bits that we want set or clear, respectively. They are in the
- * low and high half of cmd->arg1 or cmd->d[0].
- *
- * We scan options and store the bits we find set. We succeed if
- *
- * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
- *
- * The code is sometimes optimized not to store additional variables.
- */
-
-static int
-flags_match(ipfw_insn *cmd, u_int8_t bits)
-{
- u_char want_clear;
- bits = ~bits;
-
- if ( ((cmd->arg1 & 0xff) & bits) != 0)
- return 0; /* some bits we want set were clear */
- want_clear = (cmd->arg1 >> 8) & 0xff;
- if ( (want_clear & bits) != want_clear)
- return 0; /* some bits we want clear were set */
- return 1;
-}
-
-static int
-ipopts_match(struct ip *ip, ipfw_insn *cmd)
-{
- int optlen, bits = 0;
- u_char *cp = (u_char *)(ip + 1);
- int x = (ip->ip_hl << 2) - sizeof (struct ip);
-
- for (; x > 0; x -= optlen, cp += optlen) {
- int opt = cp[IPOPT_OPTVAL];
-
- if (opt == IPOPT_EOL)
- break;
- if (opt == IPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[IPOPT_OLEN];
- if (optlen <= 0 || optlen > x)
- return 0; /* invalid or truncated */
- }
- switch (opt) {
-
- default:
- break;
-
- case IPOPT_LSRR:
- bits |= IP_FW_IPOPT_LSRR;
- break;
-
- case IPOPT_SSRR:
- bits |= IP_FW_IPOPT_SSRR;
- break;
-
- case IPOPT_RR:
- bits |= IP_FW_IPOPT_RR;
- break;
-
- case IPOPT_TS:
- bits |= IP_FW_IPOPT_TS;
- break;
- }
- }
- return (flags_match(cmd, bits));
-}
-
-static int
-tcpopts_match(struct tcphdr *tcp, ipfw_insn *cmd)
-{
- int optlen, bits = 0;
- u_char *cp = (u_char *)(tcp + 1);
- int x = (tcp->th_off << 2) - sizeof(struct tcphdr);
-
- for (; x > 0; x -= optlen, cp += optlen) {
- int opt = cp[0];
- if (opt == TCPOPT_EOL)
- break;
- if (opt == TCPOPT_NOP)
- optlen = 1;
- else {
- optlen = cp[1];
- if (optlen <= 0)
- break;
- }
-
- switch (opt) {
-
- default:
- break;
-
- case TCPOPT_MAXSEG:
- bits |= IP_FW_TCPOPT_MSS;
- break;
-
- case TCPOPT_WINDOW:
- bits |= IP_FW_TCPOPT_WINDOW;
- break;
-
- case TCPOPT_SACK_PERMITTED:
- case TCPOPT_SACK:
- bits |= IP_FW_TCPOPT_SACK;
- break;
-
- case TCPOPT_TIMESTAMP:
- bits |= IP_FW_TCPOPT_TS;
- break;
-
- }
- }
- return (flags_match(cmd, bits));
-}
-
-static int
-iface_match(struct ifnet *ifp, ipfw_insn_if *cmd, struct ip_fw_chain *chain, uint32_t *tablearg)
-{
- if (ifp == NULL) /* no iface with this packet, match fails */
- return 0;
- /* Check by name or by IP address */
- if (cmd->name[0] != '\0') { /* match by name */
- if (cmd->name[0] == '\1') /* use tablearg to match */
- return ipfw_lookup_table_extended(chain, cmd->p.glob,
- ifp->if_xname, tablearg, IPFW_TABLE_INTERFACE);
- /* Check name */
- if (cmd->p.glob) {
- if (fnmatch(cmd->name, ifp->if_xname, 0) == 0)
- return(1);
- } else {
- if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0)
- return(1);
- }
- } else {
-#ifdef __FreeBSD__ /* and OSX too ? */
- struct ifaddr *ia;
-
- if_addr_rlock(ifp);
- TAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) {
- if (ia->ifa_addr->sa_family != AF_INET)
- continue;
- if (cmd->p.ip.s_addr == ((struct sockaddr_in *)
- (ia->ifa_addr))->sin_addr.s_addr) {
- if_addr_runlock(ifp);
- return(1); /* match */
- }
- }
- if_addr_runlock(ifp);
-#endif /* __FreeBSD__ */
- }
- return(0); /* no match, fail ... */
-}
-
-/*
- * The verify_path function checks if a route to the src exists and
- * if it is reachable via ifp (when provided).
- *
- * The 'verrevpath' option checks that the interface that an IP packet
- * arrives on is the same interface that traffic destined for the
- * packet's source address would be routed out of.
- * The 'versrcreach' option just checks that the source address is
- * reachable via any route (except default) in the routing table.
- * These two are a measure to block forged packets. This is also
- * commonly known as "anti-spoofing" or Unicast Reverse Path
- * Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
- * is purposely reminiscent of the Cisco IOS command,
- *
- * ip verify unicast reverse-path
- * ip verify unicast source reachable-via any
- *
- * which implements the same functionality. But note that the syntax
- * is misleading, and the check may be performed on all IP packets
- * whether unicast, multicast, or broadcast.
- */
-static int
-verify_path(struct in_addr src, struct ifnet *ifp, u_int fib)
-{
-#ifndef __FreeBSD__
- return 0;
-#else
- struct route ro;
- struct sockaddr_in *dst;
-
- bzero(&ro, sizeof(ro));
-
- dst = (struct sockaddr_in *)&(ro.ro_dst);
- dst->sin_family = AF_INET;
- dst->sin_len = sizeof(*dst);
- dst->sin_addr = src;
- in_rtalloc_ign(&ro, 0, fib);
-
- if (ro.ro_rt == NULL)
- return 0;
-
- /*
- * If ifp is provided, check for equality with rtentry.
- * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
- * in order to pass packets injected back by if_simloop():
- * if useloopback == 1 routing entry (via lo0) for our own address
- * may exist, so we need to handle routing assymetry.
- */
- if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
- RTFREE(ro.ro_rt);
- return 0;
- }
-
- /* if no ifp provided, check if rtentry is not default route */
- if (ifp == NULL &&
- satosin(rt_key(ro.ro_rt))->sin_addr.s_addr == INADDR_ANY) {
- RTFREE(ro.ro_rt);
- return 0;
- }
-
- /* or if this is a blackhole/reject route */
- if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
- RTFREE(ro.ro_rt);
- return 0;
- }
-
- /* found valid route */
- RTFREE(ro.ro_rt);
- return 1;
-#endif /* __FreeBSD__ */
-}
-
-#ifdef INET6
-/*
- * ipv6 specific rules here...
- */
-static __inline int
-icmp6type_match (int type, ipfw_insn_u32 *cmd)
-{
- return (type <= ICMP6_MAXTYPE && (cmd->d[type/32] & (1<<(type%32)) ) );
-}
-
-static int
-flow6id_match( int curr_flow, ipfw_insn_u32 *cmd )
-{
- int i;
- for (i=0; i <= cmd->o.arg1; ++i )
- if (curr_flow == cmd->d[i] )
- return 1;
- return 0;
-}
-
-/* support for IP6_*_ME opcodes */
-static int
-search_ip6_addr_net (struct in6_addr * ip6_addr)
-{
- struct ifnet *mdc;
- struct ifaddr *mdc2;
- struct in6_ifaddr *fdm;
- struct in6_addr copia;
-
- TAILQ_FOREACH(mdc, &V_ifnet, if_link) {
- if_addr_rlock(mdc);
- TAILQ_FOREACH(mdc2, &mdc->if_addrhead, ifa_link) {
- if (mdc2->ifa_addr->sa_family == AF_INET6) {
- fdm = (struct in6_ifaddr *)mdc2;
- copia = fdm->ia_addr.sin6_addr;
- /* need for leaving scope_id in the sock_addr */
- in6_clearscope(&copia);
- if (IN6_ARE_ADDR_EQUAL(ip6_addr, &copia)) {
- if_addr_runlock(mdc);
- return 1;
- }
- }
- }
- if_addr_runlock(mdc);
- }
- return 0;
-}
-
-static int
-verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
-{
- struct route_in6 ro;
- struct sockaddr_in6 *dst;
-
- bzero(&ro, sizeof(ro));
-
- dst = (struct sockaddr_in6 * )&(ro.ro_dst);
- dst->sin6_family = AF_INET6;
- dst->sin6_len = sizeof(*dst);
- dst->sin6_addr = *src;
-
- in6_rtalloc_ign(&ro, 0, fib);
- if (ro.ro_rt == NULL)
- return 0;
-
- /*
- * if ifp is provided, check for equality with rtentry
- * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp,
- * to support the case of sending packets to an address of our own.
- * (where the former interface is the first argument of if_simloop()
- * (=ifp), the latter is lo0)
- */
- if (ifp != NULL && ro.ro_rt->rt_ifa->ifa_ifp != ifp) {
- RTFREE(ro.ro_rt);
- return 0;
- }
-
- /* if no ifp provided, check if rtentry is not default route */
- if (ifp == NULL &&
- IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(ro.ro_rt))->sin6_addr)) {
- RTFREE(ro.ro_rt);
- return 0;
- }
-
- /* or if this is a blackhole/reject route */
- if (ifp == NULL && ro.ro_rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
- RTFREE(ro.ro_rt);
- return 0;
- }
-
- /* found valid route */
- RTFREE(ro.ro_rt);
- return 1;
-
-}
-
-static int
-is_icmp6_query(int icmp6_type)
-{
- if ((icmp6_type <= ICMP6_MAXTYPE) &&
- (icmp6_type == ICMP6_ECHO_REQUEST ||
- icmp6_type == ICMP6_MEMBERSHIP_QUERY ||
- icmp6_type == ICMP6_WRUREQUEST ||
- icmp6_type == ICMP6_FQDN_QUERY ||
- icmp6_type == ICMP6_NI_QUERY))
- return (1);
-
- return (0);
-}
-
-static void
-send_reject6(struct ip_fw_args *args, int code, u_int hlen, struct ip6_hdr *ip6)
-{
- struct mbuf *m;
-
- m = args->m;
- if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) {
- struct tcphdr *tcp;
- tcp = (struct tcphdr *)((char *)ip6 + hlen);
-
- if ((tcp->th_flags & TH_RST) == 0) {
- struct mbuf *m0;
- m0 = ipfw_send_pkt(args->m, &(args->f_id),
- ntohl(tcp->th_seq), ntohl(tcp->th_ack),
- tcp->th_flags | TH_RST);
- if (m0 != NULL)
- ip6_output(m0, NULL, NULL, 0, NULL, NULL,
- NULL);
- }
- FREE_PKT(m);
- } else if (code != ICMP6_UNREACH_RST) { /* Send an ICMPv6 unreach. */
-#if 0
- /*
- * Unlike above, the mbufs need to line up with the ip6 hdr,
- * as the contents are read. We need to m_adj() the
- * needed amount.
- * The mbuf will however be thrown away so we can adjust it.
- * Remember we did an m_pullup on it already so we
- * can make some assumptions about contiguousness.
- */
- if (args->L3offset)
- m_adj(m, args->L3offset);
-#endif
- icmp6_error(m, ICMP6_DST_UNREACH, code, 0);
- } else
- FREE_PKT(m);
-
- args->m = NULL;
-}
-
-#endif /* INET6 */
-
-
-/*
- * sends a reject message, consuming the mbuf passed as an argument.
- */
-static void
-send_reject(struct ip_fw_args *args, int code, int iplen, struct ip *ip)
-{
-
-#if 0
- /* XXX When ip is not guaranteed to be at mtod() we will
- * need to account for this */
- * The mbuf will however be thrown away so we can adjust it.
- * Remember we did an m_pullup on it already so we
- * can make some assumptions about contiguousness.
- */
- if (args->L3offset)
- m_adj(m, args->L3offset);
-#endif
- if (code != ICMP_REJECT_RST) { /* Send an ICMP unreach */
- /* We need the IP header in host order for icmp_error(). */
- SET_HOST_IPLEN(ip);
- icmp_error(args->m, ICMP_UNREACH, code, 0L, 0);
- } else if (args->f_id.proto == IPPROTO_TCP) {
- struct tcphdr *const tcp =
- L3HDR(struct tcphdr, mtod(args->m, struct ip *));
- if ( (tcp->th_flags & TH_RST) == 0) {
- struct mbuf *m;
- m = ipfw_send_pkt(args->m, &(args->f_id),
- ntohl(tcp->th_seq), ntohl(tcp->th_ack),
- tcp->th_flags | TH_RST);
- if (m != NULL)
- ip_output(m, NULL, NULL, 0, NULL, NULL);
- }
- FREE_PKT(args->m);
- } else
- FREE_PKT(args->m);
- args->m = NULL;
-}
-
-/*
- * Support for uid/gid/jail lookup. These tests are expensive
- * (because we may need to look into the list of active sockets)
- * so we cache the results. ugid_lookupp is 0 if we have not
- * yet done a lookup, 1 if we succeeded, and -1 if we tried
- * and failed. The function always returns the match value.
- * We could actually spare the variable and use *uc, setting
- * it to '(void *)check_uidgid if we have no info, NULL if
- * we tried and failed, or any other value if successful.
- */
-static int
-check_uidgid(ipfw_insn_u32 *insn, struct ip_fw_args *args, int *ugid_lookupp,
- struct ucred **uc)
-{
-#ifndef __FreeBSD__
- /* XXX */
- return cred_check(insn, proto, oif,
- dst_ip, dst_port, src_ip, src_port,
- (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb);
-#else /* FreeBSD */
- struct in_addr src_ip, dst_ip;
- struct inpcbinfo *pi;
- struct ipfw_flow_id *id;
- struct inpcb *pcb, *inp;
- struct ifnet *oif;
- int lookupflags;
- int match;
-
- id = &args->f_id;
- inp = args->inp;
- oif = args->oif;
-
- /*
- * Check to see if the UDP or TCP stack supplied us with
- * the PCB. If so, rather then holding a lock and looking
- * up the PCB, we can use the one that was supplied.
- */
- if (inp && *ugid_lookupp == 0) {
- INP_LOCK_ASSERT(inp);
- if (inp->inp_socket != NULL) {
- *uc = crhold(inp->inp_cred);
- *ugid_lookupp = 1;
- } else
- *ugid_lookupp = -1;
- }
- /*
- * If we have already been here and the packet has no
- * PCB entry associated with it, then we can safely
- * assume that this is a no match.
- */
- if (*ugid_lookupp == -1)
- return (0);
- if (id->proto == IPPROTO_TCP) {
- lookupflags = 0;
- pi = &V_tcbinfo;
- } else if (id->proto == IPPROTO_UDP) {
- lookupflags = INPLOOKUP_WILDCARD;
- pi = &V_udbinfo;
- } else
- return 0;
- lookupflags |= INPLOOKUP_RLOCKPCB;
- match = 0;
- if (*ugid_lookupp == 0) {
- if (id->addr_type == 6) {
-#ifdef INET6
- if (oif == NULL)
- pcb = in6_pcblookup_mbuf(pi,
- &id->src_ip6, htons(id->src_port),
- &id->dst_ip6, htons(id->dst_port),
- lookupflags, oif, args->m);
- else
- pcb = in6_pcblookup_mbuf(pi,
- &id->dst_ip6, htons(id->dst_port),
- &id->src_ip6, htons(id->src_port),
- lookupflags, oif, args->m);
-#else
- *ugid_lookupp = -1;
- return (0);
-#endif
- } else {
- src_ip.s_addr = htonl(id->src_ip);
- dst_ip.s_addr = htonl(id->dst_ip);
- if (oif == NULL)
- pcb = in_pcblookup_mbuf(pi,
- src_ip, htons(id->src_port),
- dst_ip, htons(id->dst_port),
- lookupflags, oif, args->m);
- else
- pcb = in_pcblookup_mbuf(pi,
- dst_ip, htons(id->dst_port),
- src_ip, htons(id->src_port),
- lookupflags, oif, args->m);
- }
- if (pcb != NULL) {
- INP_RLOCK_ASSERT(pcb);
- *uc = crhold(pcb->inp_cred);
- *ugid_lookupp = 1;
- INP_RUNLOCK(pcb);
- }
- if (*ugid_lookupp == 0) {
- /*
- * We tried and failed, set the variable to -1
- * so we will not try again on this packet.
- */
- *ugid_lookupp = -1;
- return (0);
- }
- }
- if (insn->o.opcode == O_UID)
- match = ((*uc)->cr_uid == (uid_t)insn->d[0]);
- else if (insn->o.opcode == O_GID)
- match = groupmember((gid_t)insn->d[0], *uc);
- else if (insn->o.opcode == O_JAIL)
- match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]);
- return (match);
-#endif /* __FreeBSD__ */
-}
-
-/*
- * Helper function to set args with info on the rule after the matching
- * one. slot is precise, whereas we guess rule_id as they are
- * assigned sequentially.
- */
-static inline void
-set_match(struct ip_fw_args *args, int slot,
- struct ip_fw_chain *chain)
-{
- args->rule.chain_id = chain->id;
- args->rule.slot = slot + 1; /* we use 0 as a marker */
- args->rule.rule_id = 1 + chain->map[slot]->id;
- args->rule.rulenum = chain->map[slot]->rulenum;
-}
-
-/*
- * The main check routine for the firewall.
- *
- * All arguments are in args so we can modify them and return them
- * back to the caller.
- *
- * Parameters:
- *
- * args->m (in/out) The packet; we set to NULL when/if we nuke it.
- * Starts with the IP header.
- * args->eh (in) Mac header if present, NULL for layer3 packet.
- * args->L3offset Number of bytes bypassed if we came from L2.
- * e.g. often sizeof(eh) ** NOTYET **
- * args->oif Outgoing interface, NULL if packet is incoming.
- * The incoming interface is in the mbuf. (in)
- * args->divert_rule (in/out)
- * Skip up to the first rule past this rule number;
- * upon return, non-zero port number for divert or tee.
- *
- * args->rule Pointer to the last matching rule (in/out)
- * args->next_hop Socket we are forwarding to (out).
- * args->next_hop6 IPv6 next hop we are forwarding to (out).
- * args->f_id Addresses grabbed from the packet (out)
- * args->rule.info a cookie depending on rule action
- *
- * Return value:
- *
- * IP_FW_PASS the packet must be accepted
- * IP_FW_DENY the packet must be dropped
- * IP_FW_DIVERT divert packet, port in m_tag
- * IP_FW_TEE tee packet, port in m_tag
- * IP_FW_DUMMYNET to dummynet, pipe in args->cookie
- * IP_FW_NETGRAPH into netgraph, cookie args->cookie
- * args->rule contains the matching rule,
- * args->rule.info has additional information.
- *
- */
-int
-ipfw_chk(struct ip_fw_args *args)
-{
-
- /*
- * Local variables holding state while processing a packet:
- *
- * IMPORTANT NOTE: to speed up the processing of rules, there
- * are some assumption on the values of the variables, which
- * are documented here. Should you change them, please check
- * the implementation of the various instructions to make sure
- * that they still work.
- *
- * args->eh The MAC header. It is non-null for a layer2
- * packet, it is NULL for a layer-3 packet.
- * **notyet**
- * args->L3offset Offset in the packet to the L3 (IP or equiv.) header.
- *
- * m | args->m Pointer to the mbuf, as received from the caller.
- * It may change if ipfw_chk() does an m_pullup, or if it
- * consumes the packet because it calls send_reject().
- * XXX This has to change, so that ipfw_chk() never modifies
- * or consumes the buffer.
- * ip is the beginning of the ip(4 or 6) header.
- * Calculated by adding the L3offset to the start of data.
- * (Until we start using L3offset, the packet is
- * supposed to start with the ip header).
- */
- struct mbuf *m = args->m;
- struct ip *ip = mtod(m, struct ip *);
-
- /*
- * For rules which contain uid/gid or jail constraints, cache
- * a copy of the users credentials after the pcb lookup has been
- * executed. This will speed up the processing of rules with
- * these types of constraints, as well as decrease contention
- * on pcb related locks.
- */
-#ifndef __FreeBSD__
- struct bsd_ucred ucred_cache;
-#else
- struct ucred *ucred_cache = NULL;
-#endif
- int ucred_lookup = 0;
-
- /*
- * oif | args->oif If NULL, ipfw_chk has been called on the
- * inbound path (ether_input, ip_input).
- * If non-NULL, ipfw_chk has been called on the outbound path
- * (ether_output, ip_output).
- */
- struct ifnet *oif = args->oif;
-
- int f_pos = 0; /* index of current rule in the array */
- int retval = 0;
-
- /*
- * hlen The length of the IP header.
- */
- u_int hlen = 0; /* hlen >0 means we have an IP pkt */
-
- /*
- * offset The offset of a fragment. offset != 0 means that
- * we have a fragment at this offset of an IPv4 packet.
- * offset == 0 means that (if this is an IPv4 packet)
- * this is the first or only fragment.
- * For IPv6 offset|ip6f_mf == 0 means there is no Fragment Header
- * or there is a single packet fragement (fragement header added
- * without needed). We will treat a single packet fragment as if
- * there was no fragment header (or log/block depending on the
- * V_fw_permit_single_frag6 sysctl setting).
- */
- u_short offset = 0;
- u_short ip6f_mf = 0;
-
- /*
- * Local copies of addresses. They are only valid if we have
- * an IP packet.
- *
- * proto The protocol. Set to 0 for non-ip packets,
- * or to the protocol read from the packet otherwise.
- * proto != 0 means that we have an IPv4 packet.
- *
- * src_port, dst_port port numbers, in HOST format. Only
- * valid for TCP and UDP packets.
- *
- * src_ip, dst_ip ip addresses, in NETWORK format.
- * Only valid for IPv4 packets.
- */
- uint8_t proto;
- uint16_t src_port = 0, dst_port = 0; /* NOTE: host format */
- struct in_addr src_ip, dst_ip; /* NOTE: network format */
- uint16_t iplen=0;
- int pktlen;
- uint16_t etype = 0; /* Host order stored ether type */
-
- /*
- * dyn_dir = MATCH_UNKNOWN when rules unchecked,
- * MATCH_NONE when checked and not matched (q = NULL),
- * MATCH_FORWARD or MATCH_REVERSE otherwise (q != NULL)
- */
- int dyn_dir = MATCH_UNKNOWN;
- ipfw_dyn_rule *q = NULL;
- struct ip_fw_chain *chain = &V_layer3_chain;
-
- /*
- * We store in ulp a pointer to the upper layer protocol header.
- * In the ipv4 case this is easy to determine from the header,
- * but for ipv6 we might have some additional headers in the middle.
- * ulp is NULL if not found.
- */
- void *ulp = NULL; /* upper layer protocol pointer. */
-
- /* XXX ipv6 variables */
- int is_ipv6 = 0;
- uint8_t icmp6_type = 0;
- uint16_t ext_hd = 0; /* bits vector for extension header filtering */
- /* end of ipv6 variables */
-
- int is_ipv4 = 0;
-
- int done = 0; /* flag to exit the outer loop */
-
- if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready))
- return (IP_FW_PASS); /* accept */
-
- dst_ip.s_addr = 0; /* make sure it is initialized */
- src_ip.s_addr = 0; /* make sure it is initialized */
- pktlen = m->m_pkthdr.len;
- args->f_id.fib = M_GETFIB(m); /* note mbuf not altered) */
- proto = args->f_id.proto = 0; /* mark f_id invalid */
- /* XXX 0 is a valid proto: IP/IPv6 Hop-by-Hop Option */
-
-/*
- * PULLUP_TO(len, p, T) makes sure that len + sizeof(T) is contiguous,
- * then it sets p to point at the offset "len" in the mbuf. WARNING: the
- * pointer might become stale after other pullups (but we never use it
- * this way).
- */
-#define PULLUP_TO(_len, p, T) PULLUP_LEN(_len, p, sizeof(T))
-#define PULLUP_LEN(_len, p, T) \
-do { \
- int x = (_len) + T; \
- if ((m)->m_len < x) { \
- args->m = m = m_pullup(m, x); \
- if (m == NULL) \
- goto pullup_failed; \
- } \
- p = (mtod(m, char *) + (_len)); \
-} while (0)
-
- /*
- * if we have an ether header,
- */
- if (args->eh)
- etype = ntohs(args->eh->ether_type);
-
- /* Identify IP packets and fill up variables. */
- if (pktlen >= sizeof(struct ip6_hdr) &&
- (args->eh == NULL || etype == ETHERTYPE_IPV6) && ip->ip_v == 6) {
- struct ip6_hdr *ip6 = (struct ip6_hdr *)ip;
- is_ipv6 = 1;
- args->f_id.addr_type = 6;
- hlen = sizeof(struct ip6_hdr);
- proto = ip6->ip6_nxt;
-
- /* Search extension headers to find upper layer protocols */
- while (ulp == NULL && offset == 0) {
- switch (proto) {
- case IPPROTO_ICMPV6:
- PULLUP_TO(hlen, ulp, struct icmp6_hdr);
- icmp6_type = ICMP6(ulp)->icmp6_type;
- break;
-
- case IPPROTO_TCP:
- PULLUP_TO(hlen, ulp, struct tcphdr);
- dst_port = TCP(ulp)->th_dport;
- src_port = TCP(ulp)->th_sport;
- /* save flags for dynamic rules */
- args->f_id._flags = TCP(ulp)->th_flags;
- break;
-
- case IPPROTO_SCTP:
- PULLUP_TO(hlen, ulp, struct sctphdr);
- src_port = SCTP(ulp)->src_port;
- dst_port = SCTP(ulp)->dest_port;
- break;
-
- case IPPROTO_UDP:
- PULLUP_TO(hlen, ulp, struct udphdr);
- dst_port = UDP(ulp)->uh_dport;
- src_port = UDP(ulp)->uh_sport;
- break;
-
- case IPPROTO_HOPOPTS: /* RFC 2460 */
- PULLUP_TO(hlen, ulp, struct ip6_hbh);
- ext_hd |= EXT_HOPOPTS;
- hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
- proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
- ulp = NULL;
- break;
-
- case IPPROTO_ROUTING: /* RFC 2460 */
- PULLUP_TO(hlen, ulp, struct ip6_rthdr);
- switch (((struct ip6_rthdr *)ulp)->ip6r_type) {
- case 0:
- ext_hd |= EXT_RTHDR0;
- break;
- case 2:
- ext_hd |= EXT_RTHDR2;
- break;
- default:
- if (V_fw_verbose)
- printf("IPFW2: IPV6 - Unknown "
- "Routing Header type(%d)\n",
- ((struct ip6_rthdr *)
- ulp)->ip6r_type);
- if (V_fw_deny_unknown_exthdrs)
- return (IP_FW_DENY);
- break;
- }
- ext_hd |= EXT_ROUTING;
- hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3;
- proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt;
- ulp = NULL;
- break;
-
- case IPPROTO_FRAGMENT: /* RFC 2460 */
- PULLUP_TO(hlen, ulp, struct ip6_frag);
- ext_hd |= EXT_FRAGMENT;
- hlen += sizeof (struct ip6_frag);
- proto = ((struct ip6_frag *)ulp)->ip6f_nxt;
- offset = ((struct ip6_frag *)ulp)->ip6f_offlg &
- IP6F_OFF_MASK;
- ip6f_mf = ((struct ip6_frag *)ulp)->ip6f_offlg &
- IP6F_MORE_FRAG;
- if (V_fw_permit_single_frag6 == 0 &&
- offset == 0 && ip6f_mf == 0) {
- if (V_fw_verbose)
- printf("IPFW2: IPV6 - Invalid "
- "Fragment Header\n");
- if (V_fw_deny_unknown_exthdrs)
- return (IP_FW_DENY);
- break;
- }
- args->f_id.extra =
- ntohl(((struct ip6_frag *)ulp)->ip6f_ident);
- ulp = NULL;
- break;
-
- case IPPROTO_DSTOPTS: /* RFC 2460 */
- PULLUP_TO(hlen, ulp, struct ip6_hbh);
- ext_hd |= EXT_DSTOPTS;
- hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3;
- proto = ((struct ip6_hbh *)ulp)->ip6h_nxt;
- ulp = NULL;
- break;
-
- case IPPROTO_AH: /* RFC 2402 */
- PULLUP_TO(hlen, ulp, struct ip6_ext);
- ext_hd |= EXT_AH;
- hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2;
- proto = ((struct ip6_ext *)ulp)->ip6e_nxt;
- ulp = NULL;
- break;
-
- case IPPROTO_ESP: /* RFC 2406 */
- PULLUP_TO(hlen, ulp, uint32_t); /* SPI, Seq# */
- /* Anything past Seq# is variable length and
- * data past this ext. header is encrypted. */
- ext_hd |= EXT_ESP;
- break;
-
- case IPPROTO_NONE: /* RFC 2460 */
- /*
- * Packet ends here, and IPv6 header has
- * already been pulled up. If ip6e_len!=0
- * then octets must be ignored.
- */
- ulp = ip; /* non-NULL to get out of loop. */
- break;
-
- case IPPROTO_OSPFIGP:
- /* XXX OSPF header check? */
- PULLUP_TO(hlen, ulp, struct ip6_ext);
- break;
-
- case IPPROTO_PIM:
- /* XXX PIM header check? */
- PULLUP_TO(hlen, ulp, struct pim);
- break;
-
- case IPPROTO_CARP:
- PULLUP_TO(hlen, ulp, struct carp_header);
- if (((struct carp_header *)ulp)->carp_version !=
- CARP_VERSION)
- return (IP_FW_DENY);
- if (((struct carp_header *)ulp)->carp_type !=
- CARP_ADVERTISEMENT)
- return (IP_FW_DENY);
- break;
-
- case IPPROTO_IPV6: /* RFC 2893 */
- PULLUP_TO(hlen, ulp, struct ip6_hdr);
- break;
-
- case IPPROTO_IPV4: /* RFC 2893 */
- PULLUP_TO(hlen, ulp, struct ip);
- break;
-
- default:
- if (V_fw_verbose)
- printf("IPFW2: IPV6 - Unknown "
- "Extension Header(%d), ext_hd=%x\n",
- proto, ext_hd);
- if (V_fw_deny_unknown_exthdrs)
- return (IP_FW_DENY);
- PULLUP_TO(hlen, ulp, struct ip6_ext);
- break;
- } /*switch */
- }
- ip = mtod(m, struct ip *);
- ip6 = (struct ip6_hdr *)ip;
- args->f_id.src_ip6 = ip6->ip6_src;
- args->f_id.dst_ip6 = ip6->ip6_dst;
- args->f_id.src_ip = 0;
- args->f_id.dst_ip = 0;
- args->f_id.flow_id6 = ntohl(ip6->ip6_flow);
- } else if (pktlen >= sizeof(struct ip) &&
- (args->eh == NULL || etype == ETHERTYPE_IP) && ip->ip_v == 4) {
- is_ipv4 = 1;
- hlen = ip->ip_hl << 2;
- args->f_id.addr_type = 4;
-
- /*
- * Collect parameters into local variables for faster matching.
- */
- proto = ip->ip_p;
- src_ip = ip->ip_src;
- dst_ip = ip->ip_dst;
- offset = ntohs(ip->ip_off) & IP_OFFMASK;
- iplen = ntohs(ip->ip_len);
- pktlen = iplen < pktlen ? iplen : pktlen;
-
- if (offset == 0) {
- switch (proto) {
- case IPPROTO_TCP:
- PULLUP_TO(hlen, ulp, struct tcphdr);
- dst_port = TCP(ulp)->th_dport;
- src_port = TCP(ulp)->th_sport;
- /* save flags for dynamic rules */
- args->f_id._flags = TCP(ulp)->th_flags;
- break;
-
- case IPPROTO_SCTP:
- PULLUP_TO(hlen, ulp, struct sctphdr);
- src_port = SCTP(ulp)->src_port;
- dst_port = SCTP(ulp)->dest_port;
- break;
-
- case IPPROTO_UDP:
- PULLUP_TO(hlen, ulp, struct udphdr);
- dst_port = UDP(ulp)->uh_dport;
- src_port = UDP(ulp)->uh_sport;
- break;
-
- case IPPROTO_ICMP:
- PULLUP_TO(hlen, ulp, struct icmphdr);
- //args->f_id.flags = ICMP(ulp)->icmp_type;
- break;
-
- default:
- break;
- }
- }
-
- ip = mtod(m, struct ip *);
- args->f_id.src_ip = ntohl(src_ip.s_addr);
- args->f_id.dst_ip = ntohl(dst_ip.s_addr);
- }
-#undef PULLUP_TO
- if (proto) { /* we may have port numbers, store them */
- args->f_id.proto = proto;
- args->f_id.src_port = src_port = ntohs(src_port);
- args->f_id.dst_port = dst_port = ntohs(dst_port);
- }
-
- IPFW_RLOCK(chain);
- if (! V_ipfw_vnet_ready) { /* shutting down, leave NOW. */
- IPFW_RUNLOCK(chain);
- return (IP_FW_PASS); /* accept */
- }
- if (args->rule.slot) {
- /*
- * Packet has already been tagged as a result of a previous
- * match on rule args->rule aka args->rule_id (PIPE, QUEUE,
- * REASS, NETGRAPH, DIVERT/TEE...)
- * Validate the slot and continue from the next one
- * if still present, otherwise do a lookup.
- */
- f_pos = (args->rule.chain_id == chain->id) ?
- args->rule.slot :
- ipfw_find_rule(chain, args->rule.rulenum,
- args->rule.rule_id);
- } else {
- f_pos = 0;
- }
-
- /*
- * Now scan the rules, and parse microinstructions for each rule.
- * We have two nested loops and an inner switch. Sometimes we
- * need to break out of one or both loops, or re-enter one of
- * the loops with updated variables. Loop variables are:
- *
- * f_pos (outer loop) points to the current rule.
- * On output it points to the matching rule.
- * done (outer loop) is used as a flag to break the loop.
- * l (inner loop) residual length of current rule.
- * cmd points to the current microinstruction.
- *
- * We break the inner loop by setting l=0 and possibly
- * cmdlen=0 if we don't want to advance cmd.
- * We break the outer loop by setting done=1
- * We can restart the inner loop by setting l>0 and f_pos, f, cmd
- * as needed.
- */
- for (; f_pos < chain->n_rules; f_pos++) {
- ipfw_insn *cmd;
- uint32_t tablearg = 0;
- int l, cmdlen, skip_or; /* skip rest of OR block */
- struct ip_fw *f;
-
- f = chain->map[f_pos];
- if (V_set_disable & (1 << f->set) )
- continue;
-
- skip_or = 0;
- for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
- l -= cmdlen, cmd += cmdlen) {
- int match;
-
- /*
- * check_body is a jump target used when we find a
- * CHECK_STATE, and need to jump to the body of
- * the target rule.
- */
-
-/* check_body: */
- cmdlen = F_LEN(cmd);
- /*
- * An OR block (insn_1 || .. || insn_n) has the
- * F_OR bit set in all but the last instruction.
- * The first match will set "skip_or", and cause
- * the following instructions to be skipped until
- * past the one with the F_OR bit clear.
- */
- if (skip_or) { /* skip this instruction */
- if ((cmd->len & F_OR) == 0)
- skip_or = 0; /* next one is good */
- continue;
- }
- match = 0; /* set to 1 if we succeed */
-
- switch (cmd->opcode) {
- /*
- * The first set of opcodes compares the packet's
- * fields with some pattern, setting 'match' if a
- * match is found. At the end of the loop there is
- * logic to deal with F_NOT and F_OR flags associated
- * with the opcode.
- */
- case O_NOP:
- match = 1;
- break;
-
- case O_FORWARD_MAC:
- printf("ipfw: opcode %d unimplemented\n",
- cmd->opcode);
- break;
-
- case O_GID:
- case O_UID:
- case O_JAIL:
- /*
- * We only check offset == 0 && proto != 0,
- * as this ensures that we have a
- * packet with the ports info.
- */
- if (offset != 0)
- break;
- if (proto == IPPROTO_TCP ||
- proto == IPPROTO_UDP)
- match = check_uidgid(
- (ipfw_insn_u32 *)cmd,
- args, &ucred_lookup,
-#ifdef __FreeBSD__
- &ucred_cache);
-#else
- (void *)&ucred_cache);
-#endif
- break;
-
- case O_RECV:
- match = iface_match(m->m_pkthdr.rcvif,
- (ipfw_insn_if *)cmd, chain, &tablearg);
- break;
-
- case O_XMIT:
- match = iface_match(oif, (ipfw_insn_if *)cmd,
- chain, &tablearg);
- break;
-
- case O_VIA:
- match = iface_match(oif ? oif :
- m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd,
- chain, &tablearg);
- break;
-
- case O_MACADDR2:
- if (args->eh != NULL) { /* have MAC header */
- u_int32_t *want = (u_int32_t *)
- ((ipfw_insn_mac *)cmd)->addr;
- u_int32_t *mask = (u_int32_t *)
- ((ipfw_insn_mac *)cmd)->mask;
- u_int32_t *hdr = (u_int32_t *)args->eh;
-
- match =
- ( want[0] == (hdr[0] & mask[0]) &&
- want[1] == (hdr[1] & mask[1]) &&
- want[2] == (hdr[2] & mask[2]) );
- }
- break;
-
- case O_MAC_TYPE:
- if (args->eh != NULL) {
- u_int16_t *p =
- ((ipfw_insn_u16 *)cmd)->ports;
- int i;
-
- for (i = cmdlen - 1; !match && i>0;
- i--, p += 2)
- match = (etype >= p[0] &&
- etype <= p[1]);
- }
- break;
-
- case O_FRAG:
- match = (offset != 0);
- break;
-
- case O_IN: /* "out" is "not in" */
- match = (oif == NULL);
- break;
-
- case O_LAYER2:
- match = (args->eh != NULL);
- break;
-
- case O_DIVERTED:
- {
- /* For diverted packets, args->rule.info
- * contains the divert port (in host format)
- * reason and direction.
- */
- uint32_t i = args->rule.info;
- match = (i&IPFW_IS_MASK) == IPFW_IS_DIVERT &&
- cmd->arg1 & ((i & IPFW_INFO_IN) ? 1 : 2);
- }
- break;
-
- case O_PROTO:
- /*
- * We do not allow an arg of 0 so the
- * check of "proto" only suffices.
- */
- match = (proto == cmd->arg1);
- break;
-
- case O_IP_SRC:
- match = is_ipv4 &&
- (((ipfw_insn_ip *)cmd)->addr.s_addr ==
- src_ip.s_addr);
- break;
-
- case O_IP_SRC_LOOKUP:
- case O_IP_DST_LOOKUP:
- if (is_ipv4) {
- uint32_t key =
- (cmd->opcode == O_IP_DST_LOOKUP) ?
- dst_ip.s_addr : src_ip.s_addr;
- uint32_t v = 0;
-
- if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) {
- /* generic lookup. The key must be
- * in 32bit big-endian format.
- */
- v = ((ipfw_insn_u32 *)cmd)->d[1];
- if (v == 0)
- key = dst_ip.s_addr;
- else if (v == 1)
- key = src_ip.s_addr;
- else if (v == 6) /* dscp */
- key = (ip->ip_tos >> 2) & 0x3f;
- else if (offset != 0)
- break;
- else if (proto != IPPROTO_TCP &&
- proto != IPPROTO_UDP)
- break;
- else if (v == 2)
- key = htonl(dst_port);
- else if (v == 3)
- key = htonl(src_port);
- else if (v == 4 || v == 5) {
- check_uidgid(
- (ipfw_insn_u32 *)cmd,
- args, &ucred_lookup,
-#ifdef __FreeBSD__
- &ucred_cache);
- if (v == 4 /* O_UID */)
- key = ucred_cache->cr_uid;
- else if (v == 5 /* O_JAIL */)
- key = ucred_cache->cr_prison->pr_id;
-#else /* !__FreeBSD__ */
- (void *)&ucred_cache);
- if (v ==4 /* O_UID */)
- key = ucred_cache.uid;
- else if (v == 5 /* O_JAIL */)
- key = ucred_cache.xid;
-#endif /* !__FreeBSD__ */
- key = htonl(key);
- } else
- break;
- }
- match = ipfw_lookup_table(chain,
- cmd->arg1, key, &v);
- if (!match)
- break;
- if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
- match =
- ((ipfw_insn_u32 *)cmd)->d[0] == v;
- else
- tablearg = v;
- } else if (is_ipv6) {
- uint32_t v = 0;
- void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ?
- &args->f_id.dst_ip6: &args->f_id.src_ip6;
- match = ipfw_lookup_table_extended(chain,
- cmd->arg1, pkey, &v,
- IPFW_TABLE_CIDR);
- if (cmdlen == F_INSN_SIZE(ipfw_insn_u32))
- match = ((ipfw_insn_u32 *)cmd)->d[0] == v;
- if (match)
- tablearg = v;
- }
- break;
-
- case O_IP_SRC_MASK:
- case O_IP_DST_MASK:
- if (is_ipv4) {
- uint32_t a =
- (cmd->opcode == O_IP_DST_MASK) ?
- dst_ip.s_addr : src_ip.s_addr;
- uint32_t *p = ((ipfw_insn_u32 *)cmd)->d;
- int i = cmdlen-1;
-
- for (; !match && i>0; i-= 2, p+= 2)
- match = (p[0] == (a & p[1]));
- }
- break;
-
- case O_IP_SRC_ME:
- if (is_ipv4) {
- struct ifnet *tif;
-
- INADDR_TO_IFP(src_ip, tif);
- match = (tif != NULL);
- break;
- }
-#ifdef INET6
- /* FALLTHROUGH */
- case O_IP6_SRC_ME:
- match= is_ipv6 && search_ip6_addr_net(&args->f_id.src_ip6);
-#endif
- break;
-
- case O_IP_DST_SET:
- case O_IP_SRC_SET:
- if (is_ipv4) {
- u_int32_t *d = (u_int32_t *)(cmd+1);
- u_int32_t addr =
- cmd->opcode == O_IP_DST_SET ?
- args->f_id.dst_ip :
- args->f_id.src_ip;
-
- if (addr < d[0])
- break;
- addr -= d[0]; /* subtract base */
- match = (addr < cmd->arg1) &&
- ( d[ 1 + (addr>>5)] &
- (1<<(addr & 0x1f)) );
- }
- break;
-
- case O_IP_DST:
- match = is_ipv4 &&
- (((ipfw_insn_ip *)cmd)->addr.s_addr ==
- dst_ip.s_addr);
- break;
-
- case O_IP_DST_ME:
- if (is_ipv4) {
- struct ifnet *tif;
-
- INADDR_TO_IFP(dst_ip, tif);
- match = (tif != NULL);
- break;
- }
-#ifdef INET6
- /* FALLTHROUGH */
- case O_IP6_DST_ME:
- match= is_ipv6 && search_ip6_addr_net(&args->f_id.dst_ip6);
-#endif
- break;
-
-
- case O_IP_SRCPORT:
- case O_IP_DSTPORT:
- /*
- * offset == 0 && proto != 0 is enough
- * to guarantee that we have a
- * packet with port info.
- */
- if ((proto==IPPROTO_UDP || proto==IPPROTO_TCP)
- && offset == 0) {
- u_int16_t x =
- (cmd->opcode == O_IP_SRCPORT) ?
- src_port : dst_port ;
- u_int16_t *p =
- ((ipfw_insn_u16 *)cmd)->ports;
- int i;
-
- for (i = cmdlen - 1; !match && i>0;
- i--, p += 2)
- match = (x>=p[0] && x<=p[1]);
- }
- break;
-
- case O_ICMPTYPE:
- match = (offset == 0 && proto==IPPROTO_ICMP &&
- icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) );
- break;
-
-#ifdef INET6
- case O_ICMP6TYPE:
- match = is_ipv6 && offset == 0 &&
- proto==IPPROTO_ICMPV6 &&
- icmp6type_match(
- ICMP6(ulp)->icmp6_type,
- (ipfw_insn_u32 *)cmd);
- break;
-#endif /* INET6 */
-
- case O_IPOPT:
- match = (is_ipv4 &&
- ipopts_match(ip, cmd) );
- break;
-
- case O_IPVER:
- match = (is_ipv4 &&
- cmd->arg1 == ip->ip_v);
- break;
-
- case O_IPID:
- case O_IPLEN:
- case O_IPTTL:
- if (is_ipv4) { /* only for IP packets */
- uint16_t x;
- uint16_t *p;
- int i;
-
- if (cmd->opcode == O_IPLEN)
- x = iplen;
- else if (cmd->opcode == O_IPTTL)
- x = ip->ip_ttl;
- else /* must be IPID */
- x = ntohs(ip->ip_id);
- if (cmdlen == 1) {
- match = (cmd->arg1 == x);
- break;
- }
- /* otherwise we have ranges */
- p = ((ipfw_insn_u16 *)cmd)->ports;
- i = cmdlen - 1;
- for (; !match && i>0; i--, p += 2)
- match = (x >= p[0] && x <= p[1]);
- }
- break;
-
- case O_IPPRECEDENCE:
- match = (is_ipv4 &&
- (cmd->arg1 == (ip->ip_tos & 0xe0)) );
- break;
-
- case O_IPTOS:
- match = (is_ipv4 &&
- flags_match(cmd, ip->ip_tos));
- break;
-
- case O_TCPDATALEN:
- if (proto == IPPROTO_TCP && offset == 0) {
- struct tcphdr *tcp;
- uint16_t x;
- uint16_t *p;
- int i;
-
- tcp = TCP(ulp);
- x = iplen -
- ((ip->ip_hl + tcp->th_off) << 2);
- if (cmdlen == 1) {
- match = (cmd->arg1 == x);
- break;
- }
- /* otherwise we have ranges */
- p = ((ipfw_insn_u16 *)cmd)->ports;
- i = cmdlen - 1;
- for (; !match && i>0; i--, p += 2)
- match = (x >= p[0] && x <= p[1]);
- }
- break;
-
- case O_TCPFLAGS:
- match = (proto == IPPROTO_TCP && offset == 0 &&
- flags_match(cmd, TCP(ulp)->th_flags));
- break;
-
- case O_TCPOPTS:
- PULLUP_LEN(hlen, ulp, (TCP(ulp)->th_off << 2));
- match = (proto == IPPROTO_TCP && offset == 0 &&
- tcpopts_match(TCP(ulp), cmd));
- break;
-
- case O_TCPSEQ:
- match = (proto == IPPROTO_TCP && offset == 0 &&
- ((ipfw_insn_u32 *)cmd)->d[0] ==
- TCP(ulp)->th_seq);
- break;
-
- case O_TCPACK:
- match = (proto == IPPROTO_TCP && offset == 0 &&
- ((ipfw_insn_u32 *)cmd)->d[0] ==
- TCP(ulp)->th_ack);
- break;
-
- case O_TCPWIN:
- if (proto == IPPROTO_TCP && offset == 0) {
- uint16_t x;
- uint16_t *p;
- int i;
-
- x = ntohs(TCP(ulp)->th_win);
- if (cmdlen == 1) {
- match = (cmd->arg1 == x);
- break;
- }
- /* Otherwise we have ranges. */
- p = ((ipfw_insn_u16 *)cmd)->ports;
- i = cmdlen - 1;
- for (; !match && i > 0; i--, p += 2)
- match = (x >= p[0] && x <= p[1]);
- }
- break;
-
- case O_ESTAB:
- /* reject packets which have SYN only */
- /* XXX should i also check for TH_ACK ? */
- match = (proto == IPPROTO_TCP && offset == 0 &&
- (TCP(ulp)->th_flags &
- (TH_RST | TH_ACK | TH_SYN)) != TH_SYN);
- break;
-
- case O_ALTQ: {
- struct pf_mtag *at;
- ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
-
- match = 1;
- at = pf_find_mtag(m);
- if (at != NULL && at->qid != 0)
- break;
- at = pf_get_mtag(m);
- if (at == NULL) {
- /*
- * Let the packet fall back to the
- * default ALTQ.
- */
- break;
- }
- at->qid = altq->qid;
- at->hdr = ip;
- break;
- }
-
- case O_LOG:
- ipfw_log(f, hlen, args, m,
- oif, offset | ip6f_mf, tablearg, ip);
- match = 1;
- break;
-
- case O_PROB:
- match = (random()<((ipfw_insn_u32 *)cmd)->d[0]);
- break;
-
- case O_VERREVPATH:
- /* Outgoing packets automatically pass/match */
- match = ((oif != NULL) ||
- (m->m_pkthdr.rcvif == NULL) ||
- (
-#ifdef INET6
- is_ipv6 ?
- verify_path6(&(args->f_id.src_ip6),
- m->m_pkthdr.rcvif, args->f_id.fib) :
-#endif
- verify_path(src_ip, m->m_pkthdr.rcvif,
- args->f_id.fib)));
- break;
-
- case O_VERSRCREACH:
- /* Outgoing packets automatically pass/match */
- match = (hlen > 0 && ((oif != NULL) ||
-#ifdef INET6
- is_ipv6 ?
- verify_path6(&(args->f_id.src_ip6),
- NULL, args->f_id.fib) :
-#endif
- verify_path(src_ip, NULL, args->f_id.fib)));
- break;
-
- case O_ANTISPOOF:
- /* Outgoing packets automatically pass/match */
- if (oif == NULL && hlen > 0 &&
- ( (is_ipv4 && in_localaddr(src_ip))
-#ifdef INET6
- || (is_ipv6 &&
- in6_localaddr(&(args->f_id.src_ip6)))
-#endif
- ))
- match =
-#ifdef INET6
- is_ipv6 ? verify_path6(
- &(args->f_id.src_ip6),
- m->m_pkthdr.rcvif,
- args->f_id.fib) :
-#endif
- verify_path(src_ip,
- m->m_pkthdr.rcvif,
- args->f_id.fib);
- else
- match = 1;
- break;
-
- case O_IPSEC:
-#ifdef IPSEC
- match = (m_tag_find(m,
- PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL);
-#endif
- /* otherwise no match */
- break;
-
-#ifdef INET6
- case O_IP6_SRC:
- match = is_ipv6 &&
- IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6,
- &((ipfw_insn_ip6 *)cmd)->addr6);
- break;
-
- case O_IP6_DST:
- match = is_ipv6 &&
- IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6,
- &((ipfw_insn_ip6 *)cmd)->addr6);
- break;
- case O_IP6_SRC_MASK:
- case O_IP6_DST_MASK:
- if (is_ipv6) {
- int i = cmdlen - 1;
- struct in6_addr p;
- struct in6_addr *d =
- &((ipfw_insn_ip6 *)cmd)->addr6;
-
- for (; !match && i > 0; d += 2,
- i -= F_INSN_SIZE(struct in6_addr)
- * 2) {
- p = (cmd->opcode ==
- O_IP6_SRC_MASK) ?
- args->f_id.src_ip6:
- args->f_id.dst_ip6;
- APPLY_MASK(&p, &d[1]);
- match =
- IN6_ARE_ADDR_EQUAL(&d[0],
- &p);
- }
- }
- break;
-
- case O_FLOW6ID:
- match = is_ipv6 &&
- flow6id_match(args->f_id.flow_id6,
- (ipfw_insn_u32 *) cmd);
- break;
-
- case O_EXT_HDR:
- match = is_ipv6 &&
- (ext_hd & ((ipfw_insn *) cmd)->arg1);
- break;
-
- case O_IP6:
- match = is_ipv6;
- break;
-#endif
-
- case O_IP4:
- match = is_ipv4;
- break;
-
- case O_TAG: {
- struct m_tag *mtag;
- uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
-
- /* Packet is already tagged with this tag? */
- mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL);
-
- /* We have `untag' action when F_NOT flag is
- * present. And we must remove this mtag from
- * mbuf and reset `match' to zero (`match' will
- * be inversed later).
- * Otherwise we should allocate new mtag and
- * push it into mbuf.
- */
- if (cmd->len & F_NOT) { /* `untag' action */
- if (mtag != NULL)
- m_tag_delete(m, mtag);
- match = 0;
- } else {
- if (mtag == NULL) {
- mtag = m_tag_alloc( MTAG_IPFW,
- tag, 0, M_NOWAIT);
- if (mtag != NULL)
- m_tag_prepend(m, mtag);
- }
- match = 1;
- }
- break;
- }
-
- case O_FIB: /* try match the specified fib */
- if (args->f_id.fib == cmd->arg1)
- match = 1;
- break;
-
- case O_SOCKARG: {
- struct inpcb *inp = args->inp;
- struct inpcbinfo *pi;
-
- if (is_ipv6) /* XXX can we remove this ? */
- break;
-
- if (proto == IPPROTO_TCP)
- pi = &V_tcbinfo;
- else if (proto == IPPROTO_UDP)
- pi = &V_udbinfo;
- else
- break;
-
- /*
- * XXXRW: so_user_cookie should almost
- * certainly be inp_user_cookie?
- */
-
- /* For incomming packet, lookup up the
- inpcb using the src/dest ip/port tuple */
- if (inp == NULL) {
- inp = in_pcblookup(pi,
- src_ip, htons(src_port),
- dst_ip, htons(dst_port),
- INPLOOKUP_RLOCKPCB, NULL);
- if (inp != NULL) {
- tablearg =
- inp->inp_socket->so_user_cookie;
- if (tablearg)
- match = 1;
- INP_RUNLOCK(inp);
- }
- } else {
- if (inp->inp_socket) {
- tablearg =
- inp->inp_socket->so_user_cookie;
- if (tablearg)
- match = 1;
- }
- }
- break;
- }
-
- case O_TAGGED: {
- struct m_tag *mtag;
- uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
-
- if (cmdlen == 1) {
- match = m_tag_locate(m, MTAG_IPFW,
- tag, NULL) != NULL;
- break;
- }
-
- /* we have ranges */
- for (mtag = m_tag_first(m);
- mtag != NULL && !match;
- mtag = m_tag_next(m, mtag)) {
- uint16_t *p;
- int i;
-
- if (mtag->m_tag_cookie != MTAG_IPFW)
- continue;
-
- p = ((ipfw_insn_u16 *)cmd)->ports;
- i = cmdlen - 1;
- for(; !match && i > 0; i--, p += 2)
- match =
- mtag->m_tag_id >= p[0] &&
- mtag->m_tag_id <= p[1];
- }
- break;
- }
-
- /*
- * The second set of opcodes represents 'actions',
- * i.e. the terminal part of a rule once the packet
- * matches all previous patterns.
- * Typically there is only one action for each rule,
- * and the opcode is stored at the end of the rule
- * (but there are exceptions -- see below).
- *
- * In general, here we set retval and terminate the
- * outer loop (would be a 'break 3' in some language,
- * but we need to set l=0, done=1)
- *
- * Exceptions:
- * O_COUNT and O_SKIPTO actions:
- * instead of terminating, we jump to the next rule
- * (setting l=0), or to the SKIPTO target (setting
- * f/f_len, cmd and l as needed), respectively.
- *
- * O_TAG, O_LOG and O_ALTQ action parameters:
- * perform some action and set match = 1;
- *
- * O_LIMIT and O_KEEP_STATE: these opcodes are
- * not real 'actions', and are stored right
- * before the 'action' part of the rule.
- * These opcodes try to install an entry in the
- * state tables; if successful, we continue with
- * the next opcode (match=1; break;), otherwise
- * the packet must be dropped (set retval,
- * break loops with l=0, done=1)
- *
- * O_PROBE_STATE and O_CHECK_STATE: these opcodes
- * cause a lookup of the state table, and a jump
- * to the 'action' part of the parent rule
- * if an entry is found, or
- * (CHECK_STATE only) a jump to the next rule if
- * the entry is not found.
- * The result of the lookup is cached so that
- * further instances of these opcodes become NOPs.
- * The jump to the next rule is done by setting
- * l=0, cmdlen=0.
- */
- case O_LIMIT:
- case O_KEEP_STATE:
- if (ipfw_install_state(f,
- (ipfw_insn_limit *)cmd, args, tablearg)) {
- /* error or limit violation */
- retval = IP_FW_DENY;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- }
- match = 1;
- break;
-
- case O_PROBE_STATE:
- case O_CHECK_STATE:
- /*
- * dynamic rules are checked at the first
- * keep-state or check-state occurrence,
- * with the result being stored in dyn_dir.
- * The compiler introduces a PROBE_STATE
- * instruction for us when we have a
- * KEEP_STATE (because PROBE_STATE needs
- * to be run first).
- */
- if (dyn_dir == MATCH_UNKNOWN &&
- (q = ipfw_lookup_dyn_rule(&args->f_id,
- &dyn_dir, proto == IPPROTO_TCP ?
- TCP(ulp) : NULL))
- != NULL) {
- /*
- * Found dynamic entry, update stats
- * and jump to the 'action' part of
- * the parent rule by setting
- * f, cmd, l and clearing cmdlen.
- */
- q->pcnt++;
- q->bcnt += pktlen;
- /* XXX we would like to have f_pos
- * readily accessible in the dynamic
- * rule, instead of having to
- * lookup q->rule.
- */
- f = q->rule;
- f_pos = ipfw_find_rule(chain,
- f->rulenum, f->id);
- cmd = ACTION_PTR(f);
- l = f->cmd_len - f->act_ofs;
- ipfw_dyn_unlock();
- cmdlen = 0;
- match = 1;
- break;
- }
- /*
- * Dynamic entry not found. If CHECK_STATE,
- * skip to next rule, if PROBE_STATE just
- * ignore and continue with next opcode.
- */
- if (cmd->opcode == O_CHECK_STATE)
- l = 0; /* exit inner loop */
- match = 1;
- break;
-
- case O_ACCEPT:
- retval = 0; /* accept */
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-
- case O_PIPE:
- case O_QUEUE:
- set_match(args, f_pos, chain);
- args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
- if (cmd->opcode == O_PIPE)
- args->rule.info |= IPFW_IS_PIPE;
- if (V_fw_one_pass)
- args->rule.info |= IPFW_ONEPASS;
- retval = IP_FW_DUMMYNET;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-
- case O_DIVERT:
- case O_TEE:
- if (args->eh) /* not on layer 2 */
- break;
- /* otherwise this is terminal */
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- retval = (cmd->opcode == O_DIVERT) ?
- IP_FW_DIVERT : IP_FW_TEE;
- set_match(args, f_pos, chain);
- args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
- break;
-
- case O_COUNT:
- f->pcnt++; /* update stats */
- f->bcnt += pktlen;
- f->timestamp = time_uptime;
- l = 0; /* exit inner loop */
- break;
-
- case O_SKIPTO:
- f->pcnt++; /* update stats */
- f->bcnt += pktlen;
- f->timestamp = time_uptime;
- /* If possible use cached f_pos (in f->next_rule),
- * whose version is written in f->next_rule
- * (horrible hacks to avoid changing the ABI).
- */
- if (cmd->arg1 != IP_FW_TABLEARG &&
- (uintptr_t)f->x_next == chain->id) {
- f_pos = (uintptr_t)f->next_rule;
- } else {
- int i = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
- /* make sure we do not jump backward */
- if (i <= f->rulenum)
- i = f->rulenum + 1;
- f_pos = ipfw_find_rule(chain, i, 0);
- /* update the cache */
- if (cmd->arg1 != IP_FW_TABLEARG) {
- f->next_rule =
- (void *)(uintptr_t)f_pos;
- f->x_next =
- (void *)(uintptr_t)chain->id;
- }
- }
- /*
- * Skip disabled rules, and re-enter
- * the inner loop with the correct
- * f_pos, f, l and cmd.
- * Also clear cmdlen and skip_or
- */
- for (; f_pos < chain->n_rules - 1 &&
- (V_set_disable &
- (1 << chain->map[f_pos]->set));
- f_pos++)
- ;
- /* Re-enter the inner loop at the skipto rule. */
- f = chain->map[f_pos];
- l = f->cmd_len;
- cmd = f->cmd;
- match = 1;
- cmdlen = 0;
- skip_or = 0;
- continue;
- break; /* not reached */
-
- case O_CALLRETURN: {
- /*
- * Implementation of `subroutine' call/return,
- * in the stack carried in an mbuf tag. This
- * is different from `skipto' in that any call
- * address is possible (`skipto' must prevent
- * backward jumps to avoid endless loops).
- * We have `return' action when F_NOT flag is
- * present. The `m_tag_id' field is used as
- * stack pointer.
- */
- struct m_tag *mtag;
- uint16_t jmpto, *stack;
-
-#define IS_CALL ((cmd->len & F_NOT) == 0)
-#define IS_RETURN ((cmd->len & F_NOT) != 0)
- /*
- * Hand-rolled version of m_tag_locate() with
- * wildcard `type'.
- * If not already tagged, allocate new tag.
- */
- mtag = m_tag_first(m);
- while (mtag != NULL) {
- if (mtag->m_tag_cookie ==
- MTAG_IPFW_CALL)
- break;
- mtag = m_tag_next(m, mtag);
- }
- if (mtag == NULL && IS_CALL) {
- mtag = m_tag_alloc(MTAG_IPFW_CALL, 0,
- IPFW_CALLSTACK_SIZE *
- sizeof(uint16_t), M_NOWAIT);
- if (mtag != NULL)
- m_tag_prepend(m, mtag);
- }
-
- /*
- * On error both `call' and `return' just
- * continue with next rule.
- */
- if (IS_RETURN && (mtag == NULL ||
- mtag->m_tag_id == 0)) {
- l = 0; /* exit inner loop */
- break;
- }
- if (IS_CALL && (mtag == NULL ||
- mtag->m_tag_id >= IPFW_CALLSTACK_SIZE)) {
- printf("ipfw: call stack error, "
- "go to next rule\n");
- l = 0; /* exit inner loop */
- break;
- }
-
- f->pcnt++; /* update stats */
- f->bcnt += pktlen;
- f->timestamp = time_uptime;
- stack = (uint16_t *)(mtag + 1);
-
- /*
- * The `call' action may use cached f_pos
- * (in f->next_rule), whose version is written
- * in f->next_rule.
- * The `return' action, however, doesn't have
- * fixed jump address in cmd->arg1 and can't use
- * cache.
- */
- if (IS_CALL) {
- stack[mtag->m_tag_id] = f->rulenum;
- mtag->m_tag_id++;
- if (cmd->arg1 != IP_FW_TABLEARG &&
- (uintptr_t)f->x_next == chain->id) {
- f_pos = (uintptr_t)f->next_rule;
- } else {
- jmpto = (cmd->arg1 ==
- IP_FW_TABLEARG) ? tablearg:
- cmd->arg1;
- f_pos = ipfw_find_rule(chain,
- jmpto, 0);
- /* update the cache */
- if (cmd->arg1 !=
- IP_FW_TABLEARG) {
- f->next_rule =
- (void *)(uintptr_t)
- f_pos;
- f->x_next =
- (void *)(uintptr_t)
- chain->id;
- }
- }
- } else { /* `return' action */
- mtag->m_tag_id--;
- jmpto = stack[mtag->m_tag_id] + 1;
- f_pos = ipfw_find_rule(chain, jmpto, 0);
- }
-
- /*
- * Skip disabled rules, and re-enter
- * the inner loop with the correct
- * f_pos, f, l and cmd.
- * Also clear cmdlen and skip_or
- */
- for (; f_pos < chain->n_rules - 1 &&
- (V_set_disable &
- (1 << chain->map[f_pos]->set)); f_pos++)
- ;
- /* Re-enter the inner loop at the dest rule. */
- f = chain->map[f_pos];
- l = f->cmd_len;
- cmd = f->cmd;
- cmdlen = 0;
- skip_or = 0;
- continue;
- break; /* NOTREACHED */
- }
-#undef IS_CALL
-#undef IS_RETURN
-
- case O_REJECT:
- /*
- * Drop the packet and send a reject notice
- * if the packet is not ICMP (or is an ICMP
- * query), and it is not multicast/broadcast.
- */
- if (hlen > 0 && is_ipv4 && offset == 0 &&
- (proto != IPPROTO_ICMP ||
- is_icmp_query(ICMP(ulp))) &&
- !(m->m_flags & (M_BCAST|M_MCAST)) &&
- !IN_MULTICAST(ntohl(dst_ip.s_addr))) {
- send_reject(args, cmd->arg1, iplen, ip);
- m = args->m;
- }
- /* FALLTHROUGH */
-#ifdef INET6
- case O_UNREACH6:
- if (hlen > 0 && is_ipv6 &&
- ((offset & IP6F_OFF_MASK) == 0) &&
- (proto != IPPROTO_ICMPV6 ||
- (is_icmp6_query(icmp6_type) == 1)) &&
- !(m->m_flags & (M_BCAST|M_MCAST)) &&
- !IN6_IS_ADDR_MULTICAST(&args->f_id.dst_ip6)) {
- send_reject6(
- args, cmd->arg1, hlen,
- (struct ip6_hdr *)ip);
- m = args->m;
- }
- /* FALLTHROUGH */
-#endif
- case O_DENY:
- retval = IP_FW_DENY;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-
- case O_FORWARD_IP:
- if (args->eh) /* not valid on layer2 pkts */
- break;
- if (q == NULL || q->rule != f ||
- dyn_dir == MATCH_FORWARD) {
- struct sockaddr_in *sa;
- sa = &(((ipfw_insn_sa *)cmd)->sa);
- if (sa->sin_addr.s_addr == INADDR_ANY) {
- bcopy(sa, &args->hopstore,
- sizeof(*sa));
- args->hopstore.sin_addr.s_addr =
- htonl(tablearg);
- args->next_hop = &args->hopstore;
- } else {
- args->next_hop = sa;
- }
- }
- retval = IP_FW_PASS;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-
-#ifdef INET6
- case O_FORWARD_IP6:
- if (args->eh) /* not valid on layer2 pkts */
- break;
- if (q == NULL || q->rule != f ||
- dyn_dir == MATCH_FORWARD) {
- struct sockaddr_in6 *sin6;
-
- sin6 = &(((ipfw_insn_sa6 *)cmd)->sa);
- args->next_hop6 = sin6;
- }
- retval = IP_FW_PASS;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-#endif
-
- case O_NETGRAPH:
- case O_NGTEE:
- set_match(args, f_pos, chain);
- args->rule.info = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
- if (V_fw_one_pass)
- args->rule.info |= IPFW_ONEPASS;
- retval = (cmd->opcode == O_NETGRAPH) ?
- IP_FW_NETGRAPH : IP_FW_NGTEE;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-
- case O_SETFIB: {
- uint32_t fib;
-
- f->pcnt++; /* update stats */
- f->bcnt += pktlen;
- f->timestamp = time_uptime;
- fib = (cmd->arg1 == IP_FW_TABLEARG) ? tablearg:
- cmd->arg1;
- if (fib >= rt_numfibs)
- fib = 0;
- M_SETFIB(m, fib);
- args->f_id.fib = fib;
- l = 0; /* exit inner loop */
- break;
- }
-
- case O_NAT:
- if (!IPFW_NAT_LOADED) {
- retval = IP_FW_DENY;
- } else {
- struct cfg_nat *t;
- int nat_id;
-
- set_match(args, f_pos, chain);
- /* Check if this is 'global' nat rule */
- if (cmd->arg1 == 0) {
- retval = ipfw_nat_ptr(args, NULL, m);
- l = 0;
- done = 1;
- break;
- }
- t = ((ipfw_insn_nat *)cmd)->nat;
- if (t == NULL) {
- nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
- tablearg : cmd->arg1;
- t = (*lookup_nat_ptr)(&chain->nat, nat_id);
-
- if (t == NULL) {
- retval = IP_FW_DENY;
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
- }
- if (cmd->arg1 != IP_FW_TABLEARG)
- ((ipfw_insn_nat *)cmd)->nat = t;
- }
- retval = ipfw_nat_ptr(args, t, m);
- }
- l = 0; /* exit inner loop */
- done = 1; /* exit outer loop */
- break;
-
- case O_REASS: {
- int ip_off;
-
- f->pcnt++;
- f->bcnt += pktlen;
- l = 0; /* in any case exit inner loop */
- ip_off = ntohs(ip->ip_off);
-
- /* if not fragmented, go to next rule */
- if ((ip_off & (IP_MF | IP_OFFMASK)) == 0)
- break;
- /*
- * ip_reass() expects len & off in host
- * byte order.
- */
- SET_HOST_IPLEN(ip);
-
- args->m = m = ip_reass(m);
-
- /*
- * do IP header checksum fixup.
- */
- if (m == NULL) { /* fragment got swallowed */
- retval = IP_FW_DENY;
- } else { /* good, packet complete */
- int hlen;
-
- ip = mtod(m, struct ip *);
- hlen = ip->ip_hl << 2;
- SET_NET_IPLEN(ip);
- ip->ip_sum = 0;
- if (hlen == sizeof(struct ip))
- ip->ip_sum = in_cksum_hdr(ip);
- else
- ip->ip_sum = in_cksum(m, hlen);
- retval = IP_FW_REASS;
- set_match(args, f_pos, chain);
- }
- done = 1; /* exit outer loop */
- break;
- }
-
- default:
- panic("-- unknown opcode %d\n", cmd->opcode);
- } /* end of switch() on opcodes */
- /*
- * if we get here with l=0, then match is irrelevant.
- */
-
- if (cmd->len & F_NOT)
- match = !match;
-
- if (match) {
- if (cmd->len & F_OR)
- skip_or = 1;
- } else {
- if (!(cmd->len & F_OR)) /* not an OR block, */
- break; /* try next rule */
- }
-
- } /* end of inner loop, scan opcodes */
-#undef PULLUP_LEN
-
- if (done)
- break;
-
-/* next_rule:; */ /* try next rule */
-
- } /* end of outer for, scan rules */
-
- if (done) {
- struct ip_fw *rule = chain->map[f_pos];
- /* Update statistics */
- rule->pcnt++;
- rule->bcnt += pktlen;
- rule->timestamp = time_uptime;
- } else {
- retval = IP_FW_DENY;
- printf("ipfw: ouch!, skip past end of rules, denying packet\n");
- }
- IPFW_RUNLOCK(chain);
-#ifdef __FreeBSD__
- if (ucred_cache != NULL)
- crfree(ucred_cache);
-#endif
- return (retval);
-
-pullup_failed:
- if (V_fw_verbose)
- printf("ipfw: pullup failed\n");
- return (IP_FW_DENY);
-}
-
-/*
- * Set maximum number of tables that can be used in given VNET ipfw instance.
- */
-#ifdef SYSCTL_NODE
-static int
-sysctl_ipfw_table_num(SYSCTL_HANDLER_ARGS)
-{
- int error;
- unsigned int ntables;
-
- ntables = V_fw_tables_max;
-
- error = sysctl_handle_int(oidp, &ntables, 0, req);
- /* Read operation or some error */
- if ((error != 0) || (req->newptr == NULL))
- return (error);
-
- return (ipfw_resize_tables(&V_layer3_chain, ntables));
-}
-#endif
-/*
- * Module and VNET glue
- */
-
-/*
- * Stuff that must be initialised only on boot or module load
- */
-static int
-ipfw_init(void)
-{
- int error = 0;
-
- ipfw_dyn_attach();
- /*
- * Only print out this stuff the first time around,
- * when called from the sysinit code.
- */
- printf("ipfw2 "
-#ifdef INET6
- "(+ipv6) "
-#endif
- "initialized, divert %s, nat %s, "
- "rule-based forwarding "
-#ifdef IPFIREWALL_FORWARD
- "enabled, "
-#else
- "disabled, "
-#endif
- "default to %s, logging ",
-#ifdef IPDIVERT
- "enabled",
-#else
- "loadable",
-#endif
-#ifdef IPFIREWALL_NAT
- "enabled",
-#else
- "loadable",
-#endif
- default_to_accept ? "accept" : "deny");
-
- /*
- * Note: V_xxx variables can be accessed here but the vnet specific
- * initializer may not have been called yet for the VIMAGE case.
- * Tuneables will have been processed. We will print out values for
- * the default vnet.
- * XXX This should all be rationalized AFTER 8.0
- */
- if (V_fw_verbose == 0)
- printf("disabled\n");
- else if (V_verbose_limit == 0)
- printf("unlimited\n");
- else
- printf("limited to %d packets/entry by default\n",
- V_verbose_limit);
-
- /* Check user-supplied table count for validness */
- if (default_fw_tables > IPFW_TABLES_MAX)
- default_fw_tables = IPFW_TABLES_MAX;
-
- ipfw_log_bpf(1); /* init */
- return (error);
-}
-
-/*
- * Called for the removal of the last instance only on module unload.
- */
-static void
-ipfw_destroy(void)
-{
-
- ipfw_log_bpf(0); /* uninit */
- ipfw_dyn_detach();
- printf("IP firewall unloaded\n");
-}
-
-/*
- * Stuff that must be initialized for every instance
- * (including the first of course).
- */
-static int
-vnet_ipfw_init(const void *unused)
-{
- int error;
- struct ip_fw *rule = NULL;
- struct ip_fw_chain *chain;
-
- chain = &V_layer3_chain;
-
- /* First set up some values that are compile time options */
- V_autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
- V_fw_deny_unknown_exthdrs = 1;
-#ifdef IPFIREWALL_VERBOSE
- V_fw_verbose = 1;
-#endif
-#ifdef IPFIREWALL_VERBOSE_LIMIT
- V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
-#endif
-#ifdef IPFIREWALL_NAT
- LIST_INIT(&chain->nat);
-#endif
-
- /* insert the default rule and create the initial map */
- chain->n_rules = 1;
- chain->static_len = sizeof(struct ip_fw);
- chain->map = malloc(sizeof(struct ip_fw *), M_IPFW, M_WAITOK | M_ZERO);
- if (chain->map)
- rule = malloc(chain->static_len, M_IPFW, M_WAITOK | M_ZERO);
-
- /* Set initial number of tables */
- V_fw_tables_max = default_fw_tables;
- error = ipfw_init_tables(chain);
- if (error) {
- printf("ipfw2: setting up tables failed\n");
- free(chain->map, M_IPFW);
- free(rule, M_IPFW);
- return (ENOSPC);
- }
-
- /* fill and insert the default rule */
- rule->act_ofs = 0;
- rule->rulenum = IPFW_DEFAULT_RULE;
- rule->cmd_len = 1;
- rule->set = RESVD_SET;
- rule->cmd[0].len = 1;
- rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
- chain->rules = chain->default_rule = chain->map[0] = rule;
- chain->id = rule->id = 1;
-
- IPFW_LOCK_INIT(chain);
- ipfw_dyn_init();
-
- /* First set up some values that are compile time options */
- V_ipfw_vnet_ready = 1; /* Open for business */
-
- /*
- * Hook the sockopt handler, and the layer2 (V_ip_fw_chk_ptr)
- * and pfil hooks for ipv4 and ipv6. Even if the latter two fail
- * we still keep the module alive because the sockopt and
- * layer2 paths are still useful.
- * ipfw[6]_hook return 0 on success, ENOENT on failure,
- * so we can ignore the exact return value and just set a flag.
- *
- * Note that V_fw[6]_enable are manipulated by a SYSCTL_PROC so
- * changes in the underlying (per-vnet) variables trigger
- * immediate hook()/unhook() calls.
- * In layer2 we have the same behaviour, except that V_ether_ipfw
- * is checked on each packet because there are no pfil hooks.
- */
- V_ip_fw_ctl_ptr = ipfw_ctl;
- V_ip_fw_chk_ptr = ipfw_chk;
- error = ipfw_attach_hooks(1);
- return (error);
-}
-
-/*
- * Called for the removal of each instance.
- */
-static int
-vnet_ipfw_uninit(const void *unused)
-{
- struct ip_fw *reap, *rule;
- struct ip_fw_chain *chain = &V_layer3_chain;
- int i;
-
- V_ipfw_vnet_ready = 0; /* tell new callers to go away */
- /*
- * disconnect from ipv4, ipv6, layer2 and sockopt.
- * Then grab, release and grab again the WLOCK so we make
- * sure the update is propagated and nobody will be in.
- */
- (void)ipfw_attach_hooks(0 /* detach */);
- V_ip_fw_chk_ptr = NULL;
- V_ip_fw_ctl_ptr = NULL;
- IPFW_UH_WLOCK(chain);
- IPFW_UH_WUNLOCK(chain);
- IPFW_UH_WLOCK(chain);
-
- IPFW_WLOCK(chain);
- ipfw_dyn_uninit(0); /* run the callout_drain */
- IPFW_WUNLOCK(chain);
-
- ipfw_destroy_tables(chain);
- reap = NULL;
- IPFW_WLOCK(chain);
- for (i = 0; i < chain->n_rules; i++) {
- rule = chain->map[i];
- rule->x_next = reap;
- reap = rule;
- }
- if (chain->map)
- free(chain->map, M_IPFW);
- IPFW_WUNLOCK(chain);
- IPFW_UH_WUNLOCK(chain);
- if (reap != NULL)
- ipfw_reap_rules(reap);
- IPFW_LOCK_DESTROY(chain);
- ipfw_dyn_uninit(1); /* free the remaining parts */
- return 0;
-}
-
-/*
- * Module event handler.
- * In general we have the choice of handling most of these events by the
- * event handler or by the (VNET_)SYS(UN)INIT handlers. I have chosen to
- * use the SYSINIT handlers as they are more capable of expressing the
- * flow of control during module and vnet operations, so this is just
- * a skeleton. Note there is no SYSINIT equivalent of the module
- * SHUTDOWN handler, but we don't have anything to do in that case anyhow.
- */
-static int
-ipfw_modevent(module_t mod, int type, void *unused)
-{
- int err = 0;
-
- switch (type) {
- case MOD_LOAD:
- /* Called once at module load or
- * system boot if compiled in. */
- break;
- case MOD_QUIESCE:
- /* Called before unload. May veto unloading. */
- break;
- case MOD_UNLOAD:
- /* Called during unload. */
- break;
- case MOD_SHUTDOWN:
- /* Called during system shutdown. */
- break;
- default:
- err = EOPNOTSUPP;
- break;
- }
- return err;
-}
-
-static moduledata_t ipfwmod = {
- "ipfw",
- ipfw_modevent,
- 0
-};
-
-/* Define startup order. */
-#define IPFW_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN
-#define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */
-#define IPFW_MODULE_ORDER (IPFW_MODEVENT_ORDER + 1) /* A little later. */
-#define IPFW_VNET_ORDER (IPFW_MODEVENT_ORDER + 2) /* Later still. */
-
-DECLARE_MODULE(ipfw, ipfwmod, IPFW_SI_SUB_FIREWALL, IPFW_MODEVENT_ORDER);
-MODULE_VERSION(ipfw, 2);
-/* should declare some dependencies here */
-
-/*
- * Starting up. Done in order after ipfwmod() has been called.
- * VNET_SYSINIT is also called for each existing vnet and each new vnet.
- */
-SYSINIT(ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
- ipfw_init, NULL);
-VNET_SYSINIT(vnet_ipfw_init, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
- vnet_ipfw_init, NULL);
-
-/*
- * Closing up shop. These are done in REVERSE ORDER, but still
- * after ipfwmod() has been called. Not called on reboot.
- * VNET_SYSUNINIT is also called for each exiting vnet as it exits.
- * or when the module is unloaded.
- */
-SYSUNINIT(ipfw_destroy, IPFW_SI_SUB_FIREWALL, IPFW_MODULE_ORDER,
- ipfw_destroy, NULL);
-VNET_SYSUNINIT(vnet_ipfw_uninit, IPFW_SI_SUB_FIREWALL, IPFW_VNET_ORDER,
- vnet_ipfw_uninit, NULL);
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_dynamic.c b/sys/netinet/ipfw/ip_fw_dynamic.c
deleted file mode 100644
index 7cff94f..0000000
--- a/sys/netinet/ipfw/ip_fw_dynamic.c
+++ /dev/null
@@ -1,1242 +0,0 @@
-/*-
- * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define DEB(x)
-#define DDB(x) x
-
-/*
- * Dynamic rule support for ipfw
- */
-
-#include "opt_ipfw.h"
-#include "opt_inet.h"
-#ifndef INET
-#error IPFIREWALL requires INET.
-#endif /* INET */
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <net/ethernet.h> /* for ETHERTYPE_IP */
-#include <net/if.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h> /* ip_defttl */
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/tcp_var.h>
-#include <netinet/udp.h>
-
-#include <netinet/ip6.h> /* IN6_ARE_ADDR_EQUAL */
-#ifdef INET6
-#include <netinet6/in6_var.h>
-#include <netinet6/ip6_var.h>
-#endif
-
-#include <machine/in_cksum.h> /* XXX for in_cksum */
-
-#ifdef MAC
-#include <security/mac/mac_framework.h>
-#endif
-
-/*
- * Description of dynamic rules.
- *
- * Dynamic rules are stored in lists accessed through a hash table
- * (ipfw_dyn_v) whose size is curr_dyn_buckets. This value can
- * be modified through the sysctl variable dyn_buckets which is
- * updated when the table becomes empty.
- *
- * XXX currently there is only one list, ipfw_dyn.
- *
- * When a packet is received, its address fields are first masked
- * with the mask defined for the rule, then hashed, then matched
- * against the entries in the corresponding list.
- * Dynamic rules can be used for different purposes:
- * + stateful rules;
- * + enforcing limits on the number of sessions;
- * + in-kernel NAT (not implemented yet)
- *
- * The lifetime of dynamic rules is regulated by dyn_*_lifetime,
- * measured in seconds and depending on the flags.
- *
- * The total number of dynamic rules is stored in dyn_count.
- * The max number of dynamic rules is dyn_max. When we reach
- * the maximum number of rules we do not create anymore. This is
- * done to avoid consuming too much memory, but also too much
- * time when searching on each packet (ideally, we should try instead
- * to put a limit on the length of the list on each bucket...).
- *
- * Each dynamic rule holds a pointer to the parent ipfw rule so
- * we know what action to perform. Dynamic rules are removed when
- * the parent rule is deleted. XXX we should make them survive.
- *
- * There are some limitations with dynamic rules -- we do not
- * obey the 'randomized match', and we do not do multiple
- * passes through the firewall. XXX check the latter!!!
- */
-
-/*
- * Static variables followed by global ones
- */
-static VNET_DEFINE(ipfw_dyn_rule **, ipfw_dyn_v);
-static VNET_DEFINE(u_int32_t, dyn_buckets);
-static VNET_DEFINE(u_int32_t, curr_dyn_buckets);
-static VNET_DEFINE(struct callout, ipfw_timeout);
-#define V_ipfw_dyn_v VNET(ipfw_dyn_v)
-#define V_dyn_buckets VNET(dyn_buckets)
-#define V_curr_dyn_buckets VNET(curr_dyn_buckets)
-#define V_ipfw_timeout VNET(ipfw_timeout)
-
-static uma_zone_t ipfw_dyn_rule_zone;
-#ifndef __FreeBSD__
-DEFINE_SPINLOCK(ipfw_dyn_mtx);
-#else
-static struct mtx ipfw_dyn_mtx; /* mutex guarding dynamic rules */
-#endif
-
-#define IPFW_DYN_LOCK_INIT() \
- mtx_init(&ipfw_dyn_mtx, "IPFW dynamic rules", NULL, MTX_DEF)
-#define IPFW_DYN_LOCK_DESTROY() mtx_destroy(&ipfw_dyn_mtx)
-#define IPFW_DYN_LOCK() mtx_lock(&ipfw_dyn_mtx)
-#define IPFW_DYN_UNLOCK() mtx_unlock(&ipfw_dyn_mtx)
-#define IPFW_DYN_LOCK_ASSERT() mtx_assert(&ipfw_dyn_mtx, MA_OWNED)
-
-void
-ipfw_dyn_unlock(void)
-{
- IPFW_DYN_UNLOCK();
-}
-
-/*
- * Timeouts for various events in handing dynamic rules.
- */
-static VNET_DEFINE(u_int32_t, dyn_ack_lifetime);
-static VNET_DEFINE(u_int32_t, dyn_syn_lifetime);
-static VNET_DEFINE(u_int32_t, dyn_fin_lifetime);
-static VNET_DEFINE(u_int32_t, dyn_rst_lifetime);
-static VNET_DEFINE(u_int32_t, dyn_udp_lifetime);
-static VNET_DEFINE(u_int32_t, dyn_short_lifetime);
-
-#define V_dyn_ack_lifetime VNET(dyn_ack_lifetime)
-#define V_dyn_syn_lifetime VNET(dyn_syn_lifetime)
-#define V_dyn_fin_lifetime VNET(dyn_fin_lifetime)
-#define V_dyn_rst_lifetime VNET(dyn_rst_lifetime)
-#define V_dyn_udp_lifetime VNET(dyn_udp_lifetime)
-#define V_dyn_short_lifetime VNET(dyn_short_lifetime)
-
-/*
- * Keepalives are sent if dyn_keepalive is set. They are sent every
- * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
- * seconds of lifetime of a rule.
- * dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
- * than dyn_keepalive_period.
- */
-
-static VNET_DEFINE(u_int32_t, dyn_keepalive_interval);
-static VNET_DEFINE(u_int32_t, dyn_keepalive_period);
-static VNET_DEFINE(u_int32_t, dyn_keepalive);
-
-#define V_dyn_keepalive_interval VNET(dyn_keepalive_interval)
-#define V_dyn_keepalive_period VNET(dyn_keepalive_period)
-#define V_dyn_keepalive VNET(dyn_keepalive)
-
-static VNET_DEFINE(u_int32_t, dyn_count); /* # of dynamic rules */
-static VNET_DEFINE(u_int32_t, dyn_max); /* max # of dynamic rules */
-
-#define V_dyn_count VNET(dyn_count)
-#define V_dyn_max VNET(dyn_max)
-
-#ifdef SYSCTL_NODE
-
-SYSBEGIN(f2)
-
-SYSCTL_DECL(_net_inet_ip_fw);
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
- CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
- "Number of dyn. buckets");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
- CTLFLAG_RD, &VNET_NAME(curr_dyn_buckets), 0,
- "Current Number of dyn. buckets");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_count,
- CTLFLAG_RD, &VNET_NAME(dyn_count), 0,
- "Number of dyn. rules");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_max,
- CTLFLAG_RW, &VNET_NAME(dyn_max), 0,
- "Max number of dyn. rules");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
- CTLFLAG_RW, &VNET_NAME(dyn_ack_lifetime), 0,
- "Lifetime of dyn. rules for acks");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime,
- CTLFLAG_RW, &VNET_NAME(dyn_syn_lifetime), 0,
- "Lifetime of dyn. rules for syn");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime,
- CTLFLAG_RW, &VNET_NAME(dyn_fin_lifetime), 0,
- "Lifetime of dyn. rules for fin");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime,
- CTLFLAG_RW, &VNET_NAME(dyn_rst_lifetime), 0,
- "Lifetime of dyn. rules for rst");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime,
- CTLFLAG_RW, &VNET_NAME(dyn_udp_lifetime), 0,
- "Lifetime of dyn. rules for UDP");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
- CTLFLAG_RW, &VNET_NAME(dyn_short_lifetime), 0,
- "Lifetime of dyn. rules for other situations");
-SYSCTL_VNET_UINT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive,
- CTLFLAG_RW, &VNET_NAME(dyn_keepalive), 0,
- "Enable keepalives for dyn. rules");
-
-SYSEND
-
-#endif /* SYSCTL_NODE */
-
-
-static __inline int
-hash_packet6(struct ipfw_flow_id *id)
-{
- u_int32_t i;
- i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^
- (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^
- (id->src_ip6.__u6_addr.__u6_addr32[2]) ^
- (id->src_ip6.__u6_addr.__u6_addr32[3]) ^
- (id->dst_port) ^ (id->src_port);
- return i;
-}
-
-/*
- * IMPORTANT: the hash function for dynamic rules must be commutative
- * in source and destination (ip,port), because rules are bidirectional
- * and we want to find both in the same bucket.
- */
-static __inline int
-hash_packet(struct ipfw_flow_id *id)
-{
- u_int32_t i;
-
-#ifdef INET6
- if (IS_IP6_FLOW_ID(id))
- i = hash_packet6(id);
- else
-#endif /* INET6 */
- i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
- i &= (V_curr_dyn_buckets - 1);
- return i;
-}
-
-static __inline void
-unlink_dyn_rule_print(struct ipfw_flow_id *id)
-{
- struct in_addr da;
-#ifdef INET6
- char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
-#else
- char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
-#endif
-
-#ifdef INET6
- if (IS_IP6_FLOW_ID(id)) {
- ip6_sprintf(src, &id->src_ip6);
- ip6_sprintf(dst, &id->dst_ip6);
- } else
-#endif
- {
- da.s_addr = htonl(id->src_ip);
- inet_ntoa_r(da, src);
- da.s_addr = htonl(id->dst_ip);
- inet_ntoa_r(da, dst);
- }
- printf("ipfw: unlink entry %s %d -> %s %d, %d left\n",
- src, id->src_port, dst, id->dst_port, V_dyn_count - 1);
-}
-
-/**
- * unlink a dynamic rule from a chain. prev is a pointer to
- * the previous one, q is a pointer to the rule to delete,
- * head is a pointer to the head of the queue.
- * Modifies q and potentially also head.
- */
-#define UNLINK_DYN_RULE(prev, head, q) { \
- ipfw_dyn_rule *old_q = q; \
- \
- /* remove a refcount to the parent */ \
- if (q->dyn_type == O_LIMIT) \
- q->parent->count--; \
- DEB(unlink_dyn_rule_print(&q->id);) \
- if (prev != NULL) \
- prev->next = q = q->next; \
- else \
- head = q = q->next; \
- V_dyn_count--; \
- uma_zfree(ipfw_dyn_rule_zone, old_q); }
-
-#define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
-
-/**
- * Remove dynamic rules pointing to "rule", or all of them if rule == NULL.
- *
- * If keep_me == NULL, rules are deleted even if not expired,
- * otherwise only expired rules are removed.
- *
- * The value of the second parameter is also used to point to identify
- * a rule we absolutely do not want to remove (e.g. because we are
- * holding a reference to it -- this is the case with O_LIMIT_PARENT
- * rules). The pointer is only used for comparison, so any non-null
- * value will do.
- */
-static void
-remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
-{
- static u_int32_t last_remove = 0;
-
-#define FORCE (keep_me == NULL)
-
- ipfw_dyn_rule *prev, *q;
- int i, pass = 0, max_pass = 0;
-
- IPFW_DYN_LOCK_ASSERT();
-
- if (V_ipfw_dyn_v == NULL || V_dyn_count == 0)
- return;
- /* do not expire more than once per second, it is useless */
- if (!FORCE && last_remove == time_uptime)
- return;
- last_remove = time_uptime;
-
- /*
- * because O_LIMIT refer to parent rules, during the first pass only
- * remove child and mark any pending LIMIT_PARENT, and remove
- * them in a second pass.
- */
-next_pass:
- for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
- for (prev=NULL, q = V_ipfw_dyn_v[i] ; q ; ) {
- /*
- * Logic can become complex here, so we split tests.
- */
- if (q == keep_me)
- goto next;
- if (rule != NULL && rule != q->rule)
- goto next; /* not the one we are looking for */
- if (q->dyn_type == O_LIMIT_PARENT) {
- /*
- * handle parent in the second pass,
- * record we need one.
- */
- max_pass = 1;
- if (pass == 0)
- goto next;
- if (FORCE && q->count != 0 ) {
- /* XXX should not happen! */
- printf("ipfw: OUCH! cannot remove rule,"
- " count %d\n", q->count);
- }
- } else {
- if (!FORCE &&
- !TIME_LEQ( q->expire, time_uptime ))
- goto next;
- }
- if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
- UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
- continue;
- }
-next:
- prev=q;
- q=q->next;
- }
- }
- if (pass++ < max_pass)
- goto next_pass;
-}
-
-void
-ipfw_remove_dyn_children(struct ip_fw *rule)
-{
- IPFW_DYN_LOCK();
- remove_dyn_rule(rule, NULL /* force removal */);
- IPFW_DYN_UNLOCK();
-}
-
-/*
- * Lookup a dynamic rule, locked version.
- */
-static ipfw_dyn_rule *
-lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
- struct tcphdr *tcp)
-{
- /*
- * Stateful ipfw extensions.
- * Lookup into dynamic session queue.
- */
-#define MATCH_REVERSE 0
-#define MATCH_FORWARD 1
-#define MATCH_NONE 2
-#define MATCH_UNKNOWN 3
- int i, dir = MATCH_NONE;
- ipfw_dyn_rule *prev, *q = NULL;
-
- IPFW_DYN_LOCK_ASSERT();
-
- if (V_ipfw_dyn_v == NULL)
- goto done; /* not found */
- i = hash_packet(pkt);
- for (prev = NULL, q = V_ipfw_dyn_v[i]; q != NULL;) {
- if (q->dyn_type == O_LIMIT_PARENT && q->count)
- goto next;
- if (TIME_LEQ(q->expire, time_uptime)) { /* expire entry */
- UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
- continue;
- }
- if (pkt->proto != q->id.proto || q->dyn_type == O_LIMIT_PARENT)
- goto next;
-
- if (IS_IP6_FLOW_ID(pkt)) {
- if (IN6_ARE_ADDR_EQUAL(&pkt->src_ip6, &q->id.src_ip6) &&
- IN6_ARE_ADDR_EQUAL(&pkt->dst_ip6, &q->id.dst_ip6) &&
- pkt->src_port == q->id.src_port &&
- pkt->dst_port == q->id.dst_port) {
- dir = MATCH_FORWARD;
- break;
- }
- if (IN6_ARE_ADDR_EQUAL(&pkt->src_ip6, &q->id.dst_ip6) &&
- IN6_ARE_ADDR_EQUAL(&pkt->dst_ip6, &q->id.src_ip6) &&
- pkt->src_port == q->id.dst_port &&
- pkt->dst_port == q->id.src_port) {
- dir = MATCH_REVERSE;
- break;
- }
- } else {
- if (pkt->src_ip == q->id.src_ip &&
- pkt->dst_ip == q->id.dst_ip &&
- pkt->src_port == q->id.src_port &&
- pkt->dst_port == q->id.dst_port) {
- dir = MATCH_FORWARD;
- break;
- }
- if (pkt->src_ip == q->id.dst_ip &&
- pkt->dst_ip == q->id.src_ip &&
- pkt->src_port == q->id.dst_port &&
- pkt->dst_port == q->id.src_port) {
- dir = MATCH_REVERSE;
- break;
- }
- }
-next:
- prev = q;
- q = q->next;
- }
- if (q == NULL)
- goto done; /* q = NULL, not found */
-
- if (prev != NULL) { /* found and not in front */
- prev->next = q->next;
- q->next = V_ipfw_dyn_v[i];
- V_ipfw_dyn_v[i] = q;
- }
- if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
- uint32_t ack;
- u_char flags = pkt->_flags & (TH_FIN | TH_SYN | TH_RST);
-
-#define BOTH_SYN (TH_SYN | (TH_SYN << 8))
-#define BOTH_FIN (TH_FIN | (TH_FIN << 8))
-#define TCP_FLAGS (TH_FLAGS | (TH_FLAGS << 8))
-#define ACK_FWD 0x10000 /* fwd ack seen */
-#define ACK_REV 0x20000 /* rev ack seen */
-
- q->state |= (dir == MATCH_FORWARD) ? flags : (flags << 8);
- switch (q->state & TCP_FLAGS) {
- case TH_SYN: /* opening */
- q->expire = time_uptime + V_dyn_syn_lifetime;
- break;
-
- case BOTH_SYN: /* move to established */
- case BOTH_SYN | TH_FIN: /* one side tries to close */
- case BOTH_SYN | (TH_FIN << 8):
-#define _SEQ_GE(a,b) ((int)(a) - (int)(b) >= 0)
- if (tcp == NULL)
- break;
-
- ack = ntohl(tcp->th_ack);
- if (dir == MATCH_FORWARD) {
- if (q->ack_fwd == 0 ||
- _SEQ_GE(ack, q->ack_fwd)) {
- q->ack_fwd = ack;
- q->state |= ACK_FWD;
- }
- } else {
- if (q->ack_rev == 0 ||
- _SEQ_GE(ack, q->ack_rev)) {
- q->ack_rev = ack;
- q->state |= ACK_REV;
- }
- }
- if ((q->state & (ACK_FWD | ACK_REV)) ==
- (ACK_FWD | ACK_REV)) {
- q->expire = time_uptime + V_dyn_ack_lifetime;
- q->state &= ~(ACK_FWD | ACK_REV);
- }
- break;
-
- case BOTH_SYN | BOTH_FIN: /* both sides closed */
- if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
- V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
- q->expire = time_uptime + V_dyn_fin_lifetime;
- break;
-
- default:
-#if 0
- /*
- * reset or some invalid combination, but can also
- * occur if we use keep-state the wrong way.
- */
- if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
- printf("invalid state: 0x%x\n", q->state);
-#endif
- if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
- V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
- q->expire = time_uptime + V_dyn_rst_lifetime;
- break;
- }
- } else if (pkt->proto == IPPROTO_UDP) {
- q->expire = time_uptime + V_dyn_udp_lifetime;
- } else {
- /* other protocols */
- q->expire = time_uptime + V_dyn_short_lifetime;
- }
-done:
- if (match_direction != NULL)
- *match_direction = dir;
- return (q);
-}
-
-ipfw_dyn_rule *
-ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt, int *match_direction,
- struct tcphdr *tcp)
-{
- ipfw_dyn_rule *q;
-
- IPFW_DYN_LOCK();
- q = lookup_dyn_rule_locked(pkt, match_direction, tcp);
- if (q == NULL)
- IPFW_DYN_UNLOCK();
- /* NB: return table locked when q is not NULL */
- return q;
-}
-
-static void
-realloc_dynamic_table(void)
-{
- IPFW_DYN_LOCK_ASSERT();
-
- /*
- * Try reallocation, make sure we have a power of 2 and do
- * not allow more than 64k entries. In case of overflow,
- * default to 1024.
- */
-
- if (V_dyn_buckets > 65536)
- V_dyn_buckets = 1024;
- if ((V_dyn_buckets & (V_dyn_buckets-1)) != 0) { /* not a power of 2 */
- V_dyn_buckets = V_curr_dyn_buckets; /* reset */
- return;
- }
- V_curr_dyn_buckets = V_dyn_buckets;
- if (V_ipfw_dyn_v != NULL)
- free(V_ipfw_dyn_v, M_IPFW);
- for (;;) {
- V_ipfw_dyn_v = malloc(V_curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
- M_IPFW, M_NOWAIT | M_ZERO);
- if (V_ipfw_dyn_v != NULL || V_curr_dyn_buckets <= 2)
- break;
- V_curr_dyn_buckets /= 2;
- }
-}
-
-/**
- * Install state of type 'type' for a dynamic session.
- * The hash table contains two type of rules:
- * - regular rules (O_KEEP_STATE)
- * - rules for sessions with limited number of sess per user
- * (O_LIMIT). When they are created, the parent is
- * increased by 1, and decreased on delete. In this case,
- * the third parameter is the parent rule and not the chain.
- * - "parent" rules for the above (O_LIMIT_PARENT).
- */
-static ipfw_dyn_rule *
-add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
-{
- ipfw_dyn_rule *r;
- int i;
-
- IPFW_DYN_LOCK_ASSERT();
-
- if (V_ipfw_dyn_v == NULL ||
- (V_dyn_count == 0 && V_dyn_buckets != V_curr_dyn_buckets)) {
- realloc_dynamic_table();
- if (V_ipfw_dyn_v == NULL)
- return NULL; /* failed ! */
- }
- i = hash_packet(id);
-
- r = uma_zalloc(ipfw_dyn_rule_zone, M_NOWAIT | M_ZERO);
- if (r == NULL) {
- printf ("ipfw: sorry cannot allocate state\n");
- return NULL;
- }
-
- /* increase refcount on parent, and set pointer */
- if (dyn_type == O_LIMIT) {
- ipfw_dyn_rule *parent = (ipfw_dyn_rule *)rule;
- if ( parent->dyn_type != O_LIMIT_PARENT)
- panic("invalid parent");
- parent->count++;
- r->parent = parent;
- rule = parent->rule;
- }
-
- r->id = *id;
- r->expire = time_uptime + V_dyn_syn_lifetime;
- r->rule = rule;
- r->dyn_type = dyn_type;
- r->pcnt = r->bcnt = 0;
- r->count = 0;
-
- r->bucket = i;
- r->next = V_ipfw_dyn_v[i];
- V_ipfw_dyn_v[i] = r;
- V_dyn_count++;
- DEB({
- struct in_addr da;
-#ifdef INET6
- char src[INET6_ADDRSTRLEN];
- char dst[INET6_ADDRSTRLEN];
-#else
- char src[INET_ADDRSTRLEN];
- char dst[INET_ADDRSTRLEN];
-#endif
-
-#ifdef INET6
- if (IS_IP6_FLOW_ID(&(r->id))) {
- ip6_sprintf(src, &r->id.src_ip6);
- ip6_sprintf(dst, &r->id.dst_ip6);
- } else
-#endif
- {
- da.s_addr = htonl(r->id.src_ip);
- inet_ntoa_r(da, src);
- da.s_addr = htonl(r->id.dst_ip);
- inet_ntoa_r(da, dst);
- }
- printf("ipfw: add dyn entry ty %d %s %d -> %s %d, total %d\n",
- dyn_type, src, r->id.src_port, dst, r->id.dst_port,
- V_dyn_count);
- })
- return r;
-}
-
-/**
- * lookup dynamic parent rule using pkt and rule as search keys.
- * If the lookup fails, then install one.
- */
-static ipfw_dyn_rule *
-lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
-{
- ipfw_dyn_rule *q;
- int i;
-
- IPFW_DYN_LOCK_ASSERT();
-
- if (V_ipfw_dyn_v) {
- int is_v6 = IS_IP6_FLOW_ID(pkt);
- i = hash_packet( pkt );
- for (q = V_ipfw_dyn_v[i] ; q != NULL ; q=q->next)
- if (q->dyn_type == O_LIMIT_PARENT &&
- rule== q->rule &&
- pkt->proto == q->id.proto &&
- pkt->src_port == q->id.src_port &&
- pkt->dst_port == q->id.dst_port &&
- (
- (is_v6 &&
- IN6_ARE_ADDR_EQUAL(&(pkt->src_ip6),
- &(q->id.src_ip6)) &&
- IN6_ARE_ADDR_EQUAL(&(pkt->dst_ip6),
- &(q->id.dst_ip6))) ||
- (!is_v6 &&
- pkt->src_ip == q->id.src_ip &&
- pkt->dst_ip == q->id.dst_ip)
- )
- ) {
- q->expire = time_uptime + V_dyn_short_lifetime;
- DEB(printf("ipfw: lookup_dyn_parent found 0x%p\n",q);)
- return q;
- }
- }
- return add_dyn_rule(pkt, O_LIMIT_PARENT, rule);
-}
-
-/**
- * Install dynamic state for rule type cmd->o.opcode
- *
- * Returns 1 (failure) if state is not installed because of errors or because
- * session limitations are enforced.
- */
-int
-ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
- struct ip_fw_args *args, uint32_t tablearg)
-{
- static int last_log;
- ipfw_dyn_rule *q;
- struct in_addr da;
-#ifdef INET6
- char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
-#else
- char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
-#endif
-
- src[0] = '\0';
- dst[0] = '\0';
-
- IPFW_DYN_LOCK();
-
- DEB(
-#ifdef INET6
- if (IS_IP6_FLOW_ID(&(args->f_id))) {
- ip6_sprintf(src, &args->f_id.src_ip6);
- ip6_sprintf(dst, &args->f_id.dst_ip6);
- } else
-#endif
- {
- da.s_addr = htonl(args->f_id.src_ip);
- inet_ntoa_r(da, src);
- da.s_addr = htonl(args->f_id.dst_ip);
- inet_ntoa_r(da, dst);
- }
- printf("ipfw: %s: type %d %s %u -> %s %u\n",
- __func__, cmd->o.opcode, src, args->f_id.src_port,
- dst, args->f_id.dst_port);
- src[0] = '\0';
- dst[0] = '\0';
- )
-
- q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
-
- if (q != NULL) { /* should never occur */
- DEB(
- if (last_log != time_uptime) {
- last_log = time_uptime;
- printf("ipfw: %s: entry already present, done\n",
- __func__);
- })
- IPFW_DYN_UNLOCK();
- return (0);
- }
-
- if (V_dyn_count >= V_dyn_max)
- /* Run out of slots, try to remove any expired rule. */
- remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
-
- if (V_dyn_count >= V_dyn_max) {
- if (last_log != time_uptime) {
- last_log = time_uptime;
- printf("ipfw: %s: Too many dynamic rules\n", __func__);
- }
- IPFW_DYN_UNLOCK();
- return (1); /* cannot install, notify caller */
- }
-
- switch (cmd->o.opcode) {
- case O_KEEP_STATE: /* bidir rule */
- add_dyn_rule(&args->f_id, O_KEEP_STATE, rule);
- break;
-
- case O_LIMIT: { /* limit number of sessions */
- struct ipfw_flow_id id;
- ipfw_dyn_rule *parent;
- uint32_t conn_limit;
- uint16_t limit_mask = cmd->limit_mask;
-
- conn_limit = (cmd->conn_limit == IP_FW_TABLEARG) ?
- tablearg : cmd->conn_limit;
-
- DEB(
- if (cmd->conn_limit == IP_FW_TABLEARG)
- printf("ipfw: %s: O_LIMIT rule, conn_limit: %u "
- "(tablearg)\n", __func__, conn_limit);
- else
- printf("ipfw: %s: O_LIMIT rule, conn_limit: %u\n",
- __func__, conn_limit);
- )
-
- id.dst_ip = id.src_ip = id.dst_port = id.src_port = 0;
- id.proto = args->f_id.proto;
- id.addr_type = args->f_id.addr_type;
- id.fib = M_GETFIB(args->m);
-
- if (IS_IP6_FLOW_ID (&(args->f_id))) {
- if (limit_mask & DYN_SRC_ADDR)
- id.src_ip6 = args->f_id.src_ip6;
- if (limit_mask & DYN_DST_ADDR)
- id.dst_ip6 = args->f_id.dst_ip6;
- } else {
- if (limit_mask & DYN_SRC_ADDR)
- id.src_ip = args->f_id.src_ip;
- if (limit_mask & DYN_DST_ADDR)
- id.dst_ip = args->f_id.dst_ip;
- }
- if (limit_mask & DYN_SRC_PORT)
- id.src_port = args->f_id.src_port;
- if (limit_mask & DYN_DST_PORT)
- id.dst_port = args->f_id.dst_port;
- if ((parent = lookup_dyn_parent(&id, rule)) == NULL) {
- printf("ipfw: %s: add parent failed\n", __func__);
- IPFW_DYN_UNLOCK();
- return (1);
- }
-
- if (parent->count >= conn_limit) {
- /* See if we can remove some expired rule. */
- remove_dyn_rule(rule, parent);
- if (parent->count >= conn_limit) {
- if (V_fw_verbose && last_log != time_uptime) {
- last_log = time_uptime;
-#ifdef INET6
- /*
- * XXX IPv6 flows are not
- * supported yet.
- */
- if (IS_IP6_FLOW_ID(&(args->f_id))) {
- char ip6buf[INET6_ADDRSTRLEN];
- snprintf(src, sizeof(src),
- "[%s]", ip6_sprintf(ip6buf,
- &args->f_id.src_ip6));
- snprintf(dst, sizeof(dst),
- "[%s]", ip6_sprintf(ip6buf,
- &args->f_id.dst_ip6));
- } else
-#endif
- {
- da.s_addr =
- htonl(args->f_id.src_ip);
- inet_ntoa_r(da, src);
- da.s_addr =
- htonl(args->f_id.dst_ip);
- inet_ntoa_r(da, dst);
- }
- log(LOG_SECURITY | LOG_DEBUG,
- "ipfw: %d %s %s:%u -> %s:%u, %s\n",
- parent->rule->rulenum,
- "drop session",
- src, (args->f_id.src_port),
- dst, (args->f_id.dst_port),
- "too many entries");
- }
- IPFW_DYN_UNLOCK();
- return (1);
- }
- }
- add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent);
- break;
- }
- default:
- printf("ipfw: %s: unknown dynamic rule type %u\n",
- __func__, cmd->o.opcode);
- IPFW_DYN_UNLOCK();
- return (1);
- }
-
- /* XXX just set lifetime */
- lookup_dyn_rule_locked(&args->f_id, NULL, NULL);
-
- IPFW_DYN_UNLOCK();
- return (0);
-}
-
-/*
- * Generate a TCP packet, containing either a RST or a keepalive.
- * When flags & TH_RST, we are sending a RST packet, because of a
- * "reset" action matched the packet.
- * Otherwise we are sending a keepalive, and flags & TH_
- * The 'replyto' mbuf is the mbuf being replied to, if any, and is required
- * so that MAC can label the reply appropriately.
- */
-struct mbuf *
-ipfw_send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
- u_int32_t ack, int flags)
-{
- struct mbuf *m = NULL; /* stupid compiler */
- int len, dir;
- struct ip *h = NULL; /* stupid compiler */
-#ifdef INET6
- struct ip6_hdr *h6 = NULL;
-#endif
- struct tcphdr *th = NULL;
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (NULL);
-
- M_SETFIB(m, id->fib);
-#ifdef MAC
- if (replyto != NULL)
- mac_netinet_firewall_reply(replyto, m);
- else
- mac_netinet_firewall_send(m);
-#else
- (void)replyto; /* don't warn about unused arg */
-#endif
-
- switch (id->addr_type) {
- case 4:
- len = sizeof(struct ip) + sizeof(struct tcphdr);
- break;
-#ifdef INET6
- case 6:
- len = sizeof(struct ip6_hdr) + sizeof(struct tcphdr);
- break;
-#endif
- default:
- /* XXX: log me?!? */
- FREE_PKT(m);
- return (NULL);
- }
- dir = ((flags & (TH_SYN | TH_RST)) == TH_SYN);
-
- m->m_data += max_linkhdr;
- m->m_flags |= M_SKIP_FIREWALL;
- m->m_pkthdr.len = m->m_len = len;
- m->m_pkthdr.rcvif = NULL;
- bzero(m->m_data, len);
-
- switch (id->addr_type) {
- case 4:
- h = mtod(m, struct ip *);
-
- /* prepare for checksum */
- h->ip_p = IPPROTO_TCP;
- h->ip_len = htons(sizeof(struct tcphdr));
- if (dir) {
- h->ip_src.s_addr = htonl(id->src_ip);
- h->ip_dst.s_addr = htonl(id->dst_ip);
- } else {
- h->ip_src.s_addr = htonl(id->dst_ip);
- h->ip_dst.s_addr = htonl(id->src_ip);
- }
-
- th = (struct tcphdr *)(h + 1);
- break;
-#ifdef INET6
- case 6:
- h6 = mtod(m, struct ip6_hdr *);
-
- /* prepare for checksum */
- h6->ip6_nxt = IPPROTO_TCP;
- h6->ip6_plen = htons(sizeof(struct tcphdr));
- if (dir) {
- h6->ip6_src = id->src_ip6;
- h6->ip6_dst = id->dst_ip6;
- } else {
- h6->ip6_src = id->dst_ip6;
- h6->ip6_dst = id->src_ip6;
- }
-
- th = (struct tcphdr *)(h6 + 1);
- break;
-#endif
- }
-
- if (dir) {
- th->th_sport = htons(id->src_port);
- th->th_dport = htons(id->dst_port);
- } else {
- th->th_sport = htons(id->dst_port);
- th->th_dport = htons(id->src_port);
- }
- th->th_off = sizeof(struct tcphdr) >> 2;
-
- if (flags & TH_RST) {
- if (flags & TH_ACK) {
- th->th_seq = htonl(ack);
- th->th_flags = TH_RST;
- } else {
- if (flags & TH_SYN)
- seq++;
- th->th_ack = htonl(seq);
- th->th_flags = TH_RST | TH_ACK;
- }
- } else {
- /*
- * Keepalive - use caller provided sequence numbers
- */
- th->th_seq = htonl(seq);
- th->th_ack = htonl(ack);
- th->th_flags = TH_ACK;
- }
-
- switch (id->addr_type) {
- case 4:
- th->th_sum = in_cksum(m, len);
-
- /* finish the ip header */
- h->ip_v = 4;
- h->ip_hl = sizeof(*h) >> 2;
- h->ip_tos = IPTOS_LOWDELAY;
- h->ip_off = 0;
- /* ip_len must be in host format for ip_output */
- h->ip_len = len;
- h->ip_ttl = V_ip_defttl;
- h->ip_sum = 0;
- break;
-#ifdef INET6
- case 6:
- th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6),
- sizeof(struct tcphdr));
-
- /* finish the ip6 header */
- h6->ip6_vfc |= IPV6_VERSION;
- h6->ip6_hlim = IPV6_DEFHLIM;
- break;
-#endif
- }
-
- return (m);
-}
-
-/*
- * This procedure is only used to handle keepalives. It is invoked
- * every dyn_keepalive_period
- */
-static void
-ipfw_tick(void * vnetx)
-{
- struct mbuf *m0, *m, *mnext, **mtailp;
-#ifdef INET6
- struct mbuf *m6, **m6_tailp;
-#endif
- int i;
- ipfw_dyn_rule *q;
-#ifdef VIMAGE
- struct vnet *vp = vnetx;
-#endif
-
- CURVNET_SET(vp);
- if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
- goto done;
-
- /*
- * We make a chain of packets to go out here -- not deferring
- * until after we drop the IPFW dynamic rule lock would result
- * in a lock order reversal with the normal packet input -> ipfw
- * call stack.
- */
- m0 = NULL;
- mtailp = &m0;
-#ifdef INET6
- m6 = NULL;
- m6_tailp = &m6;
-#endif
- IPFW_DYN_LOCK();
- for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
- for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
- if (q->dyn_type == O_LIMIT_PARENT)
- continue;
- if (q->id.proto != IPPROTO_TCP)
- continue;
- if ( (q->state & BOTH_SYN) != BOTH_SYN)
- continue;
- if (TIME_LEQ(time_uptime + V_dyn_keepalive_interval,
- q->expire))
- continue; /* too early */
- if (TIME_LEQ(q->expire, time_uptime))
- continue; /* too late, rule expired */
-
- m = (q->state & ACK_REV) ? NULL :
- ipfw_send_pkt(NULL, &(q->id), q->ack_rev - 1,
- q->ack_fwd, TH_SYN);
- mnext = (q->state & ACK_FWD) ? NULL :
- ipfw_send_pkt(NULL, &(q->id), q->ack_fwd - 1,
- q->ack_rev, 0);
-
- switch (q->id.addr_type) {
- case 4:
- if (m != NULL) {
- *mtailp = m;
- mtailp = &(*mtailp)->m_nextpkt;
- }
- if (mnext != NULL) {
- *mtailp = mnext;
- mtailp = &(*mtailp)->m_nextpkt;
- }
- break;
-#ifdef INET6
- case 6:
- if (m != NULL) {
- *m6_tailp = m;
- m6_tailp = &(*m6_tailp)->m_nextpkt;
- }
- if (mnext != NULL) {
- *m6_tailp = mnext;
- m6_tailp = &(*m6_tailp)->m_nextpkt;
- }
- break;
-#endif
- }
- }
- }
- IPFW_DYN_UNLOCK();
- for (m = m0; m != NULL; m = mnext) {
- mnext = m->m_nextpkt;
- m->m_nextpkt = NULL;
- ip_output(m, NULL, NULL, 0, NULL, NULL);
- }
-#ifdef INET6
- for (m = m6; m != NULL; m = mnext) {
- mnext = m->m_nextpkt;
- m->m_nextpkt = NULL;
- ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL);
- }
-#endif
-done:
- callout_reset_on(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
- ipfw_tick, vnetx, 0);
- CURVNET_RESTORE();
-}
-
-void
-ipfw_dyn_attach(void)
-{
- ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
- sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
- UMA_ALIGN_PTR, 0);
-
- IPFW_DYN_LOCK_INIT();
-}
-
-void
-ipfw_dyn_detach(void)
-{
- uma_zdestroy(ipfw_dyn_rule_zone);
- IPFW_DYN_LOCK_DESTROY();
-}
-
-void
-ipfw_dyn_init(void)
-{
- V_ipfw_dyn_v = NULL;
- V_dyn_buckets = 256; /* must be power of 2 */
- V_curr_dyn_buckets = 256; /* must be power of 2 */
-
- V_dyn_ack_lifetime = 300;
- V_dyn_syn_lifetime = 20;
- V_dyn_fin_lifetime = 1;
- V_dyn_rst_lifetime = 1;
- V_dyn_udp_lifetime = 10;
- V_dyn_short_lifetime = 5;
-
- V_dyn_keepalive_interval = 20;
- V_dyn_keepalive_period = 5;
- V_dyn_keepalive = 1; /* do send keepalives */
-
- V_dyn_max = 4096; /* max # of dynamic rules */
- callout_init(&V_ipfw_timeout, CALLOUT_MPSAFE);
- callout_reset_on(&V_ipfw_timeout, hz, ipfw_tick, curvnet, 0);
-}
-
-void
-ipfw_dyn_uninit(int pass)
-{
- if (pass == 0)
- callout_drain(&V_ipfw_timeout);
- else {
- if (V_ipfw_dyn_v != NULL)
- free(V_ipfw_dyn_v, M_IPFW);
- }
-}
-
-int
-ipfw_dyn_len(void)
-{
- return (V_ipfw_dyn_v == NULL) ? 0 :
- (V_dyn_count * sizeof(ipfw_dyn_rule));
-}
-
-void
-ipfw_get_dynamic(char **pbp, const char *ep)
-{
- ipfw_dyn_rule *p, *last = NULL;
- char *bp;
- int i;
-
- if (V_ipfw_dyn_v == NULL)
- return;
- bp = *pbp;
-
- IPFW_DYN_LOCK();
- for (i = 0 ; i < V_curr_dyn_buckets; i++)
- for (p = V_ipfw_dyn_v[i] ; p != NULL; p = p->next) {
- if (bp + sizeof *p <= ep) {
- ipfw_dyn_rule *dst =
- (ipfw_dyn_rule *)bp;
- bcopy(p, dst, sizeof *p);
- bcopy(&(p->rule->rulenum), &(dst->rule),
- sizeof(p->rule->rulenum));
- /*
- * store set number into high word of
- * dst->rule pointer.
- */
- bcopy(&(p->rule->set),
- (char *)&dst->rule +
- sizeof(p->rule->rulenum),
- sizeof(p->rule->set));
- /*
- * store a non-null value in "next".
- * The userland code will interpret a
- * NULL here as a marker
- * for the last dynamic rule.
- */
- bcopy(&dst, &dst->next, sizeof(dst));
- last = dst;
- dst->expire =
- TIME_LEQ(dst->expire, time_uptime) ?
- 0 : dst->expire - time_uptime ;
- bp += sizeof(ipfw_dyn_rule);
- }
- }
- IPFW_DYN_UNLOCK();
- if (last != NULL) /* mark last dynamic rule */
- bzero(&last->next, sizeof(last));
- *pbp = bp;
-}
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_log.c b/sys/netinet/ipfw/ip_fw_log.c
deleted file mode 100644
index b9ed6b3..0000000
--- a/sys/netinet/ipfw/ip_fw_log.c
+++ /dev/null
@@ -1,469 +0,0 @@
-/*-
- * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Logging support for ipfw
- */
-
-#include "opt_ipfw.h"
-#include "opt_inet.h"
-#ifndef INET
-#error IPFIREWALL requires INET.
-#endif /* INET */
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/kernel.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <net/ethernet.h> /* for ETHERTYPE_IP */
-#include <net/if.h>
-#include <net/vnet.h>
-#include <net/if_types.h> /* for IFT_ETHER */
-#include <net/bpf.h> /* for BPF */
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/tcp_var.h>
-#include <netinet/udp.h>
-
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#ifdef INET6
-#include <netinet6/in6_var.h> /* ip6_sprintf() */
-#endif
-
-#ifdef MAC
-#include <security/mac/mac_framework.h>
-#endif
-
-/*
- * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
- * Other macros just cast void * into the appropriate type
- */
-#define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
-#define TCP(p) ((struct tcphdr *)(p))
-#define SCTP(p) ((struct sctphdr *)(p))
-#define UDP(p) ((struct udphdr *)(p))
-#define ICMP(p) ((struct icmphdr *)(p))
-#define ICMP6(p) ((struct icmp6_hdr *)(p))
-
-#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
-#define SNP(buf) buf, sizeof(buf)
-
-#ifdef WITHOUT_BPF
-void
-ipfw_log_bpf(int onoff)
-{
-}
-#else /* !WITHOUT_BPF */
-static struct ifnet *log_if; /* hook to attach to bpf */
-
-/* we use this dummy function for all ifnet callbacks */
-static int
-log_dummy(struct ifnet *ifp, u_long cmd, caddr_t addr)
-{
- return EINVAL;
-}
-
-static int
-ipfw_log_output(struct ifnet *ifp, struct mbuf *m,
- struct sockaddr *dst, struct route *ro)
-{
- if (m != NULL)
- m_freem(m);
- return EINVAL;
-}
-
-static void
-ipfw_log_start(struct ifnet* ifp)
-{
- panic("ipfw_log_start() must not be called");
-}
-
-static const u_char ipfwbroadcastaddr[6] =
- { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-void
-ipfw_log_bpf(int onoff)
-{
- struct ifnet *ifp;
-
- if (onoff) {
- if (log_if)
- return;
- ifp = if_alloc(IFT_ETHER);
- if (ifp == NULL)
- return;
- if_initname(ifp, "ipfw", 0);
- ifp->if_mtu = 65536;
- ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
- ifp->if_init = (void *)log_dummy;
- ifp->if_ioctl = log_dummy;
- ifp->if_start = ipfw_log_start;
- ifp->if_output = ipfw_log_output;
- ifp->if_addrlen = 6;
- ifp->if_hdrlen = 14;
- if_attach(ifp);
- ifp->if_broadcastaddr = ipfwbroadcastaddr;
- ifp->if_baudrate = IF_Mbps(10);
- bpfattach(ifp, DLT_EN10MB, 14);
- log_if = ifp;
- } else {
- if (log_if) {
- ether_ifdetach(log_if);
- if_free(log_if);
- }
- log_if = NULL;
- }
-}
-#endif /* !WITHOUT_BPF */
-
-/*
- * We enter here when we have a rule with O_LOG.
- * XXX this function alone takes about 2Kbytes of code!
- */
-void
-ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
- struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
- struct ip *ip)
-{
- char *action;
- int limit_reached = 0;
- char action2[92], proto[128], fragment[32];
-
- if (V_fw_verbose == 0) {
-#ifndef WITHOUT_BPF
-
- if (log_if == NULL || log_if->if_bpf == NULL)
- return;
-
- if (args->eh) /* layer2, use orig hdr */
- BPF_MTAP2(log_if, args->eh, ETHER_HDR_LEN, m);
- else
- /* Add fake header. Later we will store
- * more info in the header.
- */
- BPF_MTAP2(log_if, "DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, m);
-#endif /* !WITHOUT_BPF */
- return;
- }
- /* the old 'log' function */
- fragment[0] = '\0';
- proto[0] = '\0';
-
- if (f == NULL) { /* bogus pkt */
- if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
- return;
- V_norule_counter++;
- if (V_norule_counter == V_verbose_limit)
- limit_reached = V_verbose_limit;
- action = "Refuse";
- } else { /* O_LOG is the first action, find the real one */
- ipfw_insn *cmd = ACTION_PTR(f);
- ipfw_insn_log *l = (ipfw_insn_log *)cmd;
-
- if (l->max_log != 0 && l->log_left == 0)
- return;
- l->log_left--;
- if (l->log_left == 0)
- limit_reached = l->max_log;
- cmd += F_LEN(cmd); /* point to first action */
- if (cmd->opcode == O_ALTQ) {
- ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd;
-
- snprintf(SNPARGS(action2, 0), "Altq %d",
- altq->qid);
- cmd += F_LEN(cmd);
- }
- if (cmd->opcode == O_PROB)
- cmd += F_LEN(cmd);
-
- if (cmd->opcode == O_TAG)
- cmd += F_LEN(cmd);
-
- action = action2;
- switch (cmd->opcode) {
- case O_DENY:
- action = "Deny";
- break;
-
- case O_REJECT:
- if (cmd->arg1==ICMP_REJECT_RST)
- action = "Reset";
- else if (cmd->arg1==ICMP_UNREACH_HOST)
- action = "Reject";
- else
- snprintf(SNPARGS(action2, 0), "Unreach %d",
- cmd->arg1);
- break;
-
- case O_UNREACH6:
- if (cmd->arg1==ICMP6_UNREACH_RST)
- action = "Reset";
- else
- snprintf(SNPARGS(action2, 0), "Unreach %d",
- cmd->arg1);
- break;
-
- case O_ACCEPT:
- action = "Accept";
- break;
- case O_COUNT:
- action = "Count";
- break;
- case O_DIVERT:
- snprintf(SNPARGS(action2, 0), "Divert %d",
- cmd->arg1);
- break;
- case O_TEE:
- snprintf(SNPARGS(action2, 0), "Tee %d",
- cmd->arg1);
- break;
- case O_SETFIB:
- snprintf(SNPARGS(action2, 0), "SetFib %d",
- cmd->arg1);
- break;
- case O_SKIPTO:
- snprintf(SNPARGS(action2, 0), "SkipTo %d",
- cmd->arg1);
- break;
- case O_PIPE:
- snprintf(SNPARGS(action2, 0), "Pipe %d",
- cmd->arg1);
- break;
- case O_QUEUE:
- snprintf(SNPARGS(action2, 0), "Queue %d",
- cmd->arg1);
- break;
- case O_FORWARD_IP: {
- ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
- int len;
- struct in_addr dummyaddr;
- if (sa->sa.sin_addr.s_addr == INADDR_ANY)
- dummyaddr.s_addr = htonl(tablearg);
- else
- dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
-
- len = snprintf(SNPARGS(action2, 0), "Forward to %s",
- inet_ntoa(dummyaddr));
-
- if (sa->sa.sin_port)
- snprintf(SNPARGS(action2, len), ":%d",
- sa->sa.sin_port);
- }
- break;
-#ifdef INET6
- case O_FORWARD_IP6: {
- char buf[INET6_ADDRSTRLEN];
- ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd;
- int len;
-
- len = snprintf(SNPARGS(action2, 0), "Forward to [%s]",
- ip6_sprintf(buf, &sa->sa.sin6_addr));
-
- if (sa->sa.sin6_port)
- snprintf(SNPARGS(action2, len), ":%u",
- sa->sa.sin6_port);
- }
- break;
-#endif
- case O_NETGRAPH:
- snprintf(SNPARGS(action2, 0), "Netgraph %d",
- cmd->arg1);
- break;
- case O_NGTEE:
- snprintf(SNPARGS(action2, 0), "Ngtee %d",
- cmd->arg1);
- break;
- case O_NAT:
- action = "Nat";
- break;
- case O_REASS:
- action = "Reass";
- break;
- case O_CALLRETURN:
- if (cmd->len & F_NOT)
- action = "Return";
- else
- snprintf(SNPARGS(action2, 0), "Call %d",
- cmd->arg1);
- break;
- default:
- action = "UNKNOWN";
- break;
- }
- }
-
- if (hlen == 0) { /* non-ip */
- snprintf(SNPARGS(proto, 0), "MAC");
-
- } else {
- int len;
-#ifdef INET6
- char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2];
-#else
- char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN];
-#endif
- struct icmphdr *icmp;
- struct tcphdr *tcp;
- struct udphdr *udp;
-#ifdef INET6
- struct ip6_hdr *ip6 = NULL;
- struct icmp6_hdr *icmp6;
- u_short ip6f_mf;
-#endif
- src[0] = '\0';
- dst[0] = '\0';
-#ifdef INET6
- ip6f_mf = offset & IP6F_MORE_FRAG;
- offset &= IP6F_OFF_MASK;
-
- if (IS_IP6_FLOW_ID(&(args->f_id))) {
- char ip6buf[INET6_ADDRSTRLEN];
- snprintf(src, sizeof(src), "[%s]",
- ip6_sprintf(ip6buf, &args->f_id.src_ip6));
- snprintf(dst, sizeof(dst), "[%s]",
- ip6_sprintf(ip6buf, &args->f_id.dst_ip6));
-
- ip6 = (struct ip6_hdr *)ip;
- tcp = (struct tcphdr *)(((char *)ip) + hlen);
- udp = (struct udphdr *)(((char *)ip) + hlen);
- } else
-#endif
- {
- tcp = L3HDR(struct tcphdr, ip);
- udp = L3HDR(struct udphdr, ip);
-
- inet_ntoa_r(ip->ip_src, src);
- inet_ntoa_r(ip->ip_dst, dst);
- }
-
- switch (args->f_id.proto) {
- case IPPROTO_TCP:
- len = snprintf(SNPARGS(proto, 0), "TCP %s", src);
- if (offset == 0)
- snprintf(SNPARGS(proto, len), ":%d %s:%d",
- ntohs(tcp->th_sport),
- dst,
- ntohs(tcp->th_dport));
- else
- snprintf(SNPARGS(proto, len), " %s", dst);
- break;
-
- case IPPROTO_UDP:
- len = snprintf(SNPARGS(proto, 0), "UDP %s", src);
- if (offset == 0)
- snprintf(SNPARGS(proto, len), ":%d %s:%d",
- ntohs(udp->uh_sport),
- dst,
- ntohs(udp->uh_dport));
- else
- snprintf(SNPARGS(proto, len), " %s", dst);
- break;
-
- case IPPROTO_ICMP:
- icmp = L3HDR(struct icmphdr, ip);
- if (offset == 0)
- len = snprintf(SNPARGS(proto, 0),
- "ICMP:%u.%u ",
- icmp->icmp_type, icmp->icmp_code);
- else
- len = snprintf(SNPARGS(proto, 0), "ICMP ");
- len += snprintf(SNPARGS(proto, len), "%s", src);
- snprintf(SNPARGS(proto, len), " %s", dst);
- break;
-#ifdef INET6
- case IPPROTO_ICMPV6:
- icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen);
- if (offset == 0)
- len = snprintf(SNPARGS(proto, 0),
- "ICMPv6:%u.%u ",
- icmp6->icmp6_type, icmp6->icmp6_code);
- else
- len = snprintf(SNPARGS(proto, 0), "ICMPv6 ");
- len += snprintf(SNPARGS(proto, len), "%s", src);
- snprintf(SNPARGS(proto, len), " %s", dst);
- break;
-#endif
- default:
- len = snprintf(SNPARGS(proto, 0), "P:%d %s",
- args->f_id.proto, src);
- snprintf(SNPARGS(proto, len), " %s", dst);
- break;
- }
-
-#ifdef INET6
- if (IS_IP6_FLOW_ID(&(args->f_id))) {
- if (offset & (IP6F_OFF_MASK | IP6F_MORE_FRAG))
- snprintf(SNPARGS(fragment, 0),
- " (frag %08x:%d@%d%s)",
- args->f_id.extra,
- ntohs(ip6->ip6_plen) - hlen,
- ntohs(offset) << 3, ip6f_mf ? "+" : "");
- } else
-#endif
- {
- int ipoff, iplen;
- ipoff = ntohs(ip->ip_off);
- iplen = ntohs(ip->ip_len);
- if (ipoff & (IP_MF | IP_OFFMASK))
- snprintf(SNPARGS(fragment, 0),
- " (frag %d:%d@%d%s)",
- ntohs(ip->ip_id), iplen - (ip->ip_hl << 2),
- offset << 3,
- (ipoff & IP_MF) ? "+" : "");
- }
- }
-#ifdef __FreeBSD__
- if (oif || m->m_pkthdr.rcvif)
- log(LOG_SECURITY | LOG_INFO,
- "ipfw: %d %s %s %s via %s%s\n",
- f ? f->rulenum : -1,
- action, proto, oif ? "out" : "in",
- oif ? oif->if_xname : m->m_pkthdr.rcvif->if_xname,
- fragment);
- else
-#endif
- log(LOG_SECURITY | LOG_INFO,
- "ipfw: %d %s %s [no if info]%s\n",
- f ? f->rulenum : -1,
- action, proto, fragment);
- if (limit_reached)
- log(LOG_SECURITY | LOG_NOTICE,
- "ipfw: limit %d reached on entry %d\n",
- limit_reached, f ? f->rulenum : -1);
-}
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_nat.c b/sys/netinet/ipfw/ip_fw_nat.c
deleted file mode 100644
index dbeb254..0000000
--- a/sys/netinet/ipfw/ip_fw_nat.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*-
- * Copyright (c) 2008 Paolo Pisati
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/eventhandler.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/module.h>
-#include <sys/rwlock.h>
-
-#define IPFW_INTERNAL /* Access to protected data structures in ip_fw.h. */
-
-#include <netinet/libalias/alias.h>
-#include <netinet/libalias/alias_local.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netinet/tcp.h>
-#include <netinet/udp.h>
-
-#include <machine/in_cksum.h> /* XXX for in_cksum */
-
-static VNET_DEFINE(eventhandler_tag, ifaddr_event_tag);
-#define V_ifaddr_event_tag VNET(ifaddr_event_tag)
-
-static void
-ifaddr_change(void *arg __unused, struct ifnet *ifp)
-{
- struct cfg_nat *ptr;
- struct ifaddr *ifa;
- struct ip_fw_chain *chain;
-
- chain = &V_layer3_chain;
- IPFW_WLOCK(chain);
- /* Check every nat entry... */
- LIST_FOREACH(ptr, &chain->nat, _next) {
- /* ...using nic 'ifp->if_xname' as dynamic alias address. */
- if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) != 0)
- continue;
- if_addr_rlock(ifp);
- TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
- if (ifa->ifa_addr == NULL)
- continue;
- if (ifa->ifa_addr->sa_family != AF_INET)
- continue;
- ptr->ip = ((struct sockaddr_in *)
- (ifa->ifa_addr))->sin_addr;
- LibAliasSetAddress(ptr->lib, ptr->ip);
- }
- if_addr_runlock(ifp);
- }
- IPFW_WUNLOCK(chain);
-}
-
-/*
- * delete the pointers for nat entry ix, or all of them if ix < 0
- */
-static void
-flush_nat_ptrs(struct ip_fw_chain *chain, const int ix)
-{
- int i;
- ipfw_insn_nat *cmd;
-
- IPFW_WLOCK_ASSERT(chain);
- for (i = 0; i < chain->n_rules; i++) {
- cmd = (ipfw_insn_nat *)ACTION_PTR(chain->map[i]);
- /* XXX skip log and the like ? */
- if (cmd->o.opcode == O_NAT && cmd->nat != NULL &&
- (ix < 0 || cmd->nat->id == ix))
- cmd->nat = NULL;
- }
-}
-
-static void
-del_redir_spool_cfg(struct cfg_nat *n, struct redir_chain *head)
-{
- struct cfg_redir *r, *tmp_r;
- struct cfg_spool *s, *tmp_s;
- int i, num;
-
- LIST_FOREACH_SAFE(r, head, _next, tmp_r) {
- num = 1; /* Number of alias_link to delete. */
- switch (r->mode) {
- case REDIR_PORT:
- num = r->pport_cnt;
- /* FALLTHROUGH */
- case REDIR_ADDR:
- case REDIR_PROTO:
- /* Delete all libalias redirect entry. */
- for (i = 0; i < num; i++)
- LibAliasRedirectDelete(n->lib, r->alink[i]);
- /* Del spool cfg if any. */
- LIST_FOREACH_SAFE(s, &r->spool_chain, _next, tmp_s) {
- LIST_REMOVE(s, _next);
- free(s, M_IPFW);
- }
- free(r->alink, M_IPFW);
- LIST_REMOVE(r, _next);
- free(r, M_IPFW);
- break;
- default:
- printf("unknown redirect mode: %u\n", r->mode);
- /* XXX - panic?!?!? */
- break;
- }
- }
-}
-
-static void
-add_redir_spool_cfg(char *buf, struct cfg_nat *ptr)
-{
- struct cfg_redir *r, *ser_r;
- struct cfg_spool *s, *ser_s;
- int cnt, off, i;
-
- for (cnt = 0, off = 0; cnt < ptr->redir_cnt; cnt++) {
- ser_r = (struct cfg_redir *)&buf[off];
- r = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO);
- memcpy(r, ser_r, SOF_REDIR);
- LIST_INIT(&r->spool_chain);
- off += SOF_REDIR;
- r->alink = malloc(sizeof(struct alias_link *) * r->pport_cnt,
- M_IPFW, M_WAITOK | M_ZERO);
- switch (r->mode) {
- case REDIR_ADDR:
- r->alink[0] = LibAliasRedirectAddr(ptr->lib, r->laddr,
- r->paddr);
- break;
- case REDIR_PORT:
- for (i = 0 ; i < r->pport_cnt; i++) {
- /* If remotePort is all ports, set it to 0. */
- u_short remotePortCopy = r->rport + i;
- if (r->rport_cnt == 1 && r->rport == 0)
- remotePortCopy = 0;
- r->alink[i] = LibAliasRedirectPort(ptr->lib,
- r->laddr, htons(r->lport + i), r->raddr,
- htons(remotePortCopy), r->paddr,
- htons(r->pport + i), r->proto);
- if (r->alink[i] == NULL) {
- r->alink[0] = NULL;
- break;
- }
- }
- break;
- case REDIR_PROTO:
- r->alink[0] = LibAliasRedirectProto(ptr->lib ,r->laddr,
- r->raddr, r->paddr, r->proto);
- break;
- default:
- printf("unknown redirect mode: %u\n", r->mode);
- break;
- }
- /* XXX perhaps return an error instead of panic ? */
- if (r->alink[0] == NULL)
- panic("LibAliasRedirect* returned NULL");
- /* LSNAT handling. */
- for (i = 0; i < r->spool_cnt; i++) {
- ser_s = (struct cfg_spool *)&buf[off];
- s = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO);
- memcpy(s, ser_s, SOF_SPOOL);
- LibAliasAddServer(ptr->lib, r->alink[0],
- s->addr, htons(s->port));
- off += SOF_SPOOL;
- /* Hook spool entry. */
- LIST_INSERT_HEAD(&r->spool_chain, s, _next);
- }
- /* And finally hook this redir entry. */
- LIST_INSERT_HEAD(&ptr->redir_chain, r, _next);
- }
-}
-
-static int
-ipfw_nat(struct ip_fw_args *args, struct cfg_nat *t, struct mbuf *m)
-{
- struct mbuf *mcl;
- struct ip *ip;
- /* XXX - libalias duct tape */
- int ldt, retval, found;
- struct ip_fw_chain *chain;
- char *c;
-
- ldt = 0;
- retval = 0;
- mcl = m_megapullup(m, m->m_pkthdr.len);
- if (mcl == NULL) {
- args->m = NULL;
- return (IP_FW_DENY);
- }
- ip = mtod(mcl, struct ip *);
-
- /*
- * XXX - Libalias checksum offload 'duct tape':
- *
- * locally generated packets have only pseudo-header checksum
- * calculated and libalias will break it[1], so mark them for
- * later fix. Moreover there are cases when libalias modifies
- * tcp packet data[2], mark them for later fix too.
- *
- * [1] libalias was never meant to run in kernel, so it does
- * not have any knowledge about checksum offloading, and
- * expects a packet with a full internet checksum.
- * Unfortunately, packets generated locally will have just the
- * pseudo header calculated, and when libalias tries to adjust
- * the checksum it will actually compute a wrong value.
- *
- * [2] when libalias modifies tcp's data content, full TCP
- * checksum has to be recomputed: the problem is that
- * libalias does not have any idea about checksum offloading.
- * To work around this, we do not do checksumming in LibAlias,
- * but only mark the packets in th_x2 field. If we receive a
- * marked packet, we calculate correct checksum for it
- * aware of offloading. Why such a terrible hack instead of
- * recalculating checksum for each packet?
- * Because the previous checksum was not checked!
- * Recalculating checksums for EVERY packet will hide ALL
- * transmission errors. Yes, marked packets still suffer from
- * this problem. But, sigh, natd(8) has this problem, too.
- *
- * TODO: -make libalias mbuf aware (so
- * it can handle delayed checksum and tso)
- */
-
- if (mcl->m_pkthdr.rcvif == NULL &&
- mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
- ldt = 1;
-
- c = mtod(mcl, char *);
-
- /* Check if this is 'global' instance */
- if (t == NULL) {
- if (args->oif == NULL) {
- /* Wrong direction, skip processing */
- args->m = mcl;
- return (IP_FW_NAT);
- }
-
- found = 0;
- chain = &V_layer3_chain;
- IPFW_RLOCK(chain);
- /* Check every nat entry... */
- LIST_FOREACH(t, &chain->nat, _next) {
- if ((t->mode & PKT_ALIAS_SKIP_GLOBAL) != 0)
- continue;
- retval = LibAliasOutTry(t->lib, c,
- mcl->m_len + M_TRAILINGSPACE(mcl), 0);
- if (retval == PKT_ALIAS_OK) {
- /* Nat instance recognises state */
- found = 1;
- break;
- }
- }
- IPFW_RUNLOCK(chain);
- if (found != 1) {
- /* No instance found, return ignore */
- args->m = mcl;
- return (IP_FW_NAT);
- }
- } else {
- if (args->oif == NULL)
- retval = LibAliasIn(t->lib, c,
- mcl->m_len + M_TRAILINGSPACE(mcl));
- else
- retval = LibAliasOut(t->lib, c,
- mcl->m_len + M_TRAILINGSPACE(mcl));
- }
-
- /*
- * We drop packet when:
- * 1. libalias returns PKT_ALIAS_ERROR;
- * 2. For incoming packets:
- * a) for unresolved fragments;
- * b) libalias returns PKT_ALIAS_IGNORED and
- * PKT_ALIAS_DENY_INCOMING flag is set.
- */
- if (retval == PKT_ALIAS_ERROR ||
- (args->oif == NULL && (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT ||
- (retval == PKT_ALIAS_IGNORED &&
- (t->mode & PKT_ALIAS_DENY_INCOMING) != 0)))) {
- /* XXX - should i add some logging? */
- m_free(mcl);
- args->m = NULL;
- return (IP_FW_DENY);
- }
-
- if (retval == PKT_ALIAS_RESPOND)
- mcl->m_flags |= M_SKIP_FIREWALL;
- mcl->m_pkthdr.len = mcl->m_len = ntohs(ip->ip_len);
-
- /*
- * XXX - libalias checksum offload
- * 'duct tape' (see above)
- */
-
- if ((ip->ip_off & htons(IP_OFFMASK)) == 0 &&
- ip->ip_p == IPPROTO_TCP) {
- struct tcphdr *th;
-
- th = (struct tcphdr *)(ip + 1);
- if (th->th_x2)
- ldt = 1;
- }
-
- if (ldt) {
- struct tcphdr *th;
- struct udphdr *uh;
- u_short cksum;
-
- ip->ip_len = ntohs(ip->ip_len);
- cksum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
- htons(ip->ip_p + ip->ip_len - (ip->ip_hl << 2)));
-
- switch (ip->ip_p) {
- case IPPROTO_TCP:
- th = (struct tcphdr *)(ip + 1);
- /*
- * Maybe it was set in
- * libalias...
- */
- th->th_x2 = 0;
- th->th_sum = cksum;
- mcl->m_pkthdr.csum_data =
- offsetof(struct tcphdr, th_sum);
- break;
- case IPPROTO_UDP:
- uh = (struct udphdr *)(ip + 1);
- uh->uh_sum = cksum;
- mcl->m_pkthdr.csum_data =
- offsetof(struct udphdr, uh_sum);
- break;
- }
- /* No hw checksum offloading: do it ourselves */
- if ((mcl->m_pkthdr.csum_flags & CSUM_DELAY_DATA) == 0) {
- in_delayed_cksum(mcl);
- mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
- }
- ip->ip_len = htons(ip->ip_len);
- }
- args->m = mcl;
- return (IP_FW_NAT);
-}
-
-static struct cfg_nat *
-lookup_nat(struct nat_list *l, int nat_id)
-{
- struct cfg_nat *res;
-
- LIST_FOREACH(res, l, _next) {
- if (res->id == nat_id)
- break;
- }
- return res;
-}
-
-static int
-ipfw_nat_cfg(struct sockopt *sopt)
-{
- struct cfg_nat *cfg, *ptr;
- char *buf;
- struct ip_fw_chain *chain = &V_layer3_chain;
- size_t len;
- int gencnt, error = 0;
-
- len = sopt->sopt_valsize;
- buf = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
- if ((error = sooptcopyin(sopt, buf, len, sizeof(struct cfg_nat))) != 0)
- goto out;
-
- cfg = (struct cfg_nat *)buf;
- if (cfg->id < 0) {
- error = EINVAL;
- goto out;
- }
-
- /*
- * Find/create nat rule.
- */
- IPFW_WLOCK(chain);
- gencnt = chain->gencnt;
- ptr = lookup_nat(&chain->nat, cfg->id);
- if (ptr == NULL) {
- IPFW_WUNLOCK(chain);
- /* New rule: allocate and init new instance. */
- ptr = malloc(sizeof(struct cfg_nat), M_IPFW, M_WAITOK | M_ZERO);
- ptr->lib = LibAliasInit(NULL);
- LIST_INIT(&ptr->redir_chain);
- } else {
- /* Entry already present: temporarily unhook it. */
- LIST_REMOVE(ptr, _next);
- flush_nat_ptrs(chain, cfg->id);
- IPFW_WUNLOCK(chain);
- }
-
- /*
- * Basic nat configuration.
- */
- ptr->id = cfg->id;
- /*
- * XXX - what if this rule doesn't nat any ip and just
- * redirect?
- * do we set aliasaddress to 0.0.0.0?
- */
- ptr->ip = cfg->ip;
- ptr->redir_cnt = cfg->redir_cnt;
- ptr->mode = cfg->mode;
- LibAliasSetMode(ptr->lib, cfg->mode, cfg->mode);
- LibAliasSetAddress(ptr->lib, ptr->ip);
- memcpy(ptr->if_name, cfg->if_name, IF_NAMESIZE);
-
- /*
- * Redir and LSNAT configuration.
- */
- /* Delete old cfgs. */
- del_redir_spool_cfg(ptr, &ptr->redir_chain);
- /* Add new entries. */
- add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))], ptr);
-
- IPFW_WLOCK(chain);
- /* Extra check to avoid race with another ipfw_nat_cfg() */
- if (gencnt != chain->gencnt &&
- ((cfg = lookup_nat(&chain->nat, ptr->id)) != NULL))
- LIST_REMOVE(cfg, _next);
- LIST_INSERT_HEAD(&chain->nat, ptr, _next);
- chain->gencnt++;
- IPFW_WUNLOCK(chain);
-
-out:
- free(buf, M_TEMP);
- return (error);
-}
-
-static int
-ipfw_nat_del(struct sockopt *sopt)
-{
- struct cfg_nat *ptr;
- struct ip_fw_chain *chain = &V_layer3_chain;
- int i;
-
- sooptcopyin(sopt, &i, sizeof i, sizeof i);
- /* XXX validate i */
- IPFW_WLOCK(chain);
- ptr = lookup_nat(&chain->nat, i);
- if (ptr == NULL) {
- IPFW_WUNLOCK(chain);
- return (EINVAL);
- }
- LIST_REMOVE(ptr, _next);
- flush_nat_ptrs(chain, i);
- IPFW_WUNLOCK(chain);
- del_redir_spool_cfg(ptr, &ptr->redir_chain);
- LibAliasUninit(ptr->lib);
- free(ptr, M_IPFW);
- return (0);
-}
-
-static int
-ipfw_nat_get_cfg(struct sockopt *sopt)
-{
- struct ip_fw_chain *chain = &V_layer3_chain;
- struct cfg_nat *n;
- struct cfg_redir *r;
- struct cfg_spool *s;
- char *data;
- int gencnt, nat_cnt, len, error;
-
- nat_cnt = 0;
- len = sizeof(nat_cnt);
-
- IPFW_RLOCK(chain);
-retry:
- gencnt = chain->gencnt;
- /* Estimate memory amount */
- LIST_FOREACH(n, &chain->nat, _next) {
- nat_cnt++;
- len += sizeof(struct cfg_nat);
- LIST_FOREACH(r, &n->redir_chain, _next) {
- len += sizeof(struct cfg_redir);
- LIST_FOREACH(s, &r->spool_chain, _next)
- len += sizeof(struct cfg_spool);
- }
- }
- IPFW_RUNLOCK(chain);
-
- data = malloc(len, M_TEMP, M_WAITOK | M_ZERO);
- bcopy(&nat_cnt, data, sizeof(nat_cnt));
-
- nat_cnt = 0;
- len = sizeof(nat_cnt);
-
- IPFW_RLOCK(chain);
- if (gencnt != chain->gencnt) {
- free(data, M_TEMP);
- goto retry;
- }
- /* Serialize all the data. */
- LIST_FOREACH(n, &chain->nat, _next) {
- bcopy(n, &data[len], sizeof(struct cfg_nat));
- len += sizeof(struct cfg_nat);
- LIST_FOREACH(r, &n->redir_chain, _next) {
- bcopy(r, &data[len], sizeof(struct cfg_redir));
- len += sizeof(struct cfg_redir);
- LIST_FOREACH(s, &r->spool_chain, _next) {
- bcopy(s, &data[len], sizeof(struct cfg_spool));
- len += sizeof(struct cfg_spool);
- }
- }
- }
- IPFW_RUNLOCK(chain);
-
- error = sooptcopyout(sopt, data, len);
- free(data, M_TEMP);
-
- return (error);
-}
-
-static int
-ipfw_nat_get_log(struct sockopt *sopt)
-{
- uint8_t *data;
- struct cfg_nat *ptr;
- int i, size;
- struct ip_fw_chain *chain;
-
- chain = &V_layer3_chain;
-
- IPFW_RLOCK(chain);
- /* one pass to count, one to copy the data */
- i = 0;
- LIST_FOREACH(ptr, &chain->nat, _next) {
- if (ptr->lib->logDesc == NULL)
- continue;
- i++;
- }
- size = i * (LIBALIAS_BUF_SIZE + sizeof(int));
- data = malloc(size, M_IPFW, M_NOWAIT | M_ZERO);
- if (data == NULL) {
- IPFW_RUNLOCK(chain);
- return (ENOSPC);
- }
- i = 0;
- LIST_FOREACH(ptr, &chain->nat, _next) {
- if (ptr->lib->logDesc == NULL)
- continue;
- bcopy(&ptr->id, &data[i], sizeof(int));
- i += sizeof(int);
- bcopy(ptr->lib->logDesc, &data[i], LIBALIAS_BUF_SIZE);
- i += LIBALIAS_BUF_SIZE;
- }
- IPFW_RUNLOCK(chain);
- sooptcopyout(sopt, data, size);
- free(data, M_IPFW);
- return(0);
-}
-
-static void
-ipfw_nat_init(void)
-{
-
- IPFW_WLOCK(&V_layer3_chain);
- /* init ipfw hooks */
- ipfw_nat_ptr = ipfw_nat;
- lookup_nat_ptr = lookup_nat;
- ipfw_nat_cfg_ptr = ipfw_nat_cfg;
- ipfw_nat_del_ptr = ipfw_nat_del;
- ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg;
- ipfw_nat_get_log_ptr = ipfw_nat_get_log;
- IPFW_WUNLOCK(&V_layer3_chain);
- V_ifaddr_event_tag = EVENTHANDLER_REGISTER(
- ifaddr_event, ifaddr_change,
- NULL, EVENTHANDLER_PRI_ANY);
-}
-
-static void
-ipfw_nat_destroy(void)
-{
- struct cfg_nat *ptr, *ptr_temp;
- struct ip_fw_chain *chain;
-
- chain = &V_layer3_chain;
- IPFW_WLOCK(chain);
- LIST_FOREACH_SAFE(ptr, &chain->nat, _next, ptr_temp) {
- LIST_REMOVE(ptr, _next);
- del_redir_spool_cfg(ptr, &ptr->redir_chain);
- LibAliasUninit(ptr->lib);
- free(ptr, M_IPFW);
- }
- EVENTHANDLER_DEREGISTER(ifaddr_event, V_ifaddr_event_tag);
- flush_nat_ptrs(chain, -1 /* flush all */);
- /* deregister ipfw_nat */
- ipfw_nat_ptr = NULL;
- lookup_nat_ptr = NULL;
- ipfw_nat_cfg_ptr = NULL;
- ipfw_nat_del_ptr = NULL;
- ipfw_nat_get_cfg_ptr = NULL;
- ipfw_nat_get_log_ptr = NULL;
- IPFW_WUNLOCK(chain);
-}
-
-static int
-ipfw_nat_modevent(module_t mod, int type, void *unused)
-{
- int err = 0;
-
- switch (type) {
- case MOD_LOAD:
- ipfw_nat_init();
- break;
-
- case MOD_UNLOAD:
- ipfw_nat_destroy();
- break;
-
- default:
- return EOPNOTSUPP;
- break;
- }
- return err;
-}
-
-static moduledata_t ipfw_nat_mod = {
- "ipfw_nat",
- ipfw_nat_modevent,
- 0
-};
-
-DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY);
-MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1);
-MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2);
-MODULE_VERSION(ipfw_nat, 1);
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_pfil.c b/sys/netinet/ipfw/ip_fw_pfil.c
deleted file mode 100644
index 695613d..0000000
--- a/sys/netinet/ipfw/ip_fw_pfil.c
+++ /dev/null
@@ -1,460 +0,0 @@
-/*-
- * Copyright (c) 2004 Andre Oppermann, Internet Business Solutions AG
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "opt_ipfw.h"
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#ifndef INET
-#error IPFIREWALL requires INET.
-#endif /* INET */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/module.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <sys/sysctl.h>
-
-#include <net/if.h>
-#include <net/route.h>
-#include <net/pfil.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/ip_fw.h>
-#ifdef INET6
-#include <netinet/ip6.h>
-#include <netinet6/ip6_var.h>
-#endif
-#include <netinet/ipfw/ip_fw_private.h>
-#include <netgraph/ng_ipfw.h>
-
-#include <machine/in_cksum.h>
-
-static VNET_DEFINE(int, fw_enable) = 1;
-#define V_fw_enable VNET(fw_enable)
-
-#ifdef INET6
-static VNET_DEFINE(int, fw6_enable) = 1;
-#define V_fw6_enable VNET(fw6_enable)
-#endif
-
-int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
-
-/* Forward declarations. */
-static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int);
-
-#ifdef SYSCTL_NODE
-
-SYSBEGIN(f1)
-
-SYSCTL_DECL(_net_inet_ip_fw);
-SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AUTO, enable,
- CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
- ipfw_chg_hook, "I", "Enable ipfw");
-#ifdef INET6
-SYSCTL_DECL(_net_inet6_ip6_fw);
-SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
- CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
- ipfw_chg_hook, "I", "Enable ipfw+6");
-#endif /* INET6 */
-
-SYSEND
-
-#endif /* SYSCTL_NODE */
-
-/*
- * The pfilter hook to pass packets to ipfw_chk and then to
- * dummynet, divert, netgraph or other modules.
- * The packet may be consumed.
- */
-int
-ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
- struct inpcb *inp)
-{
- struct ip_fw_args args;
- struct m_tag *tag;
- int ipfw;
- int ret;
-
- /* all the processing now uses ip_len in net format */
- if (mtod(*m0, struct ip *)->ip_v == 4)
- SET_NET_IPLEN(mtod(*m0, struct ip *));
-
- /* convert dir to IPFW values */
- dir = (dir == PFIL_IN) ? DIR_IN : DIR_OUT;
- bzero(&args, sizeof(args));
-
-again:
- /*
- * extract and remove the tag if present. If we are left
- * with onepass, optimize the outgoing path.
- */
- tag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
- if (tag != NULL) {
- args.rule = *((struct ipfw_rule_ref *)(tag+1));
- m_tag_delete(*m0, tag);
- if (args.rule.info & IPFW_ONEPASS) {
- if (mtod(*m0, struct ip *)->ip_v == 4)
- SET_HOST_IPLEN(mtod(*m0, struct ip *));
- return (0);
- }
- }
-
- args.m = *m0;
- args.oif = dir == DIR_OUT ? ifp : NULL;
- args.inp = inp;
-
- ipfw = ipfw_chk(&args);
- *m0 = args.m;
-
- KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
- __func__));
-
- /* breaking out of the switch means drop */
- ret = 0; /* default return value for pass */
- switch (ipfw) {
- case IP_FW_PASS:
- /* next_hop may be set by ipfw_chk */
- if (args.next_hop == NULL && args.next_hop6 == NULL)
- break; /* pass */
-#if !defined(IPFIREWALL_FORWARD) || (!defined(INET6) && !defined(INET))
- ret = EACCES;
-#else
- {
- struct m_tag *fwd_tag;
- size_t len;
-
- KASSERT(args.next_hop == NULL || args.next_hop6 == NULL,
- ("%s: both next_hop=%p and next_hop6=%p not NULL", __func__,
- args.next_hop, args.next_hop6));
-#ifdef INET6
- if (args.next_hop6 != NULL)
- len = sizeof(struct sockaddr_in6);
-#endif
-#ifdef INET
- if (args.next_hop != NULL)
- len = sizeof(struct sockaddr_in);
-#endif
-
- /* Incoming packets should not be tagged so we do not
- * m_tag_find. Outgoing packets may be tagged, so we
- * reuse the tag if present.
- */
- fwd_tag = (dir == DIR_IN) ? NULL :
- m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
- if (fwd_tag != NULL) {
- m_tag_unlink(*m0, fwd_tag);
- } else {
- fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, len,
- M_NOWAIT);
- if (fwd_tag == NULL) {
- ret = EACCES;
- break; /* i.e. drop */
- }
- }
-#ifdef INET6
- if (args.next_hop6 != NULL) {
- bcopy(args.next_hop6, (fwd_tag+1), len);
- if (in6_localip(&args.next_hop6->sin6_addr))
- (*m0)->m_flags |= M_FASTFWD_OURS;
- }
-#endif
-#ifdef INET
- if (args.next_hop != NULL) {
- bcopy(args.next_hop, (fwd_tag+1), len);
- if (in_localip(args.next_hop->sin_addr))
- (*m0)->m_flags |= M_FASTFWD_OURS;
- }
-#endif
- m_tag_prepend(*m0, fwd_tag);
- }
-#endif /* IPFIREWALL_FORWARD */
- break;
-
- case IP_FW_DENY:
- ret = EACCES;
- break; /* i.e. drop */
-
- case IP_FW_DUMMYNET:
- ret = EACCES;
- if (ip_dn_io_ptr == NULL)
- break; /* i.e. drop */
- if (mtod(*m0, struct ip *)->ip_v == 4)
- ret = ip_dn_io_ptr(m0, dir, &args);
- else if (mtod(*m0, struct ip *)->ip_v == 6)
- ret = ip_dn_io_ptr(m0, dir | PROTO_IPV6, &args);
- else
- break; /* drop it */
- /*
- * XXX should read the return value.
- * dummynet normally eats the packet and sets *m0=NULL
- * unless the packet can be sent immediately. In this
- * case args is updated and we should re-run the
- * check without clearing args.
- */
- if (*m0 != NULL)
- goto again;
- break;
-
- case IP_FW_TEE:
- case IP_FW_DIVERT:
- if (ip_divert_ptr == NULL) {
- ret = EACCES;
- break; /* i.e. drop */
- }
- ret = ipfw_divert(m0, dir, &args.rule,
- (ipfw == IP_FW_TEE) ? 1 : 0);
- /* continue processing for the original packet (tee). */
- if (*m0)
- goto again;
- break;
-
- case IP_FW_NGTEE:
- case IP_FW_NETGRAPH:
- if (ng_ipfw_input_p == NULL) {
- ret = EACCES;
- break; /* i.e. drop */
- }
- ret = ng_ipfw_input_p(m0, dir, &args,
- (ipfw == IP_FW_NGTEE) ? 1 : 0);
- if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */
- goto again; /* continue with packet */
- break;
-
- case IP_FW_NAT:
- /* honor one-pass in case of successful nat */
- if (V_fw_one_pass)
- break; /* ret is already 0 */
- goto again;
-
- case IP_FW_REASS:
- goto again; /* continue with packet */
-
- default:
- KASSERT(0, ("%s: unknown retval", __func__));
- }
-
- if (ret != 0) {
- if (*m0)
- FREE_PKT(*m0);
- *m0 = NULL;
- }
- if (*m0 && mtod(*m0, struct ip *)->ip_v == 4)
- SET_HOST_IPLEN(mtod(*m0, struct ip *));
- return ret;
-}
-
-/* do the divert, return 1 on error 0 on success */
-static int
-ipfw_divert(struct mbuf **m0, int incoming, struct ipfw_rule_ref *rule,
- int tee)
-{
- /*
- * ipfw_chk() has already tagged the packet with the divert tag.
- * If tee is set, copy packet and return original.
- * If not tee, consume packet and send it to divert socket.
- */
- struct mbuf *clone;
- struct ip *ip = mtod(*m0, struct ip *);
- struct m_tag *tag;
-
- /* Cloning needed for tee? */
- if (tee == 0) {
- clone = *m0; /* use the original mbuf */
- *m0 = NULL;
- } else {
- clone = m_dup(*m0, M_DONTWAIT);
- /* If we cannot duplicate the mbuf, we sacrifice the divert
- * chain and continue with the tee-ed packet.
- */
- if (clone == NULL)
- return 1;
- }
-
- /*
- * Divert listeners can normally handle non-fragmented packets,
- * but we can only reass in the non-tee case.
- * This means that listeners on a tee rule may get fragments,
- * and have to live with that.
- * Note that we now have the 'reass' ipfw option so if we care
- * we can do it before a 'tee'.
- */
- if (!tee) switch (ip->ip_v) {
- case IPVERSION:
- if (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) {
- int hlen;
- struct mbuf *reass;
-
- SET_HOST_IPLEN(ip); /* ip_reass wants host order */
- reass = ip_reass(clone); /* Reassemble packet. */
- if (reass == NULL)
- return 0; /* not an error */
- /* if reass = NULL then it was consumed by ip_reass */
- /*
- * IP header checksum fixup after reassembly and leave header
- * in network byte order.
- */
- ip = mtod(reass, struct ip *);
- hlen = ip->ip_hl << 2;
- SET_NET_IPLEN(ip);
- ip->ip_sum = 0;
- if (hlen == sizeof(struct ip))
- ip->ip_sum = in_cksum_hdr(ip);
- else
- ip->ip_sum = in_cksum(reass, hlen);
- clone = reass;
- }
- break;
-#ifdef INET6
- case IPV6_VERSION >> 4:
- {
- struct ip6_hdr *const ip6 = mtod(clone, struct ip6_hdr *);
-
- if (ip6->ip6_nxt == IPPROTO_FRAGMENT) {
- int nxt, off;
-
- off = sizeof(struct ip6_hdr);
- nxt = frag6_input(&clone, &off, 0);
- if (nxt == IPPROTO_DONE)
- return (0);
- }
- break;
- }
-#endif
- }
-
- /* attach a tag to the packet with the reinject info */
- tag = m_tag_alloc(MTAG_IPFW_RULE, 0,
- sizeof(struct ipfw_rule_ref), M_NOWAIT);
- if (tag == NULL) {
- FREE_PKT(clone);
- return 1;
- }
- *((struct ipfw_rule_ref *)(tag+1)) = *rule;
- m_tag_prepend(clone, tag);
-
- /* Do the dirty job... */
- ip_divert_ptr(clone, incoming);
- return 0;
-}
-
-/*
- * attach or detach hooks for a given protocol family
- */
-static int
-ipfw_hook(int onoff, int pf)
-{
- struct pfil_head *pfh;
-
- pfh = pfil_head_get(PFIL_TYPE_AF, pf);
- if (pfh == NULL)
- return ENOENT;
-
- (void) (onoff ? pfil_add_hook : pfil_remove_hook)
- (ipfw_check_hook, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh);
-
- return 0;
-}
-
-int
-ipfw_attach_hooks(int arg)
-{
- int error = 0;
-
- if (arg == 0) /* detach */
- ipfw_hook(0, AF_INET);
- else if (V_fw_enable && ipfw_hook(1, AF_INET) != 0) {
- error = ENOENT; /* see ip_fw_pfil.c::ipfw_hook() */
- printf("ipfw_hook() error\n");
- }
-#ifdef INET6
- if (arg == 0) /* detach */
- ipfw_hook(0, AF_INET6);
- else if (V_fw6_enable && ipfw_hook(1, AF_INET6) != 0) {
- error = ENOENT;
- printf("ipfw6_hook() error\n");
- }
-#endif
- return error;
-}
-
-int
-ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
-{
- int enable;
- int oldenable;
- int error;
- int af;
-
- if (arg1 == &VNET_NAME(fw_enable)) {
- enable = V_fw_enable;
- af = AF_INET;
- }
-#ifdef INET6
- else if (arg1 == &VNET_NAME(fw6_enable)) {
- enable = V_fw6_enable;
- af = AF_INET6;
- }
-#endif
- else
- return (EINVAL);
-
- oldenable = enable;
-
- error = sysctl_handle_int(oidp, &enable, 0, req);
-
- if (error)
- return (error);
-
- enable = (enable) ? 1 : 0;
-
- if (enable == oldenable)
- return (0);
-
- error = ipfw_hook(enable, af);
- if (error)
- return (error);
- if (af == AF_INET)
- V_fw_enable = enable;
-#ifdef INET6
- else if (af == AF_INET6)
- V_fw6_enable = enable;
-#endif
-
- return (0);
-}
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_private.h b/sys/netinet/ipfw/ip_fw_private.h
deleted file mode 100644
index 7f65c41..0000000
--- a/sys/netinet/ipfw/ip_fw_private.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/*-
- * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _IPFW2_PRIVATE_H
-#define _IPFW2_PRIVATE_H
-
-/*
- * Internal constants and data structures used by ipfw components
- * and not meant to be exported outside the kernel.
- */
-
-#ifdef _KERNEL
-
-/*
- * For platforms that do not have SYSCTL support, we wrap the
- * SYSCTL_* into a function (one per file) to collect the values
- * into an array at module initialization. The wrapping macros,
- * SYSBEGIN() and SYSEND, are empty in the default case.
- */
-#ifndef SYSBEGIN
-#define SYSBEGIN(x)
-#endif
-#ifndef SYSEND
-#define SYSEND
-#endif
-
-/* Return values from ipfw_chk() */
-enum {
- IP_FW_PASS = 0,
- IP_FW_DENY,
- IP_FW_DIVERT,
- IP_FW_TEE,
- IP_FW_DUMMYNET,
- IP_FW_NETGRAPH,
- IP_FW_NGTEE,
- IP_FW_NAT,
- IP_FW_REASS,
-};
-
-/*
- * Structure for collecting parameters to dummynet for ip6_output forwarding
- */
-struct _ip6dn_args {
- struct ip6_pktopts *opt_or;
- struct route_in6 ro_or;
- int flags_or;
- struct ip6_moptions *im6o_or;
- struct ifnet *origifp_or;
- struct ifnet *ifp_or;
- struct sockaddr_in6 dst_or;
- u_long mtu_or;
- struct route_in6 ro_pmtu_or;
-};
-
-
-/*
- * Arguments for calling ipfw_chk() and dummynet_io(). We put them
- * all into a structure because this way it is easier and more
- * efficient to pass variables around and extend the interface.
- */
-struct ip_fw_args {
- struct mbuf *m; /* the mbuf chain */
- struct ifnet *oif; /* output interface */
- struct sockaddr_in *next_hop; /* forward address */
- struct sockaddr_in6 *next_hop6; /* ipv6 forward address */
-
- /*
- * On return, it points to the matching rule.
- * On entry, rule.slot > 0 means the info is valid and
- * contains the starting rule for an ipfw search.
- * If chain_id == chain->id && slot >0 then jump to that slot.
- * Otherwise, we locate the first rule >= rulenum:rule_id
- */
- struct ipfw_rule_ref rule; /* match/restart info */
-
- struct ether_header *eh; /* for bridged packets */
-
- struct ipfw_flow_id f_id; /* grabbed from IP header */
- //uint32_t cookie; /* a cookie depending on rule action */
- struct inpcb *inp;
-
- struct _ip6dn_args dummypar; /* dummynet->ip6_output */
- struct sockaddr_in hopstore; /* store here if cannot use a pointer */
-};
-
-MALLOC_DECLARE(M_IPFW);
-
-/*
- * Hooks sometime need to know the direction of the packet
- * (divert, dummynet, netgraph, ...)
- * We use a generic definition here, with bit0-1 indicating the
- * direction, bit 2 indicating layer2 or 3, bit 3-4 indicating the
- * specific protocol
- * indicating the protocol (if necessary)
- */
-enum {
- DIR_MASK = 0x3,
- DIR_OUT = 0,
- DIR_IN = 1,
- DIR_FWD = 2,
- DIR_DROP = 3,
- PROTO_LAYER2 = 0x4, /* set for layer 2 */
- /* PROTO_DEFAULT = 0, */
- PROTO_IPV4 = 0x08,
- PROTO_IPV6 = 0x10,
- PROTO_IFB = 0x0c, /* layer2 + ifbridge */
- /* PROTO_OLDBDG = 0x14, unused, old bridge */
-};
-
-/* wrapper for freeing a packet, in case we need to do more work */
-#ifndef FREE_PKT
-#if defined(__linux__) || defined(_WIN32)
-#define FREE_PKT(m) netisr_dispatch(-1, m)
-#else
-#define FREE_PKT(m) m_freem(m)
-#endif
-#endif /* !FREE_PKT */
-
-/*
- * Function definitions.
- */
-
-/* attach (arg = 1) or detach (arg = 0) hooks */
-int ipfw_attach_hooks(int);
-#ifdef NOTYET
-void ipfw_nat_destroy(void);
-#endif
-
-/* In ip_fw_log.c */
-struct ip;
-void ipfw_log_bpf(int);
-void ipfw_log(struct ip_fw *f, u_int hlen, struct ip_fw_args *args,
- struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
- struct ip *ip);
-VNET_DECLARE(u_int64_t, norule_counter);
-#define V_norule_counter VNET(norule_counter)
-VNET_DECLARE(int, verbose_limit);
-#define V_verbose_limit VNET(verbose_limit)
-
-/* In ip_fw_dynamic.c */
-
-enum { /* result for matching dynamic rules */
- MATCH_REVERSE = 0,
- MATCH_FORWARD,
- MATCH_NONE,
- MATCH_UNKNOWN,
-};
-
-/*
- * The lock for dynamic rules is only used once outside the file,
- * and only to release the result of lookup_dyn_rule().
- * Eventually we may implement it with a callback on the function.
- */
-void ipfw_dyn_unlock(void);
-
-struct tcphdr;
-struct mbuf *ipfw_send_pkt(struct mbuf *, struct ipfw_flow_id *,
- u_int32_t, u_int32_t, int);
-int ipfw_install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
- struct ip_fw_args *args, uint32_t tablearg);
-ipfw_dyn_rule *ipfw_lookup_dyn_rule(struct ipfw_flow_id *pkt,
- int *match_direction, struct tcphdr *tcp);
-void ipfw_remove_dyn_children(struct ip_fw *rule);
-void ipfw_get_dynamic(char **bp, const char *ep);
-
-void ipfw_dyn_attach(void); /* uma_zcreate .... */
-void ipfw_dyn_detach(void); /* uma_zdestroy ... */
-void ipfw_dyn_init(void); /* per-vnet initialization */
-void ipfw_dyn_uninit(int); /* per-vnet deinitialization */
-int ipfw_dyn_len(void);
-
-/* common variables */
-VNET_DECLARE(int, fw_one_pass);
-#define V_fw_one_pass VNET(fw_one_pass)
-
-VNET_DECLARE(int, fw_verbose);
-#define V_fw_verbose VNET(fw_verbose)
-
-VNET_DECLARE(struct ip_fw_chain, layer3_chain);
-#define V_layer3_chain VNET(layer3_chain)
-
-VNET_DECLARE(u_int32_t, set_disable);
-#define V_set_disable VNET(set_disable)
-
-VNET_DECLARE(int, autoinc_step);
-#define V_autoinc_step VNET(autoinc_step)
-
-VNET_DECLARE(unsigned int, fw_tables_max);
-#define V_fw_tables_max VNET(fw_tables_max)
-
-struct ip_fw_chain {
- struct ip_fw *rules; /* list of rules */
- struct ip_fw *reap; /* list of rules to reap */
- struct ip_fw *default_rule;
- int n_rules; /* number of static rules */
- int static_len; /* total len of static rules */
- struct ip_fw **map; /* array of rule ptrs to ease lookup */
- LIST_HEAD(nat_list, cfg_nat) nat; /* list of nat entries */
- struct radix_node_head **tables; /* IPv4 tables */
- struct radix_node_head **xtables; /* extended tables */
- uint8_t *tabletype; /* Array of table types */
-#if defined( __linux__ ) || defined( _WIN32 )
- spinlock_t rwmtx;
- spinlock_t uh_lock;
-#else
- struct rwlock rwmtx;
- struct rwlock uh_lock; /* lock for upper half */
-#endif
- uint32_t id; /* ruleset id */
- uint32_t gencnt; /* generation count */
-};
-
-struct sockopt; /* used by tcp_var.h */
-
-/*
- * The lock is heavily used by ip_fw2.c (the main file) and ip_fw_nat.c
- * so the variable and the macros must be here.
- */
-
-#define IPFW_LOCK_INIT(_chain) do { \
- rw_init(&(_chain)->rwmtx, "IPFW static rules"); \
- rw_init(&(_chain)->uh_lock, "IPFW UH lock"); \
- } while (0)
-
-#define IPFW_LOCK_DESTROY(_chain) do { \
- rw_destroy(&(_chain)->rwmtx); \
- rw_destroy(&(_chain)->uh_lock); \
- } while (0)
-
-#define IPFW_WLOCK_ASSERT(_chain) rw_assert(&(_chain)->rwmtx, RA_WLOCKED)
-
-#define IPFW_RLOCK(p) rw_rlock(&(p)->rwmtx)
-#define IPFW_RUNLOCK(p) rw_runlock(&(p)->rwmtx)
-#define IPFW_WLOCK(p) rw_wlock(&(p)->rwmtx)
-#define IPFW_WUNLOCK(p) rw_wunlock(&(p)->rwmtx)
-
-#define IPFW_UH_RLOCK(p) rw_rlock(&(p)->uh_lock)
-#define IPFW_UH_RUNLOCK(p) rw_runlock(&(p)->uh_lock)
-#define IPFW_UH_WLOCK(p) rw_wlock(&(p)->uh_lock)
-#define IPFW_UH_WUNLOCK(p) rw_wunlock(&(p)->uh_lock)
-
-/* In ip_fw_sockopt.c */
-int ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id);
-int ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule);
-int ipfw_ctl(struct sockopt *sopt);
-int ipfw_chk(struct ip_fw_args *args);
-void ipfw_reap_rules(struct ip_fw *head);
-
-/* In ip_fw_pfil */
-int ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
- struct inpcb *inp);
-
-/* In ip_fw_table.c */
-struct radix_node;
-int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
- uint32_t *val);
-int ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
- uint32_t *val, int type);
-int ipfw_init_tables(struct ip_fw_chain *ch);
-void ipfw_destroy_tables(struct ip_fw_chain *ch);
-int ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl);
-int ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
- uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value);
-int ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
- uint8_t plen, uint8_t mlen, uint8_t type);
-int ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
-int ipfw_dump_table_entry(struct radix_node *rn, void *arg);
-int ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl);
-int ipfw_count_xtable(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt);
-int ipfw_dump_xtable(struct ip_fw_chain *ch, ipfw_xtable *tbl);
-int ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables);
-
-/* In ip_fw_nat.c -- XXX to be moved to ip_var.h */
-
-extern struct cfg_nat *(*lookup_nat_ptr)(struct nat_list *, int);
-
-typedef int ipfw_nat_t(struct ip_fw_args *, struct cfg_nat *, struct mbuf *);
-typedef int ipfw_nat_cfg_t(struct sockopt *);
-
-extern ipfw_nat_t *ipfw_nat_ptr;
-#define IPFW_NAT_LOADED (ipfw_nat_ptr != NULL)
-
-extern ipfw_nat_cfg_t *ipfw_nat_cfg_ptr;
-extern ipfw_nat_cfg_t *ipfw_nat_del_ptr;
-extern ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
-extern ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
-
-#endif /* _KERNEL */
-#endif /* _IPFW2_PRIVATE_H */
diff --git a/sys/netinet/ipfw/ip_fw_sockopt.c b/sys/netinet/ipfw/ip_fw_sockopt.c
deleted file mode 100644
index 2a5f4e7..0000000
--- a/sys/netinet/ipfw/ip_fw_sockopt.c
+++ /dev/null
@@ -1,1448 +0,0 @@
-/*-
- * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
- *
- * Supported by: Valeria Paoli
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Sockopt support for ipfw. The routines here implement
- * the upper half of the ipfw code.
- */
-
-#include "opt_ipfw.h"
-#include "opt_inet.h"
-#ifndef INET
-#error IPFIREWALL requires INET.
-#endif /* INET */
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h> /* struct m_tag used by nested headers */
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/priv.h>
-#include <sys/proc.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/syslog.h>
-#include <net/if.h>
-#include <net/route.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* hooks */
-#include <netinet/ip_fw.h>
-#include <netinet/ipfw/ip_fw_private.h>
-
-#ifdef MAC
-#include <security/mac/mac_framework.h>
-#endif
-
-MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
-
-/*
- * static variables followed by global ones (none in this file)
- */
-
-/*
- * Find the smallest rule >= key, id.
- * We could use bsearch but it is so simple that we code it directly
- */
-int
-ipfw_find_rule(struct ip_fw_chain *chain, uint32_t key, uint32_t id)
-{
- int i, lo, hi;
- struct ip_fw *r;
-
- for (lo = 0, hi = chain->n_rules - 1; lo < hi;) {
- i = (lo + hi) / 2;
- r = chain->map[i];
- if (r->rulenum < key)
- lo = i + 1; /* continue from the next one */
- else if (r->rulenum > key)
- hi = i; /* this might be good */
- else if (r->id < id)
- lo = i + 1; /* continue from the next one */
- else /* r->id >= id */
- hi = i; /* this might be good */
- };
- return hi;
-}
-
-/*
- * allocate a new map, returns the chain locked. extra is the number
- * of entries to add or delete.
- */
-static struct ip_fw **
-get_map(struct ip_fw_chain *chain, int extra, int locked)
-{
-
- for (;;) {
- struct ip_fw **map;
- int i;
-
- i = chain->n_rules + extra;
- map = malloc(i * sizeof(struct ip_fw *), M_IPFW,
- locked ? M_NOWAIT : M_WAITOK);
- if (map == NULL) {
- printf("%s: cannot allocate map\n", __FUNCTION__);
- return NULL;
- }
- if (!locked)
- IPFW_UH_WLOCK(chain);
- if (i >= chain->n_rules + extra) /* good */
- return map;
- /* otherwise we lost the race, free and retry */
- if (!locked)
- IPFW_UH_WUNLOCK(chain);
- free(map, M_IPFW);
- }
-}
-
-/*
- * swap the maps. It is supposed to be called with IPFW_UH_WLOCK
- */
-static struct ip_fw **
-swap_map(struct ip_fw_chain *chain, struct ip_fw **new_map, int new_len)
-{
- struct ip_fw **old_map;
-
- IPFW_WLOCK(chain);
- chain->id++;
- chain->n_rules = new_len;
- old_map = chain->map;
- chain->map = new_map;
- IPFW_WUNLOCK(chain);
- return old_map;
-}
-
-/*
- * Add a new rule to the list. Copy the rule into a malloc'ed area, then
- * possibly create a rule number and add the rule to the list.
- * Update the rule_number in the input struct so the caller knows it as well.
- * XXX DO NOT USE FOR THE DEFAULT RULE.
- * Must be called without IPFW_UH held
- */
-int
-ipfw_add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
-{
- struct ip_fw *rule;
- int i, l, insert_before;
- struct ip_fw **map; /* the new array of pointers */
-
- if (chain->rules == NULL || input_rule->rulenum > IPFW_DEFAULT_RULE-1)
- return (EINVAL);
-
- l = RULESIZE(input_rule);
- rule = malloc(l, M_IPFW, M_WAITOK | M_ZERO);
- /* get_map returns with IPFW_UH_WLOCK if successful */
- map = get_map(chain, 1, 0 /* not locked */);
- if (map == NULL) {
- free(rule, M_IPFW);
- return ENOSPC;
- }
-
- bcopy(input_rule, rule, l);
- /* clear fields not settable from userland */
- rule->x_next = NULL;
- rule->next_rule = NULL;
- rule->pcnt = 0;
- rule->bcnt = 0;
- rule->timestamp = 0;
-
- if (V_autoinc_step < 1)
- V_autoinc_step = 1;
- else if (V_autoinc_step > 1000)
- V_autoinc_step = 1000;
- /* find the insertion point, we will insert before */
- insert_before = rule->rulenum ? rule->rulenum + 1 : IPFW_DEFAULT_RULE;
- i = ipfw_find_rule(chain, insert_before, 0);
- /* duplicate first part */
- if (i > 0)
- bcopy(chain->map, map, i * sizeof(struct ip_fw *));
- map[i] = rule;
- /* duplicate remaining part, we always have the default rule */
- bcopy(chain->map + i, map + i + 1,
- sizeof(struct ip_fw *) *(chain->n_rules - i));
- if (rule->rulenum == 0) {
- /* write back the number */
- rule->rulenum = i > 0 ? map[i-1]->rulenum : 0;
- if (rule->rulenum < IPFW_DEFAULT_RULE - V_autoinc_step)
- rule->rulenum += V_autoinc_step;
- input_rule->rulenum = rule->rulenum;
- }
-
- rule->id = chain->id + 1;
- map = swap_map(chain, map, chain->n_rules + 1);
- chain->static_len += l;
- IPFW_UH_WUNLOCK(chain);
- if (map)
- free(map, M_IPFW);
- return (0);
-}
-
-/*
- * Reclaim storage associated with a list of rules. This is
- * typically the list created using remove_rule.
- * A NULL pointer on input is handled correctly.
- */
-void
-ipfw_reap_rules(struct ip_fw *head)
-{
- struct ip_fw *rule;
-
- while ((rule = head) != NULL) {
- head = head->x_next;
- free(rule, M_IPFW);
- }
-}
-
-/*
- * Used by del_entry() to check if a rule should be kept.
- * Returns 1 if the rule must be kept, 0 otherwise.
- *
- * Called with cmd = {0,1,5}.
- * cmd == 0 matches on rule numbers, excludes rules in RESVD_SET if n == 0 ;
- * cmd == 1 matches on set numbers only, rule numbers are ignored;
- * cmd == 5 matches on rule and set numbers.
- *
- * n == 0 is a wildcard for rule numbers, there is no wildcard for sets.
- *
- * Rules to keep are
- * (default || reserved || !match_set || !match_number)
- * where
- * default ::= (rule->rulenum == IPFW_DEFAULT_RULE)
- * // the default rule is always protected
- *
- * reserved ::= (cmd == 0 && n == 0 && rule->set == RESVD_SET)
- * // RESVD_SET is protected only if cmd == 0 and n == 0 ("ipfw flush")
- *
- * match_set ::= (cmd == 0 || rule->set == set)
- * // set number is ignored for cmd == 0
- *
- * match_number ::= (cmd == 1 || n == 0 || n == rule->rulenum)
- * // number is ignored for cmd == 1 or n == 0
- *
- */
-static int
-keep_rule(struct ip_fw *rule, uint8_t cmd, uint8_t set, uint32_t n)
-{
- return
- (rule->rulenum == IPFW_DEFAULT_RULE) ||
- (cmd == 0 && n == 0 && rule->set == RESVD_SET) ||
- !(cmd == 0 || rule->set == set) ||
- !(cmd == 1 || n == 0 || n == rule->rulenum);
-}
-
-/**
- * Remove all rules with given number, or do set manipulation.
- * Assumes chain != NULL && *chain != NULL.
- *
- * The argument is an uint32_t. The low 16 bit are the rule or set number;
- * the next 8 bits are the new set; the top 8 bits indicate the command:
- *
- * 0 delete rules numbered "rulenum"
- * 1 delete rules in set "rulenum"
- * 2 move rules "rulenum" to set "new_set"
- * 3 move rules from set "rulenum" to set "new_set"
- * 4 swap sets "rulenum" and "new_set"
- * 5 delete rules "rulenum" and set "new_set"
- */
-static int
-del_entry(struct ip_fw_chain *chain, uint32_t arg)
-{
- struct ip_fw *rule;
- uint32_t num; /* rule number or old_set */
- uint8_t cmd, new_set;
- int start, end, i, ofs, n;
- struct ip_fw **map = NULL;
- int error = 0;
-
- num = arg & 0xffff;
- cmd = (arg >> 24) & 0xff;
- new_set = (arg >> 16) & 0xff;
-
- if (cmd > 5 || new_set > RESVD_SET)
- return EINVAL;
- if (cmd == 0 || cmd == 2 || cmd == 5) {
- if (num >= IPFW_DEFAULT_RULE)
- return EINVAL;
- } else {
- if (num > RESVD_SET) /* old_set */
- return EINVAL;
- }
-
- IPFW_UH_WLOCK(chain); /* arbitrate writers */
- chain->reap = NULL; /* prepare for deletions */
-
- switch (cmd) {
- case 0: /* delete rules "num" (num == 0 matches all) */
- case 1: /* delete all rules in set N */
- case 5: /* delete rules with number N and set "new_set". */
-
- /*
- * Locate first rule to delete (start), the rule after
- * the last one to delete (end), and count how many
- * rules to delete (n). Always use keep_rule() to
- * determine which rules to keep.
- */
- n = 0;
- if (cmd == 1) {
- /* look for a specific set including RESVD_SET.
- * Must scan the entire range, ignore num.
- */
- new_set = num;
- for (start = -1, end = i = 0; i < chain->n_rules; i++) {
- if (keep_rule(chain->map[i], cmd, new_set, 0))
- continue;
- if (start < 0)
- start = i;
- end = i;
- n++;
- }
- end++; /* first non-matching */
- } else {
- /* Optimized search on rule numbers */
- start = ipfw_find_rule(chain, num, 0);
- for (end = start; end < chain->n_rules; end++) {
- rule = chain->map[end];
- if (num > 0 && rule->rulenum != num)
- break;
- if (!keep_rule(rule, cmd, new_set, num))
- n++;
- }
- }
-
- if (n == 0) {
- /* A flush request (arg == 0 or cmd == 1) on empty
- * ruleset returns with no error. On the contrary,
- * if there is no match on a specific request,
- * we return EINVAL.
- */
- if (arg != 0 && cmd != 1)
- error = EINVAL;
- break;
- }
-
- /* We have something to delete. Allocate the new map */
- map = get_map(chain, -n, 1 /* locked */);
- if (map == NULL) {
- error = EINVAL;
- break;
- }
-
- /* 1. bcopy the initial part of the map */
- if (start > 0)
- bcopy(chain->map, map, start * sizeof(struct ip_fw *));
- /* 2. copy active rules between start and end */
- for (i = ofs = start; i < end; i++) {
- rule = chain->map[i];
- if (keep_rule(rule, cmd, new_set, num))
- map[ofs++] = rule;
- }
- /* 3. copy the final part of the map */
- bcopy(chain->map + end, map + ofs,
- (chain->n_rules - end) * sizeof(struct ip_fw *));
- /* 4. swap the maps (under BH_LOCK) */
- map = swap_map(chain, map, chain->n_rules - n);
- /* 5. now remove the rules deleted from the old map */
- for (i = start; i < end; i++) {
- int l;
- rule = map[i];
- if (keep_rule(rule, cmd, new_set, num))
- continue;
- l = RULESIZE(rule);
- chain->static_len -= l;
- ipfw_remove_dyn_children(rule);
- rule->x_next = chain->reap;
- chain->reap = rule;
- }
- break;
-
- /*
- * In the next 3 cases the loop stops at (n_rules - 1)
- * because the default rule is never eligible..
- */
-
- case 2: /* move rules with given RULE number to new set */
- for (i = 0; i < chain->n_rules - 1; i++) {
- rule = chain->map[i];
- if (rule->rulenum == num)
- rule->set = new_set;
- }
- break;
-
- case 3: /* move rules with given SET number to new set */
- for (i = 0; i < chain->n_rules - 1; i++) {
- rule = chain->map[i];
- if (rule->set == num)
- rule->set = new_set;
- }
- break;
-
- case 4: /* swap two sets */
- for (i = 0; i < chain->n_rules - 1; i++) {
- rule = chain->map[i];
- if (rule->set == num)
- rule->set = new_set;
- else if (rule->set == new_set)
- rule->set = num;
- }
- break;
- }
-
- rule = chain->reap;
- chain->reap = NULL;
- IPFW_UH_WUNLOCK(chain);
- ipfw_reap_rules(rule);
- if (map)
- free(map, M_IPFW);
- return error;
-}
-
-/*
- * Clear counters for a specific rule.
- * Normally run under IPFW_UH_RLOCK, but these are idempotent ops
- * so we only care that rules do not disappear.
- */
-static void
-clear_counters(struct ip_fw *rule, int log_only)
-{
- ipfw_insn_log *l = (ipfw_insn_log *)ACTION_PTR(rule);
-
- if (log_only == 0) {
- rule->bcnt = rule->pcnt = 0;
- rule->timestamp = 0;
- }
- if (l->o.opcode == O_LOG)
- l->log_left = l->max_log;
-}
-
-/**
- * Reset some or all counters on firewall rules.
- * The argument `arg' is an u_int32_t. The low 16 bit are the rule number,
- * the next 8 bits are the set number, the top 8 bits are the command:
- * 0 work with rules from all set's;
- * 1 work with rules only from specified set.
- * Specified rule number is zero if we want to clear all entries.
- * log_only is 1 if we only want to reset logs, zero otherwise.
- */
-static int
-zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
-{
- struct ip_fw *rule;
- char *msg;
- int i;
-
- uint16_t rulenum = arg & 0xffff;
- uint8_t set = (arg >> 16) & 0xff;
- uint8_t cmd = (arg >> 24) & 0xff;
-
- if (cmd > 1)
- return (EINVAL);
- if (cmd == 1 && set > RESVD_SET)
- return (EINVAL);
-
- IPFW_UH_RLOCK(chain);
- if (rulenum == 0) {
- V_norule_counter = 0;
- for (i = 0; i < chain->n_rules; i++) {
- rule = chain->map[i];
- /* Skip rules not in our set. */
- if (cmd == 1 && rule->set != set)
- continue;
- clear_counters(rule, log_only);
- }
- msg = log_only ? "All logging counts reset" :
- "Accounting cleared";
- } else {
- int cleared = 0;
- for (i = 0; i < chain->n_rules; i++) {
- rule = chain->map[i];
- if (rule->rulenum == rulenum) {
- if (cmd == 0 || rule->set == set)
- clear_counters(rule, log_only);
- cleared = 1;
- }
- if (rule->rulenum > rulenum)
- break;
- }
- if (!cleared) { /* we did not find any matching rules */
- IPFW_UH_RUNLOCK(chain);
- return (EINVAL);
- }
- msg = log_only ? "logging count reset" : "cleared";
- }
- IPFW_UH_RUNLOCK(chain);
-
- if (V_fw_verbose) {
- int lev = LOG_SECURITY | LOG_NOTICE;
-
- if (rulenum)
- log(lev, "ipfw: Entry %d %s.\n", rulenum, msg);
- else
- log(lev, "ipfw: %s.\n", msg);
- }
- return (0);
-}
-
-/*
- * Check validity of the structure before insert.
- * Rules are simple, so this mostly need to check rule sizes.
- */
-static int
-check_ipfw_struct(struct ip_fw *rule, int size)
-{
- int l, cmdlen = 0;
- int have_action=0;
- ipfw_insn *cmd;
-
- if (size < sizeof(*rule)) {
- printf("ipfw: rule too short\n");
- return (EINVAL);
- }
- /* first, check for valid size */
- l = RULESIZE(rule);
- if (l != size) {
- printf("ipfw: size mismatch (have %d want %d)\n", size, l);
- return (EINVAL);
- }
- if (rule->act_ofs >= rule->cmd_len) {
- printf("ipfw: bogus action offset (%u > %u)\n",
- rule->act_ofs, rule->cmd_len - 1);
- return (EINVAL);
- }
- /*
- * Now go for the individual checks. Very simple ones, basically only
- * instruction sizes.
- */
- for (l = rule->cmd_len, cmd = rule->cmd ;
- l > 0 ; l -= cmdlen, cmd += cmdlen) {
- cmdlen = F_LEN(cmd);
- if (cmdlen > l) {
- printf("ipfw: opcode %d size truncated\n",
- cmd->opcode);
- return EINVAL;
- }
- switch (cmd->opcode) {
- case O_PROBE_STATE:
- case O_KEEP_STATE:
- case O_PROTO:
- case O_IP_SRC_ME:
- case O_IP_DST_ME:
- case O_LAYER2:
- case O_IN:
- case O_FRAG:
- case O_DIVERTED:
- case O_IPOPT:
- case O_IPTOS:
- case O_IPPRECEDENCE:
- case O_IPVER:
- case O_SOCKARG:
- case O_TCPFLAGS:
- case O_TCPOPTS:
- case O_ESTAB:
- case O_VERREVPATH:
- case O_VERSRCREACH:
- case O_ANTISPOOF:
- case O_IPSEC:
-#ifdef INET6
- case O_IP6_SRC_ME:
- case O_IP6_DST_ME:
- case O_EXT_HDR:
- case O_IP6:
-#endif
- case O_IP4:
- case O_TAG:
- if (cmdlen != F_INSN_SIZE(ipfw_insn))
- goto bad_size;
- break;
-
- case O_FIB:
- if (cmdlen != F_INSN_SIZE(ipfw_insn))
- goto bad_size;
- if (cmd->arg1 >= rt_numfibs) {
- printf("ipfw: invalid fib number %d\n",
- cmd->arg1);
- return EINVAL;
- }
- break;
-
- case O_SETFIB:
- if (cmdlen != F_INSN_SIZE(ipfw_insn))
- goto bad_size;
- if ((cmd->arg1 != IP_FW_TABLEARG) &&
- (cmd->arg1 >= rt_numfibs)) {
- printf("ipfw: invalid fib number %d\n",
- cmd->arg1);
- return EINVAL;
- }
- goto check_action;
-
- case O_UID:
- case O_GID:
- case O_JAIL:
- case O_IP_SRC:
- case O_IP_DST:
- case O_TCPSEQ:
- case O_TCPACK:
- case O_PROB:
- case O_ICMPTYPE:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_u32))
- goto bad_size;
- break;
-
- case O_LIMIT:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_limit))
- goto bad_size;
- break;
-
- case O_LOG:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_log))
- goto bad_size;
-
- ((ipfw_insn_log *)cmd)->log_left =
- ((ipfw_insn_log *)cmd)->max_log;
-
- break;
-
- case O_IP_SRC_MASK:
- case O_IP_DST_MASK:
- /* only odd command lengths */
- if ( !(cmdlen & 1) || cmdlen > 31)
- goto bad_size;
- break;
-
- case O_IP_SRC_SET:
- case O_IP_DST_SET:
- if (cmd->arg1 == 0 || cmd->arg1 > 256) {
- printf("ipfw: invalid set size %d\n",
- cmd->arg1);
- return EINVAL;
- }
- if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
- (cmd->arg1+31)/32 )
- goto bad_size;
- break;
-
- case O_IP_SRC_LOOKUP:
- case O_IP_DST_LOOKUP:
- if (cmd->arg1 >= IPFW_TABLES_MAX) {
- printf("ipfw: invalid table number %d\n",
- cmd->arg1);
- return (EINVAL);
- }
- if (cmdlen != F_INSN_SIZE(ipfw_insn) &&
- cmdlen != F_INSN_SIZE(ipfw_insn_u32) + 1 &&
- cmdlen != F_INSN_SIZE(ipfw_insn_u32))
- goto bad_size;
- break;
- case O_MACADDR2:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_mac))
- goto bad_size;
- break;
-
- case O_NOP:
- case O_IPID:
- case O_IPTTL:
- case O_IPLEN:
- case O_TCPDATALEN:
- case O_TCPWIN:
- case O_TAGGED:
- if (cmdlen < 1 || cmdlen > 31)
- goto bad_size;
- break;
-
- case O_MAC_TYPE:
- case O_IP_SRCPORT:
- case O_IP_DSTPORT: /* XXX artificial limit, 30 port pairs */
- if (cmdlen < 2 || cmdlen > 31)
- goto bad_size;
- break;
-
- case O_RECV:
- case O_XMIT:
- case O_VIA:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_if))
- goto bad_size;
- break;
-
- case O_ALTQ:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_altq))
- goto bad_size;
- break;
-
- case O_PIPE:
- case O_QUEUE:
- if (cmdlen != F_INSN_SIZE(ipfw_insn))
- goto bad_size;
- goto check_action;
-
- case O_FORWARD_IP:
-#ifdef IPFIREWALL_FORWARD
- if (cmdlen != F_INSN_SIZE(ipfw_insn_sa))
- goto bad_size;
- goto check_action;
-#else
- return EINVAL;
-#endif
-
-#ifdef INET6
- case O_FORWARD_IP6:
-#ifdef IPFIREWALL_FORWARD
- if (cmdlen != F_INSN_SIZE(ipfw_insn_sa6))
- goto bad_size;
- goto check_action;
-#else
- return (EINVAL);
-#endif
-#endif /* INET6 */
-
- case O_DIVERT:
- case O_TEE:
- if (ip_divert_ptr == NULL)
- return EINVAL;
- else
- goto check_size;
- case O_NETGRAPH:
- case O_NGTEE:
- if (ng_ipfw_input_p == NULL)
- return EINVAL;
- else
- goto check_size;
- case O_NAT:
- if (!IPFW_NAT_LOADED)
- return EINVAL;
- if (cmdlen != F_INSN_SIZE(ipfw_insn_nat))
- goto bad_size;
- goto check_action;
- case O_FORWARD_MAC: /* XXX not implemented yet */
- case O_CHECK_STATE:
- case O_COUNT:
- case O_ACCEPT:
- case O_DENY:
- case O_REJECT:
-#ifdef INET6
- case O_UNREACH6:
-#endif
- case O_SKIPTO:
- case O_REASS:
- case O_CALLRETURN:
-check_size:
- if (cmdlen != F_INSN_SIZE(ipfw_insn))
- goto bad_size;
-check_action:
- if (have_action) {
- printf("ipfw: opcode %d, multiple actions"
- " not allowed\n",
- cmd->opcode);
- return EINVAL;
- }
- have_action = 1;
- if (l != cmdlen) {
- printf("ipfw: opcode %d, action must be"
- " last opcode\n",
- cmd->opcode);
- return EINVAL;
- }
- break;
-#ifdef INET6
- case O_IP6_SRC:
- case O_IP6_DST:
- if (cmdlen != F_INSN_SIZE(struct in6_addr) +
- F_INSN_SIZE(ipfw_insn))
- goto bad_size;
- break;
-
- case O_FLOW6ID:
- if (cmdlen != F_INSN_SIZE(ipfw_insn_u32) +
- ((ipfw_insn_u32 *)cmd)->o.arg1)
- goto bad_size;
- break;
-
- case O_IP6_SRC_MASK:
- case O_IP6_DST_MASK:
- if ( !(cmdlen & 1) || cmdlen > 127)
- goto bad_size;
- break;
- case O_ICMP6TYPE:
- if( cmdlen != F_INSN_SIZE( ipfw_insn_icmp6 ) )
- goto bad_size;
- break;
-#endif
-
- default:
- switch (cmd->opcode) {
-#ifndef INET6
- case O_IP6_SRC_ME:
- case O_IP6_DST_ME:
- case O_EXT_HDR:
- case O_IP6:
- case O_UNREACH6:
- case O_IP6_SRC:
- case O_IP6_DST:
- case O_FLOW6ID:
- case O_IP6_SRC_MASK:
- case O_IP6_DST_MASK:
- case O_ICMP6TYPE:
- printf("ipfw: no IPv6 support in kernel\n");
- return EPROTONOSUPPORT;
-#endif
- default:
- printf("ipfw: opcode %d, unknown opcode\n",
- cmd->opcode);
- return EINVAL;
- }
- }
- }
- if (have_action == 0) {
- printf("ipfw: missing action\n");
- return EINVAL;
- }
- return 0;
-
-bad_size:
- printf("ipfw: opcode %d size %d wrong\n",
- cmd->opcode, cmdlen);
- return EINVAL;
-}
-
-
-/*
- * Translation of requests for compatibility with FreeBSD 7.2/8.
- * a static variable tells us if we have an old client from userland,
- * and if necessary we translate requests and responses between the
- * two formats.
- */
-static int is7 = 0;
-
-struct ip_fw7 {
- struct ip_fw7 *next; /* linked list of rules */
- struct ip_fw7 *next_rule; /* ptr to next [skipto] rule */
- /* 'next_rule' is used to pass up 'set_disable' status */
-
- uint16_t act_ofs; /* offset of action in 32-bit units */
- uint16_t cmd_len; /* # of 32-bit words in cmd */
- uint16_t rulenum; /* rule number */
- uint8_t set; /* rule set (0..31) */
- // #define RESVD_SET 31 /* set for default and persistent rules */
- uint8_t _pad; /* padding */
- // uint32_t id; /* rule id, only in v.8 */
- /* These fields are present in all rules. */
- uint64_t pcnt; /* Packet counter */
- uint64_t bcnt; /* Byte counter */
- uint32_t timestamp; /* tv_sec of last match */
-
- ipfw_insn cmd[1]; /* storage for commands */
-};
-
- int convert_rule_to_7(struct ip_fw *rule);
-int convert_rule_to_8(struct ip_fw *rule);
-
-#ifndef RULESIZE7
-#define RULESIZE7(rule) (sizeof(struct ip_fw7) + \
- ((struct ip_fw7 *)(rule))->cmd_len * 4 - 4)
-#endif
-
-
-/*
- * Copy the static and dynamic rules to the supplied buffer
- * and return the amount of space actually used.
- * Must be run under IPFW_UH_RLOCK
- */
-static size_t
-ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
-{
- char *bp = buf;
- char *ep = bp + space;
- struct ip_fw *rule, *dst;
- int l, i;
- time_t boot_seconds;
-
- boot_seconds = boottime.tv_sec;
- for (i = 0; i < chain->n_rules; i++) {
- rule = chain->map[i];
-
- if (is7) {
- /* Convert rule to FreeBSd 7.2 format */
- l = RULESIZE7(rule);
- if (bp + l + sizeof(uint32_t) <= ep) {
- int error;
- bcopy(rule, bp, l + sizeof(uint32_t));
- error = convert_rule_to_7((struct ip_fw *) bp);
- if (error)
- return 0; /*XXX correct? */
- /*
- * XXX HACK. Store the disable mask in the "next"
- * pointer in a wild attempt to keep the ABI the same.
- * Why do we do this on EVERY rule?
- */
- bcopy(&V_set_disable,
- &(((struct ip_fw7 *)bp)->next_rule),
- sizeof(V_set_disable));
- if (((struct ip_fw7 *)bp)->timestamp)
- ((struct ip_fw7 *)bp)->timestamp += boot_seconds;
- bp += l;
- }
- continue; /* go to next rule */
- }
-
- /* normal mode, don't touch rules */
- l = RULESIZE(rule);
- if (bp + l > ep) { /* should not happen */
- printf("overflow dumping static rules\n");
- break;
- }
- dst = (struct ip_fw *)bp;
- bcopy(rule, dst, l);
- /*
- * XXX HACK. Store the disable mask in the "next"
- * pointer in a wild attempt to keep the ABI the same.
- * Why do we do this on EVERY rule?
- */
- bcopy(&V_set_disable, &dst->next_rule, sizeof(V_set_disable));
- if (dst->timestamp)
- dst->timestamp += boot_seconds;
- bp += l;
- }
- ipfw_get_dynamic(&bp, ep); /* protected by the dynamic lock */
- return (bp - (char *)buf);
-}
-
-
-#define IP_FW3_OPLENGTH(x) ((x)->sopt_valsize - sizeof(ip_fw3_opheader))
-/**
- * {set|get}sockopt parser.
- */
-int
-ipfw_ctl(struct sockopt *sopt)
-{
-#define RULE_MAXSIZE (256*sizeof(u_int32_t))
- int error;
- size_t size, len, valsize;
- struct ip_fw *buf, *rule;
- struct ip_fw_chain *chain;
- u_int32_t rulenum[2];
- uint32_t opt;
- char xbuf[128];
- ip_fw3_opheader *op3 = NULL;
-
- error = priv_check(sopt->sopt_td, PRIV_NETINET_IPFW);
- if (error)
- return (error);
-
- /*
- * Disallow modifications in really-really secure mode, but still allow
- * the logging counters to be reset.
- */
- if (sopt->sopt_name == IP_FW_ADD ||
- (sopt->sopt_dir == SOPT_SET && sopt->sopt_name != IP_FW_RESETLOG)) {
- error = securelevel_ge(sopt->sopt_td->td_ucred, 3);
- if (error)
- return (error);
- }
-
- chain = &V_layer3_chain;
- error = 0;
-
- /* Save original valsize before it is altered via sooptcopyin() */
- valsize = sopt->sopt_valsize;
- if ((opt = sopt->sopt_name) == IP_FW3) {
- /*
- * Copy not less than sizeof(ip_fw3_opheader).
- * We hope any IP_FW3 command will fit into 128-byte buffer.
- */
- if ((error = sooptcopyin(sopt, xbuf, sizeof(xbuf),
- sizeof(ip_fw3_opheader))) != 0)
- return (error);
- op3 = (ip_fw3_opheader *)xbuf;
- opt = op3->opcode;
- }
-
- switch (opt) {
- case IP_FW_GET:
- /*
- * pass up a copy of the current rules. Static rules
- * come first (the last of which has number IPFW_DEFAULT_RULE),
- * followed by a possibly empty list of dynamic rule.
- * The last dynamic rule has NULL in the "next" field.
- *
- * Note that the calculated size is used to bound the
- * amount of data returned to the user. The rule set may
- * change between calculating the size and returning the
- * data in which case we'll just return what fits.
- */
- for (;;) {
- int len = 0, want;
-
- size = chain->static_len;
- size += ipfw_dyn_len();
- if (size >= sopt->sopt_valsize)
- break;
- buf = malloc(size, M_TEMP, M_WAITOK);
- IPFW_UH_RLOCK(chain);
- /* check again how much space we need */
- want = chain->static_len + ipfw_dyn_len();
- if (size >= want)
- len = ipfw_getrules(chain, buf, size);
- IPFW_UH_RUNLOCK(chain);
- if (size >= want)
- error = sooptcopyout(sopt, buf, len);
- free(buf, M_TEMP);
- if (size >= want)
- break;
- }
- break;
-
- case IP_FW_FLUSH:
- /* locking is done within del_entry() */
- error = del_entry(chain, 0); /* special case, rule=0, cmd=0 means all */
- break;
-
- case IP_FW_ADD:
- rule = malloc(RULE_MAXSIZE, M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, rule, RULE_MAXSIZE,
- sizeof(struct ip_fw7) );
-
- /*
- * If the size of commands equals RULESIZE7 then we assume
- * a FreeBSD7.2 binary is talking to us (set is7=1).
- * is7 is persistent so the next 'ipfw list' command
- * will use this format.
- * NOTE: If wrong version is guessed (this can happen if
- * the first ipfw command is 'ipfw [pipe] list')
- * the ipfw binary may crash or loop infinitly...
- */
- if (sopt->sopt_valsize == RULESIZE7(rule)) {
- is7 = 1;
- error = convert_rule_to_8(rule);
- if (error)
- return error;
- if (error == 0)
- error = check_ipfw_struct(rule, RULESIZE(rule));
- } else {
- is7 = 0;
- if (error == 0)
- error = check_ipfw_struct(rule, sopt->sopt_valsize);
- }
- if (error == 0) {
- /* locking is done within ipfw_add_rule() */
- error = ipfw_add_rule(chain, rule);
- size = RULESIZE(rule);
- if (!error && sopt->sopt_dir == SOPT_GET) {
- if (is7) {
- error = convert_rule_to_7(rule);
- size = RULESIZE7(rule);
- if (error)
- return error;
- }
- error = sooptcopyout(sopt, rule, size);
- }
- }
- free(rule, M_TEMP);
- break;
-
- case IP_FW_DEL:
- /*
- * IP_FW_DEL is used for deleting single rules or sets,
- * and (ab)used to atomically manipulate sets. Argument size
- * is used to distinguish between the two:
- * sizeof(u_int32_t)
- * delete single rule or set of rules,
- * or reassign rules (or sets) to a different set.
- * 2*sizeof(u_int32_t)
- * atomic disable/enable sets.
- * first u_int32_t contains sets to be disabled,
- * second u_int32_t contains sets to be enabled.
- */
- error = sooptcopyin(sopt, rulenum,
- 2*sizeof(u_int32_t), sizeof(u_int32_t));
- if (error)
- break;
- size = sopt->sopt_valsize;
- if (size == sizeof(u_int32_t) && rulenum[0] != 0) {
- /* delete or reassign, locking done in del_entry() */
- error = del_entry(chain, rulenum[0]);
- } else if (size == 2*sizeof(u_int32_t)) { /* set enable/disable */
- IPFW_UH_WLOCK(chain);
- V_set_disable =
- (V_set_disable | rulenum[0]) & ~rulenum[1] &
- ~(1<<RESVD_SET); /* set RESVD_SET always enabled */
- IPFW_UH_WUNLOCK(chain);
- } else
- error = EINVAL;
- break;
-
- case IP_FW_ZERO:
- case IP_FW_RESETLOG: /* argument is an u_int_32, the rule number */
- rulenum[0] = 0;
- if (sopt->sopt_val != 0) {
- error = sooptcopyin(sopt, rulenum,
- sizeof(u_int32_t), sizeof(u_int32_t));
- if (error)
- break;
- }
- error = zero_entry(chain, rulenum[0],
- sopt->sopt_name == IP_FW_RESETLOG);
- break;
-
- /*--- TABLE manipulations are protected by the IPFW_LOCK ---*/
- case IP_FW_TABLE_ADD:
- {
- ipfw_table_entry ent;
-
- error = sooptcopyin(sopt, &ent,
- sizeof(ent), sizeof(ent));
- if (error)
- break;
- error = ipfw_add_table_entry(chain, ent.tbl,
- &ent.addr, sizeof(ent.addr), ent.masklen,
- IPFW_TABLE_CIDR, ent.value);
- }
- break;
-
- case IP_FW_TABLE_DEL:
- {
- ipfw_table_entry ent;
-
- error = sooptcopyin(sopt, &ent,
- sizeof(ent), sizeof(ent));
- if (error)
- break;
- error = ipfw_del_table_entry(chain, ent.tbl,
- &ent.addr, sizeof(ent.addr), ent.masklen, IPFW_TABLE_CIDR);
- }
- break;
-
- case IP_FW_TABLE_XADD: /* IP_FW3 */
- case IP_FW_TABLE_XDEL: /* IP_FW3 */
- {
- ipfw_table_xentry *xent = (ipfw_table_xentry *)(op3 + 1);
-
- /* Check minimum header size */
- if (IP_FW3_OPLENGTH(sopt) < offsetof(ipfw_table_xentry, k)) {
- error = EINVAL;
- break;
- }
-
- /* Check if len field is valid */
- if (xent->len > sizeof(ipfw_table_xentry)) {
- error = EINVAL;
- break;
- }
-
- len = xent->len - offsetof(ipfw_table_xentry, k);
-
- error = (opt == IP_FW_TABLE_XADD) ?
- ipfw_add_table_entry(chain, xent->tbl, &xent->k,
- len, xent->masklen, xent->type, xent->value) :
- ipfw_del_table_entry(chain, xent->tbl, &xent->k,
- len, xent->masklen, xent->type);
- }
- break;
-
- case IP_FW_TABLE_FLUSH:
- {
- u_int16_t tbl;
-
- error = sooptcopyin(sopt, &tbl,
- sizeof(tbl), sizeof(tbl));
- if (error)
- break;
- error = ipfw_flush_table(chain, tbl);
- }
- break;
-
- case IP_FW_TABLE_GETSIZE:
- {
- u_int32_t tbl, cnt;
-
- if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl),
- sizeof(tbl))))
- break;
- IPFW_RLOCK(chain);
- error = ipfw_count_table(chain, tbl, &cnt);
- IPFW_RUNLOCK(chain);
- if (error)
- break;
- error = sooptcopyout(sopt, &cnt, sizeof(cnt));
- }
- break;
-
- case IP_FW_TABLE_LIST:
- {
- ipfw_table *tbl;
-
- if (sopt->sopt_valsize < sizeof(*tbl)) {
- error = EINVAL;
- break;
- }
- size = sopt->sopt_valsize;
- tbl = malloc(size, M_TEMP, M_WAITOK);
- error = sooptcopyin(sopt, tbl, size, sizeof(*tbl));
- if (error) {
- free(tbl, M_TEMP);
- break;
- }
- tbl->size = (size - sizeof(*tbl)) /
- sizeof(ipfw_table_entry);
- IPFW_RLOCK(chain);
- error = ipfw_dump_table(chain, tbl);
- IPFW_RUNLOCK(chain);
- if (error) {
- free(tbl, M_TEMP);
- break;
- }
- error = sooptcopyout(sopt, tbl, size);
- free(tbl, M_TEMP);
- }
- break;
-
- case IP_FW_TABLE_XGETSIZE: /* IP_FW3 */
- {
- uint32_t *tbl;
-
- if (IP_FW3_OPLENGTH(sopt) < sizeof(uint32_t)) {
- error = EINVAL;
- break;
- }
-
- tbl = (uint32_t *)(op3 + 1);
-
- IPFW_RLOCK(chain);
- error = ipfw_count_xtable(chain, *tbl, tbl);
- IPFW_RUNLOCK(chain);
- if (error)
- break;
- error = sooptcopyout(sopt, op3, sopt->sopt_valsize);
- }
- break;
-
- case IP_FW_TABLE_XLIST: /* IP_FW3 */
- {
- ipfw_xtable *tbl;
-
- if ((size = valsize) < sizeof(ipfw_xtable)) {
- error = EINVAL;
- break;
- }
-
- tbl = malloc(size, M_TEMP, M_ZERO | M_WAITOK);
- memcpy(tbl, op3, sizeof(ipfw_xtable));
-
- /* Get maximum number of entries we can store */
- tbl->size = (size - sizeof(ipfw_xtable)) /
- sizeof(ipfw_table_xentry);
- IPFW_RLOCK(chain);
- error = ipfw_dump_xtable(chain, tbl);
- IPFW_RUNLOCK(chain);
- if (error) {
- free(tbl, M_TEMP);
- break;
- }
-
- /* Revert size field back to bytes */
- tbl->size = tbl->size * sizeof(ipfw_table_xentry) +
- sizeof(ipfw_table);
- /*
- * Since we call sooptcopyin() with small buffer, sopt_valsize is
- * decreased to reflect supplied buffer size. Set it back to original value
- */
- sopt->sopt_valsize = valsize;
- error = sooptcopyout(sopt, tbl, size);
- free(tbl, M_TEMP);
- }
- break;
-
- /*--- NAT operations are protected by the IPFW_LOCK ---*/
- case IP_FW_NAT_CFG:
- if (IPFW_NAT_LOADED)
- error = ipfw_nat_cfg_ptr(sopt);
- else {
- printf("IP_FW_NAT_CFG: %s\n",
- "ipfw_nat not present, please load it");
- error = EINVAL;
- }
- break;
-
- case IP_FW_NAT_DEL:
- if (IPFW_NAT_LOADED)
- error = ipfw_nat_del_ptr(sopt);
- else {
- printf("IP_FW_NAT_DEL: %s\n",
- "ipfw_nat not present, please load it");
- error = EINVAL;
- }
- break;
-
- case IP_FW_NAT_GET_CONFIG:
- if (IPFW_NAT_LOADED)
- error = ipfw_nat_get_cfg_ptr(sopt);
- else {
- printf("IP_FW_NAT_GET_CFG: %s\n",
- "ipfw_nat not present, please load it");
- error = EINVAL;
- }
- break;
-
- case IP_FW_NAT_GET_LOG:
- if (IPFW_NAT_LOADED)
- error = ipfw_nat_get_log_ptr(sopt);
- else {
- printf("IP_FW_NAT_GET_LOG: %s\n",
- "ipfw_nat not present, please load it");
- error = EINVAL;
- }
- break;
-
- default:
- printf("ipfw: ipfw_ctl invalid option %d\n", sopt->sopt_name);
- error = EINVAL;
- }
-
- return (error);
-#undef RULE_MAXSIZE
-}
-
-
-#define RULE_MAXSIZE (256*sizeof(u_int32_t))
-
-/* Functions to convert rules 7.2 <==> 8.0 */
-int
-convert_rule_to_7(struct ip_fw *rule)
-{
- /* Used to modify original rule */
- struct ip_fw7 *rule7 = (struct ip_fw7 *)rule;
- /* copy of original rule, version 8 */
- struct ip_fw *tmp;
-
- /* Used to copy commands */
- ipfw_insn *ccmd, *dst;
- int ll = 0, ccmdlen = 0;
-
- tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
- if (tmp == NULL) {
- return 1; //XXX error
- }
- bcopy(rule, tmp, RULE_MAXSIZE);
-
- /* Copy fields */
- rule7->_pad = tmp->_pad;
- rule7->set = tmp->set;
- rule7->rulenum = tmp->rulenum;
- rule7->cmd_len = tmp->cmd_len;
- rule7->act_ofs = tmp->act_ofs;
- rule7->next_rule = (struct ip_fw7 *)tmp->next_rule;
- rule7->next = (struct ip_fw7 *)tmp->x_next;
- rule7->cmd_len = tmp->cmd_len;
- rule7->pcnt = tmp->pcnt;
- rule7->bcnt = tmp->bcnt;
- rule7->timestamp = tmp->timestamp;
-
- /* Copy commands */
- for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule7->cmd ;
- ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
- ccmdlen = F_LEN(ccmd);
-
- bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
-
- if (dst->opcode > O_NAT)
- /* O_REASS doesn't exists in 7.2 version, so
- * decrement opcode if it is after O_REASS
- */
- dst->opcode--;
-
- if (ccmdlen > ll) {
- printf("ipfw: opcode %d size truncated\n",
- ccmd->opcode);
- return EINVAL;
- }
- }
- free(tmp, M_TEMP);
-
- return 0;
-}
-
-int
-convert_rule_to_8(struct ip_fw *rule)
-{
- /* Used to modify original rule */
- struct ip_fw7 *rule7 = (struct ip_fw7 *) rule;
-
- /* Used to copy commands */
- ipfw_insn *ccmd, *dst;
- int ll = 0, ccmdlen = 0;
-
- /* Copy of original rule */
- struct ip_fw7 *tmp = malloc(RULE_MAXSIZE, M_TEMP, M_NOWAIT | M_ZERO);
- if (tmp == NULL) {
- return 1; //XXX error
- }
-
- bcopy(rule7, tmp, RULE_MAXSIZE);
-
- for (ll = tmp->cmd_len, ccmd = tmp->cmd, dst = rule->cmd ;
- ll > 0 ; ll -= ccmdlen, ccmd += ccmdlen, dst += ccmdlen) {
- ccmdlen = F_LEN(ccmd);
-
- bcopy(ccmd, dst, F_LEN(ccmd)*sizeof(uint32_t));
-
- if (dst->opcode > O_NAT)
- /* O_REASS doesn't exists in 7.2 version, so
- * increment opcode if it is after O_REASS
- */
- dst->opcode++;
-
- if (ccmdlen > ll) {
- printf("ipfw: opcode %d size truncated\n",
- ccmd->opcode);
- return EINVAL;
- }
- }
-
- rule->_pad = tmp->_pad;
- rule->set = tmp->set;
- rule->rulenum = tmp->rulenum;
- rule->cmd_len = tmp->cmd_len;
- rule->act_ofs = tmp->act_ofs;
- rule->next_rule = (struct ip_fw *)tmp->next_rule;
- rule->x_next = (struct ip_fw *)tmp->next;
- rule->cmd_len = tmp->cmd_len;
- rule->id = 0; /* XXX see if is ok = 0 */
- rule->pcnt = tmp->pcnt;
- rule->bcnt = tmp->bcnt;
- rule->timestamp = tmp->timestamp;
-
- free (tmp, M_TEMP);
- return 0;
-}
-
-/* end of file */
diff --git a/sys/netinet/ipfw/ip_fw_table.c b/sys/netinet/ipfw/ip_fw_table.c
deleted file mode 100644
index 597817b..0000000
--- a/sys/netinet/ipfw/ip_fw_table.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/*-
- * Copyright (c) 2004 Ruslan Ermilov and Vsevolod Lobko.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * Lookup table support for ipfw
- *
- * Lookup tables are implemented (at the moment) using the radix
- * tree used for routing tables. Tables store key-value entries, where
- * keys are network prefixes (addr/masklen), and values are integers.
- * As a degenerate case we can interpret keys as 32-bit integers
- * (with a /32 mask).
- *
- * The table is protected by the IPFW lock even for manipulation coming
- * from userland, because operations are typically fast.
- */
-
-#include "opt_ipfw.h"
-#include "opt_inet.h"
-#ifndef INET
-#error IPFIREWALL requires INET.
-#endif /* INET */
-#include "opt_inet6.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/rwlock.h>
-#include <sys/socket.h>
-#include <net/if.h> /* ip_fw.h requires IFNAMSIZ */
-#include <net/radix.h>
-#include <net/route.h>
-#include <net/vnet.h>
-
-#include <netinet/in.h>
-#include <netinet/ip_var.h> /* struct ipfw_rule_ref */
-#include <netinet/ip_fw.h>
-#include <sys/queue.h> /* LIST_HEAD */
-#include <netinet/ipfw/ip_fw_private.h>
-
-#ifdef MAC
-#include <security/mac/mac_framework.h>
-#endif
-
-static MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
-
-struct table_entry {
- struct radix_node rn[2];
- struct sockaddr_in addr, mask;
- u_int32_t value;
-};
-
-struct xaddr_iface {
- uint8_t if_len; /* length of this struct */
- uint8_t pad[7]; /* Align name */
- char ifname[IF_NAMESIZE]; /* Interface name */
-};
-
-struct table_xentry {
- struct radix_node rn[2];
- union {
-#ifdef INET6
- struct sockaddr_in6 addr6;
-#endif
- struct xaddr_iface iface;
- } a;
- union {
-#ifdef INET6
- struct sockaddr_in6 mask6;
-#endif
- struct xaddr_iface ifmask;
- } m;
- u_int32_t value;
-};
-
-/*
- * The radix code expects addr and mask to be array of bytes,
- * with the first byte being the length of the array. rn_inithead
- * is called with the offset in bits of the lookup key within the
- * array. If we use a sockaddr_in as the underlying type,
- * sin_len is conveniently located at offset 0, sin_addr is at
- * offset 4 and normally aligned.
- * But for portability, let's avoid assumption and make the code explicit
- */
-#define KEY_LEN(v) *((uint8_t *)&(v))
-#define KEY_OFS (8*offsetof(struct sockaddr_in, sin_addr))
-/*
- * Do not require radix to compare more than actual IPv4/IPv6 address
- */
-#define KEY_LEN_INET (offsetof(struct sockaddr_in, sin_addr) + sizeof(in_addr_t))
-#define KEY_LEN_INET6 (offsetof(struct sockaddr_in6, sin6_addr) + sizeof(struct in6_addr))
-#define KEY_LEN_IFACE (offsetof(struct xaddr_iface, ifname))
-
-#define OFF_LEN_INET (8 * offsetof(struct sockaddr_in, sin_addr))
-#define OFF_LEN_INET6 (8 * offsetof(struct sockaddr_in6, sin6_addr))
-#define OFF_LEN_IFACE (8 * offsetof(struct xaddr_iface, ifname))
-
-
-static inline void
-ipv6_writemask(struct in6_addr *addr6, uint8_t mask)
-{
- uint32_t *cp;
-
- for (cp = (uint32_t *)addr6; mask >= 32; mask -= 32)
- *cp++ = 0xFFFFFFFF;
- *cp = htonl(mask ? ~((1 << (32 - mask)) - 1) : 0);
-}
-
-int
-ipfw_add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
- uint8_t plen, uint8_t mlen, uint8_t type, uint32_t value)
-{
- struct radix_node_head *rnh, **rnh_ptr;
- struct table_entry *ent;
- struct table_xentry *xent;
- struct radix_node *rn;
- in_addr_t addr;
- int offset;
- void *ent_ptr;
- struct sockaddr *addr_ptr, *mask_ptr;
- char c;
-
- if (tbl >= V_fw_tables_max)
- return (EINVAL);
-
- switch (type) {
- case IPFW_TABLE_CIDR:
- if (plen == sizeof(in_addr_t)) {
-#ifdef INET
- /* IPv4 case */
- if (mlen > 32)
- return (EINVAL);
- ent = malloc(sizeof(*ent), M_IPFW_TBL, M_WAITOK | M_ZERO);
- ent->value = value;
- /* Set 'total' structure length */
- KEY_LEN(ent->addr) = KEY_LEN_INET;
- KEY_LEN(ent->mask) = KEY_LEN_INET;
- /* Set offset of IPv4 address in bits */
- offset = OFF_LEN_INET;
- ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
- addr = *((in_addr_t *)paddr);
- ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
- /* Set pointers */
- rnh_ptr = &ch->tables[tbl];
- ent_ptr = ent;
- addr_ptr = (struct sockaddr *)&ent->addr;
- mask_ptr = (struct sockaddr *)&ent->mask;
-#endif
-#ifdef INET6
- } else if (plen == sizeof(struct in6_addr)) {
- /* IPv6 case */
- if (mlen > 128)
- return (EINVAL);
- xent = malloc(sizeof(*xent), M_IPFW_TBL, M_WAITOK | M_ZERO);
- xent->value = value;
- /* Set 'total' structure length */
- KEY_LEN(xent->a.addr6) = KEY_LEN_INET6;
- KEY_LEN(xent->m.mask6) = KEY_LEN_INET6;
- /* Set offset of IPv6 address in bits */
- offset = OFF_LEN_INET6;
- ipv6_writemask(&xent->m.mask6.sin6_addr, mlen);
- memcpy(&xent->a.addr6.sin6_addr, paddr, sizeof(struct in6_addr));
- APPLY_MASK(&xent->a.addr6.sin6_addr, &xent->m.mask6.sin6_addr);
- /* Set pointers */
- rnh_ptr = &ch->xtables[tbl];
- ent_ptr = xent;
- addr_ptr = (struct sockaddr *)&xent->a.addr6;
- mask_ptr = (struct sockaddr *)&xent->m.mask6;
-#endif
- } else {
- /* Unknown CIDR type */
- return (EINVAL);
- }
- break;
-
- case IPFW_TABLE_INTERFACE:
- /* Check if string is terminated */
- c = ((char *)paddr)[IF_NAMESIZE - 1];
- ((char *)paddr)[IF_NAMESIZE - 1] = '\0';
- if (((mlen = strlen((char *)paddr)) == IF_NAMESIZE - 1) && (c != '\0'))
- return (EINVAL);
-
- /* Include last \0 into comparison */
- mlen++;
-
- xent = malloc(sizeof(*xent), M_IPFW_TBL, M_WAITOK | M_ZERO);
- xent->value = value;
- /* Set 'total' structure length */
- KEY_LEN(xent->a.iface) = KEY_LEN_IFACE + mlen;
- KEY_LEN(xent->m.ifmask) = KEY_LEN_IFACE + mlen;
- /* Set offset of interface name in bits */
- offset = OFF_LEN_IFACE;
- memcpy(xent->a.iface.ifname, paddr, mlen);
- /* Assume direct match */
- /* TODO: Add interface pattern matching */
-#if 0
- memset(xent->m.ifmask.ifname, 0xFF, IF_NAMESIZE);
- mask_ptr = (struct sockaddr *)&xent->m.ifmask;
-#endif
- /* Set pointers */
- rnh_ptr = &ch->xtables[tbl];
- ent_ptr = xent;
- addr_ptr = (struct sockaddr *)&xent->a.iface;
- mask_ptr = NULL;
- break;
-
- default:
- return (EINVAL);
- }
-
- IPFW_WLOCK(ch);
-
- /* Check if tabletype is valid */
- if ((ch->tabletype[tbl] != 0) && (ch->tabletype[tbl] != type)) {
- IPFW_WUNLOCK(ch);
- free(ent_ptr, M_IPFW_TBL);
- return (EINVAL);
- }
-
- /* Check if radix tree exists */
- if ((rnh = *rnh_ptr) == NULL) {
- IPFW_WUNLOCK(ch);
- /* Create radix for a new table */
- if (!rn_inithead((void **)&rnh, offset)) {
- free(ent_ptr, M_IPFW_TBL);
- return (ENOMEM);
- }
-
- IPFW_WLOCK(ch);
- if (*rnh_ptr != NULL) {
- /* Tree is already attached by other thread */
- rn_detachhead((void **)&rnh);
- rnh = *rnh_ptr;
- /* Check table type another time */
- if (ch->tabletype[tbl] != type) {
- IPFW_WUNLOCK(ch);
- free(ent_ptr, M_IPFW_TBL);
- return (EINVAL);
- }
- } else {
- *rnh_ptr = rnh;
- /*
- * Set table type. It can be set already
- * (if we have IPv6-only table) but setting
- * it another time does not hurt
- */
- ch->tabletype[tbl] = type;
- }
- }
-
- rn = rnh->rnh_addaddr(addr_ptr, mask_ptr, rnh, ent_ptr);
- IPFW_WUNLOCK(ch);
-
- if (rn == NULL) {
- free(ent_ptr, M_IPFW_TBL);
- return (EEXIST);
- }
- return (0);
-}
-
-int
-ipfw_del_table_entry(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
- uint8_t plen, uint8_t mlen, uint8_t type)
-{
- struct radix_node_head *rnh, **rnh_ptr;
- struct table_entry *ent;
- in_addr_t addr;
- struct sockaddr_in sa, mask;
- struct sockaddr *sa_ptr, *mask_ptr;
- char c;
-
- if (tbl >= V_fw_tables_max)
- return (EINVAL);
-
- switch (type) {
- case IPFW_TABLE_CIDR:
- if (plen == sizeof(in_addr_t)) {
- /* Set 'total' structure length */
- KEY_LEN(sa) = KEY_LEN_INET;
- KEY_LEN(mask) = KEY_LEN_INET;
- mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
- addr = *((in_addr_t *)paddr);
- sa.sin_addr.s_addr = addr & mask.sin_addr.s_addr;
- rnh_ptr = &ch->tables[tbl];
- sa_ptr = (struct sockaddr *)&sa;
- mask_ptr = (struct sockaddr *)&mask;
-#ifdef INET6
- } else if (plen == sizeof(struct in6_addr)) {
- /* IPv6 case */
- if (mlen > 128)
- return (EINVAL);
- struct sockaddr_in6 sa6, mask6;
- memset(&sa6, 0, sizeof(struct sockaddr_in6));
- memset(&mask6, 0, sizeof(struct sockaddr_in6));
- /* Set 'total' structure length */
- KEY_LEN(sa6) = KEY_LEN_INET6;
- KEY_LEN(mask6) = KEY_LEN_INET6;
- ipv6_writemask(&mask6.sin6_addr, mlen);
- memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr));
- APPLY_MASK(&sa6.sin6_addr, &mask6.sin6_addr);
- rnh_ptr = &ch->xtables[tbl];
- sa_ptr = (struct sockaddr *)&sa6;
- mask_ptr = (struct sockaddr *)&mask6;
-#endif
- } else {
- /* Unknown CIDR type */
- return (EINVAL);
- }
- break;
-
- case IPFW_TABLE_INTERFACE:
- /* Check if string is terminated */
- c = ((char *)paddr)[IF_NAMESIZE - 1];
- ((char *)paddr)[IF_NAMESIZE - 1] = '\0';
- if (((mlen = strlen((char *)paddr)) == IF_NAMESIZE - 1) && (c != '\0'))
- return (EINVAL);
-
- struct xaddr_iface ifname, ifmask;
- memset(&ifname, 0, sizeof(ifname));
-
- /* Set 'total' structure length */
- KEY_LEN(ifname) = mlen;
- KEY_LEN(ifmask) = mlen;
- /* Assume direct match */
- /* FIXME: Add interface pattern matching */
-#if 0
- memset(ifmask.ifname, 0xFF, IF_NAMESIZE);
- mask_ptr = (struct sockaddr *)&ifmask;
-#endif
- mask_ptr = NULL;
- memcpy(ifname.ifname, paddr, mlen);
- /* Set pointers */
- rnh_ptr = &ch->xtables[tbl];
- sa_ptr = (struct sockaddr *)&ifname;
-
- break;
-
- default:
- return (EINVAL);
- }
-
- IPFW_WLOCK(ch);
- if ((rnh = *rnh_ptr) == NULL) {
- IPFW_WUNLOCK(ch);
- return (ESRCH);
- }
-
- if (ch->tabletype[tbl] != type) {
- IPFW_WUNLOCK(ch);
- return (EINVAL);
- }
-
- ent = (struct table_entry *)rnh->rnh_deladdr(sa_ptr, mask_ptr, rnh);
- IPFW_WUNLOCK(ch);
-
- if (ent == NULL)
- return (ESRCH);
-
- free(ent, M_IPFW_TBL);
- return (0);
-}
-
-static int
-flush_table_entry(struct radix_node *rn, void *arg)
-{
- struct radix_node_head * const rnh = arg;
- struct table_entry *ent;
-
- ent = (struct table_entry *)
- rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, rnh);
- if (ent != NULL)
- free(ent, M_IPFW_TBL);
- return (0);
-}
-
-int
-ipfw_flush_table(struct ip_fw_chain *ch, uint16_t tbl)
-{
- struct radix_node_head *rnh, *xrnh;
-
- if (tbl >= V_fw_tables_max)
- return (EINVAL);
-
- /*
- * We free both (IPv4 and extended) radix trees and
- * clear table type here to permit table to be reused
- * for different type without module reload
- */
-
- IPFW_WLOCK(ch);
- /* Set IPv4 table pointer to zero */
- if ((rnh = ch->tables[tbl]) != NULL)
- ch->tables[tbl] = NULL;
- /* Set extended table pointer to zero */
- if ((xrnh = ch->xtables[tbl]) != NULL)
- ch->xtables[tbl] = NULL;
- /* Zero table type */
- ch->tabletype[tbl] = 0;
- IPFW_WUNLOCK(ch);
-
- if (rnh != NULL) {
- rnh->rnh_walktree(rnh, flush_table_entry, rnh);
- rn_detachhead((void **)&rnh);
- }
-
- if (xrnh != NULL) {
- xrnh->rnh_walktree(xrnh, flush_table_entry, xrnh);
- rn_detachhead((void **)&xrnh);
- }
-
- return (0);
-}
-
-void
-ipfw_destroy_tables(struct ip_fw_chain *ch)
-{
- uint16_t tbl;
-
- /* Flush all tables */
- for (tbl = 0; tbl < V_fw_tables_max; tbl++)
- ipfw_flush_table(ch, tbl);
-
- /* Free pointers itself */
- free(ch->tables, M_IPFW);
- free(ch->xtables, M_IPFW);
- free(ch->tabletype, M_IPFW);
-}
-
-int
-ipfw_init_tables(struct ip_fw_chain *ch)
-{
- /* Allocate pointers */
- ch->tables = malloc(V_fw_tables_max * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
- ch->xtables = malloc(V_fw_tables_max * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
- ch->tabletype = malloc(V_fw_tables_max * sizeof(uint8_t), M_IPFW, M_WAITOK | M_ZERO);
- return (0);
-}
-
-int
-ipfw_resize_tables(struct ip_fw_chain *ch, unsigned int ntables)
-{
- struct radix_node_head **tables, **xtables, *rnh;
- struct radix_node_head **tables_old, **xtables_old;
- uint8_t *tabletype, *tabletype_old;
- unsigned int ntables_old, tbl;
-
- /* Check new value for validity */
- if (ntables > IPFW_TABLES_MAX)
- ntables = IPFW_TABLES_MAX;
-
- /* Allocate new pointers */
- tables = malloc(ntables * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
- xtables = malloc(ntables * sizeof(void *), M_IPFW, M_WAITOK | M_ZERO);
- tabletype = malloc(ntables * sizeof(uint8_t), M_IPFW, M_WAITOK | M_ZERO);
-
- IPFW_WLOCK(ch);
-
- tbl = (ntables >= V_fw_tables_max) ? V_fw_tables_max : ntables;
-
- /* Copy old table pointers */
- memcpy(tables, ch->tables, sizeof(void *) * tbl);
- memcpy(xtables, ch->xtables, sizeof(void *) * tbl);
- memcpy(tabletype, ch->tabletype, sizeof(uint8_t) * tbl);
-
- /* Change pointers and number of tables */
- tables_old = ch->tables;
- xtables_old = ch->xtables;
- tabletype_old = ch->tabletype;
- ch->tables = tables;
- ch->xtables = xtables;
- ch->tabletype = tabletype;
-
- ntables_old = V_fw_tables_max;
- V_fw_tables_max = ntables;
-
- IPFW_WUNLOCK(ch);
-
- /* Check if we need to destroy radix trees */
- if (ntables < ntables_old) {
- for (tbl = ntables; tbl < ntables_old; tbl++) {
- if ((rnh = tables_old[tbl]) != NULL) {
- rnh->rnh_walktree(rnh, flush_table_entry, rnh);
- rn_detachhead((void **)&rnh);
- }
-
- if ((rnh = xtables_old[tbl]) != NULL) {
- rnh->rnh_walktree(rnh, flush_table_entry, rnh);
- rn_detachhead((void **)&rnh);
- }
- }
- }
-
- /* Free old pointers */
- free(tables_old, M_IPFW);
- free(xtables_old, M_IPFW);
- free(tabletype_old, M_IPFW);
-
- return (0);
-}
-
-int
-ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
- uint32_t *val)
-{
- struct radix_node_head *rnh;
- struct table_entry *ent;
- struct sockaddr_in sa;
-
- if (tbl >= V_fw_tables_max)
- return (0);
- if ((rnh = ch->tables[tbl]) == NULL)
- return (0);
- KEY_LEN(sa) = KEY_LEN_INET;
- sa.sin_addr.s_addr = addr;
- ent = (struct table_entry *)(rnh->rnh_lookup(&sa, NULL, rnh));
- if (ent != NULL) {
- *val = ent->value;
- return (1);
- }
- return (0);
-}
-
-int
-ipfw_lookup_table_extended(struct ip_fw_chain *ch, uint16_t tbl, void *paddr,
- uint32_t *val, int type)
-{
- struct radix_node_head *rnh;
- struct table_xentry *xent;
- struct sockaddr_in6 sa6;
- struct xaddr_iface iface;
-
- if (tbl >= V_fw_tables_max)
- return (0);
- if ((rnh = ch->xtables[tbl]) == NULL)
- return (0);
-
- switch (type) {
- case IPFW_TABLE_CIDR:
- KEY_LEN(sa6) = KEY_LEN_INET6;
- memcpy(&sa6.sin6_addr, paddr, sizeof(struct in6_addr));
- xent = (struct table_xentry *)(rnh->rnh_lookup(&sa6, NULL, rnh));
- break;
-
- case IPFW_TABLE_INTERFACE:
- KEY_LEN(iface) = KEY_LEN_IFACE +
- strlcpy(iface.ifname, (char *)paddr, IF_NAMESIZE);
- /* Assume direct match */
- /* FIXME: Add interface pattern matching */
- xent = (struct table_xentry *)(rnh->rnh_lookup(&iface, NULL, rnh));
- break;
-
- default:
- return (0);
- }
-
- if (xent != NULL) {
- *val = xent->value;
- return (1);
- }
- return (0);
-}
-
-static int
-count_table_entry(struct radix_node *rn, void *arg)
-{
- u_int32_t * const cnt = arg;
-
- (*cnt)++;
- return (0);
-}
-
-int
-ipfw_count_table(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
-{
- struct radix_node_head *rnh;
-
- if (tbl >= V_fw_tables_max)
- return (EINVAL);
- *cnt = 0;
- if ((rnh = ch->tables[tbl]) == NULL)
- return (0);
- rnh->rnh_walktree(rnh, count_table_entry, cnt);
- return (0);
-}
-
-static int
-dump_table_entry(struct radix_node *rn, void *arg)
-{
- struct table_entry * const n = (struct table_entry *)rn;
- ipfw_table * const tbl = arg;
- ipfw_table_entry *ent;
-
- if (tbl->cnt == tbl->size)
- return (1);
- ent = &tbl->ent[tbl->cnt];
- ent->tbl = tbl->tbl;
- if (in_nullhost(n->mask.sin_addr))
- ent->masklen = 0;
- else
- ent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
- ent->addr = n->addr.sin_addr.s_addr;
- ent->value = n->value;
- tbl->cnt++;
- return (0);
-}
-
-int
-ipfw_dump_table(struct ip_fw_chain *ch, ipfw_table *tbl)
-{
- struct radix_node_head *rnh;
-
- if (tbl->tbl >= V_fw_tables_max)
- return (EINVAL);
- tbl->cnt = 0;
- if ((rnh = ch->tables[tbl->tbl]) == NULL)
- return (0);
- rnh->rnh_walktree(rnh, dump_table_entry, tbl);
- return (0);
-}
-
-static int
-count_table_xentry(struct radix_node *rn, void *arg)
-{
- uint32_t * const cnt = arg;
-
- (*cnt) += sizeof(ipfw_table_xentry);
- return (0);
-}
-
-int
-ipfw_count_xtable(struct ip_fw_chain *ch, uint32_t tbl, uint32_t *cnt)
-{
- struct radix_node_head *rnh;
-
- if (tbl >= V_fw_tables_max)
- return (EINVAL);
- *cnt = 0;
- if ((rnh = ch->tables[tbl]) != NULL)
- rnh->rnh_walktree(rnh, count_table_xentry, cnt);
- if ((rnh = ch->xtables[tbl]) != NULL)
- rnh->rnh_walktree(rnh, count_table_xentry, cnt);
- /* Return zero if table is empty */
- if (*cnt > 0)
- (*cnt) += sizeof(ipfw_xtable);
- return (0);
-}
-
-
-static int
-dump_table_xentry_base(struct radix_node *rn, void *arg)
-{
- struct table_entry * const n = (struct table_entry *)rn;
- ipfw_xtable * const tbl = arg;
- ipfw_table_xentry *xent;
-
- /* Out of memory, returning */
- if (tbl->cnt == tbl->size)
- return (1);
- xent = &tbl->xent[tbl->cnt];
- xent->len = sizeof(ipfw_table_xentry);
- xent->tbl = tbl->tbl;
- if (in_nullhost(n->mask.sin_addr))
- xent->masklen = 0;
- else
- xent->masklen = 33 - ffs(ntohl(n->mask.sin_addr.s_addr));
- /* Save IPv4 address as deprecated IPv6 compatible */
- xent->k.addr6.s6_addr32[3] = n->addr.sin_addr.s_addr;
- xent->value = n->value;
- tbl->cnt++;
- return (0);
-}
-
-static int
-dump_table_xentry_extended(struct radix_node *rn, void *arg)
-{
- struct table_xentry * const n = (struct table_xentry *)rn;
- ipfw_xtable * const tbl = arg;
- ipfw_table_xentry *xent;
-#ifdef INET6
- int i;
- uint32_t *v;
-#endif
- /* Out of memory, returning */
- if (tbl->cnt == tbl->size)
- return (1);
- xent = &tbl->xent[tbl->cnt];
- xent->len = sizeof(ipfw_table_xentry);
- xent->tbl = tbl->tbl;
-
- switch (tbl->type) {
-#ifdef INET6
- case IPFW_TABLE_CIDR:
- /* Count IPv6 mask */
- v = (uint32_t *)&n->m.mask6.sin6_addr;
- for (i = 0; i < sizeof(struct in6_addr) / 4; i++, v++)
- xent->masklen += bitcount32(*v);
- memcpy(&xent->k, &n->a.addr6.sin6_addr, sizeof(struct in6_addr));
- break;
-#endif
- case IPFW_TABLE_INTERFACE:
- /* Assume exact mask */
- xent->masklen = 8 * IF_NAMESIZE;
- memcpy(&xent->k, &n->a.iface.ifname, IF_NAMESIZE);
- break;
-
- default:
- /* unknown, skip entry */
- return (0);
- }
-
- xent->value = n->value;
- tbl->cnt++;
- return (0);
-}
-
-int
-ipfw_dump_xtable(struct ip_fw_chain *ch, ipfw_xtable *tbl)
-{
- struct radix_node_head *rnh;
-
- if (tbl->tbl >= V_fw_tables_max)
- return (EINVAL);
- tbl->cnt = 0;
- tbl->type = ch->tabletype[tbl->tbl];
- if ((rnh = ch->tables[tbl->tbl]) != NULL)
- rnh->rnh_walktree(rnh, dump_table_xentry_base, tbl);
- if ((rnh = ch->xtables[tbl->tbl]) != NULL)
- rnh->rnh_walktree(rnh, dump_table_xentry_extended, tbl);
- return (0);
-}
-
-/* end of file */
diff --git a/sys/netinet/ipfw/test/Makefile b/sys/netinet/ipfw/test/Makefile
deleted file mode 100644
index c556a4b..0000000
--- a/sys/netinet/ipfw/test/Makefile
+++ /dev/null
@@ -1,51 +0,0 @@
-#
-# $FreeBSD$
-#
-# Makefile for building userland tests
-# this is written in a form compatible with gmake
-
-SCHED_SRCS = test_dn_sched.c
-SCHED_SRCS += dn_sched_fifo.c
-SCHED_SRCS += dn_sched_prio.c
-SCHED_SRCS += dn_sched_qfq.c
-SCHED_SRCS += dn_sched_rr.c
-SCHED_SRCS += dn_sched_wf2q.c
-SCHED_SRCS += dn_heap.c
-SCHED_SRCS += main.c
-
-SCHED_OBJS=$(SCHED_SRCS:.c=.o)
-
-HEAP_SRCS = dn_heap.c test_dn_heap.c
-HEAP_OBJS=$(HEAP_SRCS:.c=.o)
-
-VPATH= .:..
-
-CFLAGS = -I.. -I. -Wall -Werror -O3 -DIPFW
-TARGETS= test_sched # no test_heap by default
-
-all: $(TARGETS)
-
-test_heap : $(HEAP_OBJS)
- $(CC) -o $@ $(HEAP_OBJS)
-
-test_sched : $(SCHED_OBJS)
- $(CC) -o $@ $(SCHED_OBJS)
-
-$(SCHED_OBJS): dn_test.h
-main.o: mylist.h
-
-clean:
- - rm *.o $(TARGETS) *.core
-
-ALLSRCS = $(SCHED_SRCS) dn_test.h mylist.h \
- dn_sched.h dn_heap.h ip_dn_private.h Makefile
-TMPBASE = /tmp/testXYZ
-TMPDIR = $(TMPBASE)/test
-
-tgz:
- -rm -rf $(TMPDIR)
- mkdir -p $(TMPDIR)
- -cp -p $(ALLSRCS) $(TMPDIR)
- -(cd ..; cp -p $(ALLSRCS) $(TMPDIR))
- ls -la $(TMPDIR)
- (cd $(TMPBASE); tar cvzf /tmp/test.tgz test)
diff --git a/sys/netinet/ipfw/test/dn_test.h b/sys/netinet/ipfw/test/dn_test.h
deleted file mode 100644
index 4e079bc..0000000
--- a/sys/netinet/ipfw/test/dn_test.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * $FreeBSD$
- *
- * userspace compatibility code for dummynet schedulers
- */
-
-#ifndef _DN_TEST_H
-#define _DN_TEST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h> /* bzero, ffs, ... */
-#include <string.h> /* strcmp */
-#include <errno.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-extern int debug;
-#define ND(fmt, args...) do {} while (0)
-#define D1(fmt, args...) do {} while (0)
-#define D(fmt, args...) fprintf(stderr, "%-8s " fmt "\n", \
- __FUNCTION__, ## args)
-#define DX(lev, fmt, args...) do { \
- if (debug > lev) D(fmt, ## args); } while (0)
-
-
-#ifndef offsetof
-#define offsetof(t,m) (int)((&((t *)0L)->m))
-#endif
-
-#include <mylist.h>
-
-/* prevent include of other system headers */
-#define _NETINET_IP_VAR_H_ /* ip_fw_args */
-#define _IPFW2_H
-#define _SYS_MBUF_H_
-
-enum {
- DN_QUEUE,
-};
-
-enum {
- DN_SCHED_FIFO,
- DN_SCHED_WF2QP,
-};
-
-struct dn_id {
- int type, subtype, len, id;
-};
-
-struct dn_fs {
- int par[4]; /* flowset parameters */
-
- /* simulation entries.
- * 'index' is not strictly necessary
- * y is used for the inverse mapping ,
- */
- int index;
- int y; /* inverse mapping */
- int base_y; /* inverse mapping */
- int next_y; /* inverse mapping */
- int n_flows;
- int first_flow;
- int next_flow; /* first_flow + n_flows */
- /*
- * when generating, let 'cur' go from 0 to n_flows-1,
- * then point to flow first_flow + cur
- */
- int cur;
-};
-
-struct dn_sch {
-};
-
-struct dn_flow {
- struct dn_id oid;
- int length;
- int len_bytes;
- int drops;
- uint64_t tot_bytes;
- uint32_t flow_id;
- struct list_head h; /* used by the generator */
-};
-
-struct dn_link {
-};
-
-struct ip_fw_args {
-};
-
-struct mbuf {
- struct {
- int len;
- } m_pkthdr;
- struct mbuf *m_nextpkt;
- int flow_id; /* for testing, index of a flow */
- //int flowset_id; /* for testing, index of a flowset */
- void *cfg; /* config args */
-};
-
-#define MALLOC_DECLARE(x)
-#define KASSERT(x, y) do { if (!(x)) printf y ; exit(0); } while (0)
-struct ipfw_flow_id {
-};
-
-typedef void * module_t;
-
-struct _md_t {
- const char *name;
- int (*f)(module_t, int, void *);
- void *p;
-};
-
-typedef struct _md_t moduledata_t;
-
-#define DECLARE_MODULE(name, b, c, d) \
- moduledata_t *_g_##name = & b
-#define MODULE_DEPEND(a, b, c, d, e)
-
-#ifdef IPFW
-#include <dn_heap.h>
-#include <ip_dn_private.h>
-#include <dn_sched.h>
-#else
-struct dn_queue {
- struct dn_fsk *fs; /* parent flowset. */
- struct dn_sch_inst *_si; /* parent sched instance. */
-};
-struct dn_schk {
-};
-struct dn_fsk {
- struct dn_fs fs;
- struct dn_schk *sched;
-};
-struct dn_sch_inst {
- struct dn_schk *sched;
-};
-struct dn_alg {
- int type;
- const char *name;
- void *enqueue, *dequeue;
- int q_datalen, si_datalen, schk_datalen;
- int (*config)(struct dn_schk *);
- int (*new_sched)(struct dn_sch_inst *);
- int (*new_fsk)(struct dn_fsk *);
- int (*new_queue)(struct dn_queue *q);
-};
-
-#endif
-
-#ifndef __FreeBSD__
-int fls(int);
-#endif
-
-static inline void
-mq_append(struct mq *q, struct mbuf *m)
-{
- if (q->head == NULL)
- q->head = m;
- else
- q->tail->m_nextpkt = m;
- q->tail = m;
- m->m_nextpkt = NULL;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DN_TEST_H */
diff --git a/sys/netinet/ipfw/test/main.c b/sys/netinet/ipfw/test/main.c
deleted file mode 100644
index be9fdf5..0000000
--- a/sys/netinet/ipfw/test/main.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * $FreeBSD$
- *
- * Testing program for schedulers
- *
- * The framework include a simple controller which, at each
- * iteration, decides whether we can enqueue and/or dequeue.
- * Then the mainloop runs the required number of tests,
- * keeping track of statistics.
- */
-
-#include "dn_test.h"
-
-struct q_list {
- struct list_head h;
-};
-
-struct cfg_s {
- int ac;
- char * const *av;
-
- const char *name;
- int loops;
- struct timeval time;
-
- /* running counters */
- uint32_t _enqueue;
- uint32_t drop;
- uint32_t pending;
- uint32_t dequeue;
-
- /* generator parameters */
- int th_min, th_max;
- int maxburst;
- int lmin, lmax; /* packet len */
- int flows; /* number of flows */
- int flowsets; /* number of flowsets */
- int wsum; /* sum of weights of all flows */
- int max_y; /* max random number in the generation */
- int cur_y, cur_fs; /* used in generation, between 0 and max_y - 1 */
- const char *fs_config; /* flowset config */
- int can_dequeue;
- int burst; /* count of packets sent in a burst */
- struct mbuf *tosend; /* packet to send -- also flag to enqueue */
-
- struct mbuf *freelist;
-
- struct mbuf *head, *tail; /* a simple tailq */
-
- /* scheduler hooks */
- int (*enq)(struct dn_sch_inst *, struct dn_queue *,
- struct mbuf *);
- struct mbuf * (*deq)(struct dn_sch_inst *);
- /* size of the three fields including sched-specific areas */
- int schk_len;
- int q_len; /* size of a queue including sched-fields */
- int si_len; /* size of a sch_inst including sched-fields */
- char *q; /* array of flow queues */
- /* use a char* because size is variable */
- struct dn_fsk *fs; /* array of flowsets */
- struct dn_sch_inst *si;
- struct dn_schk *sched;
-
- /* generator state */
- int state; /* 0 = going up, 1: going down */
-
- /*
- * We keep lists for each backlog level, and always serve
- * the one with shortest backlog. llmask contains a bitmap
- * of lists, and ll are the heads of the lists. The last
- * entry (BACKLOG) contains all entries considered 'full'
- * XXX to optimize things, entry i could contain queues with
- * 2^{i-1}+1 .. 2^i entries.
- */
-#define BACKLOG 30
- uint32_t llmask;
- struct list_head ll[BACKLOG + 10];
-};
-
-/* FI2Q and Q2FI converts from flow_id to dn_queue and back.
- * We cannot easily use pointer arithmetic because it is variable size.
- */
-#define FI2Q(c, i) ((struct dn_queue *)((c)->q + (c)->q_len * (i)))
-#define Q2FI(c, q) (((char *)(q) - (c)->q)/(c)->q_len)
-
-int debug = 0;
-
-struct dn_parms dn_cfg;
-
-static void controller(struct cfg_s *c);
-
-/* release a packet: put the mbuf in the freelist, and the queue in
- * the bucket.
- */
-int
-drop(struct cfg_s *c, struct mbuf *m)
-{
- struct dn_queue *q;
- int i;
-
- c->drop++;
- q = FI2Q(c, m->flow_id);
- i = q->ni.length; // XXX or ffs...
-
- ND("q %p id %d current length %d", q, m->flow_id, i);
- if (i < BACKLOG) {
- struct list_head *h = &q->ni.h;
- c->llmask &= ~(1<<(i+1));
- c->llmask |= (1<<(i));
- list_del(h);
- list_add_tail(h, &c->ll[i]);
- }
- m->m_nextpkt = c->freelist;
- c->freelist = m;
- return 0;
-}
-
-/* dequeue returns NON-NULL when a packet is dropped */
-static int
-enqueue(struct cfg_s *c, void *_m)
-{
- struct mbuf *m = _m;
- if (c->enq)
- return c->enq(c->si, FI2Q(c, m->flow_id), m);
- if (c->head == NULL)
- c->head = m;
- else
- c->tail->m_nextpkt = m;
- c->tail = m;
- return 0; /* default - success */
-}
-
-/* dequeue returns NON-NULL when a packet is available */
-static void *
-dequeue(struct cfg_s *c)
-{
- struct mbuf *m;
- if (c->deq)
- return c->deq(c->si);
- if ((m = c->head)) {
- m = c->head;
- c->head = m->m_nextpkt;
- m->m_nextpkt = NULL;
- }
- return m;
-}
-
-static int
-mainloop(struct cfg_s *c)
-{
- int i;
- struct mbuf *m;
-
- for (i=0; i < c->loops; i++) {
- /* implement histeresis */
- controller(c);
- DX(3, "loop %d enq %d send %p rx %d",
- i, c->_enqueue, c->tosend, c->can_dequeue);
- if ( (m = c->tosend) ) {
- c->_enqueue++;
- if (enqueue(c, m)) {
- drop(c, m);
- ND("loop %d enqueue fail", i );
- } else {
- ND("enqueue ok");
- c->pending++;
- }
- }
- if (c->can_dequeue) {
- c->dequeue++;
- if ((m = dequeue(c))) {
- c->pending--;
- drop(c, m);
- c->drop--; /* compensate */
- }
- }
- }
- DX(1, "mainloop ends %d", i);
- return 0;
-}
-
-int
-dump(struct cfg_s *c)
-{
- int i;
- struct dn_queue *q;
-
- for (i=0; i < c->flows; i++) {
- q = FI2Q(c, i);
- DX(1, "queue %4d tot %10lld", i, q->ni.tot_bytes);
- }
- DX(1, "done %d loops\n", c->loops);
- return 0;
-}
-
-/* interpret a number in human form */
-static long
-getnum(const char *s, char **next, const char *key)
-{
- char *end = NULL;
- long l;
-
- if (next) /* default */
- *next = NULL;
- if (s && *s) {
- DX(3, "token is <%s> %s", s, key ? key : "-");
- l = strtol(s, &end, 0);
- } else {
- DX(3, "empty string");
- l = -1;
- }
- if (l < 0) {
- DX(2, "invalid %s for %s", s ? s : "NULL", (key ? key : "") );
- return 0; // invalid
- }
- if (!end || !*end)
- return l;
- if (*end == 'n')
- l = -l; /* multiply by n */
- else if (*end == 'K')
- l = l*1000;
- else if (*end == 'M')
- l = l*1000000;
- else if (*end == 'k')
- l = l*1024;
- else if (*end == 'm')
- l = l*1024*1024;
- else if (*end == 'w')
- ;
- else {/* not recognized */
- D("suffix %s for %s, next %p", end, key, next);
- end--;
- }
- end++;
- DX(3, "suffix now %s for %s, next %p", end, key, next);
- if (next && *end) {
- DX(3, "setting next to %s for %s", end, key);
- *next = end;
- }
- return l;
-}
-
-/*
- * flowsets are a comma-separated list of
- * weight:maxlen:flows
- * indicating how many flows are hooked to that fs.
- * Both weight and range can be min-max-steps.
- * In a first pass we just count the number of flowsets and flows,
- * in a second pass we complete the setup.
- */
-static void
-parse_flowsets(struct cfg_s *c, const char *fs, int pass)
-{
- char *s, *cur, *next;
- int n_flows = 0, n_fs = 0, wsum = 0;
- int i, j;
- struct dn_fs *prev = NULL;
-
- DX(3, "--- pass %d flows %d flowsets %d", pass, c->flows, c->flowsets);
- if (pass == 0)
- c->fs_config = fs;
- s = c->fs_config ? strdup(c->fs_config) : NULL;
- if (s == NULL) {
- if (pass == 0)
- D("no fsconfig");
- return;
- }
- for (next = s; (cur = strsep(&next, ","));) {
- char *p = NULL;
- int w, w_h, w_steps, wi;
- int len, len_h, l_steps, li;
- int flows;
-
- w = getnum(strsep(&cur, ":"), &p, "weight");
- if (w <= 0)
- w = 1;
- w_h = p ? getnum(p+1, &p, "weight_max") : w;
- w_steps = p ? getnum(p+1, &p, "w_steps") : (w_h == w ?1:2);
- len = getnum(strsep(&cur, ":"), &p, "len");
- if (len <= 0)
- len = 1000;
- len_h = p ? getnum(p+1, &p, "len_max") : len;
- l_steps = p ? getnum(p+1, &p, "l_steps") : (len_h == len ? 1 : 2);
- flows = getnum(strsep(&cur, ":"), NULL, "flows");
- if (flows == 0)
- flows = 1;
- DX(4, "weight %d..%d (%d) len %d..%d (%d) flows %d",
- w, w_h, w_steps, len, len_h, l_steps, flows);
- if (w == 0 || w_h < w || len == 0 || len_h < len ||
- flows == 0) {
- DX(4,"wrong parameters %s", fs);
- return;
- }
- n_flows += flows * w_steps * l_steps;
- for (i = 0; i < w_steps; i++) {
- wi = w + ((w_h - w)* i)/(w_steps == 1 ? 1 : (w_steps-1));
- for (j = 0; j < l_steps; j++, n_fs++) {
- struct dn_fs *fs = &c->fs[n_fs].fs; // tentative
- int x;
-
- li = len + ((len_h - len)* j)/(l_steps == 1 ? 1 : (l_steps-1));
- x = (wi*2048)/li;
- DX(3, "----- fs %4d weight %4d lmax %4d X %4d flows %d",
- n_fs, wi, li, x, flows);
- if (pass == 0)
- continue;
- if (c->fs == NULL || c->flowsets <= n_fs) {
- D("error in number of flowsets");
- return;
- }
- wsum += wi * flows;
- fs->par[0] = wi;
- fs->par[1] = li;
- fs->index = n_fs;
- fs->n_flows = flows;
- fs->cur = fs->first_flow = prev==NULL ? 0 : prev->next_flow;
- fs->next_flow = fs->first_flow + fs->n_flows;
- fs->y = x * flows;
- fs->base_y = (prev == NULL) ? 0 : prev->next_y;
- fs->next_y = fs->base_y + fs->y;
- prev = fs;
- }
- }
- }
- c->max_y = prev ? prev->base_y + prev->y : 0;
- c->flows = n_flows;
- c->flowsets = n_fs;
- c->wsum = wsum;
- if (pass == 0)
- return;
-
- /* now link all flows to their parent flowsets */
- DX(1,"%d flows on %d flowsets max_y %d", c->flows, c->flowsets, c->max_y);
- for (i=0; i < c->flowsets; i++) {
- struct dn_fs *fs = &c->fs[i].fs;
- DX(1, "fs %3d w %5d l %4d flow %5d .. %5d y %6d .. %6d",
- i, fs->par[0], fs->par[1],
- fs->first_flow, fs->next_flow,
- fs->base_y, fs->next_y);
- for (j = fs->first_flow; j < fs->next_flow; j++) {
- struct dn_queue *q = FI2Q(c, j);
- q->fs = &c->fs[i];
- }
- }
-}
-
-static int
-init(struct cfg_s *c)
-{
- int i;
- int ac = c->ac;
- char * const *av = c->av;
-
- c->si_len = sizeof(struct dn_sch_inst);
- c->q_len = sizeof(struct dn_queue);
- moduledata_t *mod = NULL;
- struct dn_alg *p = NULL;
-
- c->th_min = 0;
- c->th_max = -20;/* 20 packets per flow */
- c->lmin = c->lmax = 1280; /* packet len */
- c->flows = 1;
- c->flowsets = 1;
- c->name = "null";
- ac--; av++;
- while (ac > 1) {
- if (!strcmp(*av, "-n")) {
- c->loops = getnum(av[1], NULL, av[0]);
- } else if (!strcmp(*av, "-d")) {
- debug = atoi(av[1]);
- } else if (!strcmp(*av, "-alg")) {
- extern moduledata_t *_g_dn_fifo;
- extern moduledata_t *_g_dn_wf2qp;
- extern moduledata_t *_g_dn_rr;
- extern moduledata_t *_g_dn_qfq;
-#ifdef WITH_KPS
- extern moduledata_t *_g_dn_kps;
-#endif
- if (!strcmp(av[1], "rr"))
- mod = _g_dn_rr;
- else if (!strcmp(av[1], "wf2qp"))
- mod = _g_dn_wf2qp;
- else if (!strcmp(av[1], "fifo"))
- mod = _g_dn_fifo;
- else if (!strcmp(av[1], "qfq"))
- mod = _g_dn_qfq;
-#ifdef WITH_KPS
- else if (!strcmp(av[1], "kps"))
- mod = _g_dn_kps;
-#endif
- else
- mod = NULL;
- c->name = mod ? mod->name : "NULL";
- DX(3, "using scheduler %s", c->name);
- } else if (!strcmp(*av, "-len")) {
- c->lmin = getnum(av[1], NULL, av[0]);
- c->lmax = c->lmin;
- DX(3, "setting max to %d", c->th_max);
- } else if (!strcmp(*av, "-burst")) {
- c->maxburst = getnum(av[1], NULL, av[0]);
- DX(3, "setting max to %d", c->th_max);
- } else if (!strcmp(*av, "-qmax")) {
- c->th_max = getnum(av[1], NULL, av[0]);
- DX(3, "setting max to %d", c->th_max);
- } else if (!strcmp(*av, "-qmin")) {
- c->th_min = getnum(av[1], NULL, av[0]);
- DX(3, "setting min to %d", c->th_min);
- } else if (!strcmp(*av, "-flows")) {
- c->flows = getnum(av[1], NULL, av[0]);
- DX(3, "setting flows to %d", c->flows);
- } else if (!strcmp(*av, "-flowsets")) {
- parse_flowsets(c, av[1], 0);
- DX(3, "setting flowsets to %d", c->flowsets);
- } else {
- D("option %s not recognised, ignore", *av);
- }
- ac -= 2; av += 2;
- }
- if (c->maxburst <= 0)
- c->maxburst = 1;
- if (c->loops <= 0)
- c->loops = 1;
- if (c->flows <= 0)
- c->flows = 1;
- if (c->flowsets <= 0)
- c->flowsets = 1;
- if (c->lmin <= 0)
- c->lmin = 1;
- if (c->lmax <= 0)
- c->lmax = 1;
- /* multiply by N */
- if (c->th_min < 0)
- c->th_min = c->flows * -c->th_min;
- if (c->th_max < 0)
- c->th_max = c->flows * -c->th_max;
- if (c->th_max <= c->th_min)
- c->th_max = c->th_min + 1;
- if (mod) {
- p = mod->p;
- DX(3, "using module %s f %p p %p", mod->name, mod->f, mod->p);
- DX(3, "modname %s ty %d", p->name, p->type);
- c->enq = p->enqueue;
- c->deq = p->dequeue;
- c->si_len += p->si_datalen;
- c->q_len += p->q_datalen;
- c->schk_len += p->schk_datalen;
- }
- /* allocate queues, flowsets and one scheduler */
- c->q = calloc(c->flows, c->q_len);
- c->fs = calloc(c->flowsets, sizeof(struct dn_fsk));
- c->si = calloc(1, c->si_len);
- c->sched = calloc(c->flows, c->schk_len);
- if (c->q == NULL || c->fs == NULL) {
- D("error allocating memory for flows");
- exit(1);
- }
- c->si->sched = c->sched;
- if (p) {
- if (p->config)
- p->config(c->sched);
- if (p->new_sched)
- p->new_sched(c->si);
- }
- /* parse_flowsets links queues to their flowsets */
- parse_flowsets(c, av[1], 1);
- /* complete the work calling new_fsk */
- for (i = 0; i < c->flowsets; i++) {
- if (c->fs[i].fs.par[1] == 0)
- c->fs[i].fs.par[1] = 1000; /* default pkt len */
- c->fs[i].sched = c->sched;
- if (p && p->new_fsk)
- p->new_fsk(&c->fs[i]);
- }
-
- /* initialize the lists for the generator, and put
- * all flows in the list for backlog = 0
- */
- for (i=0; i <= BACKLOG+5; i++)
- INIT_LIST_HEAD(&c->ll[i]);
-
- for (i = 0; i < c->flows; i++) {
- struct dn_queue *q = FI2Q(c, i);
- if (q->fs == NULL)
- q->fs = &c->fs[0]; /* XXX */
- q->_si = c->si;
- if (p && p->new_queue)
- p->new_queue(q);
- INIT_LIST_HEAD(&q->ni.h);
- list_add_tail(&q->ni.h, &c->ll[0]);
- }
- c->llmask = 1;
- return 0;
-}
-
-
-int
-main(int ac, char *av[])
-{
- struct cfg_s c;
- struct timeval end;
- double ll;
- int i;
- char msg[40];
-
- bzero(&c, sizeof(c));
- c.ac = ac;
- c.av = av;
- init(&c);
- gettimeofday(&c.time, NULL);
- mainloop(&c);
- gettimeofday(&end, NULL);
- end.tv_sec -= c.time.tv_sec;
- end.tv_usec -= c.time.tv_usec;
- if (end.tv_usec < 0) {
- end.tv_usec += 1000000;
- end.tv_sec--;
- }
- c.time = end;
- ll = end.tv_sec*1000000 + end.tv_usec;
- ll *= 1000; /* convert to nanoseconds */
- ll /= c._enqueue;
- sprintf(msg, "1::%d", c.flows);
- D("%-8s n %d %d time %d.%06d %8.3f qlen %d %d flows %s drops %d",
- c.name, c._enqueue, c.loops,
- (int)c.time.tv_sec, (int)c.time.tv_usec, ll,
- c.th_min, c.th_max,
- c.fs_config ? c.fs_config : msg, c.drop);
- dump(&c);
- DX(1, "done ac %d av %p", ac, av);
- for (i=0; i < ac; i++)
- DX(1, "arg %d %s", i, av[i]);
- return 0;
-}
-
-/*
- * The controller decides whether in this iteration we should send
- * (the packet is in c->tosend) and/or receive (flag c->can_dequeue)
- */
-static void
-controller(struct cfg_s *c)
-{
- struct mbuf *m;
- struct dn_fs *fs;
- int flow_id;
-
- /* histeresis between max and min */
- if (c->state == 0 && c->pending >= c->th_max)
- c->state = 1;
- else if (c->state == 1 && c->pending <= c->th_min)
- c->state = 0;
- ND(1, "state %d pending %2d", c->state, c->pending);
- c->can_dequeue = c->state;
- c->tosend = NULL;
- if (c->state)
- return;
-
- if (1) {
- int i;
- struct dn_queue *q;
- struct list_head *h;
-
- i = ffs(c->llmask) - 1;
- if (i < 0) {
- DX(2, "no candidate");
- c->can_dequeue = 1;
- return;
- }
- h = &c->ll[i];
- ND(1, "backlog %d p %p prev %p next %p", i, h, h->prev, h->next);
- q = list_first_entry(h, struct dn_queue, ni.h);
- list_del(&q->ni.h);
- flow_id = Q2FI(c, q);
- DX(2, "extracted flow %p %d backlog %d", q, flow_id, i);
- if (list_empty(h)) {
- ND(2, "backlog %d empty", i);
- c->llmask &= ~(1<<i);
- }
- ND(1, "before %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
- list_add_tail(&q->ni.h, h+1);
- ND(1, " after %d p %p prev %p next %p", i+1, h+1, h[1].prev, h[1].next);
- if (i < BACKLOG) {
- ND(2, "backlog %d full", i+1);
- c->llmask |= 1<<(1+i);
- }
- fs = &q->fs->fs;
- c->cur_fs = q->fs - c->fs;
- fs->cur = flow_id;
- } else {
- /* XXX this does not work ? */
- /* now decide whom to send the packet, and the length */
- /* lookup in the flow table */
- if (c->cur_y >= c->max_y) { /* handle wraparound */
- c->cur_y = 0;
- c->cur_fs = 0;
- }
- fs = &c->fs[c->cur_fs].fs;
- flow_id = fs->cur++;
- if (fs->cur >= fs->next_flow)
- fs->cur = fs->first_flow;
- c->cur_y++;
- if (c->cur_y >= fs->next_y)
- c->cur_fs++;
- }
-
- /* construct a packet */
- if (c->freelist) {
- m = c->tosend = c->freelist;
- c->freelist = c->freelist->m_nextpkt;
- } else {
- m = c->tosend = calloc(1, sizeof(struct mbuf));
- }
- if (m == NULL)
- return;
-
- m->cfg = c;
- m->m_nextpkt = NULL;
- m->m_pkthdr.len = fs->par[1]; // XXX maxlen
- m->flow_id = flow_id;
-
- ND(2,"y %6d flow %5d fs %3d weight %4d len %4d",
- c->cur_y, m->flow_id, c->cur_fs,
- fs->par[0], m->m_pkthdr.len);
-
-}
-
-/*
-Packet allocation:
-to achieve a distribution that matches weights, for each X=w/lmax class
-we should generate a number of packets proportional to Y = X times the number
-of flows in the class.
-So we construct an array with the cumulative distribution of Y's,
-and use it to identify the flow via inverse mapping (if the Y's are
-not too many we can use an array for the lookup). In practice,
-each flow will have X entries [virtually] pointing to it.
-
-*/
diff --git a/sys/netinet/ipfw/test/mylist.h b/sys/netinet/ipfw/test/mylist.h
deleted file mode 100644
index 6247f32..0000000
--- a/sys/netinet/ipfw/test/mylist.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * $FreeBSD$
- *
- * linux-like bidirectional lists
- */
-
-#ifndef _MYLIST_H
-#define _MYLIST_H
-struct list_head {
- struct list_head *prev, *next;
-};
-
-#define INIT_LIST_HEAD(l) do { (l)->prev = (l)->next = (l); } while (0)
-#define list_empty(l) ( (l)->next == l )
-static inline void
-__list_add(struct list_head *o, struct list_head *prev,
- struct list_head *next)
-{
- next->prev = o;
- o->next = next;
- o->prev = prev;
- prev->next = o;
-}
-
-static inline void
-list_add_tail(struct list_head *o, struct list_head *head)
-{
- __list_add(o, head->prev, head);
-}
-
-#define list_first_entry(pL, ty, member) \
- (ty *)((char *)((pL)->next) - offsetof(ty, member))
-
-static inline void
-__list_del(struct list_head *prev, struct list_head *next)
-{
- next->prev = prev;
- prev->next = next;
-}
-
-static inline void
-list_del(struct list_head *entry)
-{
- ND("called on %p", entry);
- __list_del(entry->prev, entry->next);
- entry->next = entry->prev = NULL;
-}
-
-#endif /* _MYLIST_H */
diff --git a/sys/netinet/ipfw/test/test_dn_heap.c b/sys/netinet/ipfw/test/test_dn_heap.c
deleted file mode 100644
index d460cf2..0000000
--- a/sys/netinet/ipfw/test/test_dn_heap.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*-
- * Copyright (c) 1998-2002,2010 Luigi Rizzo, Universita` di Pisa
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 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.
- */
-
-/*
- * Userland code for testing binary heaps and hash tables
- *
- * $FreeBSD$
- */
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-
-#include <stdio.h>
-#include <strings.h>
-#include <stdlib.h>
-
-#include "dn_heap.h"
-#define log(x, arg...) fprintf(stderr, ## arg)
-#define panic(x...) fprintf(stderr, ## x), exit(1)
-
-#include <string.h>
-
-struct x {
- struct x *ht_link;
- char buf[0];
-};
-
-uint32_t hf(uintptr_t key, int flags, void *arg)
-{
- return (flags & DNHT_KEY_IS_OBJ) ?
- ((struct x *)key)->buf[0] : *(char *)key;
-}
-
-int matchf(void *obj, uintptr_t key, int flags, void *arg)
-{
- char *s = (flags & DNHT_KEY_IS_OBJ) ?
- ((struct x *)key)->buf : (char *)key;
- return (strcmp(((struct x *)obj)->buf, s) == 0);
-}
-
-void *newfn(uintptr_t key, int flags, void *arg)
-{
- char *s = (char *)key;
- struct x *p = malloc(sizeof(*p) + 1 + strlen(s));
- if (p)
- strcpy(p->buf, s);
- return p;
-}
-
-char *strings[] = {
- "undici", "unico", "doppio", "devoto",
- "uno", "due", "tre", "quattro", "cinque", "sei",
- "uno", "due", "tre", "quattro", "cinque", "sei",
- NULL,
-};
-
-int doprint(void *_x, void *arg)
-{
- struct x *x = _x;
- printf("found element <%s>\n", x->buf);
- return (int)arg;
-}
-
-static void
-test_hash()
-{
- char **p;
- struct dn_ht *h;
- uintptr_t x = 0;
- uintptr_t x1 = 0;
-
- /* first, find and allocate */
- h = dn_ht_init(NULL, 10, 0, hf, matchf, newfn);
-
- for (p = strings; *p; p++) {
- dn_ht_find(h, (uintptr_t)*p, DNHT_INSERT, NULL);
- }
- dn_ht_scan(h, doprint, 0);
- printf("/* second -- find without allocate */\n");
- h = dn_ht_init(NULL, 10, 0, hf, matchf, NULL);
- for (p = strings; *p; p++) {
- void **y = newfn((uintptr_t)*p, 0, NULL);
- if (x == 0)
- x = (uintptr_t)y;
- else {
- if (x1 == 0)
- x1 = (uintptr_t)*p;
- }
- dn_ht_find(h, (uintptr_t)y, DNHT_INSERT | DNHT_KEY_IS_OBJ, NULL);
- }
- dn_ht_scan(h, doprint, 0);
- printf("remove %p gives %p\n", (void *)x,
- dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
- printf("remove %p gives %p\n", (void *)x,
- dn_ht_find(h, x, DNHT_KEY_IS_OBJ | DNHT_REMOVE, NULL));
- printf("remove %p gives %p\n", (void *)x,
- dn_ht_find(h, x1, DNHT_REMOVE, NULL));
- printf("remove %p gives %p\n", (void *)x,
- dn_ht_find(h, x1, DNHT_REMOVE, NULL));
- dn_ht_scan(h, doprint, 0);
-}
-
-int
-main(int argc, char *argv[])
-{
- struct dn_heap h;
- int i, n, n2, n3;
-
- test_hash();
- return 0;
-
- /* n = elements, n2 = cycles */
- n = (argc > 1) ? atoi(argv[1]) : 0;
- if (n <= 0 || n > 1000000)
- n = 100;
- n2 = (argc > 2) ? atoi(argv[2]) : 0;
- if (n2 <= 0)
- n = 1000000;
- n3 = (argc > 3) ? atoi(argv[3]) : 0;
- bzero(&h, sizeof(h));
- heap_init(&h, n, -1);
- while (n2-- > 0) {
- uint64_t prevk = 0;
- for (i=0; i < n; i++)
- heap_insert(&h, n3 ? n-i: random(), (void *)(100+i));
-
- for (i=0; h.elements > 0; i++) {
- uint64_t k = h.p[0].key;
- if (k < prevk)
- panic("wrong sequence\n");
- prevk = k;
- if (0)
- printf("%d key %llu, val %p\n",
- i, h.p[0].key, h.p[0].object);
- heap_extract(&h, NULL);
- }
- }
- return 0;
-}
diff --git a/sys/netinet/ipfw/test/test_dn_sched.c b/sys/netinet/ipfw/test/test_dn_sched.c
deleted file mode 100644
index ee46c95..0000000
--- a/sys/netinet/ipfw/test/test_dn_sched.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * $FreeBSD$
- *
- * library functions for userland testing of dummynet schedulers
- */
-
-#include "dn_test.h"
-
-void
-m_freem(struct mbuf *m)
-{
- printf("free %p\n", m);
-}
-
-int
-dn_sched_modevent(module_t mod, int cmd, void *arg)
-{
- return 0;
-}
-
-void
-dn_free_pkts(struct mbuf *m)
-{
- struct mbuf *x;
- while ( (x = m) ) {
- m = m->m_nextpkt;
- m_freem(x);
- }
-}
-
-int
-dn_delete_queue(void *_q, void *do_free)
-{
- struct dn_queue *q = _q;
- if (q->mq.head)
- dn_free_pkts(q->mq.head);
- free(q);
- return 0;
-}
-
-/*
- * This is a simplified function for testing purposes, which does
- * not implement statistics or random loss.
- * Enqueue a packet in q, subject to space and queue management policy
- * (whose parameters are in q->fs).
- * Update stats for the queue and the scheduler.
- * Return 0 on success, 1 on drop. The packet is consumed anyways.
- */
-int
-dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
-{
- if (drop)
- goto drop;
- if (q->ni.length >= 200)
- goto drop;
- mq_append(&q->mq, m);
- q->ni.length++;
- q->ni.tot_bytes += m->m_pkthdr.len;
- return 0;
-
-drop:
- q->ni.drops++;
- return 1;
-}
-
-int
-ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
-{
- if (*v < lo) {
- *v = dflt;
- } else if (*v > hi) {
- *v = hi;
- }
- return *v;
-}
-
-#ifndef __FreeBSD__
-int
-fls(int mask)
-{
- int bit;
-
- if (mask == 0)
- return (0);
- for (bit = 1; mask != 1; bit++)
- mask = (unsigned int)mask >> 1;
- return (bit);
-}
-#endif
OpenPOWER on IntegriCloud