From fb393117fbb476b2ec7370a71ab0e8b4e5c3b541 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Mon, 4 Jun 2007 02:50:30 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'ipfilter-vendor-v4-1-23'. --- contrib/ipfilter/.cvsignore | 28 - contrib/ipfilter/BSD/.cvsignore | 22 - contrib/ipfilter/COMPILE.2.5 | 11 - contrib/ipfilter/COMPILE.Solaris2 | 19 - contrib/ipfilter/FWTK/FWTK.sed | 0 contrib/ipfilter/FWTK/fwtk-2.1-transparency.txt | 707 --- contrib/ipfilter/FWTK/tproxy.diff | 82 - contrib/ipfilter/FreeBSD-2.2/files.diffs | 24 - contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs | 24 - contrib/ipfilter/FreeBSD-2.2/in_proto.c.diffs | 16 - contrib/ipfilter/FreeBSD-2.2/ip_input.c.diffs | 32 - contrib/ipfilter/FreeBSD-2.2/ip_output.c.diffs | 67 - contrib/ipfilter/FreeBSD-2.2/kinstall | 67 - contrib/ipfilter/FreeBSD-2.2/minstall | 38 - contrib/ipfilter/FreeBSD-2.2/unkinstall | 57 - contrib/ipfilter/FreeBSD-2.2/unminstall | 36 - contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 | 26 - contrib/ipfilter/FreeBSD-3/kinstall | 52 - contrib/ipfilter/FreeBSD-3/unkinstall | 45 - contrib/ipfilter/FreeBSD-4.0/INST.FreeBSD-4 | 24 - contrib/ipfilter/FreeBSD-4.0/ipv6-patch | 61 - contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0 | 61 - contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1 | 63 - contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2 | 63 - contrib/ipfilter/FreeBSD-4.0/kinstall | 63 - contrib/ipfilter/FreeBSD-4.0/unkinstall | 49 - contrib/ipfilter/FreeBSD/conf.c.diffs | 46 - contrib/ipfilter/FreeBSD/files.diffs | 23 - contrib/ipfilter/FreeBSD/files.newconf.diffs | 23 - contrib/ipfilter/FreeBSD/files.oldconf.diffs | 23 - contrib/ipfilter/FreeBSD/filez.diffs | 23 - contrib/ipfilter/FreeBSD/in_proto.c.diffs | 16 - contrib/ipfilter/FreeBSD/ip_input.c.diffs | 88 - contrib/ipfilter/FreeBSD/ip_output.c.diffs | 36 - contrib/ipfilter/FreeBSD/kinstall | 72 - contrib/ipfilter/FreeBSD/minstall | 51 - contrib/ipfilter/FreeBSD/unkinstall | 58 - contrib/ipfilter/FreeBSD/unminstall | 49 - contrib/ipfilter/INST.FreeBSD-2.2 | 60 - contrib/ipfilter/INSTALL.BSDOS | 35 - contrib/ipfilter/INSTALL.BSDOS3 | 44 - contrib/ipfilter/INSTALL.FreeBSD | 56 - contrib/ipfilter/INSTALL.IRIX | 108 - contrib/ipfilter/INSTALL.Linux | 50 - contrib/ipfilter/INSTALL.NetBSD | 59 - contrib/ipfilter/INSTALL.Sol2 | 28 - contrib/ipfilter/INSTALL.SunOS | 40 - contrib/ipfilter/INSTALL.xBSD | 44 - contrib/ipfilter/IPF.KANJI | 465 -- contrib/ipfilter/IPFILTER.LICENCE | 29 - contrib/ipfilter/LICENCE | 16 - contrib/ipfilter/QNX_OCL.txt | 275 - contrib/ipfilter/UPGRADE_NOTICE | 10 - contrib/ipfilter/bpf.h | 450 -- contrib/ipfilter/buildlinux | 16 - contrib/ipfilter/buildsunos | 168 - contrib/ipfilter/common.c | 610 --- contrib/ipfilter/etc/etc.sed | 2 - contrib/ipfilter/facpri.c | 151 - contrib/ipfilter/facpri.h | 40 - contrib/ipfilter/fil.c | 6209 ---------------------- contrib/ipfilter/fils.c | 1536 ------ contrib/ipfilter/inet_addr.c | 199 - contrib/ipfilter/ip_auth.c | 804 --- contrib/ipfilter/ip_auth.h | 66 - contrib/ipfilter/ip_compat.h | 2295 -------- contrib/ipfilter/ip_fil.h | 1368 ----- contrib/ipfilter/ip_fil_freebsd.c | 1692 ------ contrib/ipfilter/ip_frag.c | 858 --- contrib/ipfilter/ip_frag.h | 86 - contrib/ipfilter/ip_ftp_pxy.c | 1454 ----- contrib/ipfilter/ip_h323_pxy.c | 296 -- contrib/ipfilter/ip_htable.c | 455 -- contrib/ipfilter/ip_htable.h | 71 - contrib/ipfilter/ip_ipsec_pxy.c | 343 -- contrib/ipfilter/ip_irc_pxy.c | 435 -- contrib/ipfilter/ip_lfil.c | 975 ---- contrib/ipfilter/ip_log.c | 674 --- contrib/ipfilter/ip_lookup.c | 530 -- contrib/ipfilter/ip_lookup.h | 65 - contrib/ipfilter/ip_msnrpc_pxy.c | 328 -- contrib/ipfilter/ip_nat.c | 4834 ----------------- contrib/ipfilter/ip_nat.h | 477 -- contrib/ipfilter/ip_netbios_pxy.c | 122 - contrib/ipfilter/ip_pool.c | 786 --- contrib/ipfilter/ip_pool.h | 87 - contrib/ipfilter/ip_pptp_pxy.c | 527 -- contrib/ipfilter/ip_proxy.c | 854 --- contrib/ipfilter/ip_proxy.h | 453 -- contrib/ipfilter/ip_raudio_pxy.c | 338 -- contrib/ipfilter/ip_rcmd_pxy.c | 236 - contrib/ipfilter/ip_rpcb_pxy.c | 1460 ----- contrib/ipfilter/ip_scan.c | 594 --- contrib/ipfilter/ip_scan.h | 108 - contrib/ipfilter/ip_sfil.c | 991 ---- contrib/ipfilter/ip_state.c | 3802 ------------- contrib/ipfilter/ip_state.h | 261 - contrib/ipfilter/ip_sync.c | 1001 ---- contrib/ipfilter/ip_sync.h | 117 - contrib/ipfilter/ipf.c | 764 --- contrib/ipfilter/ipfs.c | 859 --- contrib/ipfilter/ipft_ef.c | 155 - contrib/ipfilter/ipft_hx.c | 173 - contrib/ipfilter/ipft_pc.c | 275 - contrib/ipfilter/ipft_sn.c | 219 - contrib/ipfilter/ipft_td.c | 193 - contrib/ipfilter/ipft_tx.c | 353 -- contrib/ipfilter/ipl.h | 19 - contrib/ipfilter/ipl_ldev.c | 83 - contrib/ipfilter/iplang/.cvsignore | 9 - contrib/ipfilter/ipmon.c | 1493 ------ contrib/ipfilter/ipnat.c | 433 -- contrib/ipfilter/ipsd/ip_compat.h | 201 - contrib/ipfilter/ipsd/ipsd.sed | 0 contrib/ipfilter/ipsend/.cvsignore | 3 - contrib/ipfilter/ipsend/ip_compat.h | 242 - contrib/ipfilter/ipsend/ipsend.sed | 3 - contrib/ipfilter/ipsend/ultrix.c | 84 - contrib/ipfilter/ipt.c | 551 -- contrib/ipfilter/kmem.c | 244 - contrib/ipfilter/lib/addkeep.c | 84 - contrib/ipfilter/lib/extras.c | 112 - contrib/ipfilter/lib/genmask.c | 54 - contrib/ipfilter/lib/getline.c | 56 - contrib/ipfilter/lib/hexdump.c | 28 - contrib/ipfilter/lib/hostmask.c | 93 - contrib/ipfilter/lib/hostnum.c | 47 - contrib/ipfilter/lib/loglevel.c | 53 - contrib/ipfilter/lib/make_range.c | 24 - contrib/ipfilter/lib/natparse.c | 728 --- contrib/ipfilter/lib/parse.c | 752 --- contrib/ipfilter/lib/portnum.c | 62 - contrib/ipfilter/lib/ports.c | 79 - contrib/ipfilter/lib/ratoi.c | 24 - contrib/ipfilter/lib/ratoui.c | 24 - contrib/ipfilter/lib/to_interface.c | 29 - contrib/ipfilter/linux.h | 19 - contrib/ipfilter/man/ipf.1 | 109 - contrib/ipfilter/man/ipnat.1 | 48 - contrib/ipfilter/man/man.sed | 1 - contrib/ipfilter/misc.c | 207 - contrib/ipfilter/ml_ipl.c | 165 - contrib/ipfilter/mlf_ipl.c | 467 -- contrib/ipfilter/mlfk_ipl.c | 271 - contrib/ipfilter/mlh_rule.c | 114 - contrib/ipfilter/mli_ipl.c | 596 --- contrib/ipfilter/mln_ipl.c | 295 - contrib/ipfilter/mls_ipl.c | 213 - contrib/ipfilter/natparse.c | 902 ---- contrib/ipfilter/net/.cvsignore | 1 - contrib/ipfilter/opt.c | 179 - contrib/ipfilter/opt_inet6.h | 1 - contrib/ipfilter/parse.c | 1510 ------ contrib/ipfilter/pcap.h | 34 - contrib/ipfilter/printnat.c | 487 -- contrib/ipfilter/printstate.c | 151 - contrib/ipfilter/relay.c | 227 - contrib/ipfilter/rules/.cvsignore | 1 - contrib/ipfilter/rules/rules.sed | 5 - contrib/ipfilter/samples/.cvsignore | 4 - contrib/ipfilter/solaris.c | 2131 -------- contrib/ipfilter/test/.cvsignore | 87 - contrib/ipfilter/test/expected/1 | 16 - contrib/ipfilter/test/expected/10 | 108 - contrib/ipfilter/test/expected/11 | 66 - contrib/ipfilter/test/expected/12 | 54 - contrib/ipfilter/test/expected/14 | 40 - contrib/ipfilter/test/expected/2 | 36 - contrib/ipfilter/test/expected/3 | 40 - contrib/ipfilter/test/expected/4 | 40 - contrib/ipfilter/test/expected/5 | 1344 ----- contrib/ipfilter/test/expected/6 | 1344 ----- contrib/ipfilter/test/expected/7 | 54 - contrib/ipfilter/test/expected/8 | 36 - contrib/ipfilter/test/expected/9 | 108 - contrib/ipfilter/test/expected/expected.sed | 0 contrib/ipfilter/test/input/1 | 4 - contrib/ipfilter/test/input/10 | 6 - contrib/ipfilter/test/input/11 | 11 - contrib/ipfilter/test/input/12 | 35 - contrib/ipfilter/test/input/13 | 39 - contrib/ipfilter/test/input/14 | 5 - contrib/ipfilter/test/input/2 | 6 - contrib/ipfilter/test/input/3 | 5 - contrib/ipfilter/test/input/4 | 5 - contrib/ipfilter/test/input/5 | 28 - contrib/ipfilter/test/input/6 | 28 - contrib/ipfilter/test/input/7 | 9 - contrib/ipfilter/test/input/8 | 6 - contrib/ipfilter/test/input/9 | 6 - contrib/ipfilter/test/input/input.sed | 0 contrib/ipfilter/test/input/ipf6-1 | 26 - contrib/ipfilter/test/regress/1 | 4 - contrib/ipfilter/test/regress/10 | 18 - contrib/ipfilter/test/regress/11 | 6 - contrib/ipfilter/test/regress/12 | 6 - contrib/ipfilter/test/regress/13 | 6 - contrib/ipfilter/test/regress/14 | 8 - contrib/ipfilter/test/regress/2 | 6 - contrib/ipfilter/test/regress/3 | 8 - contrib/ipfilter/test/regress/4 | 8 - contrib/ipfilter/test/regress/5 | 48 - contrib/ipfilter/test/regress/6 | 48 - contrib/ipfilter/test/regress/7 | 6 - contrib/ipfilter/test/regress/8 | 6 - contrib/ipfilter/test/regress/9 | 18 - contrib/ipfilter/test/regress/ipf6-1 | 3 - contrib/ipfilter/test/regress/regress.sed | 0 contrib/ipfilter/test/test.sed | 6 - contrib/ipfilter/todo | 98 - 210 files changed, 63426 deletions(-) delete mode 100644 contrib/ipfilter/.cvsignore delete mode 100644 contrib/ipfilter/BSD/.cvsignore delete mode 100644 contrib/ipfilter/COMPILE.2.5 delete mode 100644 contrib/ipfilter/COMPILE.Solaris2 delete mode 100644 contrib/ipfilter/FWTK/FWTK.sed delete mode 100644 contrib/ipfilter/FWTK/fwtk-2.1-transparency.txt delete mode 100644 contrib/ipfilter/FWTK/tproxy.diff delete mode 100644 contrib/ipfilter/FreeBSD-2.2/files.diffs delete mode 100644 contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs delete mode 100644 contrib/ipfilter/FreeBSD-2.2/in_proto.c.diffs delete mode 100644 contrib/ipfilter/FreeBSD-2.2/ip_input.c.diffs delete mode 100644 contrib/ipfilter/FreeBSD-2.2/ip_output.c.diffs delete mode 100755 contrib/ipfilter/FreeBSD-2.2/kinstall delete mode 100755 contrib/ipfilter/FreeBSD-2.2/minstall delete mode 100755 contrib/ipfilter/FreeBSD-2.2/unkinstall delete mode 100755 contrib/ipfilter/FreeBSD-2.2/unminstall delete mode 100644 contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 delete mode 100755 contrib/ipfilter/FreeBSD-3/kinstall delete mode 100755 contrib/ipfilter/FreeBSD-3/unkinstall delete mode 100644 contrib/ipfilter/FreeBSD-4.0/INST.FreeBSD-4 delete mode 100755 contrib/ipfilter/FreeBSD-4.0/ipv6-patch delete mode 100755 contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0 delete mode 100644 contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1 delete mode 100644 contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2 delete mode 100755 contrib/ipfilter/FreeBSD-4.0/kinstall delete mode 100755 contrib/ipfilter/FreeBSD-4.0/unkinstall delete mode 100644 contrib/ipfilter/FreeBSD/conf.c.diffs delete mode 100644 contrib/ipfilter/FreeBSD/files.diffs delete mode 100644 contrib/ipfilter/FreeBSD/files.newconf.diffs delete mode 100644 contrib/ipfilter/FreeBSD/files.oldconf.diffs delete mode 100644 contrib/ipfilter/FreeBSD/filez.diffs delete mode 100644 contrib/ipfilter/FreeBSD/in_proto.c.diffs delete mode 100644 contrib/ipfilter/FreeBSD/ip_input.c.diffs delete mode 100644 contrib/ipfilter/FreeBSD/ip_output.c.diffs delete mode 100755 contrib/ipfilter/FreeBSD/kinstall delete mode 100755 contrib/ipfilter/FreeBSD/minstall delete mode 100755 contrib/ipfilter/FreeBSD/unkinstall delete mode 100755 contrib/ipfilter/FreeBSD/unminstall delete mode 100644 contrib/ipfilter/INST.FreeBSD-2.2 delete mode 100644 contrib/ipfilter/INSTALL.BSDOS delete mode 100644 contrib/ipfilter/INSTALL.BSDOS3 delete mode 100644 contrib/ipfilter/INSTALL.FreeBSD delete mode 100644 contrib/ipfilter/INSTALL.IRIX delete mode 100644 contrib/ipfilter/INSTALL.Linux delete mode 100644 contrib/ipfilter/INSTALL.NetBSD delete mode 100644 contrib/ipfilter/INSTALL.Sol2 delete mode 100644 contrib/ipfilter/INSTALL.SunOS delete mode 100644 contrib/ipfilter/INSTALL.xBSD delete mode 100644 contrib/ipfilter/IPF.KANJI delete mode 100644 contrib/ipfilter/IPFILTER.LICENCE delete mode 100644 contrib/ipfilter/LICENCE delete mode 100644 contrib/ipfilter/QNX_OCL.txt delete mode 100644 contrib/ipfilter/UPGRADE_NOTICE delete mode 100644 contrib/ipfilter/bpf.h delete mode 100755 contrib/ipfilter/buildlinux delete mode 100755 contrib/ipfilter/buildsunos delete mode 100644 contrib/ipfilter/common.c delete mode 100644 contrib/ipfilter/etc/etc.sed delete mode 100644 contrib/ipfilter/facpri.c delete mode 100644 contrib/ipfilter/facpri.h delete mode 100644 contrib/ipfilter/fil.c delete mode 100644 contrib/ipfilter/fils.c delete mode 100644 contrib/ipfilter/inet_addr.c delete mode 100644 contrib/ipfilter/ip_auth.c delete mode 100644 contrib/ipfilter/ip_auth.h delete mode 100644 contrib/ipfilter/ip_compat.h delete mode 100644 contrib/ipfilter/ip_fil.h delete mode 100644 contrib/ipfilter/ip_fil_freebsd.c delete mode 100644 contrib/ipfilter/ip_frag.c delete mode 100644 contrib/ipfilter/ip_frag.h delete mode 100644 contrib/ipfilter/ip_ftp_pxy.c delete mode 100644 contrib/ipfilter/ip_h323_pxy.c delete mode 100644 contrib/ipfilter/ip_htable.c delete mode 100644 contrib/ipfilter/ip_htable.h delete mode 100644 contrib/ipfilter/ip_ipsec_pxy.c delete mode 100644 contrib/ipfilter/ip_irc_pxy.c delete mode 100644 contrib/ipfilter/ip_lfil.c delete mode 100644 contrib/ipfilter/ip_log.c delete mode 100644 contrib/ipfilter/ip_lookup.c delete mode 100644 contrib/ipfilter/ip_lookup.h delete mode 100644 contrib/ipfilter/ip_msnrpc_pxy.c delete mode 100644 contrib/ipfilter/ip_nat.c delete mode 100644 contrib/ipfilter/ip_nat.h delete mode 100644 contrib/ipfilter/ip_netbios_pxy.c delete mode 100644 contrib/ipfilter/ip_pool.c delete mode 100644 contrib/ipfilter/ip_pool.h delete mode 100644 contrib/ipfilter/ip_pptp_pxy.c delete mode 100644 contrib/ipfilter/ip_proxy.c delete mode 100644 contrib/ipfilter/ip_proxy.h delete mode 100644 contrib/ipfilter/ip_raudio_pxy.c delete mode 100644 contrib/ipfilter/ip_rcmd_pxy.c delete mode 100644 contrib/ipfilter/ip_rpcb_pxy.c delete mode 100644 contrib/ipfilter/ip_scan.c delete mode 100644 contrib/ipfilter/ip_scan.h delete mode 100644 contrib/ipfilter/ip_sfil.c delete mode 100644 contrib/ipfilter/ip_state.c delete mode 100644 contrib/ipfilter/ip_state.h delete mode 100644 contrib/ipfilter/ip_sync.c delete mode 100644 contrib/ipfilter/ip_sync.h delete mode 100644 contrib/ipfilter/ipf.c delete mode 100644 contrib/ipfilter/ipfs.c delete mode 100644 contrib/ipfilter/ipft_ef.c delete mode 100644 contrib/ipfilter/ipft_hx.c delete mode 100644 contrib/ipfilter/ipft_pc.c delete mode 100644 contrib/ipfilter/ipft_sn.c delete mode 100644 contrib/ipfilter/ipft_td.c delete mode 100644 contrib/ipfilter/ipft_tx.c delete mode 100644 contrib/ipfilter/ipl.h delete mode 100644 contrib/ipfilter/ipl_ldev.c delete mode 100644 contrib/ipfilter/iplang/.cvsignore delete mode 100644 contrib/ipfilter/ipmon.c delete mode 100644 contrib/ipfilter/ipnat.c delete mode 100644 contrib/ipfilter/ipsd/ip_compat.h delete mode 100644 contrib/ipfilter/ipsd/ipsd.sed delete mode 100644 contrib/ipfilter/ipsend/.cvsignore delete mode 100644 contrib/ipfilter/ipsend/ip_compat.h delete mode 100644 contrib/ipfilter/ipsend/ipsend.sed delete mode 100644 contrib/ipfilter/ipsend/ultrix.c delete mode 100644 contrib/ipfilter/ipt.c delete mode 100644 contrib/ipfilter/kmem.c delete mode 100644 contrib/ipfilter/lib/addkeep.c delete mode 100644 contrib/ipfilter/lib/extras.c delete mode 100644 contrib/ipfilter/lib/genmask.c delete mode 100644 contrib/ipfilter/lib/getline.c delete mode 100644 contrib/ipfilter/lib/hexdump.c delete mode 100644 contrib/ipfilter/lib/hostmask.c delete mode 100644 contrib/ipfilter/lib/hostnum.c delete mode 100644 contrib/ipfilter/lib/loglevel.c delete mode 100644 contrib/ipfilter/lib/make_range.c delete mode 100644 contrib/ipfilter/lib/natparse.c delete mode 100644 contrib/ipfilter/lib/parse.c delete mode 100644 contrib/ipfilter/lib/portnum.c delete mode 100644 contrib/ipfilter/lib/ports.c delete mode 100644 contrib/ipfilter/lib/ratoi.c delete mode 100644 contrib/ipfilter/lib/ratoui.c delete mode 100644 contrib/ipfilter/lib/to_interface.c delete mode 100644 contrib/ipfilter/linux.h delete mode 100644 contrib/ipfilter/man/ipf.1 delete mode 100644 contrib/ipfilter/man/ipnat.1 delete mode 100644 contrib/ipfilter/man/man.sed delete mode 100644 contrib/ipfilter/misc.c delete mode 100644 contrib/ipfilter/ml_ipl.c delete mode 100644 contrib/ipfilter/mlf_ipl.c delete mode 100644 contrib/ipfilter/mlfk_ipl.c delete mode 100644 contrib/ipfilter/mlh_rule.c delete mode 100644 contrib/ipfilter/mli_ipl.c delete mode 100644 contrib/ipfilter/mln_ipl.c delete mode 100644 contrib/ipfilter/mls_ipl.c delete mode 100644 contrib/ipfilter/natparse.c delete mode 100644 contrib/ipfilter/net/.cvsignore delete mode 100644 contrib/ipfilter/opt.c delete mode 100644 contrib/ipfilter/opt_inet6.h delete mode 100644 contrib/ipfilter/parse.c delete mode 100644 contrib/ipfilter/pcap.h delete mode 100644 contrib/ipfilter/printnat.c delete mode 100644 contrib/ipfilter/printstate.c delete mode 100644 contrib/ipfilter/relay.c delete mode 100644 contrib/ipfilter/rules/.cvsignore delete mode 100644 contrib/ipfilter/rules/rules.sed delete mode 100644 contrib/ipfilter/samples/.cvsignore delete mode 100644 contrib/ipfilter/solaris.c delete mode 100644 contrib/ipfilter/test/.cvsignore delete mode 100644 contrib/ipfilter/test/expected/1 delete mode 100644 contrib/ipfilter/test/expected/10 delete mode 100644 contrib/ipfilter/test/expected/11 delete mode 100644 contrib/ipfilter/test/expected/12 delete mode 100644 contrib/ipfilter/test/expected/14 delete mode 100644 contrib/ipfilter/test/expected/2 delete mode 100644 contrib/ipfilter/test/expected/3 delete mode 100644 contrib/ipfilter/test/expected/4 delete mode 100644 contrib/ipfilter/test/expected/5 delete mode 100644 contrib/ipfilter/test/expected/6 delete mode 100644 contrib/ipfilter/test/expected/7 delete mode 100644 contrib/ipfilter/test/expected/8 delete mode 100644 contrib/ipfilter/test/expected/9 delete mode 100644 contrib/ipfilter/test/expected/expected.sed delete mode 100644 contrib/ipfilter/test/input/1 delete mode 100644 contrib/ipfilter/test/input/10 delete mode 100644 contrib/ipfilter/test/input/11 delete mode 100644 contrib/ipfilter/test/input/12 delete mode 100644 contrib/ipfilter/test/input/13 delete mode 100644 contrib/ipfilter/test/input/14 delete mode 100644 contrib/ipfilter/test/input/2 delete mode 100644 contrib/ipfilter/test/input/3 delete mode 100644 contrib/ipfilter/test/input/4 delete mode 100644 contrib/ipfilter/test/input/5 delete mode 100644 contrib/ipfilter/test/input/6 delete mode 100644 contrib/ipfilter/test/input/7 delete mode 100644 contrib/ipfilter/test/input/8 delete mode 100644 contrib/ipfilter/test/input/9 delete mode 100644 contrib/ipfilter/test/input/input.sed delete mode 100644 contrib/ipfilter/test/input/ipf6-1 delete mode 100644 contrib/ipfilter/test/regress/1 delete mode 100644 contrib/ipfilter/test/regress/10 delete mode 100644 contrib/ipfilter/test/regress/11 delete mode 100644 contrib/ipfilter/test/regress/12 delete mode 100644 contrib/ipfilter/test/regress/13 delete mode 100644 contrib/ipfilter/test/regress/14 delete mode 100644 contrib/ipfilter/test/regress/2 delete mode 100644 contrib/ipfilter/test/regress/3 delete mode 100644 contrib/ipfilter/test/regress/4 delete mode 100644 contrib/ipfilter/test/regress/5 delete mode 100644 contrib/ipfilter/test/regress/6 delete mode 100644 contrib/ipfilter/test/regress/7 delete mode 100644 contrib/ipfilter/test/regress/8 delete mode 100644 contrib/ipfilter/test/regress/9 delete mode 100644 contrib/ipfilter/test/regress/ipf6-1 delete mode 100644 contrib/ipfilter/test/regress/regress.sed delete mode 100644 contrib/ipfilter/test/test.sed delete mode 100644 contrib/ipfilter/todo diff --git a/contrib/ipfilter/.cvsignore b/contrib/ipfilter/.cvsignore deleted file mode 100644 index 616828f4144d..000000000000 --- a/contrib/ipfilter/.cvsignore +++ /dev/null @@ -1,28 +0,0 @@ -ipf -sparcv7 -sparcv9 -h -ipf-darren -bugs -ipftest -patches -state -cbits -CVS -old -new -netinet -import -bak -streams -cvs.diff -threads -glibc -hp -windows -ipnat -opt_inet6.h -ippool -ipmon -ip_rules.c -ip_rules.h diff --git a/contrib/ipfilter/BSD/.cvsignore b/contrib/ipfilter/BSD/.cvsignore deleted file mode 100644 index c149a0043f45..000000000000 --- a/contrib/ipfilter/BSD/.cvsignore +++ /dev/null @@ -1,22 +0,0 @@ -ipf -ipfs -ipfstat -ipftest -ipmon -ipnat -ipresend -ipsend -iptest -vnode_if.h -if_ipl -i386 -amiga -FreeBSD* -BSDOS* -NetBSD* -OpenBSD* -*_lex_var.h -*_y.c -*_l.c -*_y.h -ip_rules.* diff --git a/contrib/ipfilter/COMPILE.2.5 b/contrib/ipfilter/COMPILE.2.5 deleted file mode 100644 index ae550f896e49..000000000000 --- a/contrib/ipfilter/COMPILE.2.5 +++ /dev/null @@ -1,11 +0,0 @@ - -If you get the following error whilst compiling: - -In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3/include/sys/user.h:48, - from /usr/include/sys/file.h:15, - from ../ip_nat.c:15: -/usr/include/sys/psw.h:19: #error Kernel include of psw.h - -Remove (comment out) the line in -/usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3include/sys/user.h -which includes psw.h diff --git a/contrib/ipfilter/COMPILE.Solaris2 b/contrib/ipfilter/COMPILE.Solaris2 deleted file mode 100644 index 45442c5a4051..000000000000 --- a/contrib/ipfilter/COMPILE.Solaris2 +++ /dev/null @@ -1,19 +0,0 @@ -If you have BOTH GNU make and the normal make shipped with your system, -DO NOT use the GNU make to build this package. If you have any errors -relating to "(" or "TOP", check that you are using /usr/ccs/bin/make as -shipped with Solaris 2. - -If you get the following error whilst compiling: - -In file included from /usr/local/lib/gcc-lib/sparc-sun-solaris2.3/2.6.3/include/sys/user.h:48, - from /usr/include/sys/file.h:15, - from ../ip_nat.c:15: -/usr/include/sys/psw.h:19: #error Kernel include of psw.h - -That means that you have a version of gcc build under on older release -of Solaris 2.x - -You need to reinstall gcc after each Solaris upgrade; gcc creates its own -set of modified system include files which are only valid for the exact -release on which gcc was build. - diff --git a/contrib/ipfilter/FWTK/FWTK.sed b/contrib/ipfilter/FWTK/FWTK.sed deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/ipfilter/FWTK/fwtk-2.1-transparency.txt b/contrib/ipfilter/FWTK/fwtk-2.1-transparency.txt deleted file mode 100644 index 2e719383f32b..000000000000 --- a/contrib/ipfilter/FWTK/fwtk-2.1-transparency.txt +++ /dev/null @@ -1,707 +0,0 @@ -diff -c -r ./ftp-gw/ftp-gw.c ../../fwtk-2.1-violated/fwtk/ftp-gw/ftp-gw.c -*** ./ftp-gw/ftp-gw.c Thu Feb 5 19:05:43 1998 ---- ../../fwtk-2.1-violated/fwtk/ftp-gw/ftp-gw.c Thu May 21 17:36:09 1998 -*************** -*** 44,49 **** ---- 44,51 ---- - - extern char *optarg; - -+ char *getdsthost(); -+ - #include "firewall.h" - - -*************** -*** 88,93 **** ---- 90,97 ---- - static int cmdcnt = 0; - static int timeout = PROXY_TIMEOUT; - -+ static int do_transparent = 0; -+ - - static int cmd_user(); - static int cmd_authorize(); -*************** -*** 101,106 **** ---- 105,111 ---- - static int cmd_passthru(); - static void saveline(); - static void flushsaved(); -+ static int connectdest(); - - #define OP_CONN 001 /* only valid if connected */ - #define OP_WCON 002 /* writethrough if connected */ -*************** -*** 173,178 **** ---- 178,184 ---- - char xuf[1024]; - char huf[512]; - char *passuser = (char *)0; /* passed user as av */ -+ char *psychic, *hotline; - - #ifndef LOG_DAEMON - openlog("ftp-gw",LOG_PID); -*************** -*** 317,322 **** ---- 323,332 ---- - } else - timeout = PROXY_TIMEOUT; - -+ psychic = getdsthost(0, NULL); -+ if (psychic) -+ do_transparent++; -+ - /* display a welcome file or message */ - if(passuser == (char *)0) { - if((cf = cfg_get("welcome-msg",confp)) != (Cfg *)0) { -*************** -*** 324,329 **** ---- 334,345 ---- - syslog(LLEV,"fwtkcfgerr: welcome-msg must have one parameter, line %d",cf->ln); - exit(1); - } -+ if (do_transparent) { -+ if (sayfile2(0, cf->argv[0], 220)) { -+ syslog(LLEV,"fwtksyserr: cannot display welcome %.512s: %m",cf->argv[0]); -+ exit(1); -+ } -+ } else - if(sayfile(0,cf->argv[0],220)) { - syslog(LLEV,"fwtksyserr: cannot display welcome %.512s: %m",cf->argv[0]); - exit(1); -*************** -*** 336,341 **** ---- 352,360 ---- - if(say(0,"220-Proxy first requires authentication")) - exit(1); - -+ if (do_transparent) -+ sprintf(xuf, "220-%s FTP proxy (Version %s) ready.",huf, FWTK_VERSION_MINOR); -+ else - sprintf(xuf, "220 %s FTP proxy (Version %s) ready.",huf, FWTK_VERSION_MINOR); - if(say(0,xuf)) - exit(1); -*************** -*** 357,362 **** ---- 376,384 ---- - exit(1); - } - -+ if (do_transparent) -+ connectdest(psychic, 21); -+ - /* main loop */ - while(1) { - FD_ZERO(&rdy); -*************** -*** 653,658 **** ---- 675,696 ---- - return(sayn(0,noad,sizeof(noad)-1)); - } - -+ if (do_transparent) { -+ if((rfd == (-1)) && (x = connectdest(dest,port))) -+ return x; -+ -+ sprintf(buf,"USER %s",user); -+ -+ if (say(rfd, buf)) -+ return(1); -+ -+ x = getresp(rfd, buf, sizeof(buf), 1); -+ if (sendsaved(0, x)) -+ return(1); -+ -+ return(say(0, buf)); -+ } -+ - if(*dest == '\0') - dest = "localhost"; - -*************** -*** 694,705 **** - char ebuf[512]; - - strcpy(ebuf,buf); -! sprintf(buf,"521 %s: %s",dest,ebuf); - rfd = -1; - return(say(0,buf)); - } -! sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest); -! saveline(buf); - - /* we are now connected and need to try the autologin thing */ - x = getresp(rfd,buf,sizeof(buf),1); ---- 732,748 ---- - char ebuf[512]; - - strcpy(ebuf,buf); -! if (do_transparent) -! sprintf(buf, "521 %s,%d: %s", dest, ntohs(port), ebuf); -! else -! sprintf(buf,"521 %s: %s",dest,ebuf); - rfd = -1; - return(say(0,buf)); - } -! if (!do_transparent) { -! sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest); -! saveline(buf); -! } - - /* we are now connected and need to try the autologin thing */ - x = getresp(rfd,buf,sizeof(buf),1); -*************** -*** 1889,1891 **** ---- 1932,2050 ---- - dup(nread); - } - #endif -+ -+ static int connectdest(dest, port) -+ char *dest; -+ short port; -+ { -+ char buf[1024], mbuf[512]; -+ int msg_int, x; -+ -+ if(*dest == '\0') -+ dest = "localhost"; -+ -+ if(validests != (char **)0) { -+ char **xp; -+ int x; -+ -+ for(xp = validests; *xp != (char *)0; xp++) { -+ if(**xp == '!' && hostmatch(*xp + 1,dest)) { -+ return(baddest(0,dest)); -+ } else { -+ if(hostmatch(*xp,dest)) -+ break; -+ } -+ } -+ if(*xp == (char *)0) -+ return(baddest(0,dest)); -+ } -+ -+ /* Extended permissions processing goes in here for destination */ -+ if(extendperm) { -+ msg_int = auth_perm(confp, authuser, "ftp-gw", dest,(char *)0); -+ if(msg_int == 1) { -+ sprintf(mbuf,"Permission denied for user %s to connect to %s",authuser,dest); -+ syslog(LLEV,"deny host=%s/%s connect to %s user=%s",rladdr,riaddr,dest,authuser); -+ say(0,mbuf); -+ return(1); -+ } else { -+ if(msg_int == -1) { -+ sprintf(mbuf,"No match in netperm-table for %s to ftp to %s",authuser,dest); -+ say(0,mbuf); -+ return(1); -+ } -+ } -+ } -+ -+ syslog(LLEV,"permit host=%s/%s connect to %s",rladdr,riaddr,dest); -+ -+ if((rfd = conn_server(dest,port,0,buf)) < 0) { -+ char ebuf[512]; -+ -+ strcpy(ebuf,buf); -+ if (do_transparent) -+ sprintf(buf,"521 %s,%d: %s",dest,ntohs(port),ebuf); -+ else -+ sprintf(buf,"521 %s: %s",dest,ebuf); -+ rfd = -1; -+ return(say(0,buf)); -+ } -+ if (!do_transparent) { -+ sprintf(buf,"----GATEWAY CONNECTED TO %s----",dest); -+ saveline(buf); -+ } -+ -+ /* we are now connected and need to try the autologin thing */ -+ x = getresp(rfd,buf,sizeof(buf),1); -+ if(x / 100 != COMPLETE) { -+ sendsaved(0,-1); -+ return(say(0,buf)); -+ } -+ saveline(buf); -+ -+ sendsaved(0,-1); -+ return 0; -+ } -+ -+ /* quick hack */ -+ sayfile2(fd,fn,code) -+ int fd; -+ char *fn; -+ int code; -+ { -+ FILE *f; -+ char buf[BUFSIZ]; -+ char yuf[BUFSIZ]; -+ char *c; -+ int x; -+ int saidsomething = 0; -+ -+ if((f = fopen(fn,"r")) == (FILE *)0) -+ return(1); -+ while(fgets(buf,sizeof(buf),f) != (char *)0) { -+ if((c = index(buf,'\n')) != (char *)0) -+ *c = '\0'; -+ x = fgetc(f); -+ if(feof(f)) -+ sprintf(yuf,"%3.3d-%s",code,buf); -+ else { -+ sprintf(yuf,"%3.3d-%s",code,buf); -+ ungetc(x,f); -+ } -+ if(say(fd,yuf)) { -+ fclose(f); -+ return(1); -+ } -+ saidsomething++; -+ } -+ fclose(f); -+ if (!saidsomething) { -+ syslog(LLEV,"fwtkcfgerr: sayfile for %d is empty",code); -+ sprintf(yuf, "%3.3d The file to display is empty",code); -+ if(say(fd,yuf)) { -+ fclose(f); -+ return(1); -+ } -+ } -+ return(0); -+ } -diff -c -r ./http-gw/http-gw.c ../../fwtk-2.1-violated/fwtk/http-gw/http-gw.c -*** ./http-gw/http-gw.c Fri Feb 6 18:32:25 1998 ---- ../../fwtk-2.1-violated/fwtk/http-gw/http-gw.c Thu May 21 17:00:47 1998 -*************** -*** 27,32 **** ---- 27,35 ---- - static char http_buffer[8192]; - static char reason[8192]; - static int checkBrowserType = 1; -+ static int do_transparent = 0; -+ -+ char * getdsthost(); - - static void do_logging() - { char *proto = "GOPHER"; -*************** -*** 473,478 **** ---- 476,490 ---- - /*(NOT A SPECIAL FORM)*/ - - if((rem_type & TYPE_LOCAL)== 0){ -+ char * psychic = getdsthost(sockfd, &def_port); -+ if (psychic) { -+ if (strlen(psychic) <= MAXHOSTNAMELEN) { -+ do_transparent ++; -+ strncpy(def_httpd, psychic, strlen(psychic)); -+ strncpy(def_server, psychic, strlen(psychic)); -+ } -+ } -+ - /* See if it can be forwarded */ - - if( can_forward(buf)){ -*************** -*** 1564,1570 **** - parse_vec[0], - parse_vec[1], - ourname, ourport); -! }else{ - sprintf(new_reply,"%s\tgopher://%s:%s/%c%s\t%s\t%u", - parse_vec[0], parse_vec[2], - parse_vec[3], chk_type_ch, ---- 1576,1589 ---- - parse_vec[0], - parse_vec[1], - ourname, ourport); -! } -! else -! if (do_transparent) { -! sprintf(new_reply, "%s\t%s\t%s\t%s", -! parse_vec[0], parse_vec[1], -! parse_vec[2],parse_vec[3]); -! } -! else { - sprintf(new_reply,"%s\tgopher://%s:%s/%c%s\t%s\t%u", - parse_vec[0], parse_vec[2], - parse_vec[3], chk_type_ch, -diff -c -r ./lib/hnam.c ../../fwtk-2.1-violated/fwtk/lib/hnam.c -*** ./lib/hnam.c Tue Dec 10 13:08:48 1996 ---- ../../fwtk-2.1-violated/fwtk/lib/hnam.c Thu May 21 17:10:00 1998 -*************** -*** 23,28 **** ---- 23,33 ---- - - #include "firewall.h" - -+ #ifdef __FreeBSD__ /* or OpenBSD, NetBSD, BSDI, etc. Fix this for your system. */ -+ #include -+ #include "ip_nat.h" -+ #endif /* __FreeBSD__ */ -+ - - char * - maphostname(name) -*************** -*** 49,52 **** ---- 54,132 ---- - } - bcopy(hp->h_addr,&sin.sin_addr,hp->h_length); - return(inet_ntoa(sin.sin_addr)); -+ } -+ -+ char *getdsthost(fd, ptr) -+ int fd; -+ int *ptr; -+ { -+ struct sockaddr_in sin; -+ struct hostent * hp; -+ int sl = sizeof(struct sockaddr_in), err = 0, local_h = 0, i = 0; -+ char buf[255], hostbuf[255]; -+ #ifdef __FreeBSD__ -+ struct sockaddr_in rsin; -+ struct natlookup natlookup; -+ #endif -+ -+ #ifdef linux -+ if (!(err = getsockname(0, &sin, &sl))) { -+ if(ptr) -+ * ptr = ntohs(sin.sin_port); -+ -+ sprintf(buf, "%s", inet_ntoa(sin.sin_addr)); -+ gethostname(hostbuf, 254); -+ hp = gethostbyname(hostbuf); -+ while (hp->h_addr_list[i]) { -+ bzero(&sin, &sl); -+ memcpy(&sin.sin_addr, hp->h_addr_list[i++], -+ sizeof(hp->h_addr_list[i++])); -+ -+ if (!strcmp(buf, inet_ntoa(sin.sin_addr))) -+ local_h++; -+ } -+ -+ if(local_h) -+ return(NULL); -+ else -+ return(buf); -+ } -+ #endif -+ -+ #ifdef __FreeBSD__ -+ /* The basis for this block of code is Darren Reed's -+ * patches to the TIS ftwk's ftp-gw. -+ */ -+ bzero((char*)&sin, sizeof(sin)); -+ bzero((char*)&rsin, sizeof(rsin)); -+ -+ if (getsockname(fd, (struct sockaddr*)&sin, &sl) < 0) -+ return NULL; -+ -+ sl = sizeof(rsin); -+ -+ if(getpeername(fd, (struct sockaddr*)&rsin, &sl) < 0) -+ return NULL; -+ -+ natlookup.nl_inport=sin.sin_port; -+ natlookup.nl_outport=rsin.sin_port; -+ natlookup.nl_inip=sin.sin_addr; -+ natlookup.nl_outip=rsin.sin_addr; -+ -+ if ((natfd = open("/dev/ipl",O_RDONLY)) < 0) -+ return NULL; -+ -+ if (ioctl(natfd, SIOCGNATL,&natlookup) == (-1)) -+ return NULL; -+ -+ close(natfd); -+ -+ if (ptr) -+ *ptr = ntohs(natlookup.nl_inport); -+ -+ sprintf(buf, "%s", inet_ntoa(natlookup.nl_inip)); -+ #endif -+ -+ /* No transparent proxy support */ -+ return(NULL); - } -diff -c -r ./plug-gw/plug-gw.c ../../fwtk-2.1-violated/fwtk/plug-gw/plug-gw.c -*** ./plug-gw/plug-gw.c Thu Feb 5 19:07:35 1998 ---- ../../fwtk-2.1-violated/fwtk/plug-gw/plug-gw.c Thu May 21 17:29:01 1998 -*************** -*** 43,48 **** ---- 43,50 ---- - static char **validdests = (char **)0; - static int net_write(); - -+ static int do_transparent = 0; -+ - main(ac,av) - int ac; - char *av[]; -*************** -*** 198,206 **** ---- 200,220 ---- - char *ptr; - int state = 0; - int ssl_plug = 0; -+ char * getdsthost(); -+ int pport = 0; - - struct timeval timo; - -+ /* Transparent plug-gw is probably a bad idea, but then, plug-gw is a bad -+ * idea .. -+ */ -+ dhost = getdsthost(0, &pport); -+ if (dhost) { -+ do_transparent++; -+ portid = pport; -+ } -+ -+ - if(c->flags & PERM_DENY) { - if (p == -1) - syslog(LLEV,"deny host=%.512s/%.20s port=any",rhost,raddr); -*************** -*** 220,226 **** - syslog(LLEV,"fwtkcfgerr: -plug-to takes an argument, line %d",c->ln); - exit (1); - } -! dhost = av[x]; - continue; - } - ---- 234,241 ---- - syslog(LLEV,"fwtkcfgerr: -plug-to takes an argument, line %d",c->ln); - exit (1); - } -! if (!dhost) -! dhost = av[x]; - continue; - } - -diff -c -r ./rlogin-gw/rlogin-gw.c ../../fwtk-2.1-violated/fwtk/rlogin-gw/rlogin-gw.c -*** ./rlogin-gw/rlogin-gw.c Thu Feb 5 19:08:38 1998 ---- ../../fwtk-2.1-violated/fwtk/rlogin-gw/rlogin-gw.c Thu May 21 17:20:25 1998 -*************** -*** 103,108 **** ---- 103,111 ---- - static int trusted = 0; - static int doX = 0; - static char *prompt; -+ static int do_transparent = 0; -+ -+ char * getdsthost(); - - main(ac,av) - int ac; -*************** -*** 123,128 **** ---- 126,132 ---- - static char *tokav[56]; - int tokac; - struct timeval timo; -+ char * psychic; - - #ifndef LOG_NDELAY - openlog("rlogin-gw",LOG_PID); -*************** -*** 188,194 **** - xforwarder = cf->argv[0]; - } - -! - - if((cf = cfg_get("directory",confp)) != (Cfg *)0) { - if(cf->argc != 1) { ---- 192,203 ---- - xforwarder = cf->argv[0]; - } - -! psychic = getdsthost(0, NULL); -! if (psychic) { -! do_transparent++; -! strncpy(dest, psychic, 511); -! dest[511] = '\0'; -! } - - if((cf = cfg_get("directory",confp)) != (Cfg *)0) { - if(cf->argc != 1) { -*************** -*** 266,271 **** ---- 275,281 ---- - if((p = index(rusername,'@')) != (char *)0) { - char *namp; - -+ dest[0] = '\0'; - *p++ = '\0'; - if(*p == '\0') - p = "localhost"; -*************** -*** 297,302 **** ---- 307,326 ---- - - if(dest[0] != '\0') { - /* Setup connection directly to remote machine */ -+ if ((cf = cfg_get("welcome-msg",confp)) != (Cfg *)0) { -+ if (cf->argc != 1) { -+ syslog(LLEV,"fwtkcfgerr: welcome-msg must have one parameter, line %d",cf->ln); -+ exit(1); -+ } -+ -+ if (sayfile(0, cf->argv[0])) { -+ syslog(LLEV,"fwtksyserr: cannot display welcome %s: %m",cf->argv[0]); -+ exit(1); -+ } -+ } -+ -+ /* Hey fwtk developer people -- this connect_dest thing is *nasty!* */ -+ - sprintf(buf,"connect %.1000s",dest); - tokac = enargv(buf, tokav, 56, tokbuf, sizeof(tokbuf)); - if (cmd_connect(tokac, tokav, buf) != 2) -*************** -*** 535,548 **** - char ebuf[512]; - - syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,namp); -! if(strlen(namp) > 20) -! namp[20] = '\0'; -! if(rusername[0] != '\0') -! sprintf(ebuf,"Trying %s@%s...",rusername,namp); -! else -! sprintf(ebuf,"Trying %s...",namp); -! if(say(0,ebuf)) -! return(1); - } else - syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,av[1]); - if((serfd = conn_server(av[1],RLOGINPORT,1,buf)) < 0) { ---- 559,574 ---- - char ebuf[512]; - - syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,namp); -! if (!do_transparent) { -! if(strlen(namp) > 20) -! namp[20] = '\0'; -! if(rusername[0] != '\0') -! sprintf(ebuf,"Trying %s@%s...",rusername,namp); -! else -! sprintf(ebuf,"Trying %s...",namp); -! if(say(0,ebuf)) -! return(1); -! } - } else - syslog(LLEV,"permit host=%.512s/%.20s connect to %.512s",rhost,raddr,av[1]); - if((serfd = conn_server(av[1],RLOGINPORT,1,buf)) < 0) { -diff -c -r ./tn-gw/tn-gw.c ../../fwtk-2.1-violated/fwtk/tn-gw/tn-gw.c -*** ./tn-gw/tn-gw.c Thu Feb 5 19:11:36 1998 ---- ../../fwtk-2.1-violated/fwtk/tn-gw/tn-gw.c Thu May 21 17:25:06 1998 -*************** -*** 91,96 **** ---- 91,100 ---- - static int cmd_xforward(); - static int cmd_timeout(); - -+ char * getdsthost(); -+ -+ static int do_transparent = 0; -+ - static int tn3270 = 1; /* don't do tn3270 stuff */ - static int doX; - -*************** -*** 144,149 **** ---- 148,155 ---- - char tokbuf[BSIZ]; - char *tokav[56]; - int tokac; -+ int port; -+ char * psychic; - - #ifndef LOG_DAEMON - openlog("tn-gw",LOG_PID); -*************** -*** 325,330 **** ---- 331,362 ---- - } - } - -+ psychic = getdsthost(0, &port); -+ if (psychic) { -+ if ((strlen(psychic) + 10) < 510) { -+ do_transparent++; -+ if (port) -+ sprintf(dest, "%s:%d", psychic, port); -+ else -+ sprintf(dest, "%s", psychic); -+ -+ if (!welcomedone) -+ if ((cf = cfg_get("welcome-msg", confp)) != (Cfg *)0) { -+ if (cf->argc != 1) { -+ syslog(LLEV,"fwtkcfgerr: welcome-msg must have one parameter, line %d",cf->ln); -+ exit(1); -+ } -+ -+ if (sayfile(0, cf->argv[0])) { -+ syslog(LLEV,"fwtksyserr: cannot display welcome %s:%m",cf->argv[0]); -+ exit(1); -+ } -+ -+ welcomedone = 1; -+ } -+ } -+ } -+ - while (argc > 1) { - argc--; - argv++; -*************** -*** 947,955 **** - char ebuf[512]; - - syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,namp); -! sprintf(ebuf,"Trying %.100s port %d...",namp,port); -! if(say(0,ebuf)) -! return(1); - } else - syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]); - ---- 979,989 ---- - char ebuf[512]; - - syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,namp); -! if (!do_transparent) { -! sprintf(ebuf,"Trying %.100s port %d...",namp,port); -! if(say(0,ebuf)) -! return(1); -! } - } else - syslog(LLEV,"permit host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]); - -*************** -*** 991,998 **** - - syslog(LLEV,"connected host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]); - strncpy(dest,av[1], 511); -! sprintf(buf, "Connected to %.512s.", dest); -! say(0, buf); - return(2); - } - ---- 1025,1034 ---- - - syslog(LLEV,"connected host=%.512s/%.20s destination=%.512s",rladdr,riaddr,av[1]); - strncpy(dest,av[1], 511); -! if (!do_transparent) { -! sprintf(buf, "Connected to %.512s.", dest); -! say(0, buf); -! } - return(2); - } - diff --git a/contrib/ipfilter/FWTK/tproxy.diff b/contrib/ipfilter/FWTK/tproxy.diff deleted file mode 100644 index 234404bf2364..000000000000 --- a/contrib/ipfilter/FWTK/tproxy.diff +++ /dev/null @@ -1,82 +0,0 @@ -*** tproxy.c.orig Fri Dec 20 10:53:24 1996 ---- tproxy.c Sun Jan 3 11:33:55 1999 -*************** -*** 135,140 **** ---- 135,144 ---- - #include - #include - #include -+ #include -+ #include -+ #include -+ #include - #include "tproxy.h" - - #ifdef AIX -*************** -*** 147,152 **** ---- 151,159 ---- - #define bzero(buf,size) memset(buf, '\0', size); - #endif /* SYSV */ - -+ #include "ip_compat.h" -+ #include "ip_fil.h" -+ #include "ip_nat.h" - - - /* socket to audio server */ -*************** -*** 324,329 **** ---- 331,369 ---- - char localbuf[2048]; - void timeout(); - extern int errno; -+ /* -+ * IP-Filter block -+ */ -+ struct sockaddr_in laddr, faddr; -+ struct natlookup natlookup; -+ int slen, natfd; -+ -+ bzero((char *)&laddr, sizeof(laddr)); -+ bzero((char *)&faddr, sizeof(faddr)); -+ slen = sizeof(laddr); -+ if (getsockname(0, (struct sockaddr *)&laddr, &slen) < 0) -+ return -1; -+ slen = sizeof(faddr); -+ if (getpeername(0, (struct sockaddr *)&faddr, &slen) < 0) -+ return -1; -+ natlookup.nl_inport = laddr.sin_port; -+ natlookup.nl_outport = faddr.sin_port; -+ natlookup.nl_inip = laddr.sin_addr; -+ natlookup.nl_outip = faddr.sin_addr; -+ natlookup.nl_flags = IPN_TCP; -+ if ((natfd = open(IPL_NAT, O_RDONLY)) < 0) -+ return -1; -+ if (ioctl(natfd, SIOCGNATL, &natlookup) == -1) { -+ syslog(LOG_ERR, "SIOCGNATL failed: %m\n"); -+ close(natfd); -+ return -1; -+ } -+ close(natfd); -+ strcpy(hostname, inet_ntoa(natlookup.nl_realip)); -+ serverport = ntohs(natlookup.nl_realport); -+ /* -+ * End of IP-Filter block -+ */ - - /* setup a timeout in case dialog doesn't finish */ - signal(SIGALRM, timeout); -*************** -*** 337,344 **** ---- 377,386 ---- - * and modify the call to (and subroutine) serverconnect() as - * appropriate. - */ -+ #if 0 - strcpy(hostname, "randomhostname"); - serverport = 7070; -+ #endif - /* Can we connect to the server */ - if ( (serverfd = serverconnect(hostname, serverport)) < 0 ) { - /* errno may still be set from previous call */ diff --git a/contrib/ipfilter/FreeBSD-2.2/files.diffs b/contrib/ipfilter/FreeBSD-2.2/files.diffs deleted file mode 100644 index 2ada3fa4b300..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/files.diffs +++ /dev/null @@ -1,24 +0,0 @@ -*** files.orig Tue Sep 9 16:58:40 1997 ---- files Sat Apr 4 10:52:58 1998 -*************** -*** 222,227 **** ---- 222,240 ---- - netinet/tcp_timer.c optional inet - netinet/tcp_usrreq.c optional inet - netinet/udp_usrreq.c optional inet -+ netinet/ip_fil.c optional ipfilter inet -+ netinet/fil.c optional ipfilter inet -+ netinet/ip_nat.c optional ipfilter inet -+ netinet/ip_frag.c optional ipfilter inet -+ netinet/ip_state.c optional ipfilter inet -+ netinet/ip_proxy.c optional ipfilter inet -+ netinet/mlf_ipl.c optional ipfilter inet -+ netinet/ip_auth.c optional ipfilter inet -+ netinet/ip_log.c optional ipfilter inet -+ netinet/ip_scan.c optional ipfilter inet -+ netinet/ip_sync.c optional ipfilter inet -+ netinet/ip_pool.c optional ipfilter_pool inet -+ netinet/ip_rules.c optional ipfilter_compiled ipfilter inet - netipx/ipx.c optional ipx - netipx/ipx_cksum.c optional ipx - netipx/ipx_input.c optional ipx diff --git a/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs b/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs deleted file mode 100644 index 82599f199056..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs +++ /dev/null @@ -1,24 +0,0 @@ -*** files.newconf.orig Sun Jun 25 02:17:29 1995 ---- files.newconf Sun Jun 25 02:19:10 1995 -*************** -*** 161,166 **** ---- 161,179 ---- - file netinet/ip_input.c inet - file netinet/ip_mroute.c inet - file netinet/ip_output.c inet -+ file netinet/ip_fil.c ipfilter -+ file netinet/fil.c ipfilter -+ file netinet/ip_nat.c ipfilter -+ file netinet/ip_frag.c ipfilter -+ file netinet/ip_state.c ipfilter -+ file netinet/ip_proxy.c ipfilter -+ file netinet/ip_auth.c ipfilter -+ file netinet/ip_log.c ipfilter -+ file netinet/mlf_ipl.c ipfilter -+ file netinet/ip_scan.c ipfilter -+ file netinet/ip_sync.c ipfilter -+ file netinet/ip_pool.c ipfilter_pool -+ file netinet/ip_rules.c ipfilter_compiled - file netinet/raw_ip.c inet - file netinet/tcp_debug.c inet - file netinet/tcp_input.c inet diff --git a/contrib/ipfilter/FreeBSD-2.2/in_proto.c.diffs b/contrib/ipfilter/FreeBSD-2.2/in_proto.c.diffs deleted file mode 100644 index c2822d3ff9d3..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/in_proto.c.diffs +++ /dev/null @@ -1,16 +0,0 @@ -*** /sys/netinet/in_proto.c.orig Sat May 24 13:42:26 1997 ---- /sys/netinet/in_proto.c Sat May 24 13:42:36 1997 -*************** -*** 89,94 **** ---- 89,99 ---- - void eoninput(), eonctlinput(), eonprotoinit(); - #endif /* EON */ - -+ #if defined(IPFILTER) && !defined(IPFILTER_LKM) -+ void iplinit(); -+ #define ip_init iplinit -+ #endif -+ - extern struct domain inetdomain; - - struct protosw inetsw[] = { diff --git a/contrib/ipfilter/FreeBSD-2.2/ip_input.c.diffs b/contrib/ipfilter/FreeBSD-2.2/ip_input.c.diffs deleted file mode 100644 index c2b2b15301ce..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/ip_input.c.diffs +++ /dev/null @@ -1,32 +0,0 @@ -*** /sys/netinet/ip_input.c.orig Sat May 24 13:37:16 1997 ---- /sys/netinet/ip_input.c Sat May 24 13:38:58 1997 -*************** -*** 74,79 **** ---- 74,82 ---- - #ifdef IPFIREWALL - #include - #endif -+ #if defined(IPFILTER_LKM) || defined(IPFILTER) -+ int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ #endif - - int rsvp_on = 0; - static int ip_rsvp_on; -*************** -*** 310,315 **** ---- 313,327 ---- - * - Wrap: fake packet's addr/port - * - Encapsulate: put it in another IP and send out. - */ -+ #if defined(IPFILTER_LKM) || defined(IPFILTER) -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m1) || !m1) -+ return; -+ ip = mtod(m = m1, struct ip *); -+ } -+ #endif - - #ifdef COMPAT_IPFW - if (ip_fw_chk_ptr) { diff --git a/contrib/ipfilter/FreeBSD-2.2/ip_output.c.diffs b/contrib/ipfilter/FreeBSD-2.2/ip_output.c.diffs deleted file mode 100644 index ff5ae0a5d66b..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/ip_output.c.diffs +++ /dev/null @@ -1,67 +0,0 @@ -*** /sys/netinet/ip_output.c.orig Sat May 24 14:07:24 1997 ---- /sys/netinet/ip_output.c Sat May 24 15:00:29 1997 -*************** -*** 67,72 **** ---- 67,76 ---- - #else - #undef COMPAT_IPFW - #endif -+ #if defined(IPFILTER_LKM) || defined(IPFILTER) -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ #endif -+ - - u_short ip_id; - -*************** -*** 75,81 **** - __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); - static int ip_getmoptions - __P((int, struct ip_moptions *, struct mbuf **)); -! static int ip_optcopy __P((struct ip *, struct ip *)); - static int ip_pcbopts __P((struct mbuf **, struct mbuf *)); - static int ip_setmoptions - __P((int, struct ip_moptions **, struct mbuf *)); ---- 79,85 ---- - __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); - static int ip_getmoptions - __P((int, struct ip_moptions *, struct mbuf **)); -! int ip_optcopy __P((struct ip *, struct ip *)); - static int ip_pcbopts __P((struct mbuf **, struct mbuf *)); - static int ip_setmoptions - __P((int, struct ip_moptions **, struct mbuf *)); -*************** -*** 338,343 **** ---- 342,356 ---- - * - Wrap: fake packet's addr/port - * - Encapsulate: put it in another IP and send out. - */ -+ #if defined(IPFILTER_LKM) || defined(IPFILTER) -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1) -+ goto done; -+ ip = mtod(m = m1, struct ip *); -+ } -+ #endif - - #ifdef COMPAT_IPFW - if (ip_nat_ptr && !(*ip_nat_ptr)(&ip, &m, ifp, IP_NAT_OUT)) { -*************** -*** 559,565 **** - * Copy options from ip to jp, - * omitting those not copied during fragmentation. - */ -! static int - ip_optcopy(ip, jp) - struct ip *ip, *jp; - { ---- 574,580 ---- - * Copy options from ip to jp, - * omitting those not copied during fragmentation. - */ -! int - ip_optcopy(ip, jp) - struct ip *ip, *jp; - { diff --git a/contrib/ipfilter/FreeBSD-2.2/kinstall b/contrib/ipfilter/FreeBSD-2.2/kinstall deleted file mode 100755 index 5a4368eba122..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/kinstall +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo -n "Installing " -foreach i (ip_{auth,fil,frag,nat,pool,proxy,scan,state,sync}.[ch] fil.c \ - ip_*_pxy.c mlf_ipl.c ipl.h ip_compat.h ip_log.c) - echo -n "$i "; - cp $i /sys/netinet - chmod 644 /sys/netinet/$i - switch ($i) - case *.h: - /bin/cp $i /usr/include/netinet/$i - chmod 644 /usr/include/netinet/$i - breaksw - endsw -end -echo "" -echo "Copying /usr/include/osreldate.h to /sys/sys" -cp /usr/include/osreldate.h /sys/sys -echo "Patching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD-2.2/ip_{in,out}put.c.diffs FreeBSD-2.2/in_proto.c.diffs | \ -(cd /sys/netinet; patch) - -if ( -f /sys/conf/files.newconf ) then - echo "Patching /sys/conf/files.newconf" - cat FreeBSD-2.2/files.newconf.diffs | (cd /sys/conf; patch) - echo "Patching /sys/conf/files" - cat FreeBSD-2.2/files.diffs | (cd /sys/conf; patch) -endif -if ( -f /sys/conf/files.oldconf ) then - echo "Patching /sys/conf/files.oldconf" - cat FreeBSD-2.2/files.oldconf.diffs | (cd /sys/conf; patch) - echo "Patching /sys/conf/files" - cat FreeBSD-2.2/filez.diffs | (cd /sys/conf; patch) -endif - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -echo "Re-config'ing $newconfig..." -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -awk '{print $0;if($2=="INET"){print"options IPFILTER"}}' \ - $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD-2.2/minstall b/contrib/ipfilter/FreeBSD-2.2/minstall deleted file mode 100755 index 832b68e81a63..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/minstall +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD-2.2 ) cd .. -echo "Patching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD-2.2/ip_{in,out}put.c.diffs FreeBSD-2.2/in_proto.c.diffs | \ -(cd /sys/netinet; patch) - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -echo "Re-config'ing $newconfig..." -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}${bak} ) - set bak=".bak."$dot - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}$bak -endif -awk '{print $0;if($2=="INET"){print"options IPFILTER_LKM\noptions IPFILTER_LOG"}}' \ - $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD-2.2/unkinstall b/contrib/ipfilter/FreeBSD-2.2/unkinstall deleted file mode 100755 index 1955f5c415db..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/unkinstall +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo -n "Uninstalling " -foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \ - ip_auth.[ch] ip_proxy.[ch] ip_ftp_pxy.c ip_compat.h ip_log.c \ - mlf_ipl.c ipl.h) - echo -n "$i "; - /bin/rm -f /sys/netinet/$i -end -echo "" -echo "Unpatching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD-2.2/ip_{in,out}put.c.diffs FreeBSD-2.2/in_proto.c.diffs | \ -(cd /sys/netinet; patch -R) - -if ( -f /sys/conf/files.newconf ) then - echo "Unpatching /sys/conf/files.newconf" - cat FreeBSD-2.2/files.newconf.diffs | (cd /sys/conf; patch -R) - echo "Unpatching /sys/conf/files" - cat FreeBSD-2.2/files.diffs | (cd /sys/conf; patch -R) -endif -if ( -f /sys/conf/files.oldconf ) then - echo "Unpatching /sys/conf/files.oldconf" - cat FreeBSD-2.2/files.oldconf.diffs | (cd /sys/conf; patch -R) - echo "Unpatching /sys/conf/files" - cat FreeBSD-2.2/filez.diffs | (cd /sys/conf; patch -R) -endif - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -egrep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD-2.2/unminstall b/contrib/ipfilter/FreeBSD-2.2/unminstall deleted file mode 100755 index 07aaac08f2ce..000000000000 --- a/contrib/ipfilter/FreeBSD-2.2/unminstall +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo "Unpatching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD-2.2/ip_{in,out}put.c.diffs FreeBSD-2.2/in_proto.c.diffs | \ -(cd /sys/netinet; patch -R) - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.$bak -endif -grep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 b/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 deleted file mode 100644 index 5c30b57821f2..000000000000 --- a/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 +++ /dev/null @@ -1,26 +0,0 @@ -To build a kernel with the IP filter, follow these seven steps: - - 1. do "make freebsd3" - - 2. do "make install-bsd" - (probably has to be done as root) - - 3. run "FreeBSD-3/kinstall" as root - - 4. build a new kernel - - 5. install the new kernel - - 6. If not using DEVFS, create devices for IP Filter as follows: - mknod /dev/ipl c 79 0 - mknod /dev/ipnat c 79 1 - mknod /dev/ipstate c 79 2 - mknod /dev/ipauth c 79 3 - mknod /dev/ipsync c 79 4 - mknod /dev/ipscan c 79 5 - - 7. reboot - - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/FreeBSD-3/kinstall b/contrib/ipfilter/FreeBSD-3/kinstall deleted file mode 100755 index 20f0369d6eaf..000000000000 --- a/contrib/ipfilter/FreeBSD-3/kinstall +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo -n "Installing " -foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \ - ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c mlf_ipl.c ipl.h \ - ip_compat.h ip_auth.[ch] ip_log.c) - echo -n "$i "; - cp $i /sys/netinet - chmod 644 /sys/netinet/$i - switch ($i) - case *.h: - /bin/cp $i /usr/include/netinet/$i - chmod 644 /usr/include/netinet/$i - breaksw - endsw -end -echo "" -echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h" -ln -s /usr/include/osreldate.h /sys/sys/osreldate.h - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -echo "Rewriting $newconfig..." -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -awk '{print $0;if($2=="INET"){print"options IPFILTER\noptions IPFILTER_LOG"}}'\ - $confdir/$newconfig.bak > $confdir/$newconfig -echo "You will now need to run config on $newconfig and build a new kernel." -exit 0 diff --git a/contrib/ipfilter/FreeBSD-3/unkinstall b/contrib/ipfilter/FreeBSD-3/unkinstall deleted file mode 100755 index 687ebc62a7f7..000000000000 --- a/contrib/ipfilter/FreeBSD-3/unkinstall +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/csh -f -# -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo -n "Uninstalling " -foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \ - ip_auth.[ch] ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c ip_compat.h \ - ip_log.c mlf_ipl.c ipl.h) - echo -n "$i "; - /bin/rm -f /sys/netinet/$i -end -echo "" - -echo "Removing link from /usr/include/osreldate.h to /sys/sys/osreldate.h" -rm /sys/sys/osreldate.h - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -egrep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD-4.0/INST.FreeBSD-4 b/contrib/ipfilter/FreeBSD-4.0/INST.FreeBSD-4 deleted file mode 100644 index 7d1b7a2b8f4c..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/INST.FreeBSD-4 +++ /dev/null @@ -1,24 +0,0 @@ -To build a kernel with the IP filter, follow these seven steps: - - 1. do "make freebsd4" - - 2. do "make install-bsd" - (probably has to be done as root) - - 3. run "FreeBSD-4.0/kinstall" as root - - 4. build a new kernel - - 5. install the new kernel - - 6. If not using DEVFS, create devices for IP Filter as follows: - mknod /dev/ipl c 79 0 - mknod /dev/ipnat c 79 1 - mknod /dev/ipstate c 79 2 - mknod /dev/ipauth c 79 3 - - 7. reboot - - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch deleted file mode 100755 index c232b2c15972..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch +++ /dev/null @@ -1,61 +0,0 @@ -*** ip6_input.c.orig Sun Feb 13 14:32:01 2000 ---- ip6_input.c Wed Apr 26 22:31:34 2000 -*************** -*** 121,126 **** ---- 121,127 ---- - - extern struct domain inet6domain; - extern struct ip6protosw inet6sw[]; -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); - - u_char ip6_protox[IPPROTO_MAX]; - static int ip6qmaxlen = IFQ_MAXLEN; -*************** -*** 302,307 **** ---- 303,317 ---- - ip6stat.ip6s_badvers++; - in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); - goto bad; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif, -+ 0, &m1) || !m1) -+ return; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; -*** ip6_output.c.orig Fri Mar 10 01:57:16 2000 ---- ip6_output.c Wed Apr 26 22:34:34 2000 -*************** -*** 108,113 **** ---- 108,115 ---- - #include - #endif - -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ - static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options"); - - struct ip6_exthdrs { -*************** -*** 754,759 **** ---- 756,770 ---- - ip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] = 0; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) || -+ !m1) -+ goto done; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - #ifdef IPV6FIREWALL diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0 b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0 deleted file mode 100755 index c232b2c15972..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0 +++ /dev/null @@ -1,61 +0,0 @@ -*** ip6_input.c.orig Sun Feb 13 14:32:01 2000 ---- ip6_input.c Wed Apr 26 22:31:34 2000 -*************** -*** 121,126 **** ---- 121,127 ---- - - extern struct domain inet6domain; - extern struct ip6protosw inet6sw[]; -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); - - u_char ip6_protox[IPPROTO_MAX]; - static int ip6qmaxlen = IFQ_MAXLEN; -*************** -*** 302,307 **** ---- 303,317 ---- - ip6stat.ip6s_badvers++; - in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); - goto bad; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif, -+ 0, &m1) || !m1) -+ return; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; -*** ip6_output.c.orig Fri Mar 10 01:57:16 2000 ---- ip6_output.c Wed Apr 26 22:34:34 2000 -*************** -*** 108,113 **** ---- 108,115 ---- - #include - #endif - -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ - static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options"); - - struct ip6_exthdrs { -*************** -*** 754,759 **** ---- 756,770 ---- - ip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] = 0; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) || -+ !m1) -+ goto done; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - #ifdef IPV6FIREWALL diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1 b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1 deleted file mode 100644 index 90dac19eb044..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1 +++ /dev/null @@ -1,63 +0,0 @@ -*** ip6_input.c.orig Sat Jul 15 07:14:34 2000 ---- ip6_input.c Thu Oct 19 17:14:37 2000 -*************** -*** 120,125 **** ---- 120,127 ---- - - extern struct domain inet6domain; - extern struct ip6protosw inet6sw[]; -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, -+ struct mbuf **)); - - u_char ip6_protox[IPPROTO_MAX]; - static int ip6qmaxlen = IFQ_MAXLEN; -*************** -*** 289,294 **** ---- 291,305 ---- - ip6stat.ip6s_badvers++; - in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); - goto bad; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif, -+ 0, &m1) || !m1) -+ return; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; - -*** ip6_output.c.orig Sat Jul 15 07:14:35 2000 ---- ip6_output.c Thu Oct 19 17:13:53 2000 -*************** -*** 106,111 **** ---- 106,113 ---- - #include - #endif - -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ - static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options"); - - struct ip6_exthdrs { -*************** -*** 787,792 **** ---- 789,803 ---- - ip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] = 0; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) || -+ !m1) -+ goto done; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - #ifdef IPV6FIREWALL diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2 b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2 deleted file mode 100644 index 90dac19eb044..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2 +++ /dev/null @@ -1,63 +0,0 @@ -*** ip6_input.c.orig Sat Jul 15 07:14:34 2000 ---- ip6_input.c Thu Oct 19 17:14:37 2000 -*************** -*** 120,125 **** ---- 120,127 ---- - - extern struct domain inet6domain; - extern struct ip6protosw inet6sw[]; -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, -+ struct mbuf **)); - - u_char ip6_protox[IPPROTO_MAX]; - static int ip6qmaxlen = IFQ_MAXLEN; -*************** -*** 289,294 **** ---- 291,305 ---- - ip6stat.ip6s_badvers++; - in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); - goto bad; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((*fr_checkp)(ip6, sizeof(*ip6), m->m_pkthdr.rcvif, -+ 0, &m1) || !m1) -+ return; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; - -*** ip6_output.c.orig Sat Jul 15 07:14:35 2000 ---- ip6_output.c Thu Oct 19 17:13:53 2000 -*************** -*** 106,111 **** ---- 106,113 ---- - #include - #endif - -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ - static MALLOC_DEFINE(M_IPMOPTS, "ip6_moptions", "internet multicast options"); - - struct ip6_exthdrs { -*************** -*** 787,792 **** ---- 789,803 ---- - ip6->ip6_src.s6_addr16[1] = 0; - if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) - ip6->ip6_dst.s6_addr16[1] = 0; -+ } -+ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((error = (*fr_checkp)(ip6, sizeof(*ip6), ifp, 1, &m1)) || -+ !m1) -+ goto done; -+ ip6 = mtod(m = m1, struct ip6_hdr *); - } - - #ifdef IPV6FIREWALL diff --git a/contrib/ipfilter/FreeBSD-4.0/kinstall b/contrib/ipfilter/FreeBSD-4.0/kinstall deleted file mode 100755 index ebd6e2e8a075..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/kinstall +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -set ipfdir=/sys/netinet -set krev=`uname -r|sed -e 's/\([0-9\.]*\)-.*/\1/'` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -if ( -d /sys/contrib/ipfilter ) set ipfdir=/sys/contrib/ipfilter/netinet -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo -n "Installing " -foreach i (ip_{auth,fil,nat,pool,proxy,scan,state,sync}.[ch] fil.c \ - ip_*_pxy.c mlfk_ipl.c ipl.h ip_compat.h ip_log.c ) - echo -n "$i "; - cp $i /sys/netinet - chmod 644 /sys/netinet/$i - switch ($i) - case *.h: - /bin/cp $i /usr/include/netinet/$i - chmod 644 /usr/include/netinet/$i - breaksw - endsw -end -echo "" -echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h" -ln -s /usr/include/osreldate.h /sys/sys/osreldate.h - -echo "" -echo "Patching ip6_input.c and ip6_output.c" -cat FreeBSD-4.0/ipv6-patch-$krev | (cd /sys/netinet6; patch -N) - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -grep -q IPFILTER $confdir/$newconfig -if ($status == 0) then - echo "IPFilter already configured in kernel config file" - exit 0 -endif -echo "Rewriting $newconfig..." -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -awk '{print $0;if($2=="INET"){print"options IPFILTER\noptions IPFILTER_LOG"}}'\ - $confdir/$newconfig.bak > $confdir/$newconfig -echo "You will now need to run config on $newconfig and build a new kernel." -exit 0 diff --git a/contrib/ipfilter/FreeBSD-4.0/unkinstall b/contrib/ipfilter/FreeBSD-4.0/unkinstall deleted file mode 100755 index 4e9caaa9e541..000000000000 --- a/contrib/ipfilter/FreeBSD-4.0/unkinstall +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/csh -f -# -# -set dir=`pwd` -set karch=`uname -m` -set krev=`uname -r|sed -e 's/\([0-9\.]*\)-.*/\1/'` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD* ) cd .. -echo -n "Uninstalling " -foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \ - ip_auth.[ch] ip_proxy.[ch] ip_{ftp,rcmd,raudio}_pxy.c ip_compat.h \ - ip_log.c mlf_ipl.c ipl.h) - echo -n "$i "; - /bin/rm -f /sys/netinet/$i -end -echo "" - -echo "Removing link from /usr/include/osreldate.h to /sys/sys/osreldate.h" -rm /sys/sys/osreldate.h - -echo "Removing patch to ip6_input.c and ip6_output.c" -cat FreeBSD-4.0/ipv6-patch-$krev | (cd /sys/netinet6; patch -R) - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -egrep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD/conf.c.diffs b/contrib/ipfilter/FreeBSD/conf.c.diffs deleted file mode 100644 index afd288040d43..000000000000 --- a/contrib/ipfilter/FreeBSD/conf.c.diffs +++ /dev/null @@ -1,46 +0,0 @@ -*** conf.c.orig Sun Jan 14 15:39:32 1996 ---- conf.c Sun Jan 14 15:48:21 1996 -*************** -*** 1128,1133 **** ---- 1128,1149 ---- - #define labpcioctl nxioctl - #endif - -+ #ifdef IPFILTER -+ d_open_t iplopen; -+ d_close_t iplclose; -+ d_ioctl_t iplioctl; -+ # ifdef IPFILTER_LOG -+ d_read_t iplread; -+ # else -+ #define iplread nxread -+ # endif -+ #else -+ #define iplopen nxopen -+ #define iplclose nxclose -+ #define iplioctl nxioctl -+ #define iplread nxread -+ #endif -+ - /* open, close, read, write, ioctl, stop, reset, ttys, select, mmap, strat */ - struct cdevsw cdevsw[] = - { -*************** -*** 1199,1206 **** - * Otherwise, simply use the one reserved for local use. - */ - /* character device 20 is reserved for local use */ -! { nxopen, nxclose, nxread, nxwrite, /*20*/ -! nxioctl, nxstop, nxreset, nxdevtotty,/* reserved */ - nxselect, nxmmap, NULL }, - { psmopen, psmclose, psmread, nowrite, /*21*/ - psmioctl, nostop, nullreset, nodevtotty,/* psm mice */ ---- 1215,1222 ---- - * Otherwise, simply use the one reserved for local use. - */ - /* character device 20 is reserved for local use */ -! { iplopen, iplclose, iplread, nxwrite, /*20*/ -! iplioctl, nxstop, nxreset, nxdevtotty,/* reserved */ - nxselect, nxmmap, NULL }, - { psmopen, psmclose, psmread, nowrite, /*21*/ - psmioctl, nostop, nullreset, nodevtotty,/* psm mice */ diff --git a/contrib/ipfilter/FreeBSD/files.diffs b/contrib/ipfilter/FreeBSD/files.diffs deleted file mode 100644 index 2f028e337eb0..000000000000 --- a/contrib/ipfilter/FreeBSD/files.diffs +++ /dev/null @@ -1,23 +0,0 @@ -*** files.orig Sat Sep 30 18:01:55 1995 ---- files Sun Jan 14 14:32:25 1996 -*************** -*** 208,213 **** ---- 208,225 ---- - netinet/tcp_timer.c optional inet - netinet/tcp_usrreq.c optional inet - netinet/udp_usrreq.c optional inet -+ netinet/ip_fil.c optional ipfilter inet -+ netinet/fil.c optional ipfilter inet -+ netinet/ip_nat.c optional ipfilter inet -+ netinet/ip_frag.c optional ipfilter inet -+ netinet/ip_state.c optional ipfilter inet -+ netinet/ip_auth.c optional ipfilter inet -+ netinet/ip_proxy.c optional ipfilter inet -+ netinet/ip_log.c optional ipfilter inet -+ netinet/ip_scan.c optional ipfilter inet -+ netinet/ip_sync.c optional ipfilter inet -+ netinet/ip_pool.c optional ipfilter_pool ipfilter inet -+ netinet/ip_rules.c optional ipfilter_compiled ipfilter inet - netiso/clnp_debug.c optional iso - netiso/clnp_er.c optional iso - netiso/clnp_frag.c optional iso diff --git a/contrib/ipfilter/FreeBSD/files.newconf.diffs b/contrib/ipfilter/FreeBSD/files.newconf.diffs deleted file mode 100644 index 29aea54dc2fa..000000000000 --- a/contrib/ipfilter/FreeBSD/files.newconf.diffs +++ /dev/null @@ -1,23 +0,0 @@ -*** files.newconf.orig Sun Jun 25 02:17:29 1995 ---- files.newconf Sun Jun 25 02:19:10 1995 -*************** -*** 161,166 **** ---- 161,178 ---- - file netinet/ip_input.c inet - file netinet/ip_mroute.c inet - file netinet/ip_output.c inet -+ file netinet/ip_fil.c ipfilter -+ file netinet/fil.c ipfilter -+ file netinet/ip_nat.c ipfilter -+ file netinet/ip_frag.c ipfilter -+ file netinet/ip_state.c ipfilter -+ file netinet/ip_proxy.c ipfilter -+ file netinet/ip_auth.c ipfilter -+ file netinet/ip_log.c ipfilter -+ file netinet/ip_scan.c ipfilter -+ file netinet/ip_sync.c ipfilter -+ file netinet/ip_pool.c ipfilter_pool -+ file netinet/ip_rules.c ipfilter_compiled - file netinet/raw_ip.c inet - file netinet/tcp_debug.c inet - file netinet/tcp_input.c inet diff --git a/contrib/ipfilter/FreeBSD/files.oldconf.diffs b/contrib/ipfilter/FreeBSD/files.oldconf.diffs deleted file mode 100644 index ed8aff94b39f..000000000000 --- a/contrib/ipfilter/FreeBSD/files.oldconf.diffs +++ /dev/null @@ -1,23 +0,0 @@ -*** files.oldconf.orig Sat Apr 29 19:59:31 1995 ---- files.oldconf Sun Apr 23 17:54:18 1995 -*************** -*** 180,185 **** ---- 180,197 ---- - netinet/tcp_timer.c optional inet - netinet/tcp_usrreq.c optional inet - netinet/udp_usrreq.c optional inet -+ netinet/ip_fil.c optional ipfilter requires inet -+ netinet/fil.c optional ipfilter requires inet -+ netinet/ip_nat.c optional ipfilter requires inet -+ netinet/ip_frag.c optional ipfilter requires inet -+ netinet/ip_state.c optional ipfilter requires inet -+ netinet/ip_proxy.c optional ipfilter requires inet -+ netinet/ip_auth.c optional ipfilter requires inet -+ netinet/ip_log.c optional ipfilter requires inet -+ netinet/ip_scan.c optional ipfilter requires inet -+ netinet/ip_sync.c optional ipfilter requires inet -+ netinet/ip_pool.c optional ipfilter_pool requires ipfilter -+ netinet/ip_rules.c optional ipfilter_compiled requires ipfilter - netiso/clnp_debug.c optional iso - netiso/clnp_er.c optional iso - netiso/clnp_frag.c optional iso diff --git a/contrib/ipfilter/FreeBSD/filez.diffs b/contrib/ipfilter/FreeBSD/filez.diffs deleted file mode 100644 index 96560063dcd7..000000000000 --- a/contrib/ipfilter/FreeBSD/filez.diffs +++ /dev/null @@ -1,23 +0,0 @@ -*** files.orig Sat Apr 29 20:00:02 1995 ---- files Sun Apr 23 17:53:58 1995 -*************** -*** 222,227 **** ---- 222,235 ---- - file netinet/tcp_timer.c inet - file netinet/tcp_usrreq.c inet - file netinet/udp_usrreq.c inet -+ file netinet/ip_fil.c ipfilter -+ file netinet/fil.c ipfilter -+ file netinet/ip_nat.c ipfilter -+ file netinet/ip_frag.c ipfilter -+ file netinet/ip_state.c ipfilter -+ file netinet/ip_proxy.c ipfilter -+ file netinet/ip_auth.c ipfilter -+ file netinet/ip_log.c ipfilter -+ file netinet/ip_scan.c ipfilter -+ file netinet/ip_sync.c ipfilter -+ file netinet/ip_pool.c ipfilter_pool -+ file netinet/ip_rules.c ipfilter_compiled - file netiso/clnp_debug.c iso - file netiso/clnp_er.c iso - file netiso/clnp_frag.c iso diff --git a/contrib/ipfilter/FreeBSD/in_proto.c.diffs b/contrib/ipfilter/FreeBSD/in_proto.c.diffs deleted file mode 100644 index 052dd514ee18..000000000000 --- a/contrib/ipfilter/FreeBSD/in_proto.c.diffs +++ /dev/null @@ -1,16 +0,0 @@ -*** in_proto.c.orig Wed Sep 6 20:31:34 1995 ---- in_proto.c Mon Mar 11 22:40:03 1996 -*************** -*** 81,86 **** ---- 81,91 ---- - void eoninput(), eonctlinput(), eonprotoinit(); - #endif /* EON */ - -+ #ifdef IPFILTER -+ void iplinit(); -+ #define ip_init iplinit -+ #endif -+ - void rsvp_input(struct mbuf *, int); - void ipip_input(struct mbuf *, int); - diff --git a/contrib/ipfilter/FreeBSD/ip_input.c.diffs b/contrib/ipfilter/FreeBSD/ip_input.c.diffs deleted file mode 100644 index a70be897ea89..000000000000 --- a/contrib/ipfilter/FreeBSD/ip_input.c.diffs +++ /dev/null @@ -1,88 +0,0 @@ -*** /sys/netinet/ip_input.c.orig Thu Oct 24 22:27:27 1996 ---- /sys/netinet/ip_input.c Tue Feb 18 21:18:19 1997 -*************** -*** 93,98 **** ---- 93,102 ---- - int ipqmaxlen = IFQ_MAXLEN; - struct in_ifaddr *in_ifaddr; /* first inet address */ - struct ifqueue ipintrq; -+ #if defined(IPFILTER_LKM) || defined(IPFILTER) -+ int fr_check __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ #endif - - struct ipstat ipstat; - struct ipq ipq; -*************** -*** 219,226 **** - } - ip = mtod(m, struct ip *); - } -! ip->ip_sum = in_cksum(m, hlen); -! if (ip->ip_sum) { - ipstat.ips_badsum++; - goto bad; - } ---- 223,229 ---- - } - ip = mtod(m, struct ip *); - } -! if (in_cksum(m, hlen)) { - ipstat.ips_badsum++; - goto bad; - } -*************** -*** 267,272 **** ---- 270,288 ---- - goto next; - } - -+ #if defined(IPFILTER) || defined(IPFILTER_LKM) -+ /* -+ * Check if we want to allow this packet to be processed. -+ * Consider it to be bad if not. -+ */ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((*fr_checkp)(ip, hlen, m->m_pkthdr.rcvif, 0, &m1) || !m1) -+ goto next; -+ ip = mtod(m = m1, struct ip *); -+ } -+ #endif - /* - * Process options and, if not destined for us, - * ship it on. ip_dooptions returns 1 when an -*************** -*** 527,532 **** ---- 533,540 ---- - * if they are completely covered, dequeue them. - */ - while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) { -+ struct mbuf *m0; -+ - i = (ip->ip_off + ip->ip_len) - q->ip_off; - if (i < q->ip_len) { - q->ip_len -= i; -*************** -*** 526,534 **** - m_adj(dtom(q), i); - break; - } - q = q->ipf_next; -- m_freem(dtom(q->ipf_prev)); - ip_deq(q->ipf_prev); - } - - insert: ---- 542,551 ---- - m_adj(dtom(q), i); - break; - } -+ m0 = dtom(q); - q = q->ipf_next; - ip_deq(q->ipf_prev); -+ m_freem(m0); - } - - insert: diff --git a/contrib/ipfilter/FreeBSD/ip_output.c.diffs b/contrib/ipfilter/FreeBSD/ip_output.c.diffs deleted file mode 100644 index f1fe9accea03..000000000000 --- a/contrib/ipfilter/FreeBSD/ip_output.c.diffs +++ /dev/null @@ -1,36 +0,0 @@ -*** /sys/netinet/ip_output.c.orig Thu Oct 24 22:27:28 1996 ---- /sys/netinet/ip_output.c Tue Feb 18 21:38:23 1997 -*************** -*** 65,70 **** ---- 65,74 ---- - static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); - static void ip_mloopback - __P((struct ifnet *, struct mbuf *, struct sockaddr_in *)); -+ #if defined(IPFILTER_LKM) || defined(IPFILTER) -+ extern int fr_check __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ extern int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); -+ #endif - - /* - * IP output. The packet in mbuf chain m contains a skeletal IP -*************** -*** 330,335 **** ---- 334,351 ---- - m->m_flags &= ~M_BCAST; - - sendit: -+ #if defined(IPFILTER) || defined(IPFILTER_LKM) -+ /* -+ * looks like most checking has been done now...do a filter check -+ */ -+ if (fr_checkp) { -+ struct mbuf *m1 = m; -+ -+ if ((error = (*fr_checkp)(ip, hlen, ifp, 1, &m1)) || !m1) -+ goto done; -+ ip = mtod(m = m1, struct ip *); -+ } -+ #endif - /* - * Check with the firewall... - */ diff --git a/contrib/ipfilter/FreeBSD/kinstall b/contrib/ipfilter/FreeBSD/kinstall deleted file mode 100755 index 2b67b9ad995c..000000000000 --- a/contrib/ipfilter/FreeBSD/kinstall +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD ) cd .. -echo -n "Installing " -foreach i (ip_{auth,fil,frag,nat,pool,proxy,scan,state,sync}.[ch] fil.c \ - ip_*_pxy.c ip_compat.h ip_log.c ) - echo -n "$i "; - cp $i /sys/netinet - chmod 644 /sys/netinet/$i - switch ($i) - case *.h: - /bin/cp $i /usr/include/netinet/$i - chmod 644 /usr/include/netinet/$i - breaksw - endsw -end -echo "" -grep iplopen $archdir/$karch/conf.c >& /dev/null -if ( $status != 0 ) then - echo "Patching $archdir/$karch/conf.c" - cat FreeBSD/conf.c.diffs | (cd $archdir/$karch; patch) -endif -grep fr_checkp /sys/netinet/ip_input.c >& /dev/null -if ( $status != 0 ) then - echo "Patching ip_input.c, ip_output.c and in_proto.c" - cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \ - (cd /sys/netinet; patch) -endif -if ( -f /sys/conf/files.newconf ) then - echo "Patching /sys/conf/files.newconf" - cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch) - echo "Patching /sys/conf/files" - cat FreeBSD/files.diffs | (cd /sys/conf; patch) -endif -if ( -f /sys/conf/files.oldconf ) then - echo "Patching /sys/conf/files.oldconf" - cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch) - echo "Patching /sys/conf/files" - cat FreeBSD/filez.diffs | (cd /sys/conf; patch) -endif - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -echo "Re-config'ing $newconfig..." -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -awk '{print $0;if($2=="INET"){print"options IPFILTER"}}' \ - $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD/minstall b/contrib/ipfilter/FreeBSD/minstall deleted file mode 100755 index 0cfe7c360d9a..000000000000 --- a/contrib/ipfilter/FreeBSD/minstall +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD ) cd .. -echo "Patching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \ -(cd /sys/netinet; patch) - -if ( -f /sys/conf/files.newconf ) then - echo "Patching /sys/conf/files.newconf" - cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch) - echo "Patching /sys/conf/files" - cat FreeBSD/files.diffs | (cd /sys/conf; patch) -endif -if ( -f /sys/conf/files.oldconf ) then - echo "Patching /sys/conf/files.oldconf" - cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch) - echo "Patching /sys/conf/files" - cat FreeBSD/filez.diffs | (cd /sys/conf; patch) -endif - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -echo "Re-config'ing $newconfig..." -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.$bak -endif -awk '{print $0;if($2=="INET"){print"options IPFILTER_LKM"}}' \ - $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD/unkinstall b/contrib/ipfilter/FreeBSD/unkinstall deleted file mode 100755 index 8547fcd90d8b..000000000000 --- a/contrib/ipfilter/FreeBSD/unkinstall +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD ) cd .. -echo -n "Uninstalling " -foreach i (ip_fil.[ch] ip_nat.[ch] ip_frag.[ch] ip_state.[ch] fil.c \ - ip_compat.h ip_auth.[ch] ip_proxy.[ch] ip_ftp_pxy.c ip_log.c) - echo -n "$i "; - /bin/rm -f /sys/netinet/$i -end -echo "" -echo "Unpatching $archdir/$karch/conf.c" -cat FreeBSD/conf.c.diffs | (cd $archdir/$karch; patch -R) -echo "Unpatching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \ -(cd /sys/netinet; patch -R) - -if ( -f /sys/conf/files.newconf ) then - echo "Unpatching /sys/conf/files.newconf" - cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch -R) - echo "Unpatching /sys/conf/files" - cat FreeBSD/files.diffs | (cd /sys/conf; patch -R) -endif -if ( -f /sys/conf/files.oldconf ) then - echo "Unpatching /sys/conf/files.oldconf" - cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch -R) - echo "Unpatching /sys/conf/files" - cat FreeBSD/filez.diffs | (cd /sys/conf; patch -R) -endif - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.${bak} -endif -egrep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/FreeBSD/unminstall b/contrib/ipfilter/FreeBSD/unminstall deleted file mode 100755 index a25746cb4f70..000000000000 --- a/contrib/ipfilter/FreeBSD/unminstall +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/csh -f -# -set dir=`pwd` -set karch=`uname -m` -if ( -d /sys/arch/$karch ) set archdir="/sys/arch/$karch" -if ( -d /sys/$karch ) set archdir="/sys/$karch" -set confdir="$archdir/conf" - -if ( $dir =~ */FreeBSD ) cd .. -echo "Unpatching ip_input.c, ip_output.c and in_proto.c" -cat FreeBSD/ip_{in,out}put.c.diffs FreeBSD/in_proto.c.diffs | \ -(cd /sys/netinet; patch -R) - -if ( -f /sys/conf/files.newconf ) then - echo "Unpatching /sys/conf/files.newconf" - cat FreeBSD/files.newconf.diffs | (cd /sys/conf; patch -R) - echo "Unpatching /sys/conf/files" - cat FreeBSD/files.diffs | (cd /sys/conf; patch -R) -endif -if ( -f /sys/conf/files.oldconf ) then - echo "Unpatching /sys/conf/files.oldconf" - cat FreeBSD/files.oldconf.diffs | (cd /sys/conf; patch -R) - echo "Unpatching /sys/conf/files" - cat FreeBSD/filez.diffs | (cd /sys/conf; patch -R) -endif - -set config=`(cd $confdir; /bin/ls -1t [0-9A-Z_]*) | head -1` -echo -n "Kernel configuration to update [$config] " -set newconfig=$< -if ( "$newconfig" != "" ) then - set config="$confdir/$newconfig" -else - set newconfig=$config -endif -if ( -f $confdir/$newconfig ) then - mv $confdir/$newconfig $confdir/$newconfig.bak -endif -if ( -d $archdir/../compile/$newconfig ) then - set bak=".bak" - set dot=0 - while ( -d $archdir/../compile/${newconfig}.${bak} ) - set bak=".bak.$dot" - set dot=`expr 1 + $dot` - end - mv $archdir/../compile/$newconfig $archdir/../compile/${newconfig}.$bak -endif -grep -v IPFILTER $confdir/$newconfig.bak > $confdir/$newconfig -echo 'You will now need to run "config" and build a new kernel.' -exit 0 diff --git a/contrib/ipfilter/INST.FreeBSD-2.2 b/contrib/ipfilter/INST.FreeBSD-2.2 deleted file mode 100644 index 78f7295e0894..000000000000 --- a/contrib/ipfilter/INST.FreeBSD-2.2 +++ /dev/null @@ -1,60 +0,0 @@ - -To build a kernel for use with the loadable kernel module, follow these -steps: - 1. In /sys/i386/conf, create a new kernel config file (to be used - with IPFILTER), i.e. FIREWALL and run config, i.e. "config FIREWALL" - - 2. build the object files, telling it the name of the kernel to be - used. "freebsd22" MUST be the target, so the command would be - something like this: "make freebsd22 IPFILKERN=FIREWALL" - - 3. do "make install-bsd" - (probably has to be done as root) - - 4. run "FreeBSD-2.2/minstall" as root - - 5. build a new kernel - - 6. install and reboot with the new kernel - - 7. use modload(8) to load the packet filter with: - modload if_ipl.o - - 8. do "modstat" to confirm that it has been loaded successfully. - -There is no need to use mknod to create the device in /dev; -- upon loading the module, it will create itself with the correct values, - under the name (IPL_NAME) from the Makefile. It will also remove itself - from /dev when it is modunload'd. - -To build a kernel with the IP filter, follow these steps: - -*** KERNEL INSTALL CURRENTLY UNSUPPORTED *** - 1. do "make freebsd22" - - 2. do "make install-bsd" - (probably has to be done as root) - - 3. run "FreeBSD-2.2/kinstall" as root - - 4. build a new kernel - - 5a) For FreeBSD 2.2 (or later) - create devices for IP Filter as follows: - mknod /dev/ipl c 79 0 - mknod /dev/ipnat c 79 1 - mknod /dev/ipstate c 79 2 - mknod /dev/ipauth c 79 3 - - 5b) For versions prior to FreeBSD 2.2: - create devices for IP Filter as follows (assuming it was - installed into the device table as char dev 20): - mknod /dev/ipl c 20 0 - mknod /dev/ipnat c 20 1 - mknod /dev/ipstate c 20 2 - mknod /dev/ipauth c 20 3 - - 6. install and reboot with the new kernel - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/INSTALL.BSDOS b/contrib/ipfilter/INSTALL.BSDOS deleted file mode 100644 index 17d9602ef8ab..000000000000 --- a/contrib/ipfilter/INSTALL.BSDOS +++ /dev/null @@ -1,35 +0,0 @@ - -BSD/OS users. -------------- - -First, you need to build IP Filter. Do this from the "ip_fil3.2.x" -directory with the command "make bsdos". If this completes successfully, -install the various bits and pieces with "make install-bsd". - -Prior to starting, it is a good idea for you to know what your kernel config -file is (it appears that the script guesses incorrectly at present). - -Once you have that in mind, run the 'kinstall' script in the correct -BSDOS3 or BSDOS4 directory. This will attempt to patch a bunch of files -or install the relevant .o files if you don't have kernel source. -It will also go and install all the IP Filter .c and .h files where they -can be find when it comes time to build the kernel. - -The script will then pause and ask you for your kernel configuration -file. After you enter this, it will add "options IPFILTER" to your -kernel configuration file. IF YOU WANT TO DO LOGGING, ADD -"options IPFILTER_LOG" to your kernel configuration file NOW! - -Now that you've got your kernel configuration file done, use config -to setup a new kernel build and complete with make. - -When the kernel rebuilt is complete, put it into / and reboot with -your new kernel. If IP Filter has been configured into your kernel -correctly, you will see a message like this when your system boots: - -IP Filter: initialized. Default = pass all, Logging = enabled - -Upon logging in, the IP Filter commands ipfstat, et al, should all -function properly. - -Darren diff --git a/contrib/ipfilter/INSTALL.BSDOS3 b/contrib/ipfilter/INSTALL.BSDOS3 deleted file mode 100644 index 8842b981911c..000000000000 --- a/contrib/ipfilter/INSTALL.BSDOS3 +++ /dev/null @@ -1,44 +0,0 @@ - -BSD/OS 3.x users. ------------------ - -First, you will need to either: -(a) have a source license for the kernel so you can patch some files or -(b) obtain the relevant pre-compiled .o files (I can't supply these yet). - -The files which you will need patched are: -ip_input.c, ip_output.c (maybe in_proto.c and ioconf.c.i386 too - NOT sure). - -First, you need to build IP Filter. Do this from the "ip_fil3.2.x" -directory with the command "make bsdos". If this completes successfully, -install the various bits and pieces with "make install-bsd". - -Prior to starting, it is a good idea for you to know what your kernel config -file is (it appears that the script guesses incorrectly at present). - -Once you have that in mind, run the 'kinstall' script in the BSDOS3 -directory. This will attempt to patch a bunch of files. If you've -obtained the relevant .o files, ignore the errors, otherwise please -report them to me and mention which version of BSD/OS you are using -and on what platform (Sparc, i386, etc). It will also go and install -all the IP Filter .c and .h files where they can be find when it comes -time to build the kernel. - -The script will then pause and ask you for your kernel configuration -file. After you enter this, it will add "options IPFILTER" to your -kernel configuration file. IF YOU WANT TO DO LOGGING, ADD -"options IPFILTER_LOG" to your kernel configuration file NOW! - -Now that you've got your kernel configuration file done, use config -to setup a new kernel build and complete with make. - -When the kernel rebuilt is complete, put it into / and reboot with -your new kernel. If IP Filter has been configured into your kernel -correctly, you will see a message like this when your system boots: - -IP Filter: initialized. Default = pass all, Logging = enabled - -Upon logging in, the IP Filter commands ipfstat, et al, should all -function properly. - -Darren diff --git a/contrib/ipfilter/INSTALL.FreeBSD b/contrib/ipfilter/INSTALL.FreeBSD deleted file mode 100644 index a4a787ac42be..000000000000 --- a/contrib/ipfilter/INSTALL.FreeBSD +++ /dev/null @@ -1,56 +0,0 @@ - -This file is for use with FreeBSD 4.x and 5.x only. - -To build a kernel for use with the loadable kernel module, follow these -steps: - 1. For FreeBSD version: - 4.* do make freebsd4 - 5.* do make freebsd5 - - 2. do "make install-bsd" - (probably has to be done as root) - - 3. Run "BSD/kupgrade" - - 4. build a new kernel - - 5. install and reboot with the new kernel - - 6. use modload(8) to load the packet filter with: - modload if_ipl.o - - 7. do "modstat" to confirm that it has been loaded successfully. - -There is no need to use mknod to create the device in /dev; -- upon loading the module, it will create itself with the correct values, - under the name (IPL_NAME) from the Makefile. It will also remove itself - from /dev when it is modunload'd. - -To build a kernel with the IP filter, follow these steps: - - 1. For FreeBSD version: - 4.* do make freebsd4 - 5.* do make freebsd5 - - 2. do "make install-bsd" - (probably has to be done as root) - - 3. run "FreeBSD/kinstall" as root - - 4. build a new kernel - - 5. - b) If you are using FreeBSD-3 or later: - create devices for IP Filter as follows (assuming it was - installed into the device table as char dev 20): - mknod /dev/ipl c 79 0 - mknod /dev/ipnat c 79 1 - mknod /dev/ipstate c 79 2 - mknod /dev/ipauth c 79 3 - mknod /dev/ipsync c 79 4 - mknod /dev/ipscan c 79 5 - - 6. install and reboot with the new kernel - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/INSTALL.IRIX b/contrib/ipfilter/INSTALL.IRIX deleted file mode 100644 index b64d4349879b..000000000000 --- a/contrib/ipfilter/INSTALL.IRIX +++ /dev/null @@ -1,108 +0,0 @@ - -IP Filter has been mostly tested under IRIX 6.2. It should work under IRIX 6.3 -as well. Under IRIX 5.3, it has been successfully compiled and linked in the -kernel, but not tested. Compilation under IRIX >= 6.4 is not yet supported. - -To build a kernel with the IP filter and install it on your system, -follow these steps: - - 1. edit the top-level Makefile to - a) comment-out the IPFLKM definition. - This means changing the line reading: - IPFLKM=-DIPFILTER_LKM - to - #IPFLKM=-DIPFILTER_LKM - b) select the system's compiler (cc) - This means changing the line reading: - CC=gcc - to - CC=cc - b) enable full optimization - This means changing the lines reading: - DEBUG=-g - CFLAGS=-I$$(TOP) - to - DEBUG= - CFLAGS=-O2 -I$$(TOP) - - 1. do "make irix" (Warning: GNU make is not supported, so if it has - been installed on your system, verify your path and/or do "which make" - to guarantee that IRIX's /sbin/make has precedence) - - 2. do "make install-irix" as root - (a new kernel will be automatically built) - - 3. determine the filtering rules and place them in /etc/ipf.conf - and /etc/ipnat.conf - - 4. do "init 6" as root to reboot with the new kernel - - After restarting, the filter should be active and behaving according to - the rules loaded from /etc/ipf.conf and /etc/ipfnat.conf. - - These files can be changed at any time, and reloaded using the - following command sequence: - - # sh /etc/init.d/ipf stop; sh /etc/init.d/ipf start - - -To remove the IP Filter from your kernel, follow these steps: - - 1. Delete the /var/sysgen/boot/ipfilter.o file - - # rm /var/sysgen/boot/ipfilter.o - - 2. If SGI's ipfilter.o had been previously installed, restore it - back to its original location - - # mv /var/sysgen/boot/ipfilter.o.DIST /var/sysgen/boot/ipfilter.o - - 3. Build a new kernel - - # /etc/autoconfig - - 4. Delete the /etc/rc2.d/S33ipf symbolic link - - # rm /etc/rc2.d/S33ipf - - 5. Reboot - - # init 6 - - -ADDITIONAL NOTES: - - - The IP filter uses the same kernel interface to the IP driver as - SGI's ipfilter. In fact, it is installed in place of SGI's - /var/sysgen/boot/ipfilter.o module, after renaming it (if installed) - to /var/sysgen/boot/ipfilter.o.DIST. You should ensure that SGI's - ipfilterd daemon is not running simultaneously, since this package uses - the same major device number. - - - We have not tested IP Filter on a multiprocessor machine yet. - However, feel free to try it and send your experiences/patches - back to marc@CAM.ORG. SGI prescribes that kernel code be built on such - systems with -D_MP_NETLOCKS -DMP. Therefore, these flags should - probably be uncommented on the DFLAGS line of IRIX/Makefile if your - machine has more than one processor. - - - It is also possible to build IP Filter as a dynamically loadable - kernel module (by retaining the IPFLKM=-DIPFILTER_LKM definition in the - top-level Makefile), but this is not recommended other than for testing - and debugging purposes, because the only possible method for dynamic - attachment to the IP stack (instruction patching) is highly dependent - on the processor architecture. The code provided has only been tested - with IP22 CPU boards and can sometime cause panics during loading due - to a potential race condition. - - -CREDITS: - - IP Filter was ported to IRIX by Marc Boucher - - Marc Boucher wishes to thank the - ICARI Institute (http://www.icari.qc.ca) - and - Aurelio Cascio - for their financial support and testing facilities, respectively. - diff --git a/contrib/ipfilter/INSTALL.Linux b/contrib/ipfilter/INSTALL.Linux deleted file mode 100644 index 1a5d15b59f02..000000000000 --- a/contrib/ipfilter/INSTALL.Linux +++ /dev/null @@ -1,50 +0,0 @@ -IP-Filter on Linux 2.0.31 -------------------------- - -NOTE: I have *ONLY* compiled and created patches for using IP Filter on - Linux 2.0.31. Any other kernel revision may need seprate patches. - Also, I've only tested on a x86 CPU so I can't make any guarantees - about it working on Sparc/Mac/Amiga. - -First, you should do a sanity check of your system to make sure it will -compile IP Filter. You will need a "libfl" and a "libelf". If you don't -have these, install them before proceeding. - -The installation and compiliation process assumes that Linux 2.0.31 -will be in the /usr/src/linux directory and that all the symbolic links -in /usr/include match. /usr/src/linux may be a symbolic link too, but -it must point to a 2.0.31 kernel source tree. - -The first step is to make the IP Filter binaries. Do this with a -"make linux" from the ip_fil3.2.x directory. If this completes with -no errors, install IP Filter with a "make install-linux". - -Now that the user part of it is complete, it is time to work on the kernel. -To start this off, run "Linux/minstall". This will configure the devices -you will need for the IP Filter. Then run "Linux/kinstall". This will -patch your kernel source code and configuration files so you can enabled IP -Filter. You must now go to /usr/src/linux and configure your kernel using one -of the available interfaces to enable IP Filter. IP Filter will be presented -as a three way choice "y/m/n" - select "m" to enable it. Save your kernel -configuration file, rebuild, install and reboot with the new kernel. - -When you've rebooted with the new kernel, you should be able to load -IP Filter with the command "insmod if_ipl". All going will, you will -see a message like this on your console: - -IP Filter: initialized. Default = pass all, Logging = enabled - -indicating that IP Filter has successfully been loaded into the kernel -and is awaiting. - -Darren - -Features Not Available on Linux, yet: - -- compiled into the kernel -" in on to ..." -" in on dup-to ..." -" in on fastroute ..." -"block return-rst ..." -"map ... proxy ..." (Linux's masquerading is better at present) - diff --git a/contrib/ipfilter/INSTALL.NetBSD b/contrib/ipfilter/INSTALL.NetBSD deleted file mode 100644 index 012d6d7f8d2d..000000000000 --- a/contrib/ipfilter/INSTALL.NetBSD +++ /dev/null @@ -1,59 +0,0 @@ - -To build a kernel for use with the loadable kernel module, follow these -steps: - 1. do "make netbsd" - - 2. do "make install-bsd" - (probably has to be done as root) - - 3(a) NetBSD systems prior to 1.2: - run "NetBSD/minstall" as root - 3(b) NetBSD 1.2 systems or later: - run "NetBSD-1.2/minstall" as root - - 4. build a new kernel - - 5. install and reboot with the new kernel - - 6. use modload(8) to load the packet filter with: - modload if_ipl.o - - 7. do "modstat" to confirm that it has been loaded successfully. - -There is no need to use mknod to create the device in /dev; -- upon loading the module, it will create itself with the correct values, - under the name (IPL_NAME) from the Makefile. It will also remove itself - from /dev when it is modunload'd. - -To build a kernel with the IP filter, follow these steps: - - 1. do "make netbsd" - - 2. do "make install-bsd" - (probably has to be done as root) - - 3(a) NetBSD systems prior to 1.2: - run "NetBSD/kinstall" as root - 3(b) NetBSD 1.2 systems or later: - run "NetBSD-1.2/kinstall" as root - 3(c) If conf.c fails on the 2nd hunk of the patch, you will have to - manually apply the patch. - - 4. build a new kernel - - 5. Create device files. For NetBSD-1.2 (or later), use 49 as the - major number. For NetBSD-1.1 or earlier, use 59. Run these - commands as root, substituting for the appropriate number: - - mknod /dev/ipl c 0 - mknod /dev/ipnat c 1 - mknod /dev/ipstate c 2 - mknod /dev/ipauth c 3 - - ** NOTE: both the numbers 49 and 59 should be substituted with - whatever number you inserted it into conf.c as. - - 6. install and reboot with the new kernel - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/INSTALL.Sol2 b/contrib/ipfilter/INSTALL.Sol2 deleted file mode 100644 index 5ba84b931985..000000000000 --- a/contrib/ipfilter/INSTALL.Sol2 +++ /dev/null @@ -1,28 +0,0 @@ - -For those running Solaris 2.5 or later, please read COMPILE.2.5 before -building IP Filter. - -Type "make solaris" to build all the required binaries. DO NOT USE THE -GNU make!!! - -Once IP Filter has been successfully compiled, you may then install it using -the usual package method (using pkgadd), however, the package needs to be -created, prior to pkgadd'ing. To create the package in /var/spool/pkg, change -directory to SunOS5 and enter the following command: - -make package - -This will build the package into SunOS5//root, copy that to -/var/spool/pkg as a package and then start the installation using -pkgadd. - -As part of the postinstall script, it will install loadable kernel module -as part of Solaris 2 (using add_drv) making it available for immeadiate use. - -IP Filter will be installed into /opt/CYBSipf (programs, manual pages and -examples) and create a directory /etc/opt/CYBSipf with a null body file -called "ipf.conf" using touch. The rc scripts have been written to look -for the configuration file here, using the installed binaries in /sbin. - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/INSTALL.SunOS b/contrib/ipfilter/INSTALL.SunOS deleted file mode 100644 index 0d4dd8c5e07a..000000000000 --- a/contrib/ipfilter/INSTALL.SunOS +++ /dev/null @@ -1,40 +0,0 @@ - -To install as a Loadable Kernel Module (LKM): - - 1. do a "make solaris" in this directory - - 2. Run the script "SunOS4/minstall" as root. - - 3. change directory to SunOS4 and run "make install" - - 4. Reboot using the new kernel - - 5. use modload(8) to load the packet filter with: - modload if_ipl.o - - 6. do "modstat" to confirm that it has been loaded successfully. - - There is no need to use mknod to create the device in /dev; - - upon loading the module, it will create itself with the correct - values, under the name (IPL_NAME) from the Makefile. It will - also remove itself from /dev when it is modunload'd. - - -To install as part of a SunOS 4.1.x kernel: - - 1. do a "make solaris" in this directory - - 2. Run the script "SunOS4/kinstall" as root. - NOTE: This script sets up /dev/ipl as char. device 59,0 - in /sys/sun/conf.c - - 3. Run the following commands as root: - mknod /dev/ipl c 59 0 - mknod /dev/ipnat c 59 1 - mknod /dev/ipstate c 59 2 - mknod /dev/ipauth c 59 3 - - 4. Reboot using the new kernel - -Darren Reed -darrenr@pobox.com diff --git a/contrib/ipfilter/INSTALL.xBSD b/contrib/ipfilter/INSTALL.xBSD deleted file mode 100644 index b06ad4b8ab3b..000000000000 --- a/contrib/ipfilter/INSTALL.xBSD +++ /dev/null @@ -1,44 +0,0 @@ - -To build a kernel for use with the loadable kernel module, follow these -steps: - 1. do "make bsd" - - 2. cd to the "BSD" directory and type "make install" - - 3. run "4bsd/minstall" as root - - 4. build a new kernel - - 5. install and reboot with the new kernel - - 6. use modload(8) to load the packet filter with: - modload if_ipl.o - - 7. do "modstat" to confirm that it has been loaded successfully. - -There is no need to use mknod to create the device in /dev; -- upon loading the module, it will create itself with the correct values, - under the name (IPL_NAME) from the Makefile. It will also remove itself - from /dev when it is modunload'd. - -To build a kernel with the IP filter, follow these steps: - - 1. do "make bsd" - - 2. cd to the "BSD" directory and type "make install" - - 3. run "4bsd/kinstall" as root - - 4. build a new kernel - - 5. create devices for IP Filter as follows (assuming it was - installed into the device table as char dev 20): - mknod /dev/ipl c 20 0 - mknod /dev/ipnat c 20 1 - mknod /dev/ipstate c 20 2 - mknod /dev/ipauth c 20 3 - - 6. install and reboot with the new kernel - -Darren -darrenr@pobox.com diff --git a/contrib/ipfilter/IPF.KANJI b/contrib/ipfilter/IPF.KANJI deleted file mode 100644 index 85af5ce9e9aa..000000000000 --- a/contrib/ipfilter/IPF.KANJI +++ /dev/null @@ -1,465 +0,0 @@ -IP filter $B%7%g!<%H%,%$%I(B Dec, 1999 - -$B%[!<%`%Z!<%8(B: http://coombs.anu.edu.au/~avalon/ip-filter.html -FTP: ftp://coombs.anu.edu.au/pub/net/ip-filter/ - - $B30;3(B $B=c@8(B - $B;3K\(B $BBY1'(B - ------ -$B$O$8$a$K(B - -IP filter $B$r(B gateway $B%^%7%s$K%$%s%9%H!<%k$9$k$3$H$G%Q%1%C%H%U%#(B -$B%k%?%j%s%0$r9T$&$3$H$,$G$-$^$9!#(B - -$B%$%s%9%H!<%k$NJ}K!$O!"(BINSTALL$B$K=q$$$F$"$k$N$G!"$=$A$i$r;2>H$7$F(B -$B$/$@$5$$!#(BIP filter $B$N%P!<%8%g%s(B 3.3.5 $B$O!"(B - Solaris/Solaris-x86 2.3 - 8 (early access) - SunOS 4.1.1 - 4.1.4 - NetBSD 1.0 - 1.4 - FreeBSD 2.0.0 - 2.2.8 - BSD/OS-1.1 - 4 - IRIX 6.2 -$B$GF0:n$9$k$3$H$,3NG'$5$l$F$$$^$9!#(B - -$B$J$*!"(B64 bit kernel $B$NAv$C$F$k(B Solaris7 $B%^%7%s$G$O!"(Bgcc $B$H$+$G%3(B -$B%s%Q%$%k$7$?(B kernel driver $B$OF0:n$7$^$;$s!#(B - -$B$=$N$h$&$J>l9g$K$O!"(Bprecompiled binary $B$r(B -ftp://coombs.anu.edu.au/pub/net/ip-filter/ip_fil3.3.2-sparcv9.pkg.gz -(1999$BG/(B12$B7n(B14$BF|8=:_!"$^$@(B3.3.5$B$O%Q%C%1!<%8$K$J$C$F$$$^$;$s(B) -$B$+$il9g$O(B pass $B$H$J$j$^$9!#(B - -log $B$H$$$&$N$O!"$3$N%k!<%k$K%^%C%A$9$k%Q%1%C%H$N%m%0$re$N%m%0$O>C$($F(B -$B$7$^$$$^$9!#(B - -/dev/ipl $B$NFbMF$rFI$_=P$9$K$O(B ipmon $B$H$$$&%W%m%0%i%`$r;H$$$^$9!#(B -ipmon $B$O(B stdout, syslog, $B$b$7$/$ODL>o$N%U%!%$%k$K%m%0$r=PNO$7$^(B -$B$9!#5/F0;~$K(B ipmon $B$rN)$A>e$2$k$J$i!" /dev/null 2>&1 & - -${IPMONLOG} $B$OE,Ev$J%U%!%$%kL>$KCV49$7$F$/$@$5$$!#(Bsyslog $B$K=PNO(B -$B$9$k>l9g$O!"(B-s $B%*%W%7%g%s$rIU$1$^$9!#(Bsyslog $B$K=PNO$9$k>l9g!"(B -local0.info $B$r5-O?$9$k$h$&$K(B syslog.conf $B$rJT=8$7$F$/$@$5$$!#(B -$BNc$($P!"(B - -local0.info ifdef(`LOGHOST', /var/log/syslog, @loghost) - - -quick $B$H$$$&$N$O!"$3$N%k!<%k$K%^%C%A$7$?%Q%1%C%H$O0J9_$N%k!<%k$r(B -$BD4$Y$:$K!"%"%/%7%g%s(B(block or pass)$B$K=>$o$;$k$H$$$&$b$N$G$9!#$?(B -$B$@$7!"Nc30$,$"$j$^$9!#8e=R$7$^$9!#(B - - -===================== $B$3$3$+$i(B ==================== -########## group setup -# -block in on hme1 all head 100 -block out on hme1 all head 150 -pass in quick on hme0 all -pass out quick on hme0 all -===================== $B$3$3$^$G(B ==================== - -$BJN,7A$G$9!#(B - -$B30It$H$N%$%s%?!<%U%'!<%9$G$"$k(B hme1 $B$O(B incoming $B$H(B outgoing $B$G!"(B -$B$=$l$>$l(B group 100 $BHV$H(B 150 $BHV$KJ,N`$7$^$9!#(Bhead $B$H$$$&$N$O!"$3(B -$B$N%k!<%k$K%^%C%A$7$?%Q%1%C%H$r< 140 group 160 -# -## pass all TCP connection setup packets except for netbios ports (137-139). -# -pass out quick proto tcp from any to any flags S/SAFR keep state head 170 group 150 -block out log quick proto tcp from any to any port 136 >< 140 group 170 -===================== $B$3$3$^$G(B ==================== - -$B$3$l$O4pK\E*$KA4$F$N%Q%1%C%H$r5v$9%k!<%k$G$9!#$7$+$7!"(Bnetbios -(137-139/udp, tcp)$B$N%]!<%H$@$1$O6X;_$7$F$$$^$9!#(Bnetbios$B$O(B Windows -$B$N%U%!%$%k6&M-$G;H$o$l$k%]!<%H$G!"$3$N%]!<%H$,3+$$$F$$$k$H!"(B -Windows$B$N@_Dj$K$h$C$F$O!"@$3&Cf$+$i%U%!%$%k$rFI$_=q$-$G$-$k(B -$B62$l$,$"$j$^$9!#(B - -$B$3$3$G!"4JC1$K=q<0$r8+$F$*$/$H!"(B -* $B:G=i$NC18l$G!"(Bblock$B$9$k$+(Bpass$B$9$k$+;XDj$9$k(B -* proto $B$N8e$NC18l$G!"(Bprotocol$B$r;XDj$9$k(B(udp, tcp, icmp, etc.)$B!#(B -* from A to B $B$G!"$I$3$+$i$I$3$X$N%Q%1%C%H$+$r;XDj$9$k(B -* head XXX$B$r;XDj$9$k$H!"$=$N9T$G;XDj$5$l$"$?%Q%1%C%H$O!"(Bgroup - XXX$B$H$7$F;2>H$G$-$k(B -* group$B$r;XDj$9$k$3$H$G!"5,B'$rE,MQ$9$k8uJd$r(B($BM=$a(Bhead$B$G@_Dj$7$?(B) - group$B$K8BDj$G$-$k!#(B - -$B$^$?!"(Bfrom A to B$B$N(BA$B$d(BB$B$O!"(BIP$B%"%I%l%9$H(Bport$B$r=q$/$3$H$,$G$-$^$9!#(B - from any to any port 136 >< 140 -$B$H$$$&$N$O!"(B - $B!VG$0U$N%]!<%H$NG$0U$N%"%I%l%9$+$i!"(B137$BHV$+$i(B139$BHV%]!<%H$NG$0U$N(B - $B%"%I%l%9$X$N%Q%1%C%H!W(B -$B;XDj$7$F$$$k$3$H$K$J$j$^$9!#$^$?!"HV9f$NBe$o$j$K(B/etc/service$B$K5-(B -$B=R$5$l$F$$$k%5!<%S%9L>$r5-=R$9$k$3$H$b$G$-$^$9!#(B -$B$?$H$($P(B - from any to any port = telnet -$B$H(B - from any to any port = 23 -$B$OF1$80UL#$H$J$j$^$9!#(B - -$B$5$F!"$3$3$G(B quick $B$NNc30$r@bL@$7$F$*$-$^$9!#(Bquick $B$NIU$$$?(B -rule $B$,(B head $B$G?7$?$J%0%k!<%W$r:n$k>l9g!"=hM}$O$^$@$3$N;~E@(B -$B$G$O3NDj$7$^$;$s!#0J9_!"!V(Bhead $B$G@k8@$5$l$?%0%k!<%W$N%k!<%k!W(B -$B$N$_=hM}$9$k$H$$$&0UL#$K$J$j$^$9!#$G$9$+$i>e$N!"(B - -pass out quick proto udp from any to any keep state head 160 group 150 -block out log quick proto udp from any to any port 136 >< 140 group 160 - -$B$O!"$^$:(B 150$BHV%0%k!<%W$K%^%C%A$9$k(B UDP $B%Q%1%C%H$OAGDL$7(B -$B$9$k!"$,!"0J2<$N(B 160$BHV$KB0$9$k%k!<%k$r$^$@=hM}$9$k!#(B -$B$=$7$F(B2$B9TL\$G(B 160$BHV%0%k!<%W$KBP$7$F(B netbios packet $B$r(B -block $B$7$F$$$kLu$G$9!#(B -$B0l9TL\$K%^%C%A$7$?%Q%1%C%H$O0J2<$K$b$7(B150$BHV$N%0%k!<%W$N(B -$B%k!<%k$,$"$C$?$H$7$F$b!"L5;k$9$k$3$H$KCm0U$7$F$/$@$5$$!#(B - ----------- -$BpJs(B(RIP)$B$N%Q%1%C%H$O!"A4It5v$7$^$9!#(B -pass in quick proto udp from any to any port = 520 keep state group 100 - -* ICMP$B$N%Q%1%C%H$OA4It5v$7$^$9!#(B -pass in quick proto icmp from any to any group 100 - -* $BFbIt$+$i30It$X$N(Bftp$B$r5v$9$?$a$K!"(Bftp-data port$B$+$i0lHL%]!<%H$X(B - $B$NG$0U$N@\B3$r 1023 flags S/SA keep state group 100 - - $B$7$+$7!"$3$l$O0lHL$K8@$C$FB?>/4m81$J9T0Y$G$9!#@\B3$G$-$k$N$,(B - 1024$BHV0J9_$N0lHL%]!<%H$K8BDj$O$5$l$^$9$,!"$"$^$j$*4+$a$G$-$^$;$s!#(B - $B$3$N9T$r2C$($:$K!"(Bpassive mode (ftp $B$G(B pasv $B%3%^%s%I$GF~$l$k(B) - $B$G(B FTP $B$r$9$k$3$H$r4+$a$^$9!#$J$*!":G6a$N(B FTP client $B$O:G=i(B - $B$+$i(B passive mode $B$KL5>r7o$G$7$F$7$^$&$b$N$,B?$$$h$&$G$9!#(B - -* sendmail$B$d(Bftpd$B$K7R$0$H!"Ajo$O5/F0$5$l$F$$(B - $B$J$$(B daemon $B$J$N$G!"AGDL$7$7$F$b%;%-%e%j%F%#%[!<%k$K$J$k$3$H$O$"(B - $B$j$^$;$s(B(connection refused$B$K$J$k$@$1$G$9(B)$B!#$3$l$r3+$1$J$$$H!"(B - $BAjH$9$k$3$H$,$G$-$^$9!#(B - -$BB>$K$b5v$7$?$$%[%9%H$rA}$d$7$?$$$H$-$O!">e$HF1MM$K$7$F!"(Bhead$B$N8e(B -$B$K!"?7$7$$?t;z(B(112, 113$B$J$I(B)$B$r3d$jEv$F$F$/$@$5$$!#(B - -$B$b$&0lEYCm0U$7$F$*$-$^$9$,!"(Bquick $B$H(B head $B$,F1;~$K8=$l$k%k!<%k(B -$B0J9_$G$O!"(Bhead $B$G@k8@$5$l$?%0%k!<%W$N%k!<%k$7$+E,MQ$5$l$J$/$J$j(B -$B$^$9!#$G$9$+$i!">e$N(B ident $B$d(B ftp data-port $B$N$h$&$K!"FbIt$N(B -$BA4$F$N%[%9%H$K%^%C%A$9$k%k!<%k$O!"$3$N%[%9%H$K$h$k%0%k!<%WJ,$1(B -$B$NA0$KCV$/I,MW$,$"$j$^$9!#(B - - -X$B$X$O!"(Btelnet, ftp, ssh $B$r!"(BY$B$X$O!"(Bftp, http, smtp, pop $B$r5v$9$3(B -$B$H$K$7$^$9!#(B - -* X(group 110)$B$X$N(Btelnet$B$r5v$7$^$9(B -pass in quick proto tcp from any to any port = telnet keep state group 110 - -* X$B$X$N(Bftp$B$r5v$7$^$9!#(Bftp-data port $B$b3+$1$F$*$-$^$9!#(B - ($BI,MW$,$"$k$+$I$&$+3NG'$O$7$F$$$^$;$s$,!"3+$1$F$$$F$b0BA4$G$7$g$&(B)$B!#(B -pass in quick proto tcp from any to any port = ftp keep state group 110 -pass in quick proto tcp from any to any port = ftp-data keep state group 110 - -* X$B$X$N(Bssh$B$r5v$7$^$9!#(B -pass in quick proto tcp from any to any port = 22 keep state group 110 - -* Y$B$X$N(Bftp$B$r5v$7$^$9!#(B -pass in quick proto tcp from any to any port = ftp keep state group 111 -pass in quick proto tcp from any to any port = ftp-data keep state group 111 -pass in quick proto tcp from any to any port 2999 >< 3100 keep state group 111 - - Y$B$O(B anonoymous ftp $B%5!<%P$r1?1D$7$F$$$k$?$a(B wu-ftpd $B$r;H$C$F$$(B - $B$^$9!#(Bwu-ftpd $B$O(B passive mode $B$N(BFTP$B$K$bBP1~$7$F$$$^$9$N$G!"$I(B - $B$N%]!<%H$r(BPASV$BMQ$K;H$&$+!"(Bwu-ftpd $B$N@_Dj$K=q$$$F$*$/I,MW$,$"$j(B - $B$^$9!#$3$3$G$O(B3000$B$+$i(B3099$BHV%]!<%H$r;HMQ$9$k$h$&$K!"(Bwu-ftpd $B$r(B - $B@_Dj$7$F$$$^$9!#(B - - passive FTP $B$K$D$$$F2r@b$7$^$9!#(Bpassive FTP $B$O!"%/%i%$%"%s%H$,(B - $B%U%!%$%"%&%)!<%k$NFbB&$K$$$k>l9g$N$?$a$K3+H/$5$l$?%W%m%H%3%k$G(B - $B$9!#%G%U%)%k%H$G$O>e$G@bL@$7$?$h$&$K!"%G!<%?E>Aw$N$?$a!"%5!<%P(B - $B$N(B ftp-data port $B$+$i%/%i%$%"%s%H$K@\B3$,$$$-$^$9!#(B - - passive FTP $B$G$O!"%G!<%?E>Aw$b(B client $B$+$i%5!<%P$K@\B3$9$k$h$&(B - $B$K$J$j$^$9!#$=$N:]!"%5!<%P$OE,Ev$J%]!<%HHV9f$r3d$j?6$C$F!"$=$3(B - $B$K%/%i%$%"%s%H$,@\B3$9$k$h$&;X<($7$^$9!#(B - - $B$3$N$?$a!"%5!<%P$,%U%!%$%"%&%)!<%kFb$K$$$k>l9g!"E,Ev$J%]!<%HHV(B - $B9f$O%U%!%$%"%&%)!<%k$G$O$M$i$l$F$7$^$$$^$9!#$=$3$G!"(Bwu-ftpd $B$N(B - $B@_Dj$G!"3d$j?6$k%]!<%HHV9f$NHO0O$r8BDj$7$F!"$=$3$@$1%U%!%$%"(B - $B%&%)!<%k$K7j$r3+$1$F$$$k$o$1$G$9!#(Bwu-ftpd $B$N>l9g$O!"(Bftpaccess - $B$H$$$&%U%!%$%k$K(B - - # passive ports - passive ports 0.0.0.0/0 3000 3099 - - $B$HDI2C$9$k$3$H$G@_Dj$G$-$^$9!#(Bftpaccess(5)$B$r;2>H$7$F$/$@$5$$!#(B - -* Y$B$X$N(Bhttp$B$r5v$7$^$9!#(B -pass in quick proto tcp from any to any port = 80 keep state group 111 - -* Y$B$X$N(Bsmtp$B$r5v$7$^$9!#(B -pass in quick proto tcp from any to any port = smtp keep state group 111 - -* Y$B$X$N(Bpop$B$r5v$7$^$9!#(B -pass in quick proto tcp from any to any port = 110 keep state group 111 - -$B0J>e$N@_Dj$K$h$j!"(BX, Y $B0J30$N%^%7%s$X$N!"30It$+$i$N@\B3$O!"0l@Z(B -$B9T$($J$/$J$j$^$9$N$G!"(Bremote exploit $BBP:v$O!"(BX, Y $B$K$N$_9T$($P$h(B -$B$/$J$j!"4IM}$N$N%W%m%H%3%k$rDL$9>l9g$b!">e$r;29M$K$7$FDL$7$?$$%]!<%HHV9f$r=q(B -$B$/$@$1$G$9$,!"$$$/$D$+Cm0UE@$,$"$j$^$9!#0J2<$bL\$rDL$7$F$/$@$5$$!#(B - ------ -$B$=$NB>$NCm0U(B - -1) gateway $B%^%7%s$N$h$&$K!"J#?t$N(BIP$B%"%I%l%9$r;}$D%^%7%s$G%5!<%S(B -$B%9$rN)$A>e$2$k>l9g$O!"$=$l$>$l$N(BIP$B%"%I%l%9$KBP$7$F!"(Bport $B$r3+$/(B -$BI,MW$,$"$j$^$9!#Nc$($P(B X $B$,(B IP:a $B$H(B IP:b $B$r;}$D$J$i!"(Bgroup $B$O(B a, -b $B$=$l$>$lMQ0U$7$F!"N>J}$N%0%k!<%WMQ$K(B rule $B$rDI2C$9$kI,MW$,$"$j(B -$B$^$9!#0J2<$NNc$G$O!"%2!<%H%&%'%$%^%7%s(B(123.45.2.10$B$H(B123.45.1.111 -$B$N(BIP$B$r;}$D(B)$B$K(BNNTP$B%5!<%P$rN)$F$F$$$^$9!#(B - -($BNc(B) -#### grouping by host -block in log quick proto tcp from any to 123.45.2.10 flags S/SA head 112 group 100 -block in log quick proto tcp from any to 123.45.1.111 flags S/SA head 113 group 100 -#### allow NNTP -pass in quick proto tcp from any to any port = nntp keep state group 112 -pass in quick proto tcp from any to any port = nntp keep state group 113 - -gateway $B$,(B2$B$D0J>e$"$k%M%C%H%o!<%/$G$O!"N>J}$N(B gateway $B$K(B IP -filter $B$,I,MW$K$J$j!"@_Dj$O99$KJ#;($K$J$j$^$9!#$=$N$h$&$J4D6-$N(B -$B>l9g$K$O!"%^%K%e%"%k$rFI$s$G8!F$$7$F$/$@$5$$!#(B - -2) NFS$B$H(Brsh$B$O%W%m%H%3%k$N4X78>e!"(Bfirewall$BD6$($OIT2DG=$G$9!#(B - NFS$B$NBeBX$K$D$$$F$OITL@$G$9$,!"(Brsh$B$NBeBX$H$7$F$O(Bssh$B$,;H$($^$9!#(B - -3) $B30It$N(BX client $B$r!"%U%!%$%"%&%)!<%kFb$N(BX$B%5!<%P$K@\B3$5$;$?$$!"(B - $B$H$$$&$N$O(B FAQ $B$N0l$D$G$9!#$*4+$a$N2r7h:v$O!"(Bssh $B$N(B X forwarding - $B5!9=$r;H$&$3$H$G$9!#(Bssh$B$G@\B3$G$-$k$J$i$P!"$3$l$O40A4$K(B secure - $B$GHFMQE*$JJ}K!$G$9!#(B - -$B$=$l$,=PMh$J$$>l9g$O!"2f!9$O@\B3$5$;$?$$%[%9%H$N%Z%"$r%f!<%6$KJs(B -$B9p$7$F$b$i$C$F!"0J2<$N$h$&$J%k!<%k$rDI2C$7$F$$$^$9!#(B -# X:0 $B$O(B tcp:6000 $BHV$K$J$j$^$9!#(B - -# 123.45.1.Z:0 (server) <-> A.B.C.D (client) -pass in quick proto tcp from A.B.C.D port > 1023 to 123.45.1.Z port = 6000 flags S/SA keep state group 100 - ------ -$B:G8e$K!";D$k%Q%1%C%H$OA4$F%V%m%C%/$5$l$kLu$G$9$,!"$=$l$K$D$$$F$N(B -$BA4$F$N%m%0$r;D$9$3$H$r4uK>$9$k>l9g!"< 140 group 160 -# -## pass all TCP connection setup packets except for netbios ports (137-139). -# -pass out quick proto tcp from any to any flags S/SAFR keep state head 170 group 150 -block out log quick proto tcp from any to any port 136 >< 140 group 170 -# -######### INCOMING -## ICMP -pass in quick proto icmp from any to any group 100 -## RIP -pass in quick proto udp from any to any port = 520 keep state group 100 -## FTP -pass in quick proto tcp from any port = ftp-data to any port > 1023 flags S/SA keep state group 100 -## IDENT -pass in quick proto tcp from any to any port = 113 flags S/SA keep state group 100 -# -## grouping by host (112 & 113 is the gateway address) -block in log quick proto tcp from any to 123.45.1.X flags S/SA head 110 group 100 -block in log quick proto tcp from any to 123.45.1.Y flags S/SA head 111 group 100 -block in log quick proto tcp from any to 123.45.2.10 flags S/SA head 112 group 100 -block in log quick proto tcp from any to 123.45.1.111 flags S/SA head 113 group 100 -# -## telnet, ftp, ssh, www, smtp, pop -pass in quick proto tcp from any to any port = telnet keep state group 110 -pass in quick proto tcp from any to any port = ftp keep state group 110 -pass in quick proto tcp from any to any port = ftp-data keep state group 110 -pass in quick proto tcp from any to any port = 22 keep state group 110 -pass in quick proto tcp from any to any port = ftp keep state group 111 -pass in quick proto tcp from any to any port = ftp-data keep state group 111 -pass in quick proto tcp from any to any port 2999 >< 3100 keep state group 111 -pass in quick proto tcp from any to any port = 80 keep state group 111 -pass in quick proto tcp from any to any port = smtp keep state group 111 -pass in quick proto tcp from any to any port = 110 keep state -group 111 -# -## allow NNTP on the gateway -pass in quick proto tcp from any to any port = nntp keep state group 112 -pass in quick proto tcp from any to any port = nntp keep state group 113 -# -## X connections -# 123.45.1.Z:0 (server) <-> A.B.C.D (client) -pass in quick proto tcp from A.B.C.D port > 1023 to 123.45.1.Z port = 6000 flags S/SA keep state group 100 -# -## log blocked packets -## THIS MUST BE THE LAST RULE! -block in log quick from any to 123.45.1.111/24 group 100 -block in log quick from any to 123.45.2.10 group 100 -===================== $B$3$3$^$G(B ==================== - ----- -$B$3$NJ8=q$N - and YAMAMOTO Hirotaka - -THIS DOCUMENT IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. - -Permission to modify this document and to distribute it is hereby -granted, as long as above notices and copyright notice are retained. diff --git a/contrib/ipfilter/IPFILTER.LICENCE b/contrib/ipfilter/IPFILTER.LICENCE deleted file mode 100644 index 41c151ccdedb..000000000000 --- a/contrib/ipfilter/IPFILTER.LICENCE +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * The author accepts no responsibility for the use of this software and - * provides it on an ``as is'' basis without express or implied warranty. - * - * Redistribution and use, with or without modification, in source and binary - * forms, are permitted provided that this notice is preserved in its entirety - * and due credit is given to the original author and the contributors. - * - * 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, in part or in whole, and put under another distribution licence - * [including the GNU Public Licence.] - * - * 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. - * - * I hate legalese, don't you ? - */ diff --git a/contrib/ipfilter/LICENCE b/contrib/ipfilter/LICENCE deleted file mode 100644 index f4cc8ee76bfa..000000000000 --- a/contrib/ipfilter/LICENCE +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (C) 1993-2000 by Darren Reed. - * - * The author accepts no responsibility for the use of this software and - * provides it on an ``as is'' basis without express or implied warranty. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and due credit is given - * to the original author and the contributors. - * - * 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. - * - * I hate legaleese, don't you ? - */ diff --git a/contrib/ipfilter/QNX_OCL.txt b/contrib/ipfilter/QNX_OCL.txt deleted file mode 100644 index 6aa33eaf6b06..000000000000 --- a/contrib/ipfilter/QNX_OCL.txt +++ /dev/null @@ -1,275 +0,0 @@ - End User License Certificate (EULA) End User License Certificate - (EULA) - Support Support - QNX Source Licenses QNX Source Licenses - License of the month - Confidential Source License - Version 1.0 - -QNX Open Community License Version 1.0 - - THIS QNX OPEN COMMUNITY LICENSE ( "THE OCL", OR "THIS AGREEMENT") - APPLIES TO PROGRAMS THAT QNX SOFTWARE SYSTEMS LTD. ("QSS") EXPRESSLY - ELECTS TO LICENSE UNDER THE OCL TERMS. IT ALSO APPLIES TO DERIVATIVE - WORKS CREATED UNDER THIS AGREEMENT THAT CREATORS ELECT TO LICENSE TO - OTHERS IN SOURCE CODE FORM. ANY USE, REPRODUCTION, MODIFICATION OR - DISTRIBUTION OF SUCH PROGRAMS CONSTITUTES RECIPIENT'S ACCEPTANCE OF - THE OCL. THE LICENSE RIGHTS GRANTED BELOW ARE CONDITIONAL UPON - RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT AND THE FORMATION OF A - BINDING CONTRACT. NOTHING ELSE GRANTS PERMISSION TO USE, REPRODUCE, - MODIFY OR DISTRIBUTE SUCH PROGRAMS OR THEIR DERIVATIVE WORKS. THESE - ACTIONS ARE OTHERWISE PROHIBITED. CONTACT QSS IF OTHER STEPS ARE - REQUIRED LOCALLY TO CREATE A BINDING CONTRACT. - - The OCL is intended to promote the development, use and distribution - of derivative works created from QSS source code. This includes - commercial distribution of object code versions under the terms of - Recipient's own license agreement and, at Recipient's option, sharing - of source code modifications within the QNX developer's community. The - license granted under the OCL is royalty free. Recipient is entitled - to charge royalties for object code versions of derivative works that - originate with Recipient. If Recipient elects to license source code - for its derivative works to others, then it must be licensed under the - OCL. The terms of the OCL are as follows: - -1. DEFINITIONS - - "Contribution" means: - - a. in the case of QSS: (i) the Original Program, where the Original - Program originates from QSS, (ii) changes and/or additions to - Unrestricted Open Source, where the Original Program originates - from Unrestricted Open Source and where such changes and/or - additions originate from QSS, and (iii) changes and/or additions - to the Program where such changes and/or additions originate from - QSS. - b. in the case of each Contributor, changes and/or additions to the - Program, where such changes and/or additions originate from and - are distributed by that particular Contributor. - - A Contribution 'originates' from a Contributor if it was added to the - Program by such Contributor itself or anyone acting on such - Contributor's behalf. Contributions do not include additions to the - Program which: (i) are separate modules of software distributed in - conjunction with the Program under their own license agreement, and - (ii) are not derivative works of the Program. - - "Contributor" means QSS and any other entity that distributes the - Program. - - "Licensed Patents " mean patent claims licensable by Contributor to - others, which are necessarily infringed by the use or sale of its - Contribution alone or when combined with the Program. - - "Unrestricted Open Source" means published source code that is - licensed for free use and distribution under an unrestricted licensing - and distribution model, such as the Berkley Software Design ("BSD") - and "BSD-like" licenses. It specifically excludes any source code - licensed under any version of the GNU General Public License (GPL) or - the GNU Lesser/Library GPL. All "Unrestricted Open Source" license - terms appear or are clearly identified in the header of any affected - source code for the Original Program. - - "Original Program" means the original version of the software - accompanying this Agreement as released by QSS, including source code, - object code and documentation, if any. - - "Program" means the Original Program and Contributions. - - "Recipient" means anyone who receives the Program under this - Agreement, including all Contributors. - -2. GRANT OF RIGHTS - - a. Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free - copyright license to reproduce, prepare derivative works of, - publicly display, publicly perform, and directly and indirectly - sublicense and distribute the Contribution of such Contributor, if - any, and such derivative works, in source code and object code - form. - b. Subject to the terms of this Agreement, each Contributor hereby - grants Recipient a non-exclusive, worldwide, royalty-free patent - license under Licensed Patents to make, use, sell, offer to sell, - import and otherwise transfer the Contribution of such - Contributor, if any, in source code and object code form. This - patent license shall apply to the combination of the Contribution - and the Program if, at the time the Contribution is added by the - Contributor, such addition of the Contribution causes such - combination to be covered by the Licensed Patents. The patent - license shall not apply to any other combinations which include - the Contribution. - c. Recipient understands that although each Contributor grants the - licenses to its Contributions set forth herein, no assurances are - provided by any Contributor that the Program does not infringe the - patent or other intellectual property rights of any other entity. - Each Contributor disclaims any liability to Recipient for claims - brought by any other entity based on infringement of intellectual - property rights or otherwise. As a condition to exercising the - rights and licenses granted hereunder, each Recipient hereby - assumes sole responsibility to secure any other intellectual - property rights needed, if any. For example, if a third party - patent license is required to allow Recipient to distribute the - Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - d. Each Contributor represents that to its knowledge it has - sufficient copyright rights in its Contribution, if any, to grant - the copyright license set forth in this Agreement. - - 3. REQUIREMENTS - - A Contributor may choose to distribute the Program in object code form - under its own license agreement, provided that: - - a. it complies with the terms and conditions of this Agreement; and - b. its license agreement: - i. effectively disclaims on behalf of all Contributors all - warranties and conditions, express and implied, including - warranties or conditions of title and non-infringement, and - implied warranties or conditions of merchantability and - fitness for a particular purpose; - ii. effectively excludes on behalf of all Contributors all - liability for damages, including direct, indirect, special, - incidental and consequential damages, such as lost profits; - and - iii. states that any provisions which differ from this Agreement - are offered by that Contributor alone and not by any other - party. - - If the Program is made available in source code form: - - a. it must be made available under this Agreement; and - b. a copy of this Agreement must be included with each copy of the - Program. Each Contributor must include the following in a - conspicuous location in the Program along with any other copyright - or attribution statements required by the terms of any applicable - Unrestricted Open Source license: - Copyright {date here}, QNX Software Systems Ltd. and others. All - Rights Reserved. - - In addition, each Contributor must identify itself as the originator - of its Contribution, if any, in a manner that reasonably allows - subsequent Recipients to identify the originator of the Contribution. - - 4. COMMERCIAL DISTRIBUTION - - Commercial distributors of software may accept certain - responsibilities with respect to end users, business partners and the - like. While this license is intended to facilitate the commercial use - of the Program, the Contributor who includes the Program in a - commercial product offering should do so in a manner which does not - create potential liability for other Contributors. Therefore, if a - Contributor includes the Program in a commercial product offering, - such Contributor ("Commercial Contributor") hereby agrees to defend - and indemnify every other Contributor ("Indemnified Contributor") - against any losses, damages and costs (collectively "Losses") arising - from claims, lawsuits and other legal actions brought by a third party - against the Indemnified Contributor to the extent caused by the acts - or omissions of such Commercial Contributor in connection with its - distribution of the Program in a commercial product offering. The - obligations in this section do not apply to any claims or Losses - relating to any actual or alleged intellectual property infringement. - In order to qualify, an Indemnified Contributor must: a) promptly - notify the Commercial Contributor in writing of such claim, and b) - allow the Commercial Contributor to control, and cooperate with the - Commercial Contributor in, the defense and any related settlement - negotiations. The Indemnified Contributor may participate in any such - claim at its own expense. - - For example, a Contributor might include the Program in a commercial - product offering, Product X. That Contributor is then a Commercial - Contributor. If that Commercial Contributor then makes performance - claims, or offers warranties related to Product X, those performance - claims and warranties are such Commercial Contributor's responsibility - alone. Under this section, the Commercial Contributor would have to - defend claims against the other Contributors related to those - performance claims and warranties, and if a court requires any other - Contributor to pay any damages as a result, the Commercial Contributor - must pay those damages. - - 5. NO WARRANTY - - Recipient acknowledges that there may be errors or bugs in the Program - and that it is imperative that Recipient conduct thorough testing to - identify and correct any problems prior to the productive use or - commercial release of any products that use the Program, and prior to - the release of any modifications, updates or enhancements thereto. - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS - PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY - WARRANTIES OR CONDITIONS OF TITLE, NON- INFRINGEMENT, MERCHANTABILITY - OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely - responsible for determining the appropriateness of using and - distributing the Program and assumes all risks associated with its - exercise of rights under this Agreement, including but not limited to - the risks and costs of program errors, compliance with applicable - laws, damage to or loss of data, programs or equipment, and - unavailability or interruption of operations. - - 6. DISCLAIMER OF LIABILITY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR - ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING - WITHOUT LIMITATION LOST PROFITS), 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 OR - DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED - HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - 7. GENERAL - - If any provision of this Agreement is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of - the remainder of the terms of this Agreement, and without further - action by the parties hereto, such provision shall be reformed to the - minimum extent necessary to make such provision valid and enforceable. - - If Recipient institutes patent litigation against a Contributor with - respect to a patent applicable to software (including a cross-claim or - counterclaim in a lawsuit), then any patent licenses granted by that - Contributor to such recipient under this Agreement shall terminate as - of the date such litigation is filed. In addition, If Recipient - institutes patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Program - itself (excluding combinations of the Program with other software or - hardware) infringes such Recipient's patent(s), then such Recipient's - rights granted under Section 2(b) shall terminate as of the date such - litigation is filed. - - All Recipient's rights under this Agreement shall terminate if it - fails to comply with any of the material terms or conditions of this - Agreement and does not cure such failure in a reasonable period of - time after becoming aware of such noncompliance. If all Recipient's - rights under this Agreement terminate, Recipient agrees to cease use - and distribution of the Program as soon as reasonably practicable. - However, Recipient's obligations under this Agreement and any licenses - granted by Recipient relating to the Program shall continue and - survive. - - QSS may publish new versions (including revisions) of this Agreement - from time to time. Each new version of the Agreement will be given a - distinguishing version number. The Program (including Contributions) - may always be distributed subject to the version of the Agreement - under which it was received. In addition, after a new version of the - Agreement is published, Contributor may elect to distribute the - Program (including its Contributions) under the new version. No one - other than QSS has the right to modify this Agreement. Except as - expressly stated in Sections 2(a) and 2(b) above, Recipient receives - no rights or licenses to the intellectual property of any Contributor - under this Agreement, whether expressly, by implication, estoppel or - otherwise. All rights in the Program not expressly granted under this - Agreement are reserved. - - This Agreement is governed by the laws in force in the Province of - Ontario, Canada without regard to the conflict of law provisions - therein. The parties expressly disclaim the provisions of the United - Nations Convention on Contracts for the International Sale of Goods. - No party to this Agreement will bring a legal action under this - Agreement more than one year after the cause of action arose. Each - party waives its rights to a jury trial in any resulting litigation. - - * QNX is a registered trademark of QNX Software Systems Ltd. - - Document Version: ocl1_00 diff --git a/contrib/ipfilter/UPGRADE_NOTICE b/contrib/ipfilter/UPGRADE_NOTICE deleted file mode 100644 index 8b4476072b27..000000000000 --- a/contrib/ipfilter/UPGRADE_NOTICE +++ /dev/null @@ -1,10 +0,0 @@ - -NOTE: To all those upgrading from versions prior to 3.2.11 who used NAT - AND setup ACL's to allow untranslated address through from outside, - - THIS HAS BEEN FIXED - - so your ACL's will now be `broken'. Please correct your ACL's to - match the the untranslated addresses (the way it was meant to work). - -Darren diff --git a/contrib/ipfilter/bpf.h b/contrib/ipfilter/bpf.h deleted file mode 100644 index 715c79a8d173..000000000000 --- a/contrib/ipfilter/bpf.h +++ /dev/null @@ -1,450 +0,0 @@ -/*- - * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from the Stanford/CMU enet packet filter, - * (net/enet.c) distributed as part of 4.3BSD, and code contributed - * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence - * Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)bpf.h 7.1 (Berkeley) 5/7/91 - * - * @(#) $Header: /devel/CVS/IP-Filter/Attic/bpf.h,v 1.1.2.1 2002/11/07 13:18:35 darrenr Exp $ (LBL) - */ - -#ifndef BPF_MAJOR_VERSION - -#ifdef __cplusplus -extern "C" { -#endif - -/* BSD style release date */ -#define BPF_RELEASE 199606 - -typedef int bpf_int32; -typedef u_int bpf_u_int32; - -/* - * Alignment macros. BPF_WORDALIGN rounds up to the next - * even multiple of BPF_ALIGNMENT. - */ -#ifndef __NetBSD__ -#define BPF_ALIGNMENT sizeof(bpf_int32) -#else -#define BPF_ALIGNMENT sizeof(long) -#endif -#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) - -#define BPF_MAXINSNS 512 -#define BPF_MAXBUFSIZE 0x8000 -#define BPF_MINBUFSIZE 32 - -/* - * Structure for BIOCSETF. - */ -struct bpf_program { - u_int bf_len; - struct bpf_insn *bf_insns; -}; - -/* - * Struct returned by BIOCGSTATS. - */ -struct bpf_stat { - u_int bs_recv; /* number of packets received */ - u_int bs_drop; /* number of packets dropped */ -}; - -/* - * Struct return by BIOCVERSION. This represents the version number of - * the filter language described by the instruction encodings below. - * bpf understands a program iff kernel_major == filter_major && - * kernel_minor >= filter_minor, that is, if the value returned by the - * running kernel has the same major number and a minor number equal - * equal to or less than the filter being downloaded. Otherwise, the - * results are undefined, meaning an error may be returned or packets - * may be accepted haphazardly. - * It has nothing to do with the source code version. - */ -struct bpf_version { - u_short bv_major; - u_short bv_minor; -}; -/* Current version number of filter architecture. */ -#define BPF_MAJOR_VERSION 1 -#define BPF_MINOR_VERSION 1 - -/* - * BPF ioctls - * - * The first set is for compatibility with Sun's pcc style - * header files. If your using gcc, we assume that you - * have run fixincludes so the latter set should work. - */ -#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__) -#define BIOCGBLEN _IOR(B,102, u_int) -#define BIOCSBLEN _IOWR(B,102, u_int) -#define BIOCSETF _IOW(B,103, struct bpf_program) -#define BIOCFLUSH _IO(B,104) -#define BIOCPROMISC _IO(B,105) -#define BIOCGDLT _IOR(B,106, u_int) -#define BIOCGETIF _IOR(B,107, struct ifreq) -#define BIOCSETIF _IOW(B,108, struct ifreq) -#define BIOCSRTIMEOUT _IOW(B,109, struct timeval) -#define BIOCGRTIMEOUT _IOR(B,110, struct timeval) -#define BIOCGSTATS _IOR(B,111, struct bpf_stat) -#define BIOCIMMEDIATE _IOW(B,112, u_int) -#define BIOCVERSION _IOR(B,113, struct bpf_version) -#define BIOCSTCPF _IOW(B,114, struct bpf_program) -#define BIOCSUDPF _IOW(B,115, struct bpf_program) -#else -#define BIOCGBLEN _IOR('B',102, u_int) -#define BIOCSBLEN _IOWR('B',102, u_int) -#define BIOCSETF _IOW('B',103, struct bpf_program) -#define BIOCFLUSH _IO('B',104) -#define BIOCPROMISC _IO('B',105) -#define BIOCGDLT _IOR('B',106, u_int) -#define BIOCGETIF _IOR('B',107, struct ifreq) -#define BIOCSETIF _IOW('B',108, struct ifreq) -#define BIOCSRTIMEOUT _IOW('B',109, struct timeval) -#define BIOCGRTIMEOUT _IOR('B',110, struct timeval) -#define BIOCGSTATS _IOR('B',111, struct bpf_stat) -#define BIOCIMMEDIATE _IOW('B',112, u_int) -#define BIOCVERSION _IOR('B',113, struct bpf_version) -#define BIOCSTCPF _IOW('B',114, struct bpf_program) -#define BIOCSUDPF _IOW('B',115, struct bpf_program) -#endif - -/* - * Structure prepended to each packet. - */ -struct bpf_hdr { - struct timeval bh_tstamp; /* time stamp */ - bpf_u_int32 bh_caplen; /* length of captured portion */ - bpf_u_int32 bh_datalen; /* original length of packet */ - u_short bh_hdrlen; /* length of bpf header (this struct - plus alignment padding) */ -}; -/* - * Because the structure above is not a multiple of 4 bytes, some compilers - * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. - * Only the kernel needs to know about it; applications use bh_hdrlen. - */ -#if defined(KERNEL) || defined(_KERNEL) -#define SIZEOF_BPF_HDR 18 -#endif - -/* - * Data-link level type codes. - */ - -/* - * These are the types that are the same on all platforms; on other - * platforms, a should be supplied that defines the additional - * DLT_* codes appropriately for that platform (the BSDs, for example, - * should not just pick up this version of "bpf.h"; they should also define - * the additional DLT_* codes used by their kernels, as well as the values - * defined here - and, if the values they use for particular DLT_ types - * differ from those here, they should use their values, not the ones - * here). - */ -#define DLT_NULL 0 /* no link-layer encapsulation */ -#define DLT_EN10MB 1 /* Ethernet (10Mb) */ -#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ -#define DLT_AX25 3 /* Amateur Radio AX.25 */ -#define DLT_PRONET 4 /* Proteon ProNET Token Ring */ -#define DLT_CHAOS 5 /* Chaos */ -#define DLT_IEEE802 6 /* IEEE 802 Networks */ -#define DLT_ARCNET 7 /* ARCNET */ -#define DLT_SLIP 8 /* Serial Line IP */ -#define DLT_PPP 9 /* Point-to-point Protocol */ -#define DLT_FDDI 10 /* FDDI */ - -/* - * These are values from the traditional libpcap "bpf.h". - * Ports of this to particular platforms should replace these definitions - * with the ones appropriate to that platform, if the values are - * different on that platform. - */ -#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ -#define DLT_RAW 12 /* raw IP */ - -/* - * These are values from BSD/OS's "bpf.h". - * These are not the same as the values from the traditional libpcap - * "bpf.h"; however, these values shouldn't be generated by any - * OS other than BSD/OS, so the correct values to use here are the - * BSD/OS values. - * - * Platforms that have already assigned these values to other - * DLT_ codes, however, should give these codes the values - * from that platform, so that programs that use these codes will - * continue to compile - even though they won't correctly read - * files of these types. - */ -#ifdef __NetBSD__ -#ifndef DLT_SLIP_BSDOS -#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ -#endif -#else -#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */ -#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */ -#endif - -#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */ - -/* - * These values are defined by NetBSD; other platforms should refrain from - * using them for other purposes, so that NetBSD savefiles with link - * types of 50 or 51 can be read as this type on all platforms. - */ -#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */ -#define DLT_PPP_ETHER 51 /* PPP over Ethernet */ - -/* - * Values between 100 and 103 are used in capture file headers as - * link-layer types corresponding to DLT_ types that differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * This value was defined by libpcap 0.5; platforms that have defined - * it with a different value should define it here with that value - - * a link type of 104 in a save file will be mapped to DLT_C_HDLC, - * whatever value that happens to be, so programs will correctly - * handle files with that link type regardless of the value of - * DLT_C_HDLC. - * - * The name DLT_C_HDLC was used by BSD/OS; we use that name for source - * compatibility with programs written for BSD/OS. - * - * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well, - * for source compatibility with programs written for libpcap 0.5. - */ -#define DLT_C_HDLC 104 /* Cisco HDLC */ -#define DLT_CHDLC DLT_C_HDLC - -#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */ - -/* - * Values between 106 and 107 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ new types. - */ - -/* - * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except - * that the AF_ type in the link-layer header is in network byte order. - * - * OpenBSD defines it as 12, but that collides with DLT_RAW, so we - * define it as 108 here. If OpenBSD picks up this file, it should - * define DLT_LOOP as 12 in its version, as per the comment above - - * and should not use 108 as a DLT_ value. - */ -#define DLT_LOOP 108 - -/* - * Values between 109 and 112 are used in capture file headers as - * link-layer types corresponding to DLT_ types that might differ - * between platforms; don't use those values for new DLT_ types - * other than the corresponding DLT_ types. - */ - -/* - * This is for Linux cooked sockets. - */ -#define DLT_LINUX_SLL 113 - -/* - * Apple LocalTalk hardware. - */ -#define DLT_LTALK 114 - -/* - * Acorn Econet. - */ -#define DLT_ECONET 115 - -/* - * Reserved for use with OpenBSD ipfilter. - */ -#define DLT_IPFILTER 116 - -/* - * Reserved for use in capture-file headers as a link-layer type - * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, - * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it - * in capture-file headers. - */ -#define DLT_PFLOG 117 - -/* - * Registered for Cisco-internal use. - */ -#define DLT_CISCO_IOS 118 - -/* - * Reserved for 802.11 cards using the Prism II chips, with a link-layer - * header including Prism monitor mode information plus an 802.11 - * header. - */ -#define DLT_PRISM_HEADER 119 - -/* - * Reserved for Aironet 802.11 cards, with an Aironet link-layer header - * (see Doug Ambrisko's FreeBSD patches). - */ -#define DLT_AIRONET_HEADER 120 - -/* - * Reserved for Siemens HiPath HDLC. - */ -#define DLT_HHDLC 121 - -/* - * Reserved for RFC 2625 IP-over-Fibre Channel, as per a request from - * Don Lee . - * - * This is not for use with raw Fibre Channel, where the link-layer - * header starts with a Fibre Channel frame header; it's for IP-over-FC, - * where the link-layer header starts with an RFC 2625 Network_Header - * field. - */ -#define DLT_IP_OVER_FC 122 - -/* - * The instruction encodings. - */ -/* instruction classes */ -#define BPF_CLASS(code) ((code) & 0x07) -#define BPF_LD 0x00 -#define BPF_LDX 0x01 -#define BPF_ST 0x02 -#define BPF_STX 0x03 -#define BPF_ALU 0x04 -#define BPF_JMP 0x05 -#define BPF_RET 0x06 -#define BPF_MISC 0x07 - -/* ld/ldx fields */ -#define BPF_SIZE(code) ((code) & 0x18) -#define BPF_W 0x00 -#define BPF_H 0x08 -#define BPF_B 0x10 -#define BPF_MODE(code) ((code) & 0xe0) -#define BPF_IMM 0x00 -#define BPF_ABS 0x20 -#define BPF_IND 0x40 -#define BPF_MEM 0x60 -#define BPF_LEN 0x80 -#define BPF_MSH 0xa0 - -/* alu/jmp fields */ -#define BPF_OP(code) ((code) & 0xf0) -#define BPF_ADD 0x00 -#define BPF_SUB 0x10 -#define BPF_MUL 0x20 -#define BPF_DIV 0x30 -#define BPF_OR 0x40 -#define BPF_AND 0x50 -#define BPF_LSH 0x60 -#define BPF_RSH 0x70 -#define BPF_NEG 0x80 -#define BPF_JA 0x00 -#define BPF_JEQ 0x10 -#define BPF_JGT 0x20 -#define BPF_JGE 0x30 -#define BPF_JSET 0x40 -#define BPF_SRC(code) ((code) & 0x08) -#define BPF_K 0x00 -#define BPF_X 0x08 - -/* ret - BPF_K and BPF_X also apply */ -#define BPF_RVAL(code) ((code) & 0x18) -#define BPF_A 0x10 - -/* misc */ -#define BPF_MISCOP(code) ((code) & 0xf8) -#define BPF_TAX 0x00 -#define BPF_TXA 0x80 - -/* - * The instruction data structure. - */ -struct bpf_insn { - u_short code; - u_char jt; - u_char jf; - bpf_int32 k; -}; - -/* - * Macros for insn array initializers. - */ -#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } -#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } - -#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL)) -/* - * Systems based on non-BSD kernels don't have ifnet's (or they don't mean - * anything if it is in ) and won't work like this. - */ -# if __STDC__ -extern void bpf_tap(struct ifnet *, u_char *, u_int); -extern void bpf_mtap(struct ifnet *, struct mbuf *); -extern void bpfattach(struct ifnet *, u_int, u_int); -extern void bpfilterattach(int); -# else -extern void bpf_tap(); -extern void bpf_mtap(); -extern void bpfattach(); -extern void bpfilterattach(); -# endif /* __STDC__ */ -#endif /* BSD && (_KERNEL || KERNEL) */ -#if __STDC__ || defined(__cplusplus) -extern int bpf_validate(struct bpf_insn *, int); -extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); -#else -extern int bpf_validate(); -extern u_int bpf_filter(); -#endif - -/* - * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). - */ -#define BPF_MEMWORDS 16 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/contrib/ipfilter/buildlinux b/contrib/ipfilter/buildlinux deleted file mode 100755 index 7ce043fc6e6a..000000000000 --- a/contrib/ipfilter/buildlinux +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -LINUX=`uname -r | perl -e '$_=<>;@F=split(/\./);printf "%02d%02d\n",$F[0],$F[1];';` - -case ${LINUX} in - 0200) - make linuxrev "LINUXK=-DLINUX=${LINUX}" - ;; - 0201) - make linuxrev "LINUXK=-DLINUX=${LINUX}" - ;; - *) - echo "invalid linux version $LINUX" - exit 1; - ;; -esac -exit 0 diff --git a/contrib/ipfilter/buildsunos b/contrib/ipfilter/buildsunos deleted file mode 100755 index 5e857e77953c..000000000000 --- a/contrib/ipfilter/buildsunos +++ /dev/null @@ -1,168 +0,0 @@ -#! /bin/sh -if [ ! -f netinet/done ] ; then - echo "Do NOT run this script directly, do 'make solaris'!" - exit 1 -fi -# Id: buildsunos,v 2.20 2004/02/07 18:08:46 darrenr Exp -: -rev=`uname -r | sed -e 's/^\([^\.]*\)\..*/\1/'` -if [ -d /usr/ccs/bin ] ; then - PATH=/usr/ccs/bin:${PATH} - export PATH -fi - -if [ $rev = 5 ] ; then - if [ ! -d ../pfil ] ; then - cat << __EOF__ -pfil directory in .. missing, please download pfil package and extract that -into the parent directory. - -See INSTALL.Sol2 for more instructions. -__EOF__ - exit 1 - fi - # - # /usr/ucb/cc will not work - # - PATH=`echo $PATH | sed -e s:/usr/ucb::g -e s/::/:/g` - export PATH - - cpu=`uname -p` - cpudir=${cpu}-`uname -r` - solrev=`uname -r | sh -c 'IFS=. read j n x; echo $n'` - if [ ! -d SunOS5/${cpudir} -a ! -h SunOS5/${cpudir} ] ; then - mkdir -p SunOS5/${cpudir} - fi - /bin/rm -f SunOS5/${cpudir}/Makefile - /bin/rm -f SunOS5/${cpudir}/Makefile.ipsend - ln -s `pwd`/SunOS5/Makefile SunOS5/${cpudir}/Makefile - ln -s `pwd`/SunOS5/Makefile.ipsend SunOS5/${cpudir}/Makefile.ipsend - - # - # Default C compiler is "cc", override on make commandline - # - if [ "x$CC" = "x" ] ; then - if echo '' | cc -E - >/dev/null 2>&1 ; then - CC=cc - else - if echo '' | gcc -E - >/dev/null 2>&1 ; then - CC=gcc - else - echo "No working compiler found" - exit 1 - fi - fi - fi - v=`echo '__GNUC__' | 2>&1 ${CC} -E - | 2>&1 sed -ne '/^[0-9]* *$/p'` - if [ x$v != x ] ; then - CC=gcc - fi - - case "$CC" in - *gcc*) # gcc - XARCH32="" - XARCH64="-m64 -mcmodel=medlow" - ;; - *) # Sun C - XARCH32="-Xa -xildoff" - XARCH64="$XARCH32 -xarch=v9 -xchip=ultra -dalign -xcode=abs32" - ;; - esac - - export CC - - ISABITS=32 - - OBJ32=sparcv7 - ARCHINC32= - OBJ64=sparcv9 - ARCHINC64="-I/usr/include/v9" - - if [ $solrev -ge 7 ] && /bin/optisa sparcv8plus > /dev/null - then - # We run Solaris 7+ on 64 bit capable hardware. - BUILDBOTH=true - else - BUILDBOTH=false - OBJ32=. - fi - - if $BUILDBOTH - then - echo Testing compiler $CC for 64 bit object file generation. - t=conftest$$.c - trap 'rm -f $t 32.out 64.out; exit 1' 0 1 2 3 15 - cat > $t <<-EOF - #include - int main(void) - { - printf("%ld\n", (long) sizeof(long)); - exit(0); - } - EOF - - # Is it perhaps a 64 bit only compiler? - if $CC $XARCH32 $t -o 32.out >/dev/null 2>&1 && - [ "`./32.out`" = 4 ] - then :; else - echo $CC $XARCH32 cannot create 32 bit executables. 1>&2 - exit 1 - fi - if $CC $XARCH64 $t -o 64.out >/dev/null 2>&1 && - { out64=`./64.out 2>/dev/null` ; - [ "$out64" = 8 -o "`isainfo -b`" = 32 -a "$out64" = "" ] - } - then - echo "found 32/64 bit compiler" 1>&2 - CC64=true - else - CC64=false - fi - rm -f $t 32.out 64.out - trap 0 1 2 3 15 - fi - - # If we're running 64 bit, we *must* build 64 bit. - if ([ "`isainfo -b`" = 64 ]) 2>/dev/null ; then - if $CC64 ; then :; else - echo "No 64 bit capable compiler was found" 1>&2 - exit 1 - fi - ISABITS="32 64" - elif $BUILDBOTH && $CC64 - then - ISABITS="32 64" - else - OBJ32=. - fi -else - cpu=`uname -m` - cpudir=${cpu}-`uname -r` -fi - -# Default $MAKE to make -: ${MAKE:=make} - -if [ $cpu = i386 ] ; then - if [ -n "$BPFILTER" ] ; then - BPF="BPFILTER=./$BPFILTER" - fi - $MAKE $MAKEFLAGS ${1+"$@"} sunos5x86 SOLARIS2="-DSOLARIS2=$solrev" CPU= CPUDIR=${cpudir} CC="$CC $XARCH32" XARCH="$XARCH32" ARCHINC="$ARCHINC32" BITS=32 OBJ=. $BPF - exit $? -fi -if [ x$solrev = x ] ; then - make ${1+"$@"} sunos$rev "TOP=.." "ARCH=`uname -m`" - exit $? -fi -for b in $ISABITS -do - echo build $b bit binaries. - for v in OBJ ARCHINC XARCH - do - eval $v=\"\$$v$b\" - done - if [ -n "$BPFILTER" ] ; then - BPF="BPFILTER=$OBJ/$BPFILTER" - fi - $MAKE $MAKEFLAGS ${1+"$@"} sunos$rev SOLARIS2="-DSOLARIS2=$solrev" CPU= CPUDIR=${cpudir} CC="$CC $XARCH" XARCH="$XARCH" ARCHINC="$ARCHINC" BITS=$b OBJ=$OBJ $BPF || exit $? -done diff --git a/contrib/ipfilter/common.c b/contrib/ipfilter/common.c deleted file mode 100644 index fa21fc97b574..000000000000 --- a/contrib/ipfilter/common.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include "ip_fil.h" -#include "ipf.h" -#include "facpri.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $"; -#endif - -extern struct ipopt_names ionames[], secclass[]; -extern int opts; -extern int use_inet6; - - -char *proto = NULL; -char flagset[] = "FSRPAUEC"; -u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG, - TH_ECN, TH_CWR }; - -void fill6bits __P((int, u_32_t *)); -int count6bits __P((u_32_t *)); - -static char thishost[MAXHOSTNAMELEN]; - - -void initparse() -{ - gethostname(thishost, sizeof(thishost)); - thishost[sizeof(thishost) - 1] = '\0'; -} - - -int genmask(msk, mskp) -char *msk; -u_32_t *mskp; -{ - char *endptr = NULL; -#ifdef USE_INET6 - u_32_t addr; -#endif - int bits; - - if (index(msk, '.') || index(msk, 'x') || index(msk, ':')) { - /* possibly of the form xxx.xxx.xxx.xxx - * or 0xYYYYYYYY */ -#ifdef USE_INET6 - if (use_inet6) { - if (inet_pton(AF_INET6, msk, &addr) != 1) - return -1; - } else -#endif - if (inet_aton(msk, (struct in_addr *)mskp) == 0) - return -1; - } else { - /* - * set x most significant bits - */ - bits = (int)strtol(msk, &endptr, 0); - if ((*endptr != '\0') || - ((bits > 32) && !use_inet6) || (bits < 0) || - ((bits > 128) && use_inet6)) - return -1; - if (use_inet6) - fill6bits(bits, mskp); - else { - if (bits == 0) - *mskp = 0; - else - *mskp = htonl(0xffffffff << (32 - bits)); - } - } - return 0; -} - - - -void fill6bits(bits, msk) -int bits; -u_32_t *msk; -{ - int i; - - for (i = 0; bits >= 32 && i < 4 ; ++i, bits -= 32) - msk[i] = 0xffffffff; - - if (bits > 0 && i < 4) - msk[i++] = htonl(0xffffffff << (32 - bits)); - - while (i < 4) - msk[i++] = 0; -} - - -/* - * returns -1 if neither "hostmask/num" or "hostmask mask addr" are - * found in the line segments, there is an error processing this information, - * or there is an error processing ports information. - */ -int hostmask(seg, sa, msk, pp, cp, tp, linenum) -char ***seg; -u_32_t *sa, *msk; -u_short *pp, *tp; -int *cp; -int linenum; -{ - struct in_addr maskaddr; - char *s; - - /* - * is it possibly hostname/num ? - */ - if ((s = index(**seg, '/')) || - ((s = index(**seg, ':')) && !index(s + 1, ':'))) { - *s++ = '\0'; - if (genmask(s, msk) == -1) { - fprintf(stderr, "%d: bad mask (%s)\n", linenum, s); - return -1; - } - if (hostnum(sa, **seg, linenum) == -1) { - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; - } - *sa &= *msk; - (*seg)++; - return ports(seg, pp, cp, tp, linenum); - } - - /* - * look for extra segments if "mask" found in right spot - */ - if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) { - if (hostnum(sa, **seg, linenum) == -1) { - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; - } - (*seg)++; - (*seg)++; - if (inet_aton(**seg, &maskaddr) == 0) { - fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg); - return -1; - } - *msk = maskaddr.s_addr; - (*seg)++; - *sa &= *msk; - return ports(seg, pp, cp, tp, linenum); - } - - if (**seg) { - if (hostnum(sa, **seg, linenum) == -1) { - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; - } - (*seg)++; - if (use_inet6) { - u_32_t k = 0; - if (sa[0] || sa[1] || sa[2] || sa[3]) - k = 0xffffffff; - msk[0] = msk[1] = msk[2] = msk[3] = k; - } - else - *msk = *sa ? 0xffffffff : 0; - return ports(seg, pp, cp, tp, linenum); - } - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; -} - -/* - * returns an ip address as a long var as a result of either a DNS lookup or - * straight inet_addr() call - */ -int hostnum(ipa, host, linenum) -u_32_t *ipa; -char *host; -int linenum; -{ - struct hostent *hp; - struct netent *np; - struct in_addr ip; - - if (!strcasecmp("any", host)) - return 0; -#ifdef USE_INET6 - if (use_inet6) { - if (inet_pton(AF_INET6, host, ipa) == 1) - return 0; - else - return -1; - } -#endif - if (isdigit(*host) && inet_aton(host, &ip)) { - *ipa = ip.s_addr; - return 0; - } - - if (!strcasecmp("", host)) - host = thishost; - - if (!(hp = gethostbyname(host))) { - if (!(np = getnetbyname(host))) { - fprintf(stderr, "%d: can't resolve hostname: %s\n", - linenum, host); - return -1; - } - *ipa = htonl(np->n_net); - return 0; - } - *ipa = *(u_32_t *)hp->h_addr; - return 0; -} - - -/* - * check for possible presence of the port fields in the line - */ -int ports(seg, pp, cp, tp, linenum) -char ***seg; -u_short *pp, *tp; -int *cp; -int linenum; -{ - int comp = -1; - - if (!*seg || !**seg || !***seg) - return 0; - if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) { - (*seg)++; - if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq")) - comp = FR_EQUAL; - else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne")) - comp = FR_NEQUAL; - else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt")) - comp = FR_LESST; - else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt")) - comp = FR_GREATERT; - else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le")) - comp = FR_LESSTE; - else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge")) - comp = FR_GREATERTE; - else if (isalnum(***seg) && *(*seg + 2)) { - if (portnum(**seg, pp, linenum) == 0) - return -1; - (*seg)++; - if (!strcmp(**seg, "<>")) - comp = FR_OUTRANGE; - else if (!strcmp(**seg, "><")) - comp = FR_INRANGE; - else { - fprintf(stderr, - "%d: unknown range operator (%s)\n", - linenum, **seg); - return -1; - } - (*seg)++; - if (**seg == NULL) { - fprintf(stderr, "%d: missing 2nd port value\n", - linenum); - return -1; - } - if (portnum(**seg, tp, linenum) == 0) - return -1; - } else { - fprintf(stderr, "%d: unknown comparator (%s)\n", - linenum, **seg); - return -1; - } - if (comp != FR_OUTRANGE && comp != FR_INRANGE) { - (*seg)++; - if (portnum(**seg, pp, linenum) == 0) - return -1; - } - *cp = comp; - (*seg)++; - } - return 0; -} - - -/* - * find the port number given by the name, either from getservbyname() or - * straight atoi(). Return 1 on success, 0 on failure - */ -int portnum(name, port, linenum) -char *name; -u_short *port; -int linenum; -{ - struct servent *sp, *sp2; - u_short p1 = 0; - int i; - - if (isdigit(*name)) { - if (ratoi(name, &i, 0, USHRT_MAX)) { - *port = (u_short)i; - return 1; - } - fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name); - return 0; - } - if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) { - sp = getservbyname(name, proto); - if (sp) { - *port = ntohs(sp->s_port); - return 1; - } - fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name); - return 0; - } - sp = getservbyname(name, "tcp"); - if (sp) - p1 = sp->s_port; - sp2 = getservbyname(name, "udp"); - if (!sp || !sp2) { - fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n", - linenum, name); - return 0; - } - if (p1 != sp2->s_port) { - fprintf(stderr, "%d: %s %d/tcp is a different port to ", - linenum, name, p1); - fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port); - return 0; - } - *port = ntohs(p1); - return 1; -} - - -u_char tcp_flags(flgs, mask, linenum) -char *flgs; -u_char *mask; -int linenum; -{ - u_char tcpf = 0, tcpfm = 0, *fp = &tcpf; - char *s, *t; - - if (*flgs == '0') { - s = strchr(flgs, '/'); - if (s) - *s++ = '\0'; - tcpf = strtol(flgs, NULL, 0); - fp = &tcpfm; - } else - s = flgs; - - for (; *s; s++) { - if (*s == '/' && fp == &tcpf) { - fp = &tcpfm; - if (*(s + 1) == '0') - break; - continue; - } - if (!(t = index(flagset, *s))) { - fprintf(stderr, "%d: unknown flag (%c)\n", linenum, *s); - return 0; - } - *fp |= flags[t - flagset]; - } - - if (s && *s == '0') - tcpfm = strtol(s, NULL, 0); - - if (!tcpfm) { - if (tcpf == TH_SYN) - tcpfm = 0xff & ~(TH_ECN|TH_CWR); - else - tcpfm = 0xff & ~(TH_ECN); - } - *mask = tcpfm; - return tcpf; -} - - -/* - * count consecutive 1's in bit mask. If the mask generated by counting - * consecutive 1's is different to that passed, return -1, else return # - * of bits. - */ -int countbits(ip) -u_32_t ip; -{ - u_32_t ipn; - int cnt = 0, i, j; - - ip = ipn = ntohl(ip); - for (i = 32; i; i--, ipn *= 2) - if (ipn & 0x80000000) - cnt++; - else - break; - ipn = 0; - for (i = 32, j = cnt; i; i--, j--) { - ipn *= 2; - if (j > 0) - ipn++; - } - if (ipn == ip) - return cnt; - return -1; -} - - -int count6bits(msk) -u_32_t *msk; -{ - int i = 0, k; - u_32_t j; - - for (k = 3; k >= 0; k--) - if (msk[k] == 0xffffffff) - i += 32; - else { - for (j = msk[k]; j; j <<= 1) - if (j & 0x80000000) - i++; - } - return i; -} - - -char *portname(pr, port) -int pr, port; -{ - static char buf[32]; - struct protoent *p = NULL; - struct servent *sv = NULL, *sv1 = NULL; - - if (pr == -1) { - if ((sv = getservbyport(htons(port), "tcp"))) { - strncpy(buf, sv->s_name, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - sv1 = getservbyport(htons(port), "udp"); - sv = strncasecmp(buf, sv->s_name, strlen(buf)) ? - NULL : sv1; - } - if (sv) - return buf; - } else if (pr && (p = getprotobynumber(pr))) { - if ((sv = getservbyport(htons(port), p->p_name))) { - strncpy(buf, sv->s_name, sizeof(buf)-1); - buf[sizeof(buf)-1] = '\0'; - return buf; - } - } - - (void) sprintf(buf, "%d", port); - return buf; -} - - -int ratoi(ps, pi, min, max) -char *ps; -int *pi, min, max; -{ - int i; - char *pe; - - i = (int)strtol(ps, &pe, 0); - if (*pe != '\0' || i < min || i > max) - return 0; - *pi = i; - return 1; -} - - -int ratoui(ps, pi, min, max) -char *ps; -u_int *pi, min, max; -{ - u_int i; - char *pe; - - i = (u_int)strtol(ps, &pe, 0); - if (*pe != '\0' || i < min || i > max) - return 0; - *pi = i; - return 1; -} - - -void printhostmask(v, addr, mask) -int v; -u_32_t *addr, *mask; -{ - struct in_addr ipa; - int ones; - -#ifdef USE_INET6 - if (v == 6) { - ones = count6bits(mask); - if (ones == 0 && !addr[0] && !addr[1] && !addr[2] && !addr[3]) - printf("any"); - else { - char ipbuf[64]; - printf("%s/%d", - inet_ntop(AF_INET6, addr, ipbuf, sizeof(ipbuf)), - ones); - } - } - else -#endif - if (!*addr && !*mask) - printf("any"); - else { - ipa.s_addr = *addr; - printf("%s", inet_ntoa(ipa)); - if ((ones = countbits(*mask)) == -1) { - ipa.s_addr = *mask; - printf("/%s", inet_ntoa(ipa)); - } else - printf("/%d", ones); - } -} - - -void printportcmp(pr, frp) -int pr; -frpcmp_t *frp; -{ - static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=", - "<>", "><"}; - - if (frp->frp_cmp == FR_INRANGE || frp->frp_cmp == FR_OUTRANGE) - printf(" port %d %s %d", frp->frp_port, - pcmp1[frp->frp_cmp], frp->frp_top); - else - printf(" port %s %s", pcmp1[frp->frp_cmp], - portname(pr, frp->frp_port)); -} - - -void printbuf(buf, len, zend) -char *buf; -int len, zend; -{ - char *s, c; - int i; - - for (s = buf, i = len; i; i--) { - c = *s++; - if (isprint(c)) - putchar(c); - else - printf("\\%03o", c); - if ((c == '\0') && zend) - break; - } -} - - - -char *hostname(v, ip) -int v; -void *ip; -{ -#ifdef USE_INET6 - static char hostbuf[MAXHOSTNAMELEN+1]; -#endif - struct in_addr ipa; - - if (v == 4) { - ipa.s_addr = *(u_32_t *)ip; - return inet_ntoa(ipa); - } -#ifdef USE_INET6 - (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); - hostbuf[MAXHOSTNAMELEN] = '\0'; - return hostbuf; -#else - return "IPv6"; -#endif -} diff --git a/contrib/ipfilter/etc/etc.sed b/contrib/ipfilter/etc/etc.sed deleted file mode 100644 index b14fc74851d7..000000000000 --- a/contrib/ipfilter/etc/etc.sed +++ /dev/null @@ -1,2 +0,0 @@ - Æ . Ä..'! CVS - protocols diff --git a/contrib/ipfilter/facpri.c b/contrib/ipfilter/facpri.c deleted file mode 100644 index 79afdd214729..000000000000 --- a/contrib/ipfilter/facpri.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#endif -#include -#include -#include -#include -#include "facpri.h" - -#ifndef __STDC__ -# define const -#endif - -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: facpri.c,v 1.3.2.4 2001/07/15 22:06:12 darrenr Exp $"; -#endif - -typedef struct table { - char *name; - int value; -} table_t; - -table_t facs[] = { - { "kern", LOG_KERN }, { "user", LOG_USER }, - { "mail", LOG_MAIL }, { "daemon", LOG_DAEMON }, - { "auth", LOG_AUTH }, { "syslog", LOG_SYSLOG }, - { "lpr", LOG_LPR }, { "news", LOG_NEWS }, - { "uucp", LOG_UUCP }, -#if LOG_CRON == LOG_CRON2 - { "cron2", LOG_CRON1 }, -#else - { "cron", LOG_CRON1 }, -#endif -#ifdef LOG_FTP - { "ftp", LOG_FTP }, -#endif -#ifdef LOG_AUTHPRIV - { "authpriv", LOG_AUTHPRIV }, -#endif -#ifdef LOG_AUDIT - { "audit", LOG_AUDIT }, -#endif -#ifdef LOG_LFMT - { "logalert", LOG_LFMT }, -#endif -#if LOG_CRON == LOG_CRON1 - { "cron", LOG_CRON2 }, -#else - { "cron2", LOG_CRON2 }, -#endif -#ifdef LOG_SECURITY - { "security", LOG_SECURITY }, -#endif - { "local0", LOG_LOCAL0 }, { "local1", LOG_LOCAL1 }, - { "local2", LOG_LOCAL2 }, { "local3", LOG_LOCAL3 }, - { "local4", LOG_LOCAL4 }, { "local5", LOG_LOCAL5 }, - { "local6", LOG_LOCAL6 }, { "local7", LOG_LOCAL7 }, - { NULL, 0 } -}; - - -/* - * map a facility number to its name - */ -char * -fac_toname(facpri) - int facpri; -{ - int i, j, fac; - - fac = facpri & LOG_FACMASK; - j = fac >> 3; - if (j < 24) { - if (facs[j].value == fac) - return facs[j].name; - for (i = 0; facs[i].name; i++) - if (fac == facs[i].value) - return facs[i].name; - } - - return NULL; -} - - -/* - * map a facility name to its number - */ -int -fac_findname(name) - char *name; -{ - int i; - - for (i = 0; facs[i].name; i++) - if (!strcmp(facs[i].name, name)) - return facs[i].value; - return -1; -} - - -table_t pris[] = { - { "emerg", LOG_EMERG }, { "alert", LOG_ALERT }, - { "crit", LOG_CRIT }, { "err", LOG_ERR }, - { "warn", LOG_WARNING }, { "notice", LOG_NOTICE }, - { "info", LOG_INFO }, { "debug", LOG_DEBUG }, - { NULL, 0 } -}; - - -/* - * map a priority name to its number - */ -int -pri_findname(name) - char *name; -{ - int i; - - for (i = 0; pris[i].name; i++) - if (!strcmp(pris[i].name, name)) - return pris[i].value; - return -1; -} - - -/* - * map a priority number to its name - */ -char * -pri_toname(facpri) - int facpri; -{ - int i, pri; - - pri = facpri & LOG_PRIMASK; - if (pris[pri].value == pri) - return pris[pri].name; - for (i = 0; pris[i].name; i++) - if (pri == pris[i].value) - return pris[i].name; - return NULL; -} diff --git a/contrib/ipfilter/facpri.h b/contrib/ipfilter/facpri.h deleted file mode 100644 index 7b80377d112e..000000000000 --- a/contrib/ipfilter/facpri.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 1999-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * $Id: facpri.h,v 1.3.2.1 2001/06/26 10:43:11 darrenr Exp $ - */ - -#ifndef __FACPRI_H__ -#define __FACPRI_H__ - -#ifndef __P -# define P_DEF -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - -extern char *fac_toname __P((int)); -extern int fac_findname __P((char *)); - -extern char *pri_toname __P((int)); -extern int pri_findname __P((char *)); - -#ifdef P_DEF -# undef __P -# undef P_DEF -#endif - -#if LOG_CRON == (9<<3) -# define LOG_CRON1 LOG_CRON -# define LOG_CRON2 (15<<3) -#endif -#if LOG_CRON == (15<<3) -# define LOG_CRON1 (9<<3) -# define LOG_CRON2 LOG_CRON -#endif - -#endif /* __FACPRI_H__ */ diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c deleted file mode 100644 index 6f3a13d57889..000000000000 --- a/contrib/ipfilter/fil.c +++ /dev/null @@ -1,6209 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#if defined(__NetBSD__) -# if (NetBSD >= 199905) && !defined(IPFILTER_LKM) && defined(_KERNEL) -# include "opt_ipfilter_log.h" -# endif -#endif -#if defined(_KERNEL) && defined(__FreeBSD_version) && \ - (__FreeBSD_version >= 220000) -# if (__FreeBSD_version >= 400000) -# if !defined(IPFILTER_LKM) -# include "opt_inet6.h" -# endif -# if (__FreeBSD_version == 400019) -# define CSUM_DELAY_DATA -# endif -# endif -# include -#else -# include -#endif -#include -#if defined(_KERNEL) -# include -# include -#else -# include -# include -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) && \ - !defined(linux) -# include -#else -# if !defined(linux) -# include -# endif -# if (SOLARIS2 < 5) && defined(sun) -# include -# endif -#endif -#ifdef __hpux -# define _NET_ROUTE_INCLUDED -#endif -#if !defined(linux) -# include -#endif -#include -#include -#ifdef sun -# include -#endif -#if !defined(_KERNEL) && defined(__FreeBSD__) -# include "radix_ipf.h" -#endif -#include -#include -#include -#include -#if !defined(linux) -# include -#endif -#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */ -# include -# include -#endif -#include -#if !defined(__sgi) || defined(_KERNEL) -# include -# include -#endif -#ifdef __hpux -# undef _NET_ROUTE_INCLUDED -#endif -#include "netinet/ip_compat.h" -#ifdef USE_INET6 -# include -# if !SOLARIS && defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) -# include -# endif -#endif -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "netinet/ip_auth.h" -#ifdef IPFILTER_SCAN -# include "netinet/ip_scan.h" -#endif -#ifdef IPFILTER_SYNC -# include "netinet/ip_sync.h" -#endif -#include "netinet/ip_pool.h" -#include "netinet/ip_htable.h" -#ifdef IPFILTER_COMPILED -# include "netinet/ip_rules.h" -#endif -#if defined(IPFILTER_BPF) && defined(_KERNEL) -# include -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#endif -#include "netinet/ipl.h" -/* END OF INCLUDES */ - -#if !defined(lint) -static const char sccsid[] = "@(#)fil.c 1.36 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp"; -#endif - -#ifndef _KERNEL -# include "ipf.h" -# include "ipt.h" -# include "bpf-ipf.h" -extern int opts; - -# define FR_VERBOSE(verb_pr) verbose verb_pr -# define FR_DEBUG(verb_pr) debug verb_pr -#else /* #ifndef _KERNEL */ -# define FR_VERBOSE(verb_pr) -# define FR_DEBUG(verb_pr) -#endif /* _KERNEL */ - - -fr_info_t frcache[2][8]; -struct filterstats frstats[2] = { { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }; -struct frentry *ipfilter[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipfilter6[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipacct6[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } }, - *ipnatrules[2][2] = { { NULL, NULL }, { NULL, NULL } }; -struct frgroup *ipfgroups[IPL_LOGSIZE][2]; -char ipfilter_version[] = IPL_VERSION; -int fr_refcnt = 0; -/* - * For fr_running: - * 0 == loading, 1 = running, -1 = disabled, -2 = unloading - */ -int fr_running = 0; -int fr_flags = IPF_LOGGING; -int fr_active = 0; -int fr_control_forwarding = 0; -int fr_update_ipid = 0; -u_short fr_ip_id = 0; -int fr_chksrc = 0; /* causes a system crash if enabled */ -int fr_minttl = 4; -u_long fr_frouteok[2] = {0, 0}; -u_long fr_userifqs = 0; -u_long fr_badcoalesces[2] = {0, 0}; -u_char ipf_iss_secret[32]; -#if defined(IPFILTER_DEFAULT_BLOCK) -int fr_pass = FR_BLOCK|FR_NOMATCH; -#else -int fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH; -#endif -int fr_features = 0 -#ifdef IPFILTER_LKM - | IPF_FEAT_LKM -#endif -#ifdef IPFILTER_LOG - | IPF_FEAT_LOG -#endif -#ifdef IPFILTER_LOOKUP - | IPF_FEAT_LOOKUP -#endif -#ifdef IPFILTER_BPF - | IPF_FEAT_BPF -#endif -#ifdef IPFILTER_COMPILED - | IPF_FEAT_COMPILED -#endif -#ifdef IPFILTER_CKSUM - | IPF_FEAT_CKSUM -#endif -#ifdef IPFILTER_SYNC - | IPF_FEAT_SYNC -#endif -#ifdef IPFILTER_SCAN - | IPF_FEAT_SCAN -#endif -#ifdef USE_INET6 - | IPF_FEAT_IPV6 -#endif - ; - -static INLINE int fr_ipfcheck __P((fr_info_t *, frentry_t *, int)); -static int fr_portcheck __P((frpcmp_t *, u_short *)); -static int frflushlist __P((int, minor_t, int *, frentry_t **)); -static ipfunc_t fr_findfunc __P((ipfunc_t)); -static frentry_t *fr_firewall __P((fr_info_t *, u_32_t *)); -static int fr_funcinit __P((frentry_t *fr)); -static INLINE void frpr_esp __P((fr_info_t *)); -static INLINE void frpr_gre __P((fr_info_t *)); -static INLINE void frpr_udp __P((fr_info_t *)); -static INLINE void frpr_tcp __P((fr_info_t *)); -static INLINE void frpr_icmp __P((fr_info_t *)); -static INLINE void frpr_ipv4hdr __P((fr_info_t *)); -static INLINE int frpr_pullup __P((fr_info_t *, int)); -static INLINE void frpr_short __P((fr_info_t *, int)); -static INLINE void frpr_tcpcommon __P((fr_info_t *)); -static INLINE void frpr_udpcommon __P((fr_info_t *)); -static INLINE int fr_updateipid __P((fr_info_t *)); -#ifdef IPFILTER_LOOKUP -static int fr_grpmapinit __P((frentry_t *fr)); -static INLINE void *fr_resolvelookup __P((u_int, u_int, lookupfunc_t *)); -#endif -static void frsynclist __P((frentry_t *, void *)); -static ipftuneable_t *fr_findtunebyname __P((char *)); -static ipftuneable_t *fr_findtunebycookie __P((void *, void **)); - - -/* - * bit values for identifying presence of individual IP options - * All of these tables should be ordered by increasing key value on the left - * hand side to allow for binary searching of the array and include a trailer - * with a 0 for the bitmask for linear searches to easily find the end with. - */ -const struct optlist ipopts[20] = { - { IPOPT_NOP, 0x000001 }, - { IPOPT_RR, 0x000002 }, - { IPOPT_ZSU, 0x000004 }, - { IPOPT_MTUP, 0x000008 }, - { IPOPT_MTUR, 0x000010 }, - { IPOPT_ENCODE, 0x000020 }, - { IPOPT_TS, 0x000040 }, - { IPOPT_TR, 0x000080 }, - { IPOPT_SECURITY, 0x000100 }, - { IPOPT_LSRR, 0x000200 }, - { IPOPT_E_SEC, 0x000400 }, - { IPOPT_CIPSO, 0x000800 }, - { IPOPT_SATID, 0x001000 }, - { IPOPT_SSRR, 0x002000 }, - { IPOPT_ADDEXT, 0x004000 }, - { IPOPT_VISA, 0x008000 }, - { IPOPT_IMITD, 0x010000 }, - { IPOPT_EIP, 0x020000 }, - { IPOPT_FINN, 0x040000 }, - { 0, 0x000000 } -}; - -#ifdef USE_INET6 -struct optlist ip6exthdr[] = { - { IPPROTO_HOPOPTS, 0x000001 }, - { IPPROTO_IPV6, 0x000002 }, - { IPPROTO_ROUTING, 0x000004 }, - { IPPROTO_FRAGMENT, 0x000008 }, - { IPPROTO_ESP, 0x000010 }, - { IPPROTO_AH, 0x000020 }, - { IPPROTO_NONE, 0x000040 }, - { IPPROTO_DSTOPTS, 0x000080 }, - { 0, 0 } -}; -#endif - -struct optlist tcpopts[] = { - { TCPOPT_NOP, 0x000001 }, - { TCPOPT_MAXSEG, 0x000002 }, - { TCPOPT_WINDOW, 0x000004 }, - { TCPOPT_SACK_PERMITTED, 0x000008 }, - { TCPOPT_SACK, 0x000010 }, - { TCPOPT_TIMESTAMP, 0x000020 }, - { 0, 0x000000 } -}; - -/* - * bit values for identifying presence of individual IP security options - */ -const struct optlist secopt[8] = { - { IPSO_CLASS_RES4, 0x01 }, - { IPSO_CLASS_TOPS, 0x02 }, - { IPSO_CLASS_SECR, 0x04 }, - { IPSO_CLASS_RES3, 0x08 }, - { IPSO_CLASS_CONF, 0x10 }, - { IPSO_CLASS_UNCL, 0x20 }, - { IPSO_CLASS_RES2, 0x40 }, - { IPSO_CLASS_RES1, 0x80 } -}; - - -/* - * Table of functions available for use with call rules. - */ -static ipfunc_resolve_t fr_availfuncs[] = { -#ifdef IPFILTER_LOOKUP - { "fr_srcgrpmap", fr_srcgrpmap, fr_grpmapinit }, - { "fr_dstgrpmap", fr_dstgrpmap, fr_grpmapinit }, -#endif - { "", NULL } -}; - - -/* - * The next section of code is a a collection of small routines that set - * fields in the fr_info_t structure passed based on properties of the - * current packet. There are different routines for the same protocol - * for each of IPv4 and IPv6. Adding a new protocol, for which there - * will "special" inspection for setup, is now more easily done by adding - * a new routine and expanding the frpr_ipinit*() function rather than by - * adding more code to a growing switch statement. - */ -#ifdef USE_INET6 -static INLINE void frpr_udp6 __P((fr_info_t *)); -static INLINE void frpr_tcp6 __P((fr_info_t *)); -static INLINE void frpr_icmp6 __P((fr_info_t *)); -static INLINE void frpr_ipv6hdr __P((fr_info_t *)); -static INLINE void frpr_short6 __P((fr_info_t *, int)); -static INLINE int frpr_hopopts6 __P((fr_info_t *)); -static INLINE int frpr_routing6 __P((fr_info_t *)); -static INLINE int frpr_dstopts6 __P((fr_info_t *)); -static INLINE int frpr_fragment6 __P((fr_info_t *)); - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_short6 */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* This is function enforces the 'is a packet too short to be legit' rule */ -/* for IPv6 and marks the packet with FI_SHORT if so. See function comment */ -/* for frpr_short() for more details. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_short6(fin, min) -fr_info_t *fin; -int min; -{ - fr_ip_t *fi = &fin->fin_fi; - int off; - - off = fin->fin_off; - if (off == 0) { - if (fin->fin_plen < fin->fin_hlen + min) - fi->fi_flx |= FI_SHORT; - } else if (off < min) { - fi->fi_flx |= FI_SHORT; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_ipv6hdr */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* Copy values from the IPv6 header into the fr_info_t struct and call the */ -/* per-protocol analyzer if it exists. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_ipv6hdr(fin) -fr_info_t *fin; -{ - int p, go = 1, i, hdrcount, coalesced; - ip6_t *ip6 = (ip6_t *)fin->fin_ip; - fr_ip_t *fi = &fin->fin_fi; - - fin->fin_off = 0; - - fi->fi_tos = 0; - fi->fi_optmsk = 0; - fi->fi_secmsk = 0; - fi->fi_auth = 0; - - coalesced = (fin->fin_flx & FI_COALESCE) ? 1 : 0; - p = ip6->ip6_nxt; - fi->fi_ttl = ip6->ip6_hlim; - fi->fi_src.in6 = ip6->ip6_src; - fi->fi_dst.in6 = ip6->ip6_dst; - fin->fin_id = (u_short)(ip6->ip6_flow & 0xffff); - - hdrcount = 0; - while (go && !(fin->fin_flx & (FI_BAD|FI_SHORT))) { - switch (p) - { - case IPPROTO_UDP : - frpr_udp6(fin); - go = 0; - break; - - case IPPROTO_TCP : - frpr_tcp6(fin); - go = 0; - break; - - case IPPROTO_ICMPV6 : - frpr_icmp6(fin); - go = 0; - break; - - case IPPROTO_GRE : - frpr_gre(fin); - go = 0; - break; - - case IPPROTO_HOPOPTS : - /* - * Actually, hop by hop header is only allowed right - * after IPv6 header! - */ - if (hdrcount != 0) - fin->fin_flx |= FI_BAD; - - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } - p = frpr_hopopts6(fin); - break; - - case IPPROTO_DSTOPTS : - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } - p = frpr_dstopts6(fin); - break; - - case IPPROTO_ROUTING : - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } - p = frpr_routing6(fin); - break; - - case IPPROTO_ESP : - frpr_esp(fin); - /*FALLTHROUGH*/ - case IPPROTO_AH : - case IPPROTO_IPV6 : - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == p) { - fin->fin_flx |= ip6exthdr[i].ol_bit; - break; - } - go = 0; - break; - - case IPPROTO_NONE : - go = 0; - break; - - case IPPROTO_FRAGMENT : - if (coalesced == 0) { - coalesced = fr_coalesce(fin); - if (coalesced != 1) - return; - } - p = frpr_fragment6(fin); - break; - - default : - go = 0; - break; - } - hdrcount++; - - /* - * It is important to note that at this point, for the - * extension headers (go != 0), the entire header may not have - * been pulled up when the code gets to this point. This is - * only done for "go != 0" because the other header handlers - * will all pullup their complete header and the other - * indicator of an incomplete header is that this eas just an - * extension header. - */ - if ((go != 0) && (p != IPPROTO_NONE) && - (frpr_pullup(fin, 0) == -1)) { - p = IPPROTO_NONE; - go = 0; - } - } - fi->fi_p = p; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_hopopts6 */ -/* Returns: int - value of the next header or IPPROTO_NONE if error */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* This is function checks pending hop by hop options extension header */ -/* ------------------------------------------------------------------------ */ -static INLINE int frpr_hopopts6(fin) -fr_info_t *fin; -{ - struct ip6_ext *hdr; - u_short shift; - int i; - - fin->fin_flx |= FI_V6EXTHDR; - - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - if (frpr_pullup(fin, 8) == -1) - return IPPROTO_NONE; - - hdr = fin->fin_dp; - shift = 8 + (hdr->ip6e_len << 3); - if (shift > fin->fin_dlen) { /* Nasty extension header length? */ - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_HOPOPTS) { - fin->fin_optmsk |= ip6exthdr[i].ol_bit; - break; - } - - fin->fin_dp = (char *)fin->fin_dp + shift; - fin->fin_dlen -= shift; - - return hdr->ip6e_nxt; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_routing6 */ -/* Returns: int - value of the next header or IPPROTO_NONE if error */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* This is function checks pending routing extension header */ -/* ------------------------------------------------------------------------ */ -static INLINE int frpr_routing6(fin) -fr_info_t *fin; -{ - struct ip6_ext *hdr; - u_short shift; - int i; - - fin->fin_flx |= FI_V6EXTHDR; - - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - if (frpr_pullup(fin, 8) == -1) - return IPPROTO_NONE; - hdr = fin->fin_dp; - - shift = 8 + (hdr->ip6e_len << 3); - /* - * Nasty extension header length? - */ - if ((shift > fin->fin_dlen) || (shift < sizeof(struct ip6_hdr)) || - ((shift - sizeof(struct ip6_hdr)) & 15)) { - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_ROUTING) { - fin->fin_optmsk |= ip6exthdr[i].ol_bit; - break; - } - - fin->fin_dp = (char *)fin->fin_dp + shift; - fin->fin_dlen -= shift; - - return hdr->ip6e_nxt; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_fragment6 */ -/* Returns: int - value of the next header or IPPROTO_NONE if error */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* Examine the IPv6 fragment header and extract fragment offset information.*/ -/* ------------------------------------------------------------------------ */ -static INLINE int frpr_fragment6(fin) -fr_info_t *fin; -{ - struct ip6_frag *frag; - struct ip6_ext *hdr; - int i; - - fin->fin_flx |= (FI_FRAG|FI_V6EXTHDR); - - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - /* - * Only one frgament header is allowed per IPv6 packet but it need - * not be the first nor last (not possible in some cases.) - */ - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_FRAGMENT) - break; - - if (fin->fin_optmsk & ip6exthdr[i].ol_bit) { - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - fin->fin_optmsk |= ip6exthdr[i].ol_bit; - - if (frpr_pullup(fin, sizeof(*frag)) == -1) - return IPPROTO_NONE; - hdr = fin->fin_dp; - - /* - * Length must be zero, i.e. it has no length. - */ - if (hdr->ip6e_len != 0) { - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - if ((int)(fin->fin_dlen - sizeof(*frag)) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - frag = fin->fin_dp; - fin->fin_off = frag->ip6f_offlg & IP6F_OFF_MASK; - fin->fin_off <<= 3; - if (fin->fin_off != 0) - fin->fin_flx |= FI_FRAGBODY; - - fin->fin_dp = (char *)fin->fin_dp + sizeof(*frag); - fin->fin_dlen -= sizeof(*frag); - - return frag->ip6f_nxt; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_dstopts6 */ -/* Returns: int - value of the next header or IPPROTO_NONE if error */ -/* Parameters: fin(I) - pointer to packet information */ -/* nextheader(I) - stores next header value */ -/* */ -/* IPv6 Only */ -/* This is function checks pending destination options extension header */ -/* ------------------------------------------------------------------------ */ -static INLINE int frpr_dstopts6(fin) -fr_info_t *fin; -{ - struct ip6_ext *hdr; - u_short shift; - int i; - - /* 8 is default length of extension hdr */ - if ((fin->fin_dlen - 8) < 0) { - fin->fin_flx |= FI_SHORT; - return IPPROTO_NONE; - } - - if (frpr_pullup(fin, 8) == -1) - return IPPROTO_NONE; - hdr = fin->fin_dp; - - shift = 8 + (hdr->ip6e_len << 3); - if (shift > fin->fin_dlen) { /* Nasty extension header length? */ - fin->fin_flx |= FI_BAD; - return IPPROTO_NONE; - } - - for (i = 0; ip6exthdr[i].ol_bit != 0; i++) - if (ip6exthdr[i].ol_val == IPPROTO_DSTOPTS) - break; - fin->fin_optmsk |= ip6exthdr[i].ol_bit; - fin->fin_dp = (char *)fin->fin_dp + shift; - fin->fin_dlen -= shift; - - return hdr->ip6e_nxt; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_icmp6 */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* This routine is mainly concerned with determining the minimum valid size */ -/* for an ICMPv6 packet. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_icmp6(fin) -fr_info_t *fin; -{ - int minicmpsz = sizeof(struct icmp6_hdr); - struct icmp6_hdr *icmp6; - - if (frpr_pullup(fin, ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t)) == -1) - return; - - if (fin->fin_dlen > 1) { - icmp6 = fin->fin_dp; - - fin->fin_data[0] = *(u_short *)icmp6; - - switch (icmp6->icmp6_type) - { - case ICMP6_ECHO_REPLY : - case ICMP6_ECHO_REQUEST : - minicmpsz = ICMP6ERR_MINPKTLEN - sizeof(ip6_t); - break; - case ICMP6_DST_UNREACH : - case ICMP6_PACKET_TOO_BIG : - case ICMP6_TIME_EXCEEDED : - case ICMP6_PARAM_PROB : - if ((fin->fin_m != NULL) && - (M_LEN(fin->fin_m) < fin->fin_plen)) { - if (fr_coalesce(fin) != 1) - return; - } - fin->fin_flx |= FI_ICMPERR; - minicmpsz = ICMP6ERR_IPICMPHLEN - sizeof(ip6_t); - break; - default : - break; - } - } - - frpr_short(fin, minicmpsz); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_udp6 */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* Analyse the packet for IPv6/UDP properties. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_udp6(fin) -fr_info_t *fin; -{ - - fr_checkv6sum(fin); - - frpr_short(fin, sizeof(struct udphdr)); - - frpr_udpcommon(fin); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_tcp6 */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv6 Only */ -/* Analyse the packet for IPv6/TCP properties. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_tcp6(fin) -fr_info_t *fin; -{ - - fr_checkv6sum(fin); - - frpr_short(fin, sizeof(struct tcphdr)); - - frpr_tcpcommon(fin); -} -#endif /* USE_INET6 */ - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_pullup */ -/* Returns: int - 0 == pullup succeeded, -1 == failure */ -/* Parameters: fin(I) - pointer to packet information */ -/* plen(I) - length (excluding L3 header) to pullup */ -/* */ -/* Short inline function to cut down on code duplication to perform a call */ -/* to fr_pullup to ensure there is the required amount of data, */ -/* consecutively in the packet buffer. */ -/* ------------------------------------------------------------------------ */ -static INLINE int frpr_pullup(fin, plen) -fr_info_t *fin; -int plen; -{ -#if defined(_KERNEL) - if (fin->fin_m != NULL) { - if (fin->fin_dp != NULL) - plen += (char *)fin->fin_dp - - ((char *)fin->fin_ip + fin->fin_hlen); - plen += fin->fin_hlen; - if (M_LEN(fin->fin_m) < plen) { - if (fr_pullup(fin->fin_m, fin, plen) == NULL) - return -1; - } - } -#endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_short */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* min(I) - minimum header size */ -/* */ -/* Check if a packet is "short" as defined by min. The rule we are */ -/* applying here is that the packet must not be fragmented within the layer */ -/* 4 header. That is, it must not be a fragment that has its offset set to */ -/* start within the layer 4 header (hdrmin) or if it is at offset 0, the */ -/* entire layer 4 header must be present (min). */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_short(fin, min) -fr_info_t *fin; -int min; -{ - fr_ip_t *fi = &fin->fin_fi; - int off; - - off = fin->fin_off; - if (off == 0) { - if (fin->fin_plen < fin->fin_hlen + min) - fi->fi_flx |= FI_SHORT; - } else if (off < min) { - fi->fi_flx |= FI_SHORT; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_icmp */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv4 Only */ -/* Do a sanity check on the packet for ICMP (v4). In nearly all cases, */ -/* except extrememly bad packets, both type and code will be present. */ -/* The expected minimum size of an ICMP packet is very much dependant on */ -/* the type of it. */ -/* */ -/* XXX - other ICMP sanity checks? */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_icmp(fin) -fr_info_t *fin; -{ - int minicmpsz = sizeof(struct icmp); - icmphdr_t *icmp; - - if (frpr_pullup(fin, ICMPERR_ICMPHLEN) == -1) - return; - - fr_checkv4sum(fin); - - if (!fin->fin_off && (fin->fin_dlen > 1)) { - icmp = fin->fin_dp; - - fin->fin_data[0] = *(u_short *)icmp; - - switch (icmp->icmp_type) - { - case ICMP_ECHOREPLY : - case ICMP_ECHO : - /* Router discovery messaes - RFC 1256 */ - case ICMP_ROUTERADVERT : - case ICMP_ROUTERSOLICIT : - minicmpsz = ICMP_MINLEN; - break; - /* - * type(1) + code(1) + cksum(2) + id(2) seq(2) + - * 3 * timestamp(3 * 4) - */ - case ICMP_TSTAMP : - case ICMP_TSTAMPREPLY : - minicmpsz = 20; - break; - /* - * type(1) + code(1) + cksum(2) + id(2) seq(2) + - * mask(4) - */ - case ICMP_MASKREQ : - case ICMP_MASKREPLY : - minicmpsz = 12; - break; - /* - * type(1) + code(1) + cksum(2) + id(2) seq(2) + ip(20+) - */ - case ICMP_UNREACH : - case ICMP_SOURCEQUENCH : - case ICMP_REDIRECT : - case ICMP_TIMXCEED : - case ICMP_PARAMPROB : - if (fr_coalesce(fin) != 1) - return; - fin->fin_flx |= FI_ICMPERR; - break; - default : - break; - } - - if (fin->fin_dlen >= 6) /* ID field */ - fin->fin_data[1] = icmp->icmp_id; - } - - frpr_short(fin, minicmpsz); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_tcpcommon */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* TCP header sanity checking. Look for bad combinations of TCP flags, */ -/* and make some checks with how they interact with other fields. */ -/* If compiled with IPFILTER_CKSUM, check to see if the TCP checksum is */ -/* valid and mark the packet as bad if not. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_tcpcommon(fin) -fr_info_t *fin; -{ - int flags, tlen; - tcphdr_t *tcp; - fr_ip_t *fi; - - fi = &fin->fin_fi; - fi->fi_flx |= FI_TCPUDP; - if (fin->fin_off != 0) - return; - - if (frpr_pullup(fin, sizeof(*tcp)) == -1) - return; - tcp = fin->fin_dp; - - if (fin->fin_dlen > 3) { - fin->fin_sport = ntohs(tcp->th_sport); - fin->fin_dport = ntohs(tcp->th_dport); - } - - if ((fi->fi_flx & FI_SHORT) != 0) - return; - - /* - * Use of the TCP data offset *must* result in a value that is at - * least the same size as the TCP header. - */ - tlen = TCP_OFF(tcp) << 2; - if (tlen < sizeof(tcphdr_t)) { - fin->fin_flx |= FI_BAD; - return; - } - - flags = tcp->th_flags; - fin->fin_tcpf = tcp->th_flags; - - /* - * If the urgent flag is set, then the urgent pointer must - * also be set and vice versa. Good TCP packets do not have - * just one of these set. - */ - if ((flags & TH_URG) != 0 && (tcp->th_urp == 0)) { - fin->fin_flx |= FI_BAD; - } else if ((flags & TH_URG) == 0 && (tcp->th_urp != 0)) { - /* Ignore this case, it shows up in "real" traffic with */ - /* bogus values in the urgent pointer field. */ - ; - } else if (((flags & (TH_SYN|TH_FIN)) != 0) && - ((flags & (TH_RST|TH_ACK)) == TH_RST)) { - /* TH_FIN|TH_RST|TH_ACK seems to appear "naturally" */ - fin->fin_flx |= FI_BAD; - } else if (!(flags & TH_ACK)) { - /* - * If the ack bit isn't set, then either the SYN or - * RST bit must be set. If the SYN bit is set, then - * we expect the ACK field to be 0. If the ACK is - * not set and if URG, PSH or FIN are set, consdier - * that to indicate a bad TCP packet. - */ - if ((flags == TH_SYN) && (tcp->th_ack != 0)) { - /* - * Cisco PIX sets the ACK field to a random value. - * In light of this, do not set FI_BAD until a patch - * is available from Cisco to ensure that - * interoperability between existing systems is - * achieved. - */ - /*fin->fin_flx |= FI_BAD*/; - } else if (!(flags & (TH_RST|TH_SYN))) { - fin->fin_flx |= FI_BAD; - } else if ((flags & (TH_URG|TH_PUSH|TH_FIN)) != 0) { - fin->fin_flx |= FI_BAD; - } - } - - /* - * At this point, it's not exactly clear what is to be gained by - * marking up which TCP options are and are not present. The one we - * are most interested in is the TCP window scale. This is only in - * a SYN packet [RFC1323] so we don't need this here...? - * Now if we were to analyse the header for passive fingerprinting, - * then that might add some weight to adding this... - */ - if (tlen == sizeof(tcphdr_t)) - return; - - if (frpr_pullup(fin, tlen) == -1) - return; - -#if 0 - ip = fin->fin_ip; - s = (u_char *)(tcp + 1); - off = IP_HL(ip) << 2; -# ifdef _KERNEL - if (fin->fin_mp != NULL) { - mb_t *m = *fin->fin_mp; - - if (off + tlen > M_LEN(m)) - return; - } -# endif - for (tlen -= (int)sizeof(*tcp); tlen > 0; ) { - opt = *s; - if (opt == '\0') - break; - else if (opt == TCPOPT_NOP) - ol = 1; - else { - if (tlen < 2) - break; - ol = (int)*(s + 1); - if (ol < 2 || ol > tlen) - break; - } - - for (i = 9, mv = 4; mv >= 0; ) { - op = ipopts + i; - if (opt == (u_char)op->ol_val) { - optmsk |= op->ol_bit; - break; - } - } - tlen -= ol; - s += ol; - } -#endif /* 0 */ -} - - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_udpcommon */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Extract the UDP source and destination ports, if present. If compiled */ -/* with IPFILTER_CKSUM, check to see if the UDP checksum is valid. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_udpcommon(fin) -fr_info_t *fin; -{ - udphdr_t *udp; - fr_ip_t *fi; - - fi = &fin->fin_fi; - fi->fi_flx |= FI_TCPUDP; - - if (!fin->fin_off && (fin->fin_dlen > 3)) { - if (frpr_pullup(fin, sizeof(*udp)) == -1) { - fi->fi_flx |= FI_SHORT; - return; - } - - udp = fin->fin_dp; - - fin->fin_sport = ntohs(udp->uh_sport); - fin->fin_dport = ntohs(udp->uh_dport); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_tcp */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv4 Only */ -/* Analyse the packet for IPv4/TCP properties. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_tcp(fin) -fr_info_t *fin; -{ - - fr_checkv4sum(fin); - - frpr_short(fin, sizeof(tcphdr_t)); - - frpr_tcpcommon(fin); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_udp */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv4 Only */ -/* Analyse the packet for IPv4/UDP properties. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_udp(fin) -fr_info_t *fin; -{ - - fr_checkv4sum(fin); - - frpr_short(fin, sizeof(udphdr_t)); - - frpr_udpcommon(fin); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_esp */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Analyse the packet for ESP properties. */ -/* The minimum length is taken to be the SPI (32bits) plus a tail (32bits) */ -/* even though the newer ESP packets must also have a sequence number that */ -/* is 32bits as well, it is not possible(?) to determine the version from a */ -/* simple packet header. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_esp(fin) -fr_info_t *fin; -{ - if (frpr_pullup(fin, 8) == -1) - return; - - if (fin->fin_v == 4) - frpr_short(fin, 8); -#ifdef USE_INET6 - else if (fin->fin_v == 6) - frpr_short6(fin, sizeof(grehdr_t)); -#endif -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_gre */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Analyse the packet for GRE properties. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_gre(fin) -fr_info_t *fin; -{ - grehdr_t *gre; - - if (frpr_pullup(fin, sizeof(grehdr_t)) == -1) - return; - - if (fin->fin_v == 4) - frpr_short(fin, sizeof(grehdr_t)); -#ifdef USE_INET6 - else if (fin->fin_v == 6) - frpr_short6(fin, sizeof(grehdr_t)); -#endif - gre = fin->fin_dp; - if (GRE_REV(gre->gr_flags) == 1) - fin->fin_data[0] = gre->gr_call; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frpr_ipv4hdr */ -/* Returns: void */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* IPv4 Only */ -/* Analyze the IPv4 header and set fields in the fr_info_t structure. */ -/* Check all options present and flag their presence if any exist. */ -/* ------------------------------------------------------------------------ */ -static INLINE void frpr_ipv4hdr(fin) -fr_info_t *fin; -{ - u_short optmsk = 0, secmsk = 0, auth = 0; - int hlen, ol, mv, p, i; - const struct optlist *op; - u_char *s, opt; - u_short off; - fr_ip_t *fi; - ip_t *ip; - - fi = &fin->fin_fi; - hlen = fin->fin_hlen; - - ip = fin->fin_ip; - p = ip->ip_p; - fi->fi_p = p; - fi->fi_tos = ip->ip_tos; - fin->fin_id = ip->ip_id; - off = ip->ip_off; - - /* Get both TTL and protocol */ - fi->fi_p = ip->ip_p; - fi->fi_ttl = ip->ip_ttl; -#if 0 - (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4)); -#endif - - /* Zero out bits not used in IPv6 address */ - fi->fi_src.i6[1] = 0; - fi->fi_src.i6[2] = 0; - fi->fi_src.i6[3] = 0; - fi->fi_dst.i6[1] = 0; - fi->fi_dst.i6[2] = 0; - fi->fi_dst.i6[3] = 0; - - fi->fi_saddr = ip->ip_src.s_addr; - fi->fi_daddr = ip->ip_dst.s_addr; - - /* - * set packet attribute flags based on the offset and - * calculate the byte offset that it represents. - */ - if ((off & IP_MF) != 0) { - fi->fi_flx |= FI_FRAG; - if (fin->fin_dlen == 0) - fi->fi_flx |= FI_BAD; - } - - off &= IP_MF|IP_OFFMASK; - if (off != 0) { - fi->fi_flx |= FI_FRAG; - off &= IP_OFFMASK; - if (off != 0) { - fin->fin_flx |= FI_FRAGBODY; - off <<= 3; - if (off + fin->fin_dlen > 0xffff) { - fi->fi_flx |= FI_BAD; - } - } - } - fin->fin_off = off; - - /* - * Call per-protocol setup and checking - */ - switch (p) - { - case IPPROTO_UDP : - frpr_udp(fin); - break; - case IPPROTO_TCP : - frpr_tcp(fin); - break; - case IPPROTO_ICMP : - frpr_icmp(fin); - break; - case IPPROTO_ESP : - frpr_esp(fin); - break; - case IPPROTO_GRE : - frpr_gre(fin); - break; - } - - ip = fin->fin_ip; - if (ip == NULL) - return; - - /* - * If it is a standard IP header (no options), set the flag fields - * which relate to options to 0. - */ - if (hlen == sizeof(*ip)) { - fi->fi_optmsk = 0; - fi->fi_secmsk = 0; - fi->fi_auth = 0; - return; - } - - /* - * So the IP header has some IP options attached. Walk the entire - * list of options present with this packet and set flags to indicate - * which ones are here and which ones are not. For the somewhat out - * of date and obscure security classification options, set a flag to - * represent which classification is present. - */ - fi->fi_flx |= FI_OPTIONS; - - for (s = (u_char *)(ip + 1), hlen -= (int)sizeof(*ip); hlen > 0; ) { - opt = *s; - if (opt == '\0') - break; - else if (opt == IPOPT_NOP) - ol = 1; - else { - if (hlen < 2) - break; - ol = (int)*(s + 1); - if (ol < 2 || ol > hlen) - break; - } - for (i = 9, mv = 4; mv >= 0; ) { - op = ipopts + i; - if ((opt == (u_char)op->ol_val) && (ol > 4)) { - optmsk |= op->ol_bit; - if (opt == IPOPT_SECURITY) { - const struct optlist *sp; - u_char sec; - int j, m; - - sec = *(s + 2); /* classification */ - for (j = 3, m = 2; m >= 0; ) { - sp = secopt + j; - if (sec == sp->ol_val) { - secmsk |= sp->ol_bit; - auth = *(s + 3); - auth *= 256; - auth += *(s + 4); - break; - } - if (sec < sp->ol_val) - j -= m; - else - j += m; - m--; - } - } - break; - } - if (opt < op->ol_val) - i -= mv; - else - i += mv; - mv--; - } - hlen -= ol; - s += ol; - } - - /* - * - */ - if (auth && !(auth & 0x0100)) - auth &= 0xff00; - fi->fi_optmsk = optmsk; - fi->fi_secmsk = secmsk; - fi->fi_auth = auth; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_makefrip */ -/* Returns: void */ -/* Parameters: hlen(I) - length of IP packet header */ -/* ip(I) - pointer to the IP header */ -/* fin(IO) - pointer to packet information */ -/* */ -/* Compact the IP header into a structure which contains just the info. */ -/* which is useful for comparing IP headers with and store this information */ -/* in the fr_info_t structure pointer to by fin. At present, it is assumed */ -/* this function will be called with either an IPv4 or IPv6 packet. */ -/* ------------------------------------------------------------------------ */ -int fr_makefrip(hlen, ip, fin) -int hlen; -ip_t *ip; -fr_info_t *fin; -{ - int v; - - fin->fin_nat = NULL; - fin->fin_state = NULL; - fin->fin_depth = 0; - fin->fin_hlen = (u_short)hlen; - fin->fin_ip = ip; - fin->fin_rule = 0xffffffff; - fin->fin_group[0] = -1; - fin->fin_group[1] = '\0'; - fin->fin_dlen = fin->fin_plen - hlen; - fin->fin_dp = (char *)ip + hlen; - - v = fin->fin_v; - if (v == 4) - frpr_ipv4hdr(fin); -#ifdef USE_INET6 - else if (v == 6) - frpr_ipv6hdr(fin); -#endif - if (fin->fin_ip == NULL) - return -1; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_portcheck */ -/* Returns: int - 1 == port matched, 0 == port match failed */ -/* Parameters: frp(I) - pointer to port check `expression' */ -/* pop(I) - pointer to port number to evaluate */ -/* */ -/* Perform a comparison of a port number against some other(s), using a */ -/* structure with compare information stored in it. */ -/* ------------------------------------------------------------------------ */ -static INLINE int fr_portcheck(frp, pop) -frpcmp_t *frp; -u_short *pop; -{ - u_short tup, po; - int err = 1; - - tup = *pop; - po = frp->frp_port; - - /* - * Do opposite test to that required and continue if that succeeds. - */ - switch (frp->frp_cmp) - { - case FR_EQUAL : - if (tup != po) /* EQUAL */ - err = 0; - break; - case FR_NEQUAL : - if (tup == po) /* NOTEQUAL */ - err = 0; - break; - case FR_LESST : - if (tup >= po) /* LESSTHAN */ - err = 0; - break; - case FR_GREATERT : - if (tup <= po) /* GREATERTHAN */ - err = 0; - break; - case FR_LESSTE : - if (tup > po) /* LT or EQ */ - err = 0; - break; - case FR_GREATERTE : - if (tup < po) /* GT or EQ */ - err = 0; - break; - case FR_OUTRANGE : - if (tup >= po && tup <= frp->frp_top) /* Out of range */ - err = 0; - break; - case FR_INRANGE : - if (tup <= po || tup >= frp->frp_top) /* In range */ - err = 0; - break; - case FR_INCRANGE : - if (tup < po || tup > frp->frp_top) /* Inclusive range */ - err = 0; - break; - default : - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_tcpudpchk */ -/* Returns: int - 1 == protocol matched, 0 == check failed */ -/* Parameters: fin(I) - pointer to packet information */ -/* ft(I) - pointer to structure with comparison data */ -/* */ -/* Compares the current pcket (assuming it is TCP/UDP) information with a */ -/* structure containing information that we want to match against. */ -/* ------------------------------------------------------------------------ */ -int fr_tcpudpchk(fin, ft) -fr_info_t *fin; -frtuc_t *ft; -{ - int err = 1; - - /* - * Both ports should *always* be in the first fragment. - * So far, I cannot find any cases where they can not be. - * - * compare destination ports - */ - if (ft->ftu_dcmp) - err = fr_portcheck(&ft->ftu_dst, &fin->fin_dport); - - /* - * compare source ports - */ - if (err && ft->ftu_scmp) - err = fr_portcheck(&ft->ftu_src, &fin->fin_sport); - - /* - * If we don't have all the TCP/UDP header, then how can we - * expect to do any sort of match on it ? If we were looking for - * TCP flags, then NO match. If not, then match (which should - * satisfy the "short" class too). - */ - if (err && (fin->fin_p == IPPROTO_TCP)) { - if (fin->fin_flx & FI_SHORT) - return !(ft->ftu_tcpf | ft->ftu_tcpfm); - /* - * Match the flags ? If not, abort this match. - */ - if (ft->ftu_tcpfm && - ft->ftu_tcpf != (fin->fin_tcpf & ft->ftu_tcpfm)) { - FR_DEBUG(("f. %#x & %#x != %#x\n", fin->fin_tcpf, - ft->ftu_tcpfm, ft->ftu_tcpf)); - err = 0; - } - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ipfcheck */ -/* Returns: int - 0 == match, 1 == no match */ -/* Parameters: fin(I) - pointer to packet information */ -/* fr(I) - pointer to filter rule */ -/* portcmp(I) - flag indicating whether to attempt matching on */ -/* TCP/UDP port data. */ -/* */ -/* Check to see if a packet matches an IPFilter rule. Checks of addresses, */ -/* port numbers, etc, for "standard" IPFilter rules are all orchestrated in */ -/* this function. */ -/* ------------------------------------------------------------------------ */ -static INLINE int fr_ipfcheck(fin, fr, portcmp) -fr_info_t *fin; -frentry_t *fr; -int portcmp; -{ - u_32_t *ld, *lm, *lip; - fripf_t *fri; - fr_ip_t *fi; - int i; - - fi = &fin->fin_fi; - fri = fr->fr_ipf; - lip = (u_32_t *)fi; - lm = (u_32_t *)&fri->fri_mip; - ld = (u_32_t *)&fri->fri_ip; - - /* - * first 32 bits to check coversion: - * IP version, TOS, TTL, protocol - */ - i = ((*lip & *lm) != *ld); - FR_DEBUG(("0. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - if (i) - return 1; - - /* - * Next 32 bits is a constructed bitmask indicating which IP options - * are present (if any) in this packet. - */ - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("1. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - if (i) - return 1; - - lip++, lm++, ld++; - /* - * Unrolled loops (4 each, for 32 bits) for address checks. - */ - /* - * Check the source address. - */ -#ifdef IPFILTER_LOOKUP - if (fr->fr_satype == FRI_LOOKUP) { - i = (*fr->fr_srcfunc)(fr->fr_srcptr, fi->fi_v, lip); - if (i == -1) - return 1; - lip += 3; - lm += 3; - ld += 3; - } else { -#endif - i = ((*lip & *lm) != *ld); - FR_DEBUG(("2a. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - if (fi->fi_v == 6) { - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("2b. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("2c. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("2d. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - } else { - lip += 3; - lm += 3; - ld += 3; - } -#ifdef IPFILTER_LOOKUP - } -#endif - i ^= (fr->fr_flags & FR_NOTSRCIP) >> 6; - if (i) - return 1; - - /* - * Check the destination address. - */ - lip++, lm++, ld++; -#ifdef IPFILTER_LOOKUP - if (fr->fr_datype == FRI_LOOKUP) { - i = (*fr->fr_dstfunc)(fr->fr_dstptr, fi->fi_v, lip); - if (i == -1) - return 1; - lip += 3; - lm += 3; - ld += 3; - } else { -#endif - i = ((*lip & *lm) != *ld); - FR_DEBUG(("3a. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - if (fi->fi_v == 6) { - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("3b. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("3c. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("3d. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - } else { - lip += 3; - lm += 3; - ld += 3; - } -#ifdef IPFILTER_LOOKUP - } -#endif - i ^= (fr->fr_flags & FR_NOTDSTIP) >> 7; - if (i) - return 1; - /* - * IP addresses matched. The next 32bits contains: - * mast of old IP header security & authentication bits. - */ - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("4. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - - /* - * Next we have 32 bits of packet flags. - */ - lip++, lm++, ld++; - i |= ((*lip & *lm) != *ld); - FR_DEBUG(("5. %#08x & %#08x != %#08x\n", - *lip, *lm, *ld)); - - if (i == 0) { - /* - * If a fragment, then only the first has what we're - * looking for here... - */ - if (portcmp) { - if (!fr_tcpudpchk(fin, &fr->fr_tuc)) - i = 1; - } else { - if (fr->fr_dcmp || fr->fr_scmp || - fr->fr_tcpf || fr->fr_tcpfm) - i = 1; - if (fr->fr_icmpm || fr->fr_icmp) { - if (((fi->fi_p != IPPROTO_ICMP) && - (fi->fi_p != IPPROTO_ICMPV6)) || - fin->fin_off || (fin->fin_dlen < 2)) - i = 1; - else if ((fin->fin_data[0] & fr->fr_icmpm) != - fr->fr_icmp) { - FR_DEBUG(("i. %#x & %#x != %#x\n", - fin->fin_data[0], - fr->fr_icmpm, fr->fr_icmp)); - i = 1; - } - } - } - } - return i; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_scanlist */ -/* Returns: int - result flags of scanning filter list */ -/* Parameters: fin(I) - pointer to packet information */ -/* pass(I) - default result to return for filtering */ -/* */ -/* Check the input/output list of rules for a match to the current packet. */ -/* If a match is found, the value of fr_flags from the rule becomes the */ -/* return value and fin->fin_fr points to the matched rule. */ -/* */ -/* This function may be called recusively upto 16 times (limit inbuilt.) */ -/* When unwinding, it should finish up with fin_depth as 0. */ -/* */ -/* Could be per interface, but this gets real nasty when you don't have, */ -/* or can't easily change, the kernel source code to . */ -/* ------------------------------------------------------------------------ */ -int fr_scanlist(fin, pass) -fr_info_t *fin; -u_32_t pass; -{ - int rulen, portcmp, off, logged, skip; - struct frentry *fr, *fnext; - u_32_t passt; - - /* - * Do not allow nesting deeper than 16 levels. - */ - if (fin->fin_depth >= 16) - return pass; - - fr = fin->fin_fr; - - /* - * If there are no rules in this list, return now. - */ - if (fr == NULL) - return pass; - - skip = 0; - logged = 0; - portcmp = 0; - fin->fin_depth++; - fin->fin_fr = NULL; - off = fin->fin_off; - - if ((fin->fin_flx & FI_TCPUDP) && (fin->fin_dlen > 3) && !off) - portcmp = 1; - - for (rulen = 0; fr; fr = fnext, rulen++) { - fnext = fr->fr_next; - if (skip != 0) { - FR_VERBOSE(("%d (%#x)\n", skip, fr->fr_flags)); - skip--; - continue; - } - - /* - * In all checks below, a null (zero) value in the - * filter struture is taken to mean a wildcard. - * - * check that we are working for the right interface - */ -#ifdef _KERNEL - if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp) - continue; -#else - if (opts & (OPT_VERBOSE|OPT_DEBUG)) - printf("\n"); - FR_VERBOSE(("%c", FR_ISSKIP(pass) ? 's' : - FR_ISPASS(pass) ? 'p' : - FR_ISACCOUNT(pass) ? 'A' : - FR_ISAUTH(pass) ? 'a' : - (pass & FR_NOMATCH) ? 'n' :'b')); - if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp) - continue; - FR_VERBOSE((":i")); -#endif - - switch (fr->fr_type) - { - case FR_T_IPF : - case FR_T_IPF|FR_T_BUILTIN : - if (fr_ipfcheck(fin, fr, portcmp)) - continue; - break; -#if defined(IPFILTER_BPF) - case FR_T_BPFOPC : - case FR_T_BPFOPC|FR_T_BUILTIN : - { - u_char *mc; - int wlen; - - if (*fin->fin_mp == NULL) - continue; - if (fin->fin_v != fr->fr_v) - continue; - mc = (u_char *)fin->fin_m; - wlen = fin->fin_dlen + fin->fin_hlen; - if (!bpf_filter(fr->fr_data, mc, wlen, 0)) - continue; - break; - } -#endif - case FR_T_CALLFUNC|FR_T_BUILTIN : - { - frentry_t *f; - - f = (*fr->fr_func)(fin, &pass); - if (f != NULL) - fr = f; - else - continue; - break; - } - default : - break; - } - - if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) { - if (fin->fin_nattag == NULL) - continue; - if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) == 0) - continue; - } - FR_VERBOSE(("=%s.%d *", fr->fr_group, rulen)); - - passt = fr->fr_flags; - - /* - * Allowing a rule with the "keep state" flag set to match - * packets that have been tagged "out of window" by the TCP - * state tracking is foolish as the attempt to add a new - * state entry to the table will fail. - */ - if ((passt & FR_KEEPSTATE) && (fin->fin_flx & FI_OOW)) - continue; - - /* - * If the rule is a "call now" rule, then call the function - * in the rule, if it exists and use the results from that. - * If the function pointer is bad, just make like we ignore - * it, except for increasing the hit counter. - */ - if ((passt & FR_CALLNOW) != 0) { - ATOMIC_INC64(fr->fr_hits); - if ((fr->fr_func != NULL) && - (fr->fr_func != (ipfunc_t)-1)) { - frentry_t *frs; - - frs = fin->fin_fr; - fin->fin_fr = fr; - fr = (*fr->fr_func)(fin, &passt); - if (fr == NULL) { - fin->fin_fr = frs; - continue; - } - passt = fr->fr_flags; - fin->fin_fr = fr; - } - } else { - fin->fin_fr = fr; - } - -#ifdef IPFILTER_LOG - /* - * Just log this packet... - */ - if ((passt & FR_LOGMASK) == FR_LOG) { - if (ipflog(fin, passt) == -1) { - if (passt & FR_LOGORBLOCK) { - passt &= ~FR_CMDMASK; - passt |= FR_BLOCK|FR_QUICK; - } - ATOMIC_INCL(frstats[fin->fin_out].fr_skip); - } - ATOMIC_INCL(frstats[fin->fin_out].fr_pkl); - logged = 1; - } -#endif /* IPFILTER_LOG */ - fr->fr_bytes += (U_QUAD_T)fin->fin_plen; - if (FR_ISSKIP(passt)) - skip = fr->fr_arg; - else if ((passt & FR_LOGMASK) != FR_LOG) - pass = passt; - if (passt & (FR_RETICMP|FR_FAKEICMP)) - fin->fin_icode = fr->fr_icode; - FR_DEBUG(("pass %#x\n", pass)); - ATOMIC_INC64(fr->fr_hits); - fin->fin_rule = rulen; - (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); - if (fr->fr_grp != NULL) { - fin->fin_fr = *fr->fr_grp; - pass = fr_scanlist(fin, pass); - if (fin->fin_fr == NULL) { - fin->fin_rule = rulen; - (void) strncpy(fin->fin_group, fr->fr_group, - FR_GROUPLEN); - fin->fin_fr = fr; - } - if (fin->fin_flx & FI_DONTCACHE) - logged = 1; - } - if (pass & FR_QUICK) - break; - } - if (logged) - fin->fin_flx |= FI_DONTCACHE; - fin->fin_depth--; - return pass; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_acctpkt */ -/* Returns: frentry_t* - always returns NULL */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(IO) - pointer to current/new filter decision (unused) */ -/* */ -/* Checks a packet against accounting rules, if there are any for the given */ -/* IP protocol version. */ -/* */ -/* N.B.: this function returns NULL to match the prototype used by other */ -/* functions called from the IPFilter "mainline" in fr_check(). */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_acctpkt(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - char group[FR_GROUPLEN]; - frentry_t *fr, *frsave; - u_32_t pass, rulen; - - passp = passp; -#ifdef USE_INET6 - if (fin->fin_v == 6) - fr = ipacct6[fin->fin_out][fr_active]; - else -#endif - fr = ipacct[fin->fin_out][fr_active]; - - if (fr != NULL) { - frsave = fin->fin_fr; - bcopy(fin->fin_group, group, FR_GROUPLEN); - rulen = fin->fin_rule; - fin->fin_fr = fr; - pass = fr_scanlist(fin, FR_NOMATCH); - if (FR_ISACCOUNT(pass)) { - ATOMIC_INCL(frstats[0].fr_acct); - } - fin->fin_fr = frsave; - bcopy(group, fin->fin_group, FR_GROUPLEN); - fin->fin_rule = rulen; - } - return NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_firewall */ -/* Returns: frentry_t* - returns pointer to matched rule, if no matches */ -/* were found, returns NULL. */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(IO) - pointer to current/new filter decision (unused) */ -/* */ -/* Applies an appropriate set of firewall rules to the packet, to see if */ -/* there are any matches. The first check is to see if a match can be seen */ -/* in the cache. If not, then search an appropriate list of rules. Once a */ -/* matching rule is found, take any appropriate actions as defined by the */ -/* rule - except logging. */ -/* ------------------------------------------------------------------------ */ -static frentry_t *fr_firewall(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - frentry_t *fr; - fr_info_t *fc; - u_32_t pass; - int out; - - out = fin->fin_out; - pass = *passp; - - /* - * If a packet is found in the auth table, then skip checking - * the access lists for permission but we do need to consider - * the result as if it were from the ACL's. - */ - fc = &frcache[out][CACHE_HASH(fin)]; - if (!bcmp((char *)fin, (char *)fc, FI_CSIZE)) { - /* - * copy cached data so we can unlock the mutex - * earlier. - */ - bcopy((char *)fc, (char *)fin, FI_COPYSIZE); - ATOMIC_INCL(frstats[out].fr_chit); - if ((fr = fin->fin_fr) != NULL) { - ATOMIC_INC64(fr->fr_hits); - pass = fr->fr_flags; - } - } else { -#ifdef USE_INET6 - if (fin->fin_v == 6) - fin->fin_fr = ipfilter6[out][fr_active]; - else -#endif - fin->fin_fr = ipfilter[out][fr_active]; - if (fin->fin_fr != NULL) - pass = fr_scanlist(fin, fr_pass); - if (((pass & FR_KEEPSTATE) == 0) && - ((fin->fin_flx & FI_DONTCACHE) == 0)) - bcopy((char *)fin, (char *)fc, FI_COPYSIZE); - if ((pass & FR_NOMATCH)) { - ATOMIC_INCL(frstats[out].fr_nom); - } - fr = fin->fin_fr; - } - - /* - * Apply packets per second rate-limiting to a rule as required. - */ - if ((fr != NULL) && (fr->fr_pps != 0) && - !ppsratecheck(&fr->fr_lastpkt, &fr->fr_curpps, fr->fr_pps)) { - pass &= ~(FR_CMDMASK|FR_DUP|FR_RETICMP|FR_RETRST); - pass |= FR_BLOCK; - ATOMIC_INCL(frstats[out].fr_ppshit); - } - - /* - * If we fail to add a packet to the authorization queue, then we - * drop the packet later. However, if it was added then pretend - * we've dropped it already. - */ - if (FR_ISAUTH(pass)) { - if (fr_newauth(fin->fin_m, fin) != 0) { -#ifdef _KERNEL - fin->fin_m = *fin->fin_mp = NULL; -#else - ; -#endif - fin->fin_error = 0; - } else - fin->fin_error = ENOSPC; - } - - if ((fr != NULL) && (fr->fr_func != NULL) && - (fr->fr_func != (ipfunc_t)-1) && !(pass & FR_CALLNOW)) - (void) (*fr->fr_func)(fin, &pass); - - /* - * If a rule is a pre-auth rule, check again in the list of rules - * loaded for authenticated use. It does not particulary matter - * if this search fails because a "preauth" result, from a rule, - * is treated as "not a pass", hence the packet is blocked. - */ - if (FR_ISPREAUTH(pass)) { - if ((fin->fin_fr = ipauth) != NULL) - pass = fr_scanlist(fin, fr_pass); - } - - /* - * If the rule has "keep frag" and the packet is actually a fragment, - * then create a fragment state entry. - */ - if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) { - if (fin->fin_flx & FI_FRAG) { - if (fr_newfrag(fin, pass) == -1) { - ATOMIC_INCL(frstats[out].fr_bnfr); - } else { - ATOMIC_INCL(frstats[out].fr_nfr); - } - } else { - ATOMIC_INCL(frstats[out].fr_cfr); - } - } - - /* - * Finally, if we've asked to track state for this packet, set it up. - */ - if ((pass & FR_KEEPSTATE) && !(fin->fin_flx & FI_STATE)) { - if (fr_addstate(fin, NULL, 0) != NULL) { - ATOMIC_INCL(frstats[out].fr_ads); - } else { - ATOMIC_INCL(frstats[out].fr_bads); - if (FR_ISPASS(pass)) { - pass &= ~FR_CMDMASK; - pass |= FR_BLOCK; - } - } - } - - fr = fin->fin_fr; - - if (passp != NULL) - *passp = pass; - - return fr; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_check */ -/* Returns: int - 0 == packet allowed through, */ -/* User space: */ -/* -1 == packet blocked */ -/* 1 == packet not matched */ -/* -2 == requires authantication */ -/* Kernel: */ -/* > 0 == filter error # for packet */ -/* Parameters: ip(I) - pointer to start of IPv4/6 packet */ -/* hlen(I) - length of header */ -/* ifp(I) - pointer to interface this packet is on */ -/* out(I) - 0 == packet going in, 1 == packet going out */ -/* mp(IO) - pointer to caller's buffer pointer that holds this */ -/* IP packet. */ -/* Solaris & HP-UX ONLY : */ -/* qpi(I) - pointer to STREAMS queue information for this */ -/* interface & direction. */ -/* */ -/* fr_check() is the master function for all IPFilter packet processing. */ -/* It orchestrates: Network Address Translation (NAT), checking for packet */ -/* authorisation (or pre-authorisation), presence of related state info., */ -/* generating log entries, IP packet accounting, routing of packets as */ -/* directed by firewall rules and of course whether or not to allow the */ -/* packet to be further processed by the kernel. */ -/* */ -/* For packets blocked, the contents of "mp" will be NULL'd and the buffer */ -/* freed. Packets passed may be returned with the pointer pointed to by */ -/* by "mp" changed to a new buffer. */ -/* ------------------------------------------------------------------------ */ -int fr_check(ip, hlen, ifp, out -#if defined(_KERNEL) && defined(MENTAT) -, qif, mp) -void *qif; -#else -, mp) -#endif -mb_t **mp; -ip_t *ip; -int hlen; -void *ifp; -int out; -{ - /* - * The above really sucks, but short of writing a diff - */ - fr_info_t frinfo; - fr_info_t *fin = &frinfo; - u_32_t pass = fr_pass; - frentry_t *fr = NULL; - int v = IP_V(ip); - mb_t *mc = NULL; - mb_t *m; -#ifdef USE_INET6 - ip6_t *ip6; -#endif - - /* - * The first part of fr_check() deals with making sure that what goes - * into the filtering engine makes some sense. Information about the - * the packet is distilled, collected into a fr_info_t structure and - * the an attempt to ensure the buffer the packet is in is big enough - * to hold all the required packet headers. - */ -#ifdef _KERNEL -# ifdef MENTAT - qpktinfo_t *qpi = qif; - - if ((u_int)ip & 0x3) - return 2; -# endif - - READ_ENTER(&ipf_global); - - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_global); - return 0; - } - - bzero((char *)fin, sizeof(*fin)); - -# ifdef MENTAT - if (qpi->qpi_flags & QF_GROUP) - fin->fin_flx |= FI_MBCAST; - m = qpi->qpi_m; - fin->fin_qfm = m; - fin->fin_qpi = qpi; -# else /* MENTAT */ - - m = *mp; - -# if defined(M_MCAST) - if ((m->m_flags & M_MCAST) != 0) - fin->fin_flx |= FI_MBCAST|FI_MULTICAST; -# endif -# if defined(M_BCAST) - if ((m->m_flags & M_BCAST) != 0) - fin->fin_flx |= FI_MBCAST|FI_BROADCAST; -# endif -# ifdef M_CANFASTFWD - /* - * XXX For now, IP Filter and fast-forwarding of cached flows - * XXX are mutually exclusive. Eventually, IP Filter should - * XXX get a "can-fast-forward" filter rule. - */ - m->m_flags &= ~M_CANFASTFWD; -# endif /* M_CANFASTFWD */ -# ifdef CSUM_DELAY_DATA - /* - * disable delayed checksums. - */ - if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { - in_delayed_cksum(m); - m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; - } -# endif /* CSUM_DELAY_DATA */ -# endif /* MENTAT */ -#else - READ_ENTER(&ipf_global); - - bzero((char *)fin, sizeof(*fin)); - m = *mp; -#endif /* _KERNEL */ - - fin->fin_v = v; - fin->fin_m = m; - fin->fin_ip = ip; - fin->fin_mp = mp; - fin->fin_out = out; - fin->fin_ifp = ifp; - fin->fin_error = ENETUNREACH; - fin->fin_hlen = (u_short )hlen; - fin->fin_dp = (char *)ip + hlen; - - fin->fin_ipoff = (char *)ip - MTOD(m, char *); - -#ifdef USE_INET6 - if (v == 6) { - ATOMIC_INCL(frstats[out].fr_ipv6); - /* - * Jumbo grams are quite likely too big for internal buffer - * structures to handle comfortably, for now, so just drop - * them. - */ - ip6 = (ip6_t *)ip; - fin->fin_plen = ntohs(ip6->ip6_plen); - if (fin->fin_plen == 0) { - pass = FR_BLOCK|FR_NOMATCH; - goto filtered; - } - fin->fin_plen += sizeof(ip6_t); - } else -#endif - { -#if (OpenBSD >= 200311) && defined(_KERNEL) - ip->ip_len = ntohs(ip->ip_len); - ip->ip_off = ntohs(ip->ip_off); -#endif - fin->fin_plen = ip->ip_len; - } - - if (fr_makefrip(hlen, ip, fin) == -1) - goto finished; - - /* - * For at least IPv6 packets, if a m_pullup() fails then this pointer - * becomes NULL and so we have no packet to free. - */ - if (*fin->fin_mp == NULL) - goto finished; - - if (!out) { - if (v == 4) { -#ifdef _KERNEL - if (fr_chksrc && !fr_verifysrc(fin)) { - ATOMIC_INCL(frstats[0].fr_badsrc); - fin->fin_flx |= FI_BADSRC; - } -#endif - if (fin->fin_ip->ip_ttl < fr_minttl) { - ATOMIC_INCL(frstats[0].fr_badttl); - fin->fin_flx |= FI_LOWTTL; - } - } -#ifdef USE_INET6 - else if (v == 6) { - ip6 = (ip6_t *)ip; - if (ip6->ip6_hlim < fr_minttl) { - ATOMIC_INCL(frstats[0].fr_badttl); - fin->fin_flx |= FI_LOWTTL; - } - } -#endif - } - - if (fin->fin_flx & FI_SHORT) { - ATOMIC_INCL(frstats[out].fr_short); - } - - READ_ENTER(&ipf_mutex); - - /* - * Check auth now. This, combined with the check below to see if apass - * is 0 is to ensure that we don't count the packet twice, which can - * otherwise occur when we reprocess it. As it is, we only count it - * after it has no auth. table matchup. This also stops NAT from - * occuring until after the packet has been auth'd. - */ - fr = fr_checkauth(fin, &pass); - if (!out) { - if (fr_checknatin(fin, &pass) == -1) { - RWLOCK_EXIT(&ipf_mutex); - goto finished; - } - } - if (!out) - (void) fr_acctpkt(fin, NULL); - - if (fr == NULL) - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) == FI_FRAG) - fr = fr_knownfrag(fin, &pass); - if (fr == NULL) - fr = fr_checkstate(fin, &pass); - - if ((pass & FR_NOMATCH) || (fr == NULL)) - fr = fr_firewall(fin, &pass); - - fin->fin_fr = fr; - - /* - * Only count/translate packets which will be passed on, out the - * interface. - */ - if (out && FR_ISPASS(pass)) { - (void) fr_acctpkt(fin, NULL); - - if (fr_checknatout(fin, &pass) == -1) { - RWLOCK_EXIT(&ipf_mutex); - goto finished; - } else if ((fr_update_ipid != 0) && (v == 4)) { - if (fr_updateipid(fin) == -1) { - ATOMIC_INCL(frstats[1].fr_ipud); - pass &= ~FR_CMDMASK; - pass |= FR_BLOCK; - } else { - ATOMIC_INCL(frstats[0].fr_ipud); - } - } - } - -#ifdef IPFILTER_LOG - if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) { - (void) fr_dolog(fin, &pass); - } -#endif - - if (fin->fin_state != NULL) - fr_statederef(fin, (ipstate_t **)&fin->fin_state); - - if (fin->fin_nat != NULL) - fr_natderef((nat_t **)&fin->fin_nat); - - /* - * Only allow FR_DUP to work if a rule matched - it makes no sense to - * set FR_DUP as a "default" as there are no instructions about where - * to send the packet. Use fin_m here because it may have changed - * (without an update of 'm') in prior processing. - */ - if ((fr != NULL) && (pass & FR_DUP)) { - mc = M_DUPLICATE(fin->fin_m); - } - - if (pass & (FR_RETRST|FR_RETICMP)) { - /* - * Should we return an ICMP packet to indicate error - * status passing through the packet filter ? - * WARNING: ICMP error packets AND TCP RST packets should - * ONLY be sent in repsonse to incoming packets. Sending them - * in response to outbound packets can result in a panic on - * some operating systems. - */ - if (!out) { - if (pass & FR_RETICMP) { - int dst; - - if ((pass & FR_RETMASK) == FR_FAKEICMP) - dst = 1; - else - dst = 0; - (void) fr_send_icmp_err(ICMP_UNREACH, fin, dst); - ATOMIC_INCL(frstats[0].fr_ret); - } else if (((pass & FR_RETMASK) == FR_RETRST) && - !(fin->fin_flx & FI_SHORT)) { - if (fr_send_reset(fin) == 0) { - ATOMIC_INCL(frstats[1].fr_ret); - } - } - } else { - if (pass & FR_RETRST) - fin->fin_error = ECONNRESET; - } - } - - /* - * If we didn't drop off the bottom of the list of rules (and thus - * the 'current' rule fr is not NULL), then we may have some extra - * instructions about what to do with a packet. - * Once we're finished return to our caller, freeing the packet if - * we are dropping it (* BSD ONLY *). - * Reassign m from fin_m as we may have a new buffer, now. - */ -#if defined(USE_INET6) || (defined(__sgi) && defined(_KERNEL)) -filtered: -#endif - m = fin->fin_m; - - if (fr != NULL) { - frdest_t *fdp; - - fdp = &fr->fr_tifs[fin->fin_rev]; - - if (!out && (pass & FR_FASTROUTE)) { - /* - * For fastroute rule, no destioation interface defined - * so pass NULL as the frdest_t parameter - */ - (void) fr_fastroute(m, mp, fin, NULL); - m = *mp = NULL; - } else if ((fdp->fd_ifp != NULL) && - (fdp->fd_ifp != (struct ifnet *)-1)) { - /* this is for to rules: */ - (void) fr_fastroute(m, mp, fin, fdp); - m = *mp = NULL; - } - - /* - * Generate a duplicated packet. - */ - if (mc != NULL) - (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif); - } - - /* - * This late because the likes of fr_fastroute() use fin_fr. - */ - RWLOCK_EXIT(&ipf_mutex); - -finished: - if (!FR_ISPASS(pass)) { - ATOMIC_INCL(frstats[out].fr_block); - if (*mp != NULL) { - FREE_MB_T(*mp); - m = *mp = NULL; - } - } else { - ATOMIC_INCL(frstats[out].fr_pass); -#if defined(_KERNEL) && defined(__sgi) - if ((fin->fin_hbuf != NULL) && - (mtod(fin->fin_m, struct ip *) != fin->fin_ip)) { - COPYBACK(m, 0, fin->fin_plen, fin->fin_hbuf); - } -#endif - } - - RWLOCK_EXIT(&ipf_global); -#ifdef _KERNEL -# if OpenBSD >= 200311 - if (FR_ISPASS(pass) && (v == 4)) { - ip = fin->fin_ip; - ip->ip_len = ntohs(ip->ip_len); - ip->ip_off = ntohs(ip->ip_off); - } -# endif - return (FR_ISPASS(pass)) ? 0 : fin->fin_error; -#else /* _KERNEL */ - FR_VERBOSE(("fin_flx %#x pass %#x ", fin->fin_flx, pass)); - if ((pass & FR_NOMATCH) != 0) - return 1; - - if ((pass & FR_RETMASK) != 0) - switch (pass & FR_RETMASK) - { - case FR_RETRST : - return 3; - case FR_RETICMP : - return 4; - case FR_FAKEICMP : - return 5; - } - - switch (pass & FR_CMDMASK) - { - case FR_PASS : - return 0; - case FR_BLOCK : - return -1; - case FR_AUTH : - return -2; - case FR_ACCOUNT : - return -3; - case FR_PREAUTH : - return -4; - } - return 2; -#endif /* _KERNEL */ -} - - -#ifdef IPFILTER_LOG -/* ------------------------------------------------------------------------ */ -/* Function: fr_dolog */ -/* Returns: frentry_t* - returns contents of fin_fr (no change made) */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(IO) - pointer to current/new filter decision (unused) */ -/* */ -/* Checks flags set to see how a packet should be logged, if it is to be */ -/* logged. Adjust statistics based on its success or not. */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_dolog(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - u_32_t pass; - int out; - - out = fin->fin_out; - pass = *passp; - - if ((fr_flags & FF_LOGNOMATCH) && (pass & FR_NOMATCH)) { - pass |= FF_LOGNOMATCH; - ATOMIC_INCL(frstats[out].fr_npkl); - goto logit; - } else if (((pass & FR_LOGMASK) == FR_LOGP) || - (FR_ISPASS(pass) && (fr_flags & FF_LOGPASS))) { - if ((pass & FR_LOGMASK) != FR_LOGP) - pass |= FF_LOGPASS; - ATOMIC_INCL(frstats[out].fr_ppkl); - goto logit; - } else if (((pass & FR_LOGMASK) == FR_LOGB) || - (FR_ISBLOCK(pass) && (fr_flags & FF_LOGBLOCK))) { - if ((pass & FR_LOGMASK) != FR_LOGB) - pass |= FF_LOGBLOCK; - ATOMIC_INCL(frstats[out].fr_bpkl); -logit: - if (ipflog(fin, pass) == -1) { - ATOMIC_INCL(frstats[out].fr_skip); - - /* - * If the "or-block" option has been used then - * block the packet if we failed to log it. - */ - if ((pass & FR_LOGORBLOCK) && - FR_ISPASS(pass)) { - pass &= ~FR_CMDMASK; - pass |= FR_BLOCK; - } - } - *passp = pass; - } - - return fin->fin_fr; -} -#endif /* IPFILTER_LOG */ - - -/* ------------------------------------------------------------------------ */ -/* Function: ipf_cksum */ -/* Returns: u_short - IP header checksum */ -/* Parameters: addr(I) - pointer to start of buffer to checksum */ -/* len(I) - length of buffer in bytes */ -/* */ -/* Calculate the two's complement 16 bit checksum of the buffer passed. */ -/* */ -/* N.B.: addr should be 16bit aligned. */ -/* ------------------------------------------------------------------------ */ -u_short ipf_cksum(addr, len) -u_short *addr; -int len; -{ - u_32_t sum = 0; - - for (sum = 0; len > 1; len -= 2) - sum += *addr++; - - /* mop up an odd byte, if necessary */ - if (len == 1) - sum += *(u_char *)addr; - - /* - * add back carry outs from top 16 bits to low 16 bits - */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - return (u_short)(~sum); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_cksum */ -/* Returns: u_short - layer 4 checksum */ -/* Parameters: m(I ) - pointer to buffer holding packet */ -/* ip(I) - pointer to IP header */ -/* l4proto(I) - protocol to caclulate checksum for */ -/* l4hdr(I) - pointer to layer 4 header */ -/* */ -/* Calculates the TCP checksum for the packet held in "m", using the data */ -/* in the IP header "ip" to seed it. */ -/* */ -/* NB: This function assumes we've pullup'd enough for all of the IP header */ -/* and the TCP header. We also assume that data blocks aren't allocated in */ -/* odd sizes. */ -/* */ -/* Expects ip_len to be in host byte order when called. */ -/* ------------------------------------------------------------------------ */ -u_short fr_cksum(m, ip, l4proto, l4hdr) -mb_t *m; -ip_t *ip; -int l4proto; -void *l4hdr; -{ - u_short *sp, slen, sumsave, l4hlen, *csump; - u_int sum, sum2; - int hlen; -#ifdef USE_INET6 - ip6_t *ip6; -#endif - - csump = NULL; - sumsave = 0; - l4hlen = 0; - sp = NULL; - slen = 0; - hlen = 0; - sum = 0; - - /* - * Add up IP Header portion - */ -#ifdef USE_INET6 - if (IP_V(ip) == 4) { -#endif - hlen = IP_HL(ip) << 2; - slen = ip->ip_len - hlen; - sum = htons((u_short)l4proto); - sum += htons(slen); - sp = (u_short *)&ip->ip_src; - sum += *sp++; /* ip_src */ - sum += *sp++; - sum += *sp++; /* ip_dst */ - sum += *sp++; -#ifdef USE_INET6 - } else if (IP_V(ip) == 6) { - ip6 = (ip6_t *)ip; - hlen = sizeof(*ip6); - slen = ntohs(ip6->ip6_plen); - sum = htons((u_short)l4proto); - sum += htons(slen); - sp = (u_short *)&ip6->ip6_src; - sum += *sp++; /* ip6_src */ - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; /* ip6_dst */ - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - sum += *sp++; - } -#endif - - switch (l4proto) - { - case IPPROTO_UDP : - csump = &((udphdr_t *)l4hdr)->uh_sum; - l4hlen = sizeof(udphdr_t); - break; - - case IPPROTO_TCP : - csump = &((tcphdr_t *)l4hdr)->th_sum; - l4hlen = sizeof(tcphdr_t); - break; - case IPPROTO_ICMP : - csump = &((icmphdr_t *)l4hdr)->icmp_cksum; - l4hlen = 4; - sum = 0; - break; - default : - break; - } - - if (csump != NULL) { - sumsave = *csump; - *csump = 0; - } - - l4hlen = l4hlen; /* LINT */ - -#ifdef _KERNEL -# ifdef MENTAT - { - void *rp = m->b_rptr; - - if ((unsigned char *)ip > m->b_rptr && (unsigned char *)ip < m->b_wptr) - m->b_rptr = (u_char *)ip; - sum2 = ip_cksum(m, hlen, sum); /* hlen == offset */ - m->b_rptr = rp; - sum2 = (u_short)(~sum2 & 0xffff); - } -# else /* MENTAT */ -# if defined(BSD) || defined(sun) -# if BSD >= 199103 - m->m_data += hlen; -# else - m->m_off += hlen; -# endif - m->m_len -= hlen; - sum2 = in_cksum(m, slen); - m->m_len += hlen; -# if BSD >= 199103 - m->m_data -= hlen; -# else - m->m_off -= hlen; -# endif - /* - * Both sum and sum2 are partial sums, so combine them together. - */ - sum += ~sum2 & 0xffff; - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum2 = ~sum & 0xffff; -# else /* defined(BSD) || defined(sun) */ -{ - union { - u_char c[2]; - u_short s; - } bytes; - u_short len = ip->ip_len; -# if defined(__sgi) - int add; -# endif - - /* - * Add up IP Header portion - */ - if (sp != (u_short *)l4hdr) - sp = (u_short *)l4hdr; - - switch (l4proto) - { - case IPPROTO_UDP : - sum += *sp++; /* sport */ - sum += *sp++; /* dport */ - sum += *sp++; /* udp length */ - sum += *sp++; /* checksum */ - break; - - case IPPROTO_TCP : - sum += *sp++; /* sport */ - sum += *sp++; /* dport */ - sum += *sp++; /* seq */ - sum += *sp++; - sum += *sp++; /* ack */ - sum += *sp++; - sum += *sp++; /* off */ - sum += *sp++; /* win */ - sum += *sp++; /* checksum */ - sum += *sp++; /* urp */ - break; - case IPPROTO_ICMP : - sum = *sp++; /* type/code */ - sum += *sp++; /* checksum */ - break; - } - -# ifdef __sgi - /* - * In case we had to copy the IP & TCP header out of mbufs, - * skip over the mbuf bits which are the header - */ - if ((caddr_t)ip != mtod(m, caddr_t)) { - hlen = (caddr_t)sp - (caddr_t)ip; - while (hlen) { - add = MIN(hlen, m->m_len); - sp = (u_short *)(mtod(m, caddr_t) + add); - hlen -= add; - if (add == m->m_len) { - m = m->m_next; - if (!hlen) { - if (!m) - break; - sp = mtod(m, u_short *); - } - PANIC((!m),("fr_cksum(1): not enough data")); - } - } - } -# endif - - len -= (l4hlen + hlen); - if (len <= 0) - goto nodata; - - while (len > 1) { - if (((caddr_t)sp - mtod(m, caddr_t)) >= m->m_len) { - m = m->m_next; - PANIC((!m),("fr_cksum(2): not enough data")); - sp = mtod(m, u_short *); - } - if (((caddr_t)(sp + 1) - mtod(m, caddr_t)) > m->m_len) { - bytes.c[0] = *(u_char *)sp; - m = m->m_next; - PANIC((!m),("fr_cksum(3): not enough data")); - sp = mtod(m, u_short *); - bytes.c[1] = *(u_char *)sp; - sum += bytes.s; - sp = (u_short *)((u_char *)sp + 1); - } - if ((u_long)sp & 1) { - bcopy((char *)sp++, (char *)&bytes.s, sizeof(bytes.s)); - sum += bytes.s; - } else - sum += *sp++; - len -= 2; - } - - if (len != 0) - sum += ntohs(*(u_char *)sp << 8); -nodata: - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum2 = (u_short)(~sum & 0xffff); -} -# endif /* defined(BSD) || defined(sun) */ -# endif /* MENTAT */ -#else /* _KERNEL */ - for (; slen > 1; slen -= 2) - sum += *sp++; - if (slen) - sum += ntohs(*(u_char *)sp << 8); - while (sum > 0xffff) - sum = (sum & 0xffff) + (sum >> 16); - sum2 = (u_short)(~sum & 0xffff); -#endif /* _KERNEL */ - if (csump != NULL) - *csump = sumsave; - return sum2; -} - - -#if defined(_KERNEL) && ( ((BSD < 199103) && !defined(MENTAT)) || \ - defined(__sgi) ) && !defined(linux) -/* - * Copyright (c) 1982, 1986, 1988, 1991, 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. - * - * @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94 - * Id: fil.c,v 2.243.2.57 2005/03/28 10:47:50 darrenr Exp - */ -/* - * Copy data from an mbuf chain starting "off" bytes from the beginning, - * continuing for "len" bytes, into the indicated buffer. - */ -void -m_copydata(m, off, len, cp) - mb_t *m; - int off; - int len; - caddr_t cp; -{ - unsigned count; - - if (off < 0 || len < 0) - panic("m_copydata"); - while (off > 0) { - if (m == 0) - panic("m_copydata"); - if (off < m->m_len) - break; - off -= m->m_len; - m = m->m_next; - } - while (len > 0) { - if (m == 0) - panic("m_copydata"); - count = MIN(m->m_len - off, len); - bcopy(mtod(m, caddr_t) + off, cp, count); - len -= count; - cp += count; - off = 0; - m = m->m_next; - } -} - - -/* - * Copy data from a buffer back into the indicated mbuf chain, - * starting "off" bytes from the beginning, extending the mbuf - * chain if necessary. - */ -void -m_copyback(m0, off, len, cp) - struct mbuf *m0; - int off; - int len; - caddr_t cp; -{ - int mlen; - struct mbuf *m = m0, *n; - int totlen = 0; - - if (m0 == 0) - return; - while (off > (mlen = m->m_len)) { - off -= mlen; - totlen += mlen; - if (m->m_next == 0) { - n = m_getclr(M_DONTWAIT, m->m_type); - if (n == 0) - goto out; - n->m_len = min(MLEN, len + off); - m->m_next = n; - } - m = m->m_next; - } - while (len > 0) { - mlen = min (m->m_len - off, len); - bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen); - cp += mlen; - len -= mlen; - mlen += off; - off = 0; - totlen += mlen; - if (len == 0) - break; - if (m->m_next == 0) { - n = m_get(M_DONTWAIT, m->m_type); - if (n == 0) - break; - n->m_len = min(MLEN, len); - m->m_next = n; - } - m = m->m_next; - } -out: -#if 0 - if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen)) - m->m_pkthdr.len = totlen; -#endif - return; -} -#endif /* (_KERNEL) && ( ((BSD < 199103) && !MENTAT) || __sgi) */ - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_findgroup */ -/* Returns: frgroup_t * - NULL = group not found, else pointer to group */ -/* Parameters: group(I) - group name to search for */ -/* unit(I) - device to which this group belongs */ -/* set(I) - which set of rules (inactive/inactive) this is */ -/* fgpp(O) - pointer to place to store pointer to the pointer */ -/* to where to add the next (last) group or where */ -/* to delete group from. */ -/* */ -/* Search amongst the defined groups for a particular group number. */ -/* ------------------------------------------------------------------------ */ -frgroup_t *fr_findgroup(group, unit, set, fgpp) -char *group; -minor_t unit; -int set; -frgroup_t ***fgpp; -{ - frgroup_t *fg, **fgp; - - /* - * Which list of groups to search in is dependant on which list of - * rules are being operated on. - */ - fgp = &ipfgroups[unit][set]; - - while ((fg = *fgp) != NULL) { - if (strncmp(group, fg->fg_name, FR_GROUPLEN) == 0) - break; - else - fgp = &fg->fg_next; - } - if (fgpp != NULL) - *fgpp = fgp; - return fg; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_addgroup */ -/* Returns: frgroup_t * - NULL == did not create group, */ -/* != NULL == pointer to the group */ -/* Parameters: num(I) - group number to add */ -/* head(I) - rule pointer that is using this as the head */ -/* flags(I) - rule flags which describe the type of rule it is */ -/* unit(I) - device to which this group will belong to */ -/* set(I) - which set of rules (inactive/inactive) this is */ -/* Write Locks: ipf_mutex */ -/* */ -/* Add a new group head, or if it already exists, increase the reference */ -/* count to it. */ -/* ------------------------------------------------------------------------ */ -frgroup_t *fr_addgroup(group, head, flags, unit, set) -char *group; -void *head; -u_32_t flags; -minor_t unit; -int set; -{ - frgroup_t *fg, **fgp; - u_32_t gflags; - - if (group == NULL) - return NULL; - - if (unit == IPL_LOGIPF && *group == '\0') - return NULL; - - fgp = NULL; - gflags = flags & FR_INOUT; - - fg = fr_findgroup(group, unit, set, &fgp); - if (fg != NULL) { - if (fg->fg_flags == 0) - fg->fg_flags = gflags; - else if (gflags != fg->fg_flags) - return NULL; - fg->fg_ref++; - return fg; - } - KMALLOC(fg, frgroup_t *); - if (fg != NULL) { - fg->fg_head = head; - fg->fg_start = NULL; - fg->fg_next = *fgp; - bcopy(group, fg->fg_name, FR_GROUPLEN); - fg->fg_flags = gflags; - fg->fg_ref = 1; - *fgp = fg; - } - return fg; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_delgroup */ -/* Returns: Nil */ -/* Parameters: group(I) - group name to delete */ -/* unit(I) - device to which this group belongs */ -/* set(I) - which set of rules (inactive/inactive) this is */ -/* Write Locks: ipf_mutex */ -/* */ -/* Attempt to delete a group head. */ -/* Only do this when its reference count reaches 0. */ -/* ------------------------------------------------------------------------ */ -void fr_delgroup(group, unit, set) -char *group; -minor_t unit; -int set; -{ - frgroup_t *fg, **fgp; - - fg = fr_findgroup(group, unit, set, &fgp); - if (fg == NULL) - return; - - fg->fg_ref--; - if (fg->fg_ref == 0) { - *fgp = fg->fg_next; - KFREE(fg); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_getrulen */ -/* Returns: frentry_t * - NULL == not found, else pointer to rule n */ -/* Parameters: unit(I) - device for which to count the rule's number */ -/* flags(I) - which set of rules to find the rule in */ -/* group(I) - group name */ -/* n(I) - rule number to find */ -/* */ -/* Find rule # n in group # g and return a pointer to it. Return NULl if */ -/* group # g doesn't exist or there are less than n rules in the group. */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_getrulen(unit, group, n) -int unit; -char *group; -u_32_t n; -{ - frentry_t *fr; - frgroup_t *fg; - - fg = fr_findgroup(group, unit, fr_active, NULL); - if (fg == NULL) - return NULL; - for (fr = fg->fg_head; fr && n; fr = fr->fr_next, n--) - ; - if (n != 0) - return NULL; - return fr; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_rulen */ -/* Returns: int - >= 0 - rule number, -1 == search failed */ -/* Parameters: unit(I) - device for which to count the rule's number */ -/* fr(I) - pointer to rule to match */ -/* */ -/* Return the number for a rule on a specific filtering device. */ -/* ------------------------------------------------------------------------ */ -int fr_rulen(unit, fr) -int unit; -frentry_t *fr; -{ - frentry_t *fh; - frgroup_t *fg; - u_32_t n = 0; - - if (fr == NULL) - return -1; - fg = fr_findgroup(fr->fr_group, unit, fr_active, NULL); - if (fg == NULL) - return -1; - for (fh = fg->fg_head; fh; n++, fh = fh->fr_next) - if (fh == fr) - break; - if (fh == NULL) - return -1; - return n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frflushlist */ -/* Returns: int - >= 0 - number of flushed rules */ -/* Parameters: set(I) - which set of rules (inactive/inactive) this is */ -/* unit(I) - device for which to flush rules */ -/* flags(I) - which set of rules to flush */ -/* nfreedp(O) - pointer to int where flush count is stored */ -/* listp(I) - pointer to list to flush pointer */ -/* Write Locks: ipf_mutex */ -/* */ -/* Recursively flush rules from the list, descending groups as they are */ -/* encountered. if a rule is the head of a group and it has lost all its */ -/* group members, then also delete the group reference. nfreedp is needed */ -/* to store the accumulating count of rules removed, whereas the returned */ -/* value is just the number removed from the current list. The latter is */ -/* needed to correctly adjust reference counts on rules that define groups. */ -/* */ -/* NOTE: Rules not loaded from user space cannot be flushed. */ -/* ------------------------------------------------------------------------ */ -static int frflushlist(set, unit, nfreedp, listp) -int set; -minor_t unit; -int *nfreedp; -frentry_t **listp; -{ - int freed = 0, i; - frentry_t *fp; - - while ((fp = *listp) != NULL) { - if ((fp->fr_type & FR_T_BUILTIN) || - !(fp->fr_flags & FR_COPIED)) { - listp = &fp->fr_next; - continue; - } - *listp = fp->fr_next; - if (fp->fr_grp != NULL) { - i = frflushlist(set, unit, nfreedp, fp->fr_grp); - fp->fr_ref -= i; - } - - if (fp->fr_grhead != NULL) { - fr_delgroup(fp->fr_grhead, unit, set); - *fp->fr_grhead = '\0'; - } - - ASSERT(fp->fr_ref > 0); - fp->fr_next = NULL; - if (fr_derefrule(&fp) == 0) - freed++; - } - *nfreedp += freed; - return freed; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: frflush */ -/* Returns: int - >= 0 - number of flushed rules */ -/* Parameters: unit(I) - device for which to flush rules */ -/* flags(I) - which set of rules to flush */ -/* */ -/* Calls flushlist() for all filter rules (accounting, firewall - both IPv4 */ -/* and IPv6) as defined by the value of flags. */ -/* ------------------------------------------------------------------------ */ -int frflush(unit, proto, flags) -minor_t unit; -int proto, flags; -{ - int flushed = 0, set; - - WRITE_ENTER(&ipf_mutex); - bzero((char *)frcache, sizeof(frcache)); - - set = fr_active; - if ((flags & FR_INACTIVE) == FR_INACTIVE) - set = 1 - set; - - if (flags & FR_OUTQUE) { - if (proto == 0 || proto == 6) { - (void) frflushlist(set, unit, - &flushed, &ipfilter6[1][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct6[1][set]); - } - if (proto == 0 || proto == 4) { - (void) frflushlist(set, unit, - &flushed, &ipfilter[1][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct[1][set]); - } - } - if (flags & FR_INQUE) { - if (proto == 0 || proto == 6) { - (void) frflushlist(set, unit, - &flushed, &ipfilter6[0][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct6[0][set]); - } - if (proto == 0 || proto == 4) { - (void) frflushlist(set, unit, - &flushed, &ipfilter[0][set]); - (void) frflushlist(set, unit, - &flushed, &ipacct[0][set]); - } - } - RWLOCK_EXIT(&ipf_mutex); - - if (unit == IPL_LOGIPF) { - int tmp; - - tmp = frflush(IPL_LOGCOUNT, proto, flags); - if (tmp >= 0) - flushed += tmp; - } - return flushed; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: memstr */ -/* Returns: char * - NULL if failed, != NULL pointer to matching bytes */ -/* Parameters: src(I) - pointer to byte sequence to match */ -/* dst(I) - pointer to byte sequence to search */ -/* slen(I) - match length */ -/* dlen(I) - length available to search in */ -/* */ -/* Search dst for a sequence of bytes matching those at src and extend for */ -/* slen bytes. */ -/* ------------------------------------------------------------------------ */ -char *memstr(src, dst, slen, dlen) -char *src, *dst; -int slen, dlen; -{ - char *s = NULL; - - while (dlen >= slen) { - if (bcmp(src, dst, slen) == 0) { - s = dst; - break; - } - dst++; - dlen--; - } - return s; -} -/* ------------------------------------------------------------------------ */ -/* Function: fr_fixskip */ -/* Returns: Nil */ -/* Parameters: listp(IO) - pointer to start of list with skip rule */ -/* rp(I) - rule added/removed with skip in it. */ -/* addremove(I) - adjustment (-1/+1) to make to skip count, */ -/* depending on whether a rule was just added */ -/* or removed. */ -/* */ -/* Adjust all the rules in a list which would have skip'd past the position */ -/* where we are inserting to skip to the right place given the change. */ -/* ------------------------------------------------------------------------ */ -void fr_fixskip(listp, rp, addremove) -frentry_t **listp, *rp; -int addremove; -{ - int rules, rn; - frentry_t *fp; - - rules = 0; - for (fp = *listp; (fp != NULL) && (fp != rp); fp = fp->fr_next) - rules++; - - if (!fp) - return; - - for (rn = 0, fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++) - if (FR_ISSKIP(fp->fr_flags) && (rn + fp->fr_arg >= rules)) - fp->fr_arg += addremove; -} - - -#ifdef _KERNEL -/* ------------------------------------------------------------------------ */ -/* Function: count4bits */ -/* Returns: int - >= 0 - number of consecutive bits in input */ -/* Parameters: ip(I) - 32bit IP address */ -/* */ -/* IPv4 ONLY */ -/* count consecutive 1's in bit mask. If the mask generated by counting */ -/* consecutive 1's is different to that passed, return -1, else return # */ -/* of bits. */ -/* ------------------------------------------------------------------------ */ -int count4bits(ip) -u_32_t ip; -{ - u_32_t ipn; - int cnt = 0, i, j; - - ip = ipn = ntohl(ip); - for (i = 32; i; i--, ipn *= 2) - if (ipn & 0x80000000) - cnt++; - else - break; - ipn = 0; - for (i = 32, j = cnt; i; i--, j--) { - ipn *= 2; - if (j > 0) - ipn++; - } - if (ipn == ip) - return cnt; - return -1; -} - - -# if 0 -/* ------------------------------------------------------------------------ */ -/* Function: count6bits */ -/* Returns: int - >= 0 - number of consecutive bits in input */ -/* Parameters: msk(I) - pointer to start of IPv6 bitmask */ -/* */ -/* IPv6 ONLY */ -/* count consecutive 1's in bit mask. */ -/* ------------------------------------------------------------------------ */ -int count6bits(msk) -u_32_t *msk; -{ - int i = 0, k; - u_32_t j; - - for (k = 3; k >= 0; k--) - if (msk[k] == 0xffffffff) - i += 32; - else { - for (j = msk[k]; j; j <<= 1) - if (j & 0x80000000) - i++; - } - return i; -} -# endif -#endif /* _KERNEL */ - - -/* ------------------------------------------------------------------------ */ -/* Function: frsynclist */ -/* Returns: void */ -/* Parameters: fr(I) - start of filter list to sync interface names for */ -/* ifp(I) - interface pointer for limiting sync lookups */ -/* Write Locks: ipf_mutex */ -/* */ -/* Walk through a list of filter rules and resolve any interface names into */ -/* pointers. Where dynamic addresses are used, also update the IP address */ -/* used in the rule. The interface pointer is used to limit the lookups to */ -/* a specific set of matching names if it is non-NULL. */ -/* ------------------------------------------------------------------------ */ -static void frsynclist(fr, ifp) -frentry_t *fr; -void *ifp; -{ - frdest_t *fdp; - int v, i; - - for (; fr; fr = fr->fr_next) { - v = fr->fr_v; - - /* - * Lookup all the interface names that are part of the rule. - */ - for (i = 0; i < 4; i++) { - if ((ifp != NULL) && (fr->fr_ifas[i] != ifp)) - continue; - fr->fr_ifas[i] = fr_resolvenic(fr->fr_ifnames[i], v); - } - - if (fr->fr_type == FR_T_IPF) { - if (fr->fr_satype != FRI_NORMAL && - fr->fr_satype != FRI_LOOKUP) { - (void)fr_ifpaddr(v, fr->fr_satype, - fr->fr_ifas[fr->fr_sifpidx], - &fr->fr_src, &fr->fr_smsk); - } - if (fr->fr_datype != FRI_NORMAL && - fr->fr_datype != FRI_LOOKUP) { - (void)fr_ifpaddr(v, fr->fr_datype, - fr->fr_ifas[fr->fr_difpidx], - &fr->fr_dst, &fr->fr_dmsk); - } - } - - fdp = &fr->fr_tifs[0]; - if ((ifp == NULL) || (fdp->fd_ifp == ifp)) - fr_resolvedest(fdp, v); - - fdp = &fr->fr_tifs[1]; - if ((ifp == NULL) || (fdp->fd_ifp == ifp)) - fr_resolvedest(fdp, v); - - fdp = &fr->fr_dif; - if ((ifp == NULL) || (fdp->fd_ifp == ifp)) { - fr_resolvedest(fdp, v); - - fr->fr_flags &= ~FR_DUP; - if ((fdp->fd_ifp != (void *)-1) && - (fdp->fd_ifp != NULL)) - fr->fr_flags |= FR_DUP; - } - -#ifdef IPFILTER_LOOKUP - if (fr->fr_type == FR_T_IPF && fr->fr_satype == FRI_LOOKUP && - fr->fr_srcptr == NULL) { - fr->fr_srcptr = fr_resolvelookup(fr->fr_srctype, - fr->fr_srcnum, - &fr->fr_srcfunc); - } - if (fr->fr_type == FR_T_IPF && fr->fr_datype == FRI_LOOKUP && - fr->fr_dstptr == NULL) { - fr->fr_dstptr = fr_resolvelookup(fr->fr_dsttype, - fr->fr_dstnum, - &fr->fr_dstfunc); - } -#endif - } -} - - -#ifdef _KERNEL -/* ------------------------------------------------------------------------ */ -/* Function: frsync */ -/* Returns: void */ -/* Parameters: Nil */ -/* */ -/* frsync() is called when we suspect that the interface list or */ -/* information about interfaces (like IP#) has changed. Go through all */ -/* filter rules, NAT entries and the state table and check if anything */ -/* needs to be changed/updated. */ -/* ------------------------------------------------------------------------ */ -void frsync(ifp) -void *ifp; -{ - int i; - -# if !SOLARIS - fr_natsync(ifp); - fr_statesync(ifp); -# endif - - WRITE_ENTER(&ipf_mutex); - frsynclist(ipacct[0][fr_active], ifp); - frsynclist(ipacct[1][fr_active], ifp); - frsynclist(ipfilter[0][fr_active], ifp); - frsynclist(ipfilter[1][fr_active], ifp); - frsynclist(ipacct6[0][fr_active], ifp); - frsynclist(ipacct6[1][fr_active], ifp); - frsynclist(ipfilter6[0][fr_active], ifp); - frsynclist(ipfilter6[1][fr_active], ifp); - - for (i = 0; i < IPL_LOGSIZE; i++) { - frgroup_t *g; - - for (g = ipfgroups[i][0]; g != NULL; g = g->fg_next) - frsynclist(g->fg_start, ifp); - for (g = ipfgroups[i][1]; g != NULL; g = g->fg_next) - frsynclist(g->fg_start, ifp); - } - RWLOCK_EXIT(&ipf_mutex); -} - - -/* - * In the functions below, bcopy() is called because the pointer being - * copied _from_ in this instance is a pointer to a char buf (which could - * end up being unaligned) and on the kernel's local stack. - */ -/* ------------------------------------------------------------------------ */ -/* Function: copyinptr */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: src(I) - pointer to the source address */ -/* dst(I) - destination address */ -/* size(I) - number of bytes to copy */ -/* */ -/* Copy a block of data in from user space, given a pointer to the pointer */ -/* to start copying from (src) and a pointer to where to store it (dst). */ -/* NB: src - pointer to user space pointer, dst - kernel space pointer */ -/* ------------------------------------------------------------------------ */ -int copyinptr(src, dst, size) -void *src, *dst; -size_t size; -{ - caddr_t ca; - int err; - -# if SOLARIS - err = COPYIN(src, (caddr_t)&ca, sizeof(ca)); - if (err != 0) - return err; -# else - bcopy(src, (caddr_t)&ca, sizeof(ca)); -# endif - err = COPYIN(ca, dst, size); - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: copyoutptr */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: src(I) - pointer to the source address */ -/* dst(I) - destination address */ -/* size(I) - number of bytes to copy */ -/* */ -/* Copy a block of data out to user space, given a pointer to the pointer */ -/* to start copying from (src) and a pointer to where to store it (dst). */ -/* NB: src - kernel space pointer, dst - pointer to user space pointer. */ -/* ------------------------------------------------------------------------ */ -int copyoutptr(src, dst, size) -void *src, *dst; -size_t size; -{ - caddr_t ca; - int err; - -# if SOLARIS - err = COPYIN(dst, (caddr_t)&ca, sizeof(ca)); - if (err != 0) - return err; -# else - bcopy(dst, (caddr_t)&ca, sizeof(ca)); -# endif - err = COPYOUT(src, ca, size); - return err; -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_lock */ -/* Returns: (void) */ -/* Parameters: data(I) - pointer to lock value to set */ -/* lockp(O) - pointer to location to store old lock value */ -/* */ -/* Get the new value for the lock integer, set it and return the old value */ -/* in *lockp. */ -/* ------------------------------------------------------------------------ */ -void fr_lock(data, lockp) -caddr_t data; -int *lockp; -{ - int arg; - - BCOPYIN(data, (caddr_t)&arg, sizeof(arg)); - BCOPYOUT((caddr_t)lockp, data, sizeof(*lockp)); - *lockp = arg; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_getstat */ -/* Returns: Nil */ -/* Parameters: fiop(I) - pointer to ipfilter stats structure */ -/* */ -/* Stores a copy of current pointers, counters, etc, in the friostat */ -/* structure. */ -/* ------------------------------------------------------------------------ */ -void fr_getstat(fiop) -friostat_t *fiop; -{ - int i, j; - - bcopy((char *)frstats, (char *)fiop->f_st, sizeof(filterstats_t) * 2); - fiop->f_locks[IPL_LOGSTATE] = fr_state_lock; - fiop->f_locks[IPL_LOGNAT] = fr_nat_lock; - fiop->f_locks[IPL_LOGIPF] = fr_frag_lock; - fiop->f_locks[IPL_LOGAUTH] = fr_auth_lock; - - for (i = 0; i < 2; i++) - for (j = 0; j < 2; j++) { - fiop->f_ipf[i][j] = ipfilter[i][j]; - fiop->f_acct[i][j] = ipacct[i][j]; - fiop->f_ipf6[i][j] = ipfilter6[i][j]; - fiop->f_acct6[i][j] = ipacct6[i][j]; - } - - fiop->f_ticks = fr_ticks; - fiop->f_active = fr_active; - fiop->f_froute[0] = fr_frouteok[0]; - fiop->f_froute[1] = fr_frouteok[1]; - - fiop->f_running = fr_running; - for (i = 0; i < IPL_LOGSIZE; i++) { - fiop->f_groups[i][0] = ipfgroups[i][0]; - fiop->f_groups[i][1] = ipfgroups[i][1]; - } -#ifdef IPFILTER_LOG - fiop->f_logging = 1; -#else - fiop->f_logging = 0; -#endif - fiop->f_defpass = fr_pass; - fiop->f_features = fr_features; - (void) strncpy(fiop->f_version, ipfilter_version, - sizeof(fiop->f_version)); -} - - -#ifdef USE_INET6 -int icmptoicmp6types[ICMP_MAXTYPE+1] = { - ICMP6_ECHO_REPLY, /* 0: ICMP_ECHOREPLY */ - -1, /* 1: UNUSED */ - -1, /* 2: UNUSED */ - ICMP6_DST_UNREACH, /* 3: ICMP_UNREACH */ - -1, /* 4: ICMP_SOURCEQUENCH */ - ND_REDIRECT, /* 5: ICMP_REDIRECT */ - -1, /* 6: UNUSED */ - -1, /* 7: UNUSED */ - ICMP6_ECHO_REQUEST, /* 8: ICMP_ECHO */ - -1, /* 9: UNUSED */ - -1, /* 10: UNUSED */ - ICMP6_TIME_EXCEEDED, /* 11: ICMP_TIMXCEED */ - ICMP6_PARAM_PROB, /* 12: ICMP_PARAMPROB */ - -1, /* 13: ICMP_TSTAMP */ - -1, /* 14: ICMP_TSTAMPREPLY */ - -1, /* 15: ICMP_IREQ */ - -1, /* 16: ICMP_IREQREPLY */ - -1, /* 17: ICMP_MASKREQ */ - -1, /* 18: ICMP_MASKREPLY */ -}; - - -int icmptoicmp6unreach[ICMP_MAX_UNREACH] = { - ICMP6_DST_UNREACH_ADDR, /* 0: ICMP_UNREACH_NET */ - ICMP6_DST_UNREACH_ADDR, /* 1: ICMP_UNREACH_HOST */ - -1, /* 2: ICMP_UNREACH_PROTOCOL */ - ICMP6_DST_UNREACH_NOPORT, /* 3: ICMP_UNREACH_PORT */ - -1, /* 4: ICMP_UNREACH_NEEDFRAG */ - ICMP6_DST_UNREACH_NOTNEIGHBOR, /* 5: ICMP_UNREACH_SRCFAIL */ - ICMP6_DST_UNREACH_ADDR, /* 6: ICMP_UNREACH_NET_UNKNOWN */ - ICMP6_DST_UNREACH_ADDR, /* 7: ICMP_UNREACH_HOST_UNKNOWN */ - -1, /* 8: ICMP_UNREACH_ISOLATED */ - ICMP6_DST_UNREACH_ADMIN, /* 9: ICMP_UNREACH_NET_PROHIB */ - ICMP6_DST_UNREACH_ADMIN, /* 10: ICMP_UNREACH_HOST_PROHIB */ - -1, /* 11: ICMP_UNREACH_TOSNET */ - -1, /* 12: ICMP_UNREACH_TOSHOST */ - ICMP6_DST_UNREACH_ADMIN, /* 13: ICMP_UNREACH_ADMIN_PROHIBIT */ -}; -int icmpreplytype6[ICMP6_MAXTYPE + 1]; -#endif - -int icmpreplytype4[ICMP_MAXTYPE + 1]; - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_matchicmpqueryreply */ -/* Returns: int - 1 if "icmp" is a valid reply to "ic" else 0. */ -/* Parameters: v(I) - IP protocol version (4 or 6) */ -/* ic(I) - ICMP information */ -/* icmp(I) - ICMP packet header */ -/* rev(I) - direction (0 = forward/1 = reverse) of packet */ -/* */ -/* Check if the ICMP packet defined by the header pointed to by icmp is a */ -/* reply to one as described by what's in ic. If it is a match, return 1, */ -/* else return 0 for no match. */ -/* ------------------------------------------------------------------------ */ -int fr_matchicmpqueryreply(v, ic, icmp, rev) -int v; -icmpinfo_t *ic; -icmphdr_t *icmp; -int rev; -{ - int ictype; - - ictype = ic->ici_type; - - if (v == 4) { - /* - * If we matched its type on the way in, then when going out - * it will still be the same type. - */ - if ((!rev && (icmp->icmp_type == ictype)) || - (rev && (icmpreplytype4[ictype] == icmp->icmp_type))) { - if (icmp->icmp_type != ICMP_ECHOREPLY) - return 1; - if (icmp->icmp_id == ic->ici_id) - return 1; - } - } -#ifdef USE_INET6 - else if (v == 6) { - if ((!rev && (icmp->icmp_type == ictype)) || - (rev && (icmpreplytype6[ictype] == icmp->icmp_type))) { - if (icmp->icmp_type != ICMP6_ECHO_REPLY) - return 1; - if (icmp->icmp_id == ic->ici_id) - return 1; - } - } -#endif - return 0; -} - - -#ifdef IPFILTER_LOOKUP -/* ------------------------------------------------------------------------ */ -/* Function: fr_resolvelookup */ -/* Returns: void * - NULL = failure, else success. */ -/* Parameters: type(I) - type of lookup these parameters are for. */ -/* number(I) - table number to use when searching */ -/* funcptr(IO) - pointer to pointer for storing IP address */ -/* searching function. */ -/* */ -/* Search for the "table" number passed in amongst those configured for */ -/* that particular type. If the type is recognised then the function to */ -/* call to do the IP address search will be change, regardless of whether */ -/* or not the "table" number exists. */ -/* ------------------------------------------------------------------------ */ -static void *fr_resolvelookup(type, number, funcptr) -u_int type, number; -lookupfunc_t *funcptr; -{ - char name[FR_GROUPLEN]; - iphtable_t *iph; - ip_pool_t *ipo; - void *ptr; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%u", number); -#else - (void) sprintf(name, "%u", number); -#endif - - READ_ENTER(&ip_poolrw); - - switch (type) - { - case IPLT_POOL : -# if (defined(__osf__) && defined(_KERNEL)) - ptr = NULL; - *funcptr = NULL; -# else - ipo = ip_pool_find(IPL_LOGIPF, name); - ptr = ipo; - if (ipo != NULL) { - ATOMIC_INC32(ipo->ipo_ref); - } - *funcptr = ip_pool_search; -# endif - break; - case IPLT_HASH : - iph = fr_findhtable(IPL_LOGIPF, name); - ptr = iph; - if (iph != NULL) { - ATOMIC_INC32(iph->iph_ref); - } - *funcptr = fr_iphmfindip; - break; - default: - ptr = NULL; - *funcptr = NULL; - break; - } - RWLOCK_EXIT(&ip_poolrw); - - return ptr; -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: frrequest */ -/* Returns: int - 0 == success, > 0 == errno value */ -/* Parameters: unit(I) - device for which this is for */ -/* req(I) - ioctl command (SIOC*) */ -/* data(I) - pointr to ioctl data */ -/* set(I) - 1 or 0 (filter set) */ -/* makecopy(I) - flag indicating whether data points to a rule */ -/* in kernel space & hence doesn't need copying. */ -/* */ -/* This function handles all the requests which operate on the list of */ -/* filter rules. This includes adding, deleting, insertion. It is also */ -/* responsible for creating groups when a "head" rule is loaded. Interface */ -/* names are resolved here and other sanity checks are made on the content */ -/* of the rule structure being loaded. If a rule has user defined timeouts */ -/* then make sure they are created and initialised before exiting. */ -/* ------------------------------------------------------------------------ */ -int frrequest(unit, req, data, set, makecopy) -int unit; -ioctlcmd_t req; -int set, makecopy; -caddr_t data; -{ - frentry_t frd, *fp, *f, **fprev, **ftail; - int error = 0, in, v; - void *ptr, *uptr; - u_int *p, *pp; - frgroup_t *fg; - char *group; - - fg = NULL; - fp = &frd; - if (makecopy != 0) { - error = fr_inobj(data, fp, IPFOBJ_FRENTRY); - if (error) - return EFAULT; - if ((fp->fr_flags & FR_T_BUILTIN) != 0) - return EINVAL; - fp->fr_ref = 0; - fp->fr_flags |= FR_COPIED; - } else { - fp = (frentry_t *)data; - if ((fp->fr_type & FR_T_BUILTIN) == 0) - return EINVAL; - fp->fr_flags &= ~FR_COPIED; - } - - if (((fp->fr_dsize == 0) && (fp->fr_data != NULL)) || - ((fp->fr_dsize != 0) && (fp->fr_data == NULL))) - return EINVAL; - - v = fp->fr_v; - uptr = fp->fr_data; - - /* - * Only filter rules for IPv4 or IPv6 are accepted. - */ - if (v == 4) - /*EMPTY*/; -#ifdef USE_INET6 - else if (v == 6) - /*EMPTY*/; -#endif - else { - return EINVAL; - } - - /* - * If the rule is being loaded from user space, i.e. we had to copy it - * into kernel space, then do not trust the function pointer in the - * rule. - */ - if ((makecopy == 1) && (fp->fr_func != NULL)) { - if (fr_findfunc(fp->fr_func) == NULL) - return ESRCH; - error = fr_funcinit(fp); - if (error != 0) - return error; - } - - ptr = NULL; - /* - * Check that the group number does exist and that its use (in/out) - * matches what the rule is. - */ - if (!strncmp(fp->fr_grhead, "0", FR_GROUPLEN)) - *fp->fr_grhead = '\0'; - group = fp->fr_group; - if (!strncmp(group, "0", FR_GROUPLEN)) - *group = '\0'; - - if (FR_ISACCOUNT(fp->fr_flags)) - unit = IPL_LOGCOUNT; - - if ((req != (int)SIOCZRLST) && (*group != '\0')) { - fg = fr_findgroup(group, unit, set, NULL); - if (fg == NULL) - return ESRCH; - if (fg->fg_flags == 0) - fg->fg_flags = fp->fr_flags & FR_INOUT; - else if (fg->fg_flags != (fp->fr_flags & FR_INOUT)) - return ESRCH; - } - - in = (fp->fr_flags & FR_INQUE) ? 0 : 1; - - /* - * Work out which rule list this change is being applied to. - */ - ftail = NULL; - fprev = NULL; - if (unit == IPL_LOGAUTH) - fprev = &ipauth; - else if (v == 4) { - if (FR_ISACCOUNT(fp->fr_flags)) - fprev = &ipacct[in][set]; - else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) != 0) - fprev = &ipfilter[in][set]; - } else if (v == 6) { - if (FR_ISACCOUNT(fp->fr_flags)) - fprev = &ipacct6[in][set]; - else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) != 0) - fprev = &ipfilter6[in][set]; - } - if (fprev == NULL) - return ESRCH; - - if (*group != '\0') { - if (!fg && !(fg = fr_findgroup(group, unit, set, NULL))) - return ESRCH; - fprev = &fg->fg_start; - } - - for (f = *fprev; (f = *fprev) != NULL; fprev = &f->fr_next) - if (fp->fr_collect <= f->fr_collect) - break; - ftail = fprev; - - /* - * Copy in extra data for the rule. - */ - if (fp->fr_dsize != 0) { - if (makecopy != 0) { - KMALLOCS(ptr, void *, fp->fr_dsize); - if (!ptr) - return ENOMEM; - error = COPYIN(uptr, ptr, fp->fr_dsize); - } else { - ptr = uptr; - error = 0; - } - if (error != 0) { - KFREES(ptr, fp->fr_dsize); - return ENOMEM; - } - fp->fr_data = ptr; - } else - fp->fr_data = NULL; - - /* - * Perform per-rule type sanity checks of their members. - */ - switch (fp->fr_type & ~FR_T_BUILTIN) - { -#if defined(IPFILTER_BPF) - case FR_T_BPFOPC : - if (fp->fr_dsize == 0) - return EINVAL; - if (!bpf_validate(ptr, fp->fr_dsize/sizeof(struct bpf_insn))) { - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; - } - break; -#endif - case FR_T_IPF : - if (fp->fr_dsize != sizeof(fripf_t)) - return EINVAL; - - /* - * Allowing a rule with both "keep state" and "with oow" is - * pointless because adding a state entry to the table will - * fail with the out of window (oow) flag set. - */ - if ((fp->fr_flags & FR_KEEPSTATE) && (fp->fr_flx & FI_OOW)) - return EINVAL; - - switch (fp->fr_satype) - { - case FRI_BROADCAST : - case FRI_DYNAMIC : - case FRI_NETWORK : - case FRI_NETMASKED : - case FRI_PEERADDR : - if (fp->fr_sifpidx < 0 || fp->fr_sifpidx > 3) { - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; - } - break; -#ifdef IPFILTER_LOOKUP - case FRI_LOOKUP : - fp->fr_srcptr = fr_resolvelookup(fp->fr_srctype, - fp->fr_srcnum, - &fp->fr_srcfunc); - break; -#endif - default : - break; - } - - switch (fp->fr_datype) - { - case FRI_BROADCAST : - case FRI_DYNAMIC : - case FRI_NETWORK : - case FRI_NETMASKED : - case FRI_PEERADDR : - if (fp->fr_difpidx < 0 || fp->fr_difpidx > 3) { - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; - } - break; -#ifdef IPFILTER_LOOKUP - case FRI_LOOKUP : - fp->fr_dstptr = fr_resolvelookup(fp->fr_dsttype, - fp->fr_dstnum, - &fp->fr_dstfunc); - break; -#endif - default : - - break; - } - break; - case FR_T_NONE : - break; - case FR_T_CALLFUNC : - break; - case FR_T_COMPIPF : - break; - default : - if (makecopy && fp->fr_data != NULL) { - KFREES(fp->fr_data, fp->fr_dsize); - } - return EINVAL; - } - - /* - * Lookup all the interface names that are part of the rule. - */ - frsynclist(fp, NULL); - fp->fr_statecnt = 0; - - /* - * Look for an existing matching filter rule, but don't include the - * next or interface pointer in the comparison (fr_next, fr_ifa). - * This elminates rules which are indentical being loaded. Checksum - * the constant part of the filter rule to make comparisons quicker - * (this meaning no pointers are included). - */ - for (fp->fr_cksum = 0, p = (u_int *)&fp->fr_func, pp = &fp->fr_cksum; - p < pp; p++) - fp->fr_cksum += *p; - pp = (u_int *)(fp->fr_caddr + fp->fr_dsize); - for (p = (u_int *)fp->fr_data; p < pp; p++) - fp->fr_cksum += *p; - - WRITE_ENTER(&ipf_mutex); - bzero((char *)frcache, sizeof(frcache)); - - for (; (f = *ftail) != NULL; ftail = &f->fr_next) - if ((fp->fr_cksum == f->fr_cksum) && - (f->fr_dsize == fp->fr_dsize) && - !bcmp((char *)&f->fr_func, - (char *)&fp->fr_func, FR_CMPSIZ) && - (!ptr || !f->fr_data || - !bcmp((char *)ptr, (char *)f->fr_data, f->fr_dsize))) - break; - - /* - * If zero'ing statistics, copy current to caller and zero. - */ - if (req == (ioctlcmd_t)SIOCZRLST) { - if (f == NULL) - error = ESRCH; - else { - /* - * Copy and reduce lock because of impending copyout. - * Well we should, but if we do then the atomicity of - * this call and the correctness of fr_hits and - * fr_bytes cannot be guaranteed. As it is, this code - * only resets them to 0 if they are successfully - * copied out into user space. - */ - bcopy((char *)f, (char *)fp, sizeof(*f)); - /* MUTEX_DOWNGRADE(&ipf_mutex); */ - - /* - * When we copy this rule back out, set the data - * pointer to be what it was in user space. - */ - fp->fr_data = uptr; - error = fr_outobj(data, fp, IPFOBJ_FRENTRY); - - if (error == 0) { - if ((f->fr_dsize != 0) && (uptr != NULL)) - error = COPYOUT(f->fr_data, uptr, - f->fr_dsize); - if (error == 0) { - f->fr_hits = 0; - f->fr_bytes = 0; - } - } - } - - if ((ptr != NULL) && (makecopy != 0)) { - KFREES(ptr, fp->fr_dsize); - } - RWLOCK_EXIT(&ipf_mutex); - return error; - } - - if (!f) { - if (req == (ioctlcmd_t)SIOCINAFR || - req == (ioctlcmd_t)SIOCINIFR) { - ftail = fprev; - if (fp->fr_hits != 0) { - while (--fp->fr_hits && (f = *ftail)) - ftail = &f->fr_next; - } - f = NULL; - ptr = NULL; - error = 0; - } - } - - /* - * Request to remove a rule. - */ - if (req == (ioctlcmd_t)SIOCRMAFR || req == (ioctlcmd_t)SIOCRMIFR) { - if (!f) - error = ESRCH; - else { - /* - * Do not allow activity from user space to interfere - * with rules not loaded that way. - */ - if ((makecopy == 1) && !(f->fr_flags & FR_COPIED)) { - error = EPERM; - goto done; - } - - /* - * Return EBUSY if the rule is being reference by - * something else (eg state information. - */ - if (f->fr_ref > 1) { - error = EBUSY; - goto done; - } -#ifdef IPFILTER_SCAN - if (f->fr_isctag[0] != '\0' && - (f->fr_isc != (struct ipscan *)-1)) - ipsc_detachfr(f); -#endif - if ((fg != NULL) && (fg->fg_head != NULL)) - fg->fg_head->fr_ref--; - if (unit == IPL_LOGAUTH) { - error = fr_preauthcmd(req, f, ftail); - goto done; - } - if (*f->fr_grhead != '\0') - fr_delgroup(f->fr_grhead, unit, set); - fr_fixskip(fprev, f, -1); - *ftail = f->fr_next; - f->fr_next = NULL; - (void)fr_derefrule(&f); - } - } else { - /* - * Not removing, so we must be adding/inserting a rule. - */ - if (f) - error = EEXIST; - else { - if (unit == IPL_LOGAUTH) { - error = fr_preauthcmd(req, fp, ftail); - goto done; - } - if (makecopy) { - KMALLOC(f, frentry_t *); - } else - f = fp; - if (f != NULL) { - if (fg != NULL && fg->fg_head!= NULL ) - fg->fg_head->fr_ref++; - if (fp != f) - bcopy((char *)fp, (char *)f, - sizeof(*f)); - MUTEX_NUKE(&f->fr_lock); - MUTEX_INIT(&f->fr_lock, "filter rule lock"); -#ifdef IPFILTER_SCAN - if (f->fr_isctag[0] != '\0' && - ipsc_attachfr(f)) - f->fr_isc = (struct ipscan *)-1; -#endif - f->fr_hits = 0; - if (makecopy != 0) - f->fr_ref = 1; - f->fr_next = *ftail; - *ftail = f; - if (req == (ioctlcmd_t)SIOCINIFR || - req == (ioctlcmd_t)SIOCINAFR) - fr_fixskip(fprev, f, 1); - f->fr_grp = NULL; - group = f->fr_grhead; - if (*group != '\0') { - fg = fr_addgroup(group, f, f->fr_flags, - unit, set); - if (fg != NULL) - f->fr_grp = &fg->fg_start; - } - } else - error = ENOMEM; - } - } -done: - RWLOCK_EXIT(&ipf_mutex); - if ((ptr != NULL) && (error != 0) && (makecopy != 0)) { - KFREES(ptr, fp->fr_dsize); - } - return (error); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_funcinit */ -/* Returns: int - 0 == success, else ESRCH: cannot resolve rule details */ -/* Parameters: fr(I) - pointer to filter rule */ -/* */ -/* If a rule is a call rule, then check if the function it points to needs */ -/* an init function to be called now the rule has been loaded. */ -/* ------------------------------------------------------------------------ */ -static int fr_funcinit(fr) -frentry_t *fr; -{ - ipfunc_resolve_t *ft; - int err; - - err = ESRCH; - - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) - if (ft->ipfu_addr == fr->fr_func) { - err = 0; - if (ft->ipfu_init != NULL) - err = (*ft->ipfu_init)(fr); - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_findfunc */ -/* Returns: ipfunc_t - pointer to function if found, else NULL */ -/* Parameters: funcptr(I) - function pointer to lookup */ -/* */ -/* Look for a function in the table of known functions. */ -/* ------------------------------------------------------------------------ */ -static ipfunc_t fr_findfunc(funcptr) -ipfunc_t funcptr; -{ - ipfunc_resolve_t *ft; - - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) - if (ft->ipfu_addr == funcptr) - return funcptr; - return NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_resolvefunc */ -/* Returns: int - 0 == success, else error */ -/* Parameters: data(IO) - ioctl data pointer to ipfunc_resolve_t struct */ -/* */ -/* Copy in a ipfunc_resolve_t structure and then fill in the missing field. */ -/* This will either be the function name (if the pointer is set) or the */ -/* function pointer if the name is set. When found, fill in the other one */ -/* so that the entire, complete, structure can be copied back to user space.*/ -/* ------------------------------------------------------------------------ */ -int fr_resolvefunc(data) -void *data; -{ - ipfunc_resolve_t res, *ft; - - BCOPYIN(data, &res, sizeof(res)); - - if (res.ipfu_addr == NULL && res.ipfu_name[0] != '\0') { - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) - if (strncmp(res.ipfu_name, ft->ipfu_name, - sizeof(res.ipfu_name)) == 0) { - res.ipfu_addr = ft->ipfu_addr; - res.ipfu_init = ft->ipfu_init; - if (COPYOUT(&res, data, sizeof(res)) != 0) - return EFAULT; - return 0; - } - } - if (res.ipfu_addr != NULL && res.ipfu_name[0] == '\0') { - for (ft = fr_availfuncs; ft->ipfu_addr != NULL; ft++) - if (ft->ipfu_addr == res.ipfu_addr) { - (void) strncpy(res.ipfu_name, ft->ipfu_name, - sizeof(res.ipfu_name)); - res.ipfu_init = ft->ipfu_init; - if (COPYOUT(&res, data, sizeof(res)) != 0) - return EFAULT; - return 0; - } - } - return ESRCH; -} - - -#if !defined(_KERNEL) || (!defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__FreeBSD__)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version < 490000)) || \ - (defined(__NetBSD__) && (__NetBSD_Version__ < 105000000)) || \ - (defined(__OpenBSD__) && (OpenBSD < 200006)) -/* - * From: NetBSD - * ppsratecheck(): packets (or events) per second limitation. - */ -int -ppsratecheck(lasttime, curpps, maxpps) - struct timeval *lasttime; - int *curpps; - int maxpps; /* maximum pps allowed */ -{ - struct timeval tv, delta; - int rv; - - GETKTIME(&tv); - - delta.tv_sec = tv.tv_sec - lasttime->tv_sec; - delta.tv_usec = tv.tv_usec - lasttime->tv_usec; - if (delta.tv_usec < 0) { - delta.tv_sec--; - delta.tv_usec += 1000000; - } - - /* - * check for 0,0 is so that the message will be seen at least once. - * if more than one second have passed since the last update of - * lasttime, reset the counter. - * - * we do increment *curpps even in *curpps < maxpps case, as some may - * try to use *curpps for stat purposes as well. - */ - if ((lasttime->tv_sec == 0 && lasttime->tv_usec == 0) || - delta.tv_sec >= 1) { - *lasttime = tv; - *curpps = 0; - rv = 1; - } else if (maxpps < 0) - rv = 1; - else if (*curpps < maxpps) - rv = 1; - else - rv = 0; - *curpps = *curpps + 1; - - return (rv); -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_derefrule */ -/* Returns: int - 0 == rule freed up, else rule not freed */ -/* Parameters: fr(I) - pointer to filter rule */ -/* */ -/* Decrement the reference counter to a rule by one. If it reaches zero, */ -/* free it and any associated storage space being used by it. */ -/* ------------------------------------------------------------------------ */ -int fr_derefrule(frp) -frentry_t **frp; -{ - frentry_t *fr; - - fr = *frp; - - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref--; - if (fr->fr_ref == 0) { - MUTEX_EXIT(&fr->fr_lock); - MUTEX_DESTROY(&fr->fr_lock); - -#ifdef IPFILTER_LOOKUP - if (fr->fr_type == FR_T_IPF && fr->fr_satype == FRI_LOOKUP) - ip_lookup_deref(fr->fr_srctype, fr->fr_srcptr); - if (fr->fr_type == FR_T_IPF && fr->fr_datype == FRI_LOOKUP) - ip_lookup_deref(fr->fr_dsttype, fr->fr_dstptr); -#endif - - if (fr->fr_dsize) { - KFREES(fr->fr_data, fr->fr_dsize); - } - if ((fr->fr_flags & FR_COPIED) != 0) { - KFREE(fr); - return 0; - } - return 1; - } else { - MUTEX_EXIT(&fr->fr_lock); - } - *frp = NULL; - return -1; -} - - -#ifdef IPFILTER_LOOKUP -/* ------------------------------------------------------------------------ */ -/* Function: fr_grpmapinit */ -/* Returns: int - 0 == success, else ESRCH because table entry not found*/ -/* Parameters: fr(I) - pointer to rule to find hash table for */ -/* */ -/* Looks for group hash table fr_arg and stores a pointer to it in fr_ptr. */ -/* fr_ptr is later used by fr_srcgrpmap and fr_dstgrpmap. */ -/* ------------------------------------------------------------------------ */ -static int fr_grpmapinit(fr) -frentry_t *fr; -{ - char name[FR_GROUPLEN]; - iphtable_t *iph; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%d", fr->fr_arg); -#else - (void) sprintf(name, "%d", fr->fr_arg); -#endif - iph = fr_findhtable(IPL_LOGIPF, name); - if (iph == NULL) - return ESRCH; - if ((iph->iph_flags & FR_INOUT) != (fr->fr_flags & FR_INOUT)) - return ESRCH; - fr->fr_ptr = iph; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_srcgrpmap */ -/* Returns: frentry_t * - pointer to "new last matching" rule or NULL */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(IO) - pointer to current/new filter decision (unused) */ -/* */ -/* Look for a rule group head in a hash table, using the source address as */ -/* the key, and descend into that group and continue matching rules against */ -/* the packet. */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_srcgrpmap(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - frgroup_t *fg; - void *rval; - - rval = fr_iphmfindgroup(fin->fin_fr->fr_ptr, &fin->fin_src); - if (rval == NULL) - return NULL; - - fg = rval; - fin->fin_fr = fg->fg_start; - (void) fr_scanlist(fin, *passp); - return fin->fin_fr; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_dstgrpmap */ -/* Returns: frentry_t * - pointer to "new last matching" rule or NULL */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(IO) - pointer to current/new filter decision (unused) */ -/* */ -/* Look for a rule group head in a hash table, using the destination */ -/* address as the key, and descend into that group and continue matching */ -/* rules against the packet. */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_dstgrpmap(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - frgroup_t *fg; - void *rval; - - rval = fr_iphmfindgroup(fin->fin_fr->fr_ptr, &fin->fin_dst); - if (rval == NULL) - return NULL; - - fg = rval; - fin->fin_fr = fg->fg_start; - (void) fr_scanlist(fin, *passp); - return fin->fin_fr; -} -#endif /* IPFILTER_LOOKUP */ - -/* - * Queue functions - * =============== - * These functions manage objects on queues for efficient timeouts. There are - * a number of system defined queues as well as user defined timeouts. It is - * expected that a lock is held in the domain in which the queue belongs - * (i.e. either state or NAT) when calling any of these functions that prevents - * fr_freetimeoutqueue() from being called at the same time as any other. - */ - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_addtimeoutqueue */ -/* Returns: struct ifqtq * - NULL if malloc fails, else pointer to */ -/* timeout queue with given interval. */ -/* Parameters: parent(I) - pointer to pointer to parent node of this list */ -/* of interface queues. */ -/* seconds(I) - timeout value in seconds for this queue. */ -/* */ -/* This routine first looks for a timeout queue that matches the interval */ -/* being requested. If it finds one, increments the reference counter and */ -/* returns a pointer to it. If none are found, it allocates a new one and */ -/* inserts it at the top of the list. */ -/* */ -/* Locking. */ -/* It is assumed that the caller of this function has an appropriate lock */ -/* held (exclusively) in the domain that encompases 'parent'. */ -/* ------------------------------------------------------------------------ */ -ipftq_t *fr_addtimeoutqueue(parent, seconds) -ipftq_t **parent; -u_int seconds; -{ - ipftq_t *ifq; - u_int period; - - period = seconds * IPF_HZ_DIVIDE; - - MUTEX_ENTER(&ipf_timeoutlock); - for (ifq = *parent; ifq != NULL; ifq = ifq->ifq_next) { - if (ifq->ifq_ttl == period) { - /* - * Reset the delete flag, if set, so the structure - * gets reused rather than freed and reallocated. - */ - MUTEX_ENTER(&ifq->ifq_lock); - ifq->ifq_flags &= ~IFQF_DELETE; - ifq->ifq_ref++; - MUTEX_EXIT(&ifq->ifq_lock); - MUTEX_EXIT(&ipf_timeoutlock); - - return ifq; - } - } - - KMALLOC(ifq, ipftq_t *); - if (ifq != NULL) { - ifq->ifq_ttl = period; - ifq->ifq_head = NULL; - ifq->ifq_tail = &ifq->ifq_head; - ifq->ifq_next = *parent; - ifq->ifq_pnext = parent; - ifq->ifq_ref = 1; - ifq->ifq_flags = IFQF_USER; - *parent = ifq; - fr_userifqs++; - MUTEX_NUKE(&ifq->ifq_lock); - MUTEX_INIT(&ifq->ifq_lock, "ipftq mutex"); - } - MUTEX_EXIT(&ipf_timeoutlock); - return ifq; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_deletetimeoutqueue */ -/* Returns: int - new reference count value of the timeout queue */ -/* Parameters: ifq(I) - timeout queue which is losing a reference. */ -/* Locks: ifq->ifq_lock */ -/* */ -/* This routine must be called when we're discarding a pointer to a timeout */ -/* queue object, taking care of the reference counter. */ -/* */ -/* Now that this just sets a DELETE flag, it requires the expire code to */ -/* check the list of user defined timeout queues and call the free function */ -/* below (currently commented out) to stop memory leaking. It is done this */ -/* way because the locking may not be sufficient to safely do a free when */ -/* this function is called. */ -/* ------------------------------------------------------------------------ */ -int fr_deletetimeoutqueue(ifq) -ipftq_t *ifq; -{ - - ifq->ifq_ref--; - if ((ifq->ifq_ref == 0) && ((ifq->ifq_flags & IFQF_USER) != 0)) { - ifq->ifq_flags |= IFQF_DELETE; - } - - return ifq->ifq_ref; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_freetimeoutqueue */ -/* Parameters: ifq(I) - timeout queue which is losing a reference. */ -/* Returns: Nil */ -/* */ -/* Locking: */ -/* It is assumed that the caller of this function has an appropriate lock */ -/* held (exclusively) in the domain that encompases the callers "domain". */ -/* The ifq_lock for this structure should not be held. */ -/* */ -/* Remove a user definde timeout queue from the list of queues it is in and */ -/* tidy up after this is done. */ -/* ------------------------------------------------------------------------ */ -void fr_freetimeoutqueue(ifq) -ipftq_t *ifq; -{ - - - if (((ifq->ifq_flags & IFQF_DELETE) == 0) || (ifq->ifq_ref != 0) || - ((ifq->ifq_flags & IFQF_USER) == 0)) { - printf("fr_freetimeoutqueue(%lx) flags 0x%x ttl %d ref %d\n", - (u_long)ifq, ifq->ifq_flags, ifq->ifq_ttl, - ifq->ifq_ref); - return; - } - - /* - * Remove from its position in the list. - */ - *ifq->ifq_pnext = ifq->ifq_next; - if (ifq->ifq_next != NULL) - ifq->ifq_next->ifq_pnext = ifq->ifq_pnext; - - MUTEX_DESTROY(&ifq->ifq_lock); - fr_userifqs--; - KFREE(ifq); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_deletequeueentry */ -/* Returns: Nil */ -/* Parameters: tqe(I) - timeout queue entry to delete */ -/* ifq(I) - timeout queue to remove entry from */ -/* */ -/* Remove a tail queue entry from its queue and make it an orphan. */ -/* fr_deletetimeoutqueue is called to make sure the reference count on the */ -/* queue is correct. We can't, however, call fr_freetimeoutqueue because */ -/* the correct lock(s) may not be held that would make it safe to do so. */ -/* ------------------------------------------------------------------------ */ -void fr_deletequeueentry(tqe) -ipftqent_t *tqe; -{ - ipftq_t *ifq; - - ifq = tqe->tqe_ifq; - if (ifq == NULL) - return; - - MUTEX_ENTER(&ifq->ifq_lock); - - if (tqe->tqe_pnext != NULL) { - *tqe->tqe_pnext = tqe->tqe_next; - if (tqe->tqe_next != NULL) - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - else /* we must be the tail anyway */ - ifq->ifq_tail = tqe->tqe_pnext; - - tqe->tqe_pnext = NULL; - tqe->tqe_ifq = NULL; - } - - (void) fr_deletetimeoutqueue(ifq); - - MUTEX_EXIT(&ifq->ifq_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_queuefront */ -/* Returns: Nil */ -/* Parameters: tqe(I) - pointer to timeout queue entry */ -/* */ -/* Move a queue entry to the front of the queue, if it isn't already there. */ -/* ------------------------------------------------------------------------ */ -void fr_queuefront(tqe) -ipftqent_t *tqe; -{ - ipftq_t *ifq; - - ifq = tqe->tqe_ifq; - if (ifq == NULL) - return; - - MUTEX_ENTER(&ifq->ifq_lock); - if (ifq->ifq_head != tqe) { - *tqe->tqe_pnext = tqe->tqe_next; - if (tqe->tqe_next) - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - else - ifq->ifq_tail = tqe->tqe_pnext; - - tqe->tqe_next = ifq->ifq_head; - ifq->ifq_head->tqe_pnext = &tqe->tqe_next; - ifq->ifq_head = tqe; - tqe->tqe_pnext = &ifq->ifq_head; - } - MUTEX_EXIT(&ifq->ifq_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_queueback */ -/* Returns: Nil */ -/* Parameters: tqe(I) - pointer to timeout queue entry */ -/* */ -/* Move a queue entry to the back of the queue, if it isn't already there. */ -/* ------------------------------------------------------------------------ */ -void fr_queueback(tqe) -ipftqent_t *tqe; -{ - ipftq_t *ifq; - - ifq = tqe->tqe_ifq; - if (ifq == NULL) - return; - tqe->tqe_die = fr_ticks + ifq->ifq_ttl; - - MUTEX_ENTER(&ifq->ifq_lock); - if (tqe->tqe_next == NULL) { /* at the end already ? */ - MUTEX_EXIT(&ifq->ifq_lock); - return; - } - - /* - * Remove from list - */ - *tqe->tqe_pnext = tqe->tqe_next; - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - - /* - * Make it the last entry. - */ - tqe->tqe_next = NULL; - tqe->tqe_pnext = ifq->ifq_tail; - *ifq->ifq_tail = tqe; - ifq->ifq_tail = &tqe->tqe_next; - MUTEX_EXIT(&ifq->ifq_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_queueappend */ -/* Returns: Nil */ -/* Parameters: tqe(I) - pointer to timeout queue entry */ -/* ifq(I) - pointer to timeout queue */ -/* parent(I) - owing object pointer */ -/* */ -/* Add a new item to this queue and put it on the very end. */ -/* ------------------------------------------------------------------------ */ -void fr_queueappend(tqe, ifq, parent) -ipftqent_t *tqe; -ipftq_t *ifq; -void *parent; -{ - - MUTEX_ENTER(&ifq->ifq_lock); - tqe->tqe_parent = parent; - tqe->tqe_pnext = ifq->ifq_tail; - *ifq->ifq_tail = tqe; - ifq->ifq_tail = &tqe->tqe_next; - tqe->tqe_next = NULL; - tqe->tqe_ifq = ifq; - tqe->tqe_die = fr_ticks + ifq->ifq_ttl; - ifq->ifq_ref++; - MUTEX_EXIT(&ifq->ifq_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_movequeue */ -/* Returns: Nil */ -/* Parameters: tq(I) - pointer to timeout queue information */ -/* oifp(I) - old timeout queue entry was on */ -/* nifp(I) - new timeout queue to put entry on */ -/* */ -/* Move a queue entry from one timeout queue to another timeout queue. */ -/* If it notices that the current entry is already last and does not need */ -/* to move queue, the return. */ -/* ------------------------------------------------------------------------ */ -void fr_movequeue(tqe, oifq, nifq) -ipftqent_t *tqe; -ipftq_t *oifq, *nifq; -{ - /* - * Is the operation here going to be a no-op ? - */ - MUTEX_ENTER(&oifq->ifq_lock); - if (oifq == nifq && *oifq->ifq_tail == tqe) { - MUTEX_EXIT(&oifq->ifq_lock); - return; - } - - /* - * Remove from the old queue - */ - *tqe->tqe_pnext = tqe->tqe_next; - if (tqe->tqe_next) - tqe->tqe_next->tqe_pnext = tqe->tqe_pnext; - else - oifq->ifq_tail = tqe->tqe_pnext; - tqe->tqe_next = NULL; - - /* - * If we're moving from one queue to another, release the lock on the - * old queue and get a lock on the new queue. For user defined queues, - * if we're moving off it, call delete in case it can now be freed. - */ - if (oifq != nifq) { - tqe->tqe_ifq = NULL; - - (void) fr_deletetimeoutqueue(oifq); - - MUTEX_EXIT(&oifq->ifq_lock); - - MUTEX_ENTER(&nifq->ifq_lock); - - tqe->tqe_ifq = nifq; - nifq->ifq_ref++; - } - - /* - * Add to the bottom of the new queue - */ - tqe->tqe_die = fr_ticks + nifq->ifq_ttl; - tqe->tqe_pnext = nifq->ifq_tail; - *nifq->ifq_tail = tqe; - nifq->ifq_tail = &tqe->tqe_next; - MUTEX_EXIT(&nifq->ifq_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_updateipid */ -/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* When we are doing NAT, change the IP of every packet to represent a */ -/* single sequence of packets coming from the host, hiding any host */ -/* specific sequencing that might otherwise be revealed. If the packet is */ -/* a fragment, then store the 'new' IPid in the fragment cache and look up */ -/* the fragment cache for non-leading fragments. If a non-leading fragment */ -/* has no match in the cache, return an error. */ -/* ------------------------------------------------------------------------ */ -static INLINE int fr_updateipid(fin) -fr_info_t *fin; -{ - u_short id, ido, sums; - u_32_t sumd, sum; - ip_t *ip; - - if (fin->fin_off != 0) { - sum = fr_ipid_knownfrag(fin); - if (sum == 0xffffffff) - return -1; - sum &= 0xffff; - id = (u_short)sum; - } else { - id = fr_nextipid(fin); - if (fin->fin_off == 0 && (fin->fin_flx & FI_FRAG) != 0) - (void) fr_ipid_newfrag(fin, (u_32_t)id); - } - - ip = fin->fin_ip; - ido = ntohs(ip->ip_id); - if (id == ido) - return 0; - ip->ip_id = htons(id); - CALC_SUMD(ido, id, sumd); /* DESTRUCTIVE MACRO! id,ido change */ - sum = (~ntohs(ip->ip_sum)) & 0xffff; - sum += sumd; - sum = (sum >> 16) + (sum & 0xffff); - sum = (sum >> 16) + (sum & 0xffff); - sums = ~(u_short)sum; - ip->ip_sum = htons(sums); - return 0; -} - - -#ifdef NEED_FRGETIFNAME -/* ------------------------------------------------------------------------ */ -/* Function: fr_getifname */ -/* Returns: char * - pointer to interface name */ -/* Parameters: ifp(I) - pointer to network interface */ -/* buffer(O) - pointer to where to store interface name */ -/* */ -/* Constructs an interface name in the buffer passed. The buffer passed is */ -/* expected to be at least LIFNAMSIZ in bytes big. If buffer is passed in */ -/* as a NULL pointer then return a pointer to a static array. */ -/* ------------------------------------------------------------------------ */ -char *fr_getifname(ifp, buffer) -struct ifnet *ifp; -char *buffer; -{ - static char namebuf[LIFNAMSIZ]; -# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \ - defined(__sgi) || defined(linux) || \ - (defined(sun) && !defined(__SVR4) && !defined(__svr4__)) - int unit, space; - char temp[20]; - char *s; -# endif - - if (buffer == NULL) - buffer = namebuf; - (void) strncpy(buffer, ifp->if_name, LIFNAMSIZ); - buffer[LIFNAMSIZ - 1] = '\0'; -# if defined(MENTAT) || defined(__FreeBSD__) || defined(__osf__) || \ - defined(__sgi) || \ - (defined(sun) && !defined(__SVR4) && !defined(__svr4__)) - for (s = buffer; *s; s++) - ; - unit = ifp->if_unit; - space = LIFNAMSIZ - (s - buffer); - if (space > 0) { -# if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(temp, sizeof(temp), "%d", unit); -# else - (void) sprintf(temp, "%d", unit); -# endif - (void) strncpy(s, temp, space); - } -# endif - return buffer; -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ioctlswitch */ -/* Returns: int - -1 continue processing, else ioctl return value */ -/* Parameters: unit(I) - device unit opened */ -/* data(I) - pointer to ioctl data */ -/* cmd(I) - ioctl command */ -/* mode(I) - mode value */ -/* */ -/* Based on the value of unit, call the appropriate ioctl handler or return */ -/* EIO if ipfilter is not running. Also checks if write perms are req'd */ -/* for the device in order to execute the ioctl. */ -/* ------------------------------------------------------------------------ */ -int fr_ioctlswitch(unit, data, cmd, mode) -int unit, mode; -ioctlcmd_t cmd; -void *data; -{ - int error = 0; - - switch (unit) - { - case IPL_LOGIPF : - error = -1; - break; - case IPL_LOGNAT : - if (fr_running > 0) - error = fr_nat_ioctl(data, cmd, mode); - else - error = EIO; - break; - case IPL_LOGSTATE : - if (fr_running > 0) - error = fr_state_ioctl(data, cmd, mode); - else - error = EIO; - break; - case IPL_LOGAUTH : - if (fr_running > 0) { - if ((cmd == (ioctlcmd_t)SIOCADAFR) || - (cmd == (ioctlcmd_t)SIOCRMAFR)) { - if (!(mode & FWRITE)) { - error = EPERM; - } else { - error = frrequest(unit, cmd, data, - fr_active, 1); - } - } else { - error = fr_auth_ioctl(data, cmd, mode); - } - } else - error = EIO; - break; - case IPL_LOGSYNC : -#ifdef IPFILTER_SYNC - if (fr_running > 0) - error = fr_sync_ioctl(data, cmd, mode); - else -#endif - error = EIO; - break; - case IPL_LOGSCAN : -#ifdef IPFILTER_SCAN - if (fr_running > 0) - error = fr_scan_ioctl(data, cmd, mode); - else -#endif - error = EIO; - break; - case IPL_LOGLOOKUP : -#ifdef IPFILTER_LOOKUP - if (fr_running > 0) - error = ip_lookup_ioctl(data, cmd, mode); - else -#endif - error = EIO; - break; - default : - error = EIO; - break; - } - - return error; -} - - -/* - * This array defines the expected size of objects coming into the kernel - * for the various recognised object types. - */ -#define NUM_OBJ_TYPES 14 - -static int fr_objbytes[NUM_OBJ_TYPES][2] = { - { 1, sizeof(struct frentry) }, /* frentry */ - { 0, sizeof(struct friostat) }, - { 0, sizeof(struct fr_info) }, - { 0, sizeof(struct fr_authstat) }, - { 0, sizeof(struct ipfrstat) }, - { 0, sizeof(struct ipnat) }, - { 0, sizeof(struct natstat) }, - { 0, sizeof(struct ipstate_save) }, - { 1, sizeof(struct nat_save) }, /* nat_save */ - { 0, sizeof(struct natlookup) }, - { 1, sizeof(struct ipstate) }, /* ipstate */ - { 0, sizeof(struct ips_stat) }, - { 0, sizeof(struct frauth) }, - { 0, sizeof(struct ipftune) } -}; - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_inobj */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* ptr(I) - pointer to store real data in */ -/* type(I) - type of structure being moved */ -/* */ -/* Copy in the contents of what the ipfobj_t points to. In future, we */ -/* add things to check for version numbers, sizes, etc, to make it backward */ -/* compatible at the ABI for user land. */ -/* ------------------------------------------------------------------------ */ -int fr_inobj(data, ptr, type) -void *data; -void *ptr; -int type; -{ - ipfobj_t obj; - int error = 0; - - if ((type < 0) || (type > NUM_OBJ_TYPES-1)) - return EINVAL; - - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); - - if (obj.ipfo_type != type) - return EINVAL; - -#ifndef IPFILTER_COMPAT - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - return EINVAL; -#else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; -#endif - - if ((fr_objbytes[type][0] & 1) != 0) { - error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, - fr_objbytes[type][1]); - } else { - error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, - obj.ipfo_size); - } - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_inobjsz */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* ptr(I) - pointer to store real data in */ -/* type(I) - type of structure being moved */ -/* sz(I) - size of data to copy */ -/* */ -/* As per fr_inobj, except the size of the object to copy in is passed in */ -/* but it must not be smaller than the size defined for the type and the */ -/* type must allow for varied sized objects. The extra requirement here is */ -/* that sz must match the size of the object being passed in - this is not */ -/* not possible nor required in fr_inobj(). */ -/* ------------------------------------------------------------------------ */ -int fr_inobjsz(data, ptr, type, sz) -void *data; -void *ptr; -int type, sz; -{ - ipfobj_t obj; - int error; - - if ((type < 0) || (type > NUM_OBJ_TYPES-1)) - return EINVAL; - if (((fr_objbytes[type][0] & 1) == 0) || (sz < fr_objbytes[type][1])) - return EINVAL; - - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); - - if (obj.ipfo_type != type) - return EINVAL; - -#ifndef IPFILTER_COMPAT - if (obj.ipfo_size != sz) - return EINVAL; -#else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if (obj.ipfo_size != sz) - /* XXX compatibility hook here */ - return EINVAL; -#endif - - error = COPYIN((caddr_t)obj.ipfo_ptr, (caddr_t)ptr, sz); - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_outobjsz */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* ptr(I) - pointer to store real data in */ -/* type(I) - type of structure being moved */ -/* sz(I) - size of data to copy */ -/* */ -/* As per fr_outobj, except the size of the object to copy out is passed in */ -/* but it must not be smaller than the size defined for the type and the */ -/* type must allow for varied sized objects. The extra requirement here is */ -/* that sz must match the size of the object being passed in - this is not */ -/* not possible nor required in fr_outobj(). */ -/* ------------------------------------------------------------------------ */ -int fr_outobjsz(data, ptr, type, sz) -void *data; -void *ptr; -int type, sz; -{ - ipfobj_t obj; - int error; - - if ((type < 0) || (type > NUM_OBJ_TYPES-1) || - ((fr_objbytes[type][0] & 1) == 0) || - (sz < fr_objbytes[type][1])) - return EINVAL; - - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); - - if (obj.ipfo_type != type) - return EINVAL; - -#ifndef IPFILTER_COMPAT - if (obj.ipfo_size != sz) - return EINVAL; -#else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if (obj.ipfo_size != sz) - /* XXX compatibility hook here */ - return EINVAL; -#endif - - error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, sz); - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_outobj */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* ptr(I) - pointer to store real data in */ -/* type(I) - type of structure being moved */ -/* */ -/* Copy out the contents of what ptr is to where ipfobj points to. In */ -/* future, we add things to check for version numbers, sizes, etc, to make */ -/* it backward compatible at the ABI for user land. */ -/* ------------------------------------------------------------------------ */ -int fr_outobj(data, ptr, type) -void *data; -void *ptr; -int type; -{ - ipfobj_t obj; - int error; - - if ((type < 0) || (type > NUM_OBJ_TYPES-1)) - return EINVAL; - - BCOPYIN((caddr_t)data, (caddr_t)&obj, sizeof(obj)); - - if (obj.ipfo_type != type) - return EINVAL; - -#ifndef IPFILTER_COMPAT - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - return EINVAL; -#else - if (obj.ipfo_rev != IPFILTER_VERSION) - /* XXX compatibility hook here */ - ; - if ((fr_objbytes[type][0] & 1) != 0) { - if (obj.ipfo_size < fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; - } else if (obj.ipfo_size != fr_objbytes[type][1]) - /* XXX compatibility hook here */ - return EINVAL; -#endif - - error = COPYOUT((caddr_t)ptr, (caddr_t)obj.ipfo_ptr, obj.ipfo_size); - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checkl4sum */ -/* Returns: int - 0 = good, -1 = bad, 1 = cannot check */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* If possible, calculate the layer 4 checksum for the packet. If this is */ -/* not possible, return without indicating a failure or success but in a */ -/* way that is ditinguishable. */ -/* ------------------------------------------------------------------------ */ -int fr_checkl4sum(fin) -fr_info_t *fin; -{ - u_short sum, hdrsum, *csump; - udphdr_t *udp; - int dosum; - - if ((fin->fin_flx & FI_NOCKSUM) != 0) - return 0; - - /* - * If the TCP packet isn't a fragment, isn't too short and otherwise - * isn't already considered "bad", then validate the checksum. If - * this check fails then considered the packet to be "bad". - */ - if ((fin->fin_flx & (FI_FRAG|FI_SHORT|FI_BAD)) != 0) - return 1; - - csump = NULL; - hdrsum = 0; - dosum = 0; - sum = 0; - -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) - if (dohwcksum && ((*fin->fin_mp)->b_ick_flag == ICK_VALID)) { - hdrsum = 0; - sum = 0; - } else { -#endif - switch (fin->fin_p) - { - case IPPROTO_TCP : - csump = &((tcphdr_t *)fin->fin_dp)->th_sum; - dosum = 1; - break; - - case IPPROTO_UDP : - udp = fin->fin_dp; - if (udp->uh_sum != 0) { - csump = &udp->uh_sum; - dosum = 1; - } - break; - - case IPPROTO_ICMP : - csump = &((struct icmp *)fin->fin_dp)->icmp_cksum; - dosum = 1; - break; - - default : - return 1; - /*NOTREACHED*/ - } - - if (csump != NULL) - hdrsum = *csump; - - if (dosum) - sum = fr_cksum(fin->fin_m, fin->fin_ip, - fin->fin_p, fin->fin_dp); -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) - } -#endif -#if !defined(_KERNEL) - if (sum == hdrsum) { - FR_DEBUG(("checkl4sum: %hx == %hx\n", sum, hdrsum)); - } else { - FR_DEBUG(("checkl4sum: %hx != %hx\n", sum, hdrsum)); - } -#endif - if (hdrsum == sum) - return 0; - return -1; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ifpfillv4addr */ -/* Returns: int - 0 = address update, -1 = address not updated */ -/* Parameters: atype(I) - type of network address update to perform */ -/* sin(I) - pointer to source of address information */ -/* mask(I) - pointer to source of netmask information */ -/* inp(I) - pointer to destination address store */ -/* inpmask(I) - pointer to destination netmask store */ -/* */ -/* Given a type of network address update (atype) to perform, copy */ -/* information from sin/mask into inp/inpmask. If ipnmask is NULL then no */ -/* netmask update is performed unless FRI_NETMASKED is passed as atype, in */ -/* which case the operation fails. For all values of atype other than */ -/* FRI_NETMASKED, if inpmask is non-NULL then the mask is set to an all 1s */ -/* value. */ -/* ------------------------------------------------------------------------ */ -int fr_ifpfillv4addr(atype, sin, mask, inp, inpmask) -int atype; -struct sockaddr_in *sin, *mask; -struct in_addr *inp, *inpmask; -{ - if (inpmask != NULL && atype != FRI_NETMASKED) - inpmask->s_addr = 0xffffffff; - - if (atype == FRI_NETWORK || atype == FRI_NETMASKED) { - if (atype == FRI_NETMASKED) { - if (inpmask == NULL) - return -1; - inpmask->s_addr = mask->sin_addr.s_addr; - } - inp->s_addr = sin->sin_addr.s_addr & mask->sin_addr.s_addr; - } else { - inp->s_addr = sin->sin_addr.s_addr; - } - return 0; -} - - -#ifdef USE_INET6 -/* ------------------------------------------------------------------------ */ -/* Function: fr_ifpfillv6addr */ -/* Returns: int - 0 = address update, -1 = address not updated */ -/* Parameters: atype(I) - type of network address update to perform */ -/* sin(I) - pointer to source of address information */ -/* mask(I) - pointer to source of netmask information */ -/* inp(I) - pointer to destination address store */ -/* inpmask(I) - pointer to destination netmask store */ -/* */ -/* Given a type of network address update (atype) to perform, copy */ -/* information from sin/mask into inp/inpmask. If ipnmask is NULL then no */ -/* netmask update is performed unless FRI_NETMASKED is passed as atype, in */ -/* which case the operation fails. For all values of atype other than */ -/* FRI_NETMASKED, if inpmask is non-NULL then the mask is set to an all 1s */ -/* value. */ -/* ------------------------------------------------------------------------ */ -int fr_ifpfillv6addr(atype, sin, mask, inp, inpmask) -int atype; -struct sockaddr_in6 *sin, *mask; -struct in_addr *inp, *inpmask; -{ - i6addr_t *src, *dst, *and, *dmask; - - src = (i6addr_t *)&sin->sin6_addr; - and = (i6addr_t *)&mask->sin6_addr; - dst = (i6addr_t *)inp; - dmask = (i6addr_t *)inpmask; - - if (inpmask != NULL && atype != FRI_NETMASKED) { - dmask->i6[0] = 0xffffffff; - dmask->i6[1] = 0xffffffff; - dmask->i6[2] = 0xffffffff; - dmask->i6[3] = 0xffffffff; - } - - if (atype == FRI_NETWORK || atype == FRI_NETMASKED) { - if (atype == FRI_NETMASKED) { - if (inpmask == NULL) - return -1; - dmask->i6[0] = and->i6[0]; - dmask->i6[1] = and->i6[1]; - dmask->i6[2] = and->i6[2]; - dmask->i6[3] = and->i6[3]; - } - - dst->i6[0] = src->i6[0] & and->i6[0]; - dst->i6[1] = src->i6[1] & and->i6[1]; - dst->i6[2] = src->i6[2] & and->i6[2]; - dst->i6[3] = src->i6[3] & and->i6[3]; - } else { - dst->i6[0] = src->i6[0]; - dst->i6[1] = src->i6[1]; - dst->i6[2] = src->i6[2]; - dst->i6[3] = src->i6[3]; - } - return 0; -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_matchtag */ -/* Returns: 0 == mismatch, 1 == match. */ -/* Parameters: tag1(I) - pointer to first tag to compare */ -/* tag2(I) - pointer to second tag to compare */ -/* */ -/* Returns true (non-zero) or false(0) if the two tag structures can be */ -/* considered to be a match or not match, respectively. The tag is 16 */ -/* bytes long (16 characters) but that is overlayed with 4 32bit ints so */ -/* compare the ints instead, for speed. tag1 is the master of the */ -/* comparison. This function should only be called with both tag1 and tag2 */ -/* as non-NULL pointers. */ -/* ------------------------------------------------------------------------ */ -int fr_matchtag(tag1, tag2) -ipftag_t *tag1, *tag2; -{ - if (tag1 == tag2) - return 1; - - if ((tag1->ipt_num[0] == 0) && (tag2->ipt_num[0] == 0)) - return 1; - - if ((tag1->ipt_num[0] == tag2->ipt_num[0]) && - (tag1->ipt_num[1] == tag2->ipt_num[1]) && - (tag1->ipt_num[2] == tag2->ipt_num[2]) && - (tag1->ipt_num[3] == tag2->ipt_num[3])) - return 1; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_coalesce */ -/* Returns: 1 == success, -1 == failure, 0 == no change */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Attempt to get all of the packet data into a single, contiguous buffer. */ -/* If this call returns a failure then the buffers have also been freed. */ -/* ------------------------------------------------------------------------ */ -int fr_coalesce(fin) -fr_info_t *fin; -{ - if ((fin->fin_flx & FI_COALESCE) != 0) - return 1; - - /* - * If the mbuf pointers indicate that there is no mbuf to work with, - * return but do not indicate success or failure. - */ - if (fin->fin_m == NULL || fin->fin_mp == NULL) - return 0; - -#if defined(_KERNEL) - if (fr_pullup(fin->fin_m, fin, fin->fin_plen) == NULL) { - ATOMIC_INCL(fr_badcoalesces[fin->fin_out]); -# ifdef MENTAT - FREE_MB_T(*fin->fin_mp); -# endif - *fin->fin_mp = NULL; - fin->fin_m = NULL; - return -1; - } -#else - fin = fin; /* LINT */ -#endif - return 1; -} - - -/* - * The following table lists all of the tunable variables that can be - * accessed via SIOCIPFGET/SIOCIPFSET/SIOCIPFGETNEXt. The format of each row - * in the table below is as follows: - * - * pointer to value, name of value, minimum, maximum, size of the value's - * container, value attribute flags - * - * For convienience, IPFT_RDONLY means the value is read-only, IPFT_WRDISABLED - * means the value can only be written to when IPFilter is loaded but disabled. - * The obvious implication is if neither of these are set then the value can be - * changed at any time without harm. - */ -ipftuneable_t ipf_tuneables[] = { - /* filtering */ - { { &fr_flags }, "fr_flags", 0, 0xffffffff, - sizeof(fr_flags), 0 }, - { { &fr_active }, "fr_active", 0, 0, - sizeof(fr_active), IPFT_RDONLY }, - { { &fr_control_forwarding }, "fr_control_forwarding", 0, 1, - sizeof(fr_control_forwarding), 0 }, - { { &fr_update_ipid }, "fr_update_ipid", 0, 1, - sizeof(fr_update_ipid), 0 }, - { { &fr_chksrc }, "fr_chksrc", 0, 1, - sizeof(fr_chksrc), 0 }, - { { &fr_pass }, "fr_pass", 0, 0xffffffff, - sizeof(fr_pass), 0 }, - /* state */ - { { &fr_tcpidletimeout }, "fr_tcpidletimeout", 1, 0x7fffffff, - sizeof(fr_tcpidletimeout), IPFT_WRDISABLED }, - { { &fr_tcpclosewait }, "fr_tcpclosewait", 1, 0x7fffffff, - sizeof(fr_tcpclosewait), IPFT_WRDISABLED }, - { { &fr_tcplastack }, "fr_tcplastack", 1, 0x7fffffff, - sizeof(fr_tcplastack), IPFT_WRDISABLED }, - { { &fr_tcptimeout }, "fr_tcptimeout", 1, 0x7fffffff, - sizeof(fr_tcptimeout), IPFT_WRDISABLED }, - { { &fr_tcpclosed }, "fr_tcpclosed", 1, 0x7fffffff, - sizeof(fr_tcpclosed), IPFT_WRDISABLED }, - { { &fr_tcphalfclosed }, "fr_tcphalfclosed", 1, 0x7fffffff, - sizeof(fr_tcphalfclosed), IPFT_WRDISABLED }, - { { &fr_udptimeout }, "fr_udptimeout", 1, 0x7fffffff, - sizeof(fr_udptimeout), IPFT_WRDISABLED }, - { { &fr_udpacktimeout }, "fr_udpacktimeout", 1, 0x7fffffff, - sizeof(fr_udpacktimeout), IPFT_WRDISABLED }, - { { &fr_icmptimeout }, "fr_icmptimeout", 1, 0x7fffffff, - sizeof(fr_icmptimeout), IPFT_WRDISABLED }, - { { &fr_icmpacktimeout }, "fr_icmpacktimeout", 1, 0x7fffffff, - sizeof(fr_icmpacktimeout), IPFT_WRDISABLED }, - { { &fr_iptimeout }, "fr_iptimeout", 1, 0x7fffffff, - sizeof(fr_iptimeout), IPFT_WRDISABLED }, - { { &fr_statemax }, "fr_statemax", 1, 0x7fffffff, - sizeof(fr_statemax), 0 }, - { { &fr_statesize }, "fr_statesize", 1, 0x7fffffff, - sizeof(fr_statesize), IPFT_WRDISABLED }, - { { &fr_state_lock }, "fr_state_lock", 0, 1, - sizeof(fr_state_lock), IPFT_RDONLY }, - { { &fr_state_maxbucket }, "fr_state_maxbucket", 1, 0x7fffffff, - sizeof(fr_state_maxbucket), IPFT_WRDISABLED }, - { { &fr_state_maxbucket_reset }, "fr_state_maxbucket_reset", 0, 1, - sizeof(fr_state_maxbucket_reset), IPFT_WRDISABLED }, - { { &ipstate_logging }, "ipstate_logging", 0, 1, - sizeof(ipstate_logging), 0 }, - /* nat */ - { { &fr_nat_lock }, "fr_nat_lock", 0, 1, - sizeof(fr_nat_lock), IPFT_RDONLY }, - { { &ipf_nattable_sz }, "ipf_nattable_sz", 1, 0x7fffffff, - sizeof(ipf_nattable_sz), IPFT_WRDISABLED }, - { { &ipf_nattable_max }, "ipf_nattable_max", 1, 0x7fffffff, - sizeof(ipf_nattable_max), 0 }, - { { &ipf_natrules_sz }, "ipf_natrules_sz", 1, 0x7fffffff, - sizeof(ipf_natrules_sz), IPFT_WRDISABLED }, - { { &ipf_rdrrules_sz }, "ipf_rdrrules_sz", 1, 0x7fffffff, - sizeof(ipf_rdrrules_sz), IPFT_WRDISABLED }, - { { &ipf_hostmap_sz }, "ipf_hostmap_sz", 1, 0x7fffffff, - sizeof(ipf_hostmap_sz), IPFT_WRDISABLED }, - { { &fr_nat_maxbucket }, "fr_nat_maxbucket", 1, 0x7fffffff, - sizeof(fr_nat_maxbucket), IPFT_WRDISABLED }, - { { &fr_nat_maxbucket_reset }, "fr_nat_maxbucket_reset", 0, 1, - sizeof(fr_nat_maxbucket_reset), IPFT_WRDISABLED }, - { { &nat_logging }, "nat_logging", 0, 1, - sizeof(nat_logging), 0 }, - { { &fr_defnatage }, "fr_defnatage", 1, 0x7fffffff, - sizeof(fr_defnatage), IPFT_WRDISABLED }, - { { &fr_defnatipage }, "fr_defnatipage", 1, 0x7fffffff, - sizeof(fr_defnatipage), IPFT_WRDISABLED }, - { { &fr_defnaticmpage }, "fr_defnaticmpage", 1, 0x7fffffff, - sizeof(fr_defnaticmpage), IPFT_WRDISABLED }, - /* frag */ - { { &ipfr_size }, "ipfr_size", 1, 0x7fffffff, - sizeof(ipfr_size), IPFT_WRDISABLED }, - { { &fr_ipfrttl }, "fr_ipfrttl", 1, 0x7fffffff, - sizeof(fr_ipfrttl), IPFT_WRDISABLED }, -#ifdef IPFILTER_LOG - /* log */ - { { &ipl_suppress }, "ipl_suppress", 0, 1, - sizeof(ipl_suppress), 0 }, - { { &ipl_buffer_sz }, "ipl_buffer_sz", 0, 0, - sizeof(ipl_buffer_sz), IPFT_RDONLY }, - { { &ipl_logmax }, "ipl_logmax", 0, 0x7fffffff, - sizeof(ipl_logmax), IPFT_WRDISABLED }, - { { &ipl_logall }, "ipl_logall", 0, 1, - sizeof(ipl_logall), 0 }, - { { &ipl_logsize }, "ipl_logsize", 0, 0x80000, - sizeof(ipl_logsize), 0 }, -#endif - { { NULL }, NULL, 0, 0 } -}; - -static ipftuneable_t *ipf_tunelist = NULL; - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_findtunebycookie */ -/* Returns: NULL = search failed, else pointer to tune struct */ -/* Parameters: cookie(I) - cookie value to search for amongst tuneables */ -/* next(O) - pointer to place to store the cookie for the */ -/* "next" tuneable, if it is desired. */ -/* */ -/* This function is used to walk through all of the existing tunables with */ -/* successive calls. It searches the known tunables for the one which has */ -/* a matching value for "cookie" - ie its address. When returning a match, */ -/* the next one to be found may be returned inside next. */ -/* ------------------------------------------------------------------------ */ -static ipftuneable_t *fr_findtunebycookie(cookie, next) -void *cookie, **next; -{ - ipftuneable_t *ta, **tap; - - for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++) - if (ta == cookie) { - if (next != NULL) { - /* - * If the next entry in the array has a name - * present, then return a pointer to it for - * where to go next, else return a pointer to - * the dynaminc list as a key to search there - * next. This facilitates a weak linking of - * the two "lists" together. - */ - if ((ta + 1)->ipft_name != NULL) - *next = ta + 1; - else - *next = &ipf_tunelist; - } - return ta; - } - - for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next) - if (tap == cookie) { - if (next != NULL) - *next = &ta->ipft_next; - return ta; - } - - if (next != NULL) - *next = NULL; - return NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_findtunebyname */ -/* Returns: NULL = search failed, else pointer to tune struct */ -/* Parameters: name(I) - name of the tuneable entry to find. */ -/* */ -/* Search the static array of tuneables and the list of dynamic tuneables */ -/* for an entry with a matching name. If we can find one, return a pointer */ -/* to the matching structure. */ -/* ------------------------------------------------------------------------ */ -static ipftuneable_t *fr_findtunebyname(name) -char *name; -{ - ipftuneable_t *ta; - - for (ta = ipf_tuneables; ta->ipft_name != NULL; ta++) - if (!strcmp(ta->ipft_name, name)) { - return ta; - } - - for (ta = ipf_tunelist; ta != NULL; ta = ta->ipft_next) - if (!strcmp(ta->ipft_name, name)) { - return ta; - } - - return NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_addipftune */ -/* Returns: int - 0 == success, else failure */ -/* Parameters: newtune - pointer to new tune struct to add to tuneables */ -/* */ -/* Appends the tune structure pointer to by "newtune" to the end of the */ -/* current list of "dynamic" tuneable parameters. Once added, the owner */ -/* of the object is not expected to ever change "ipft_next". */ -/* ------------------------------------------------------------------------ */ -int fr_addipftune(newtune) -ipftuneable_t *newtune; -{ - ipftuneable_t *ta, **tap; - - ta = fr_findtunebyname(newtune->ipft_name); - if (ta != NULL) - return EEXIST; - - for (tap = &ipf_tunelist; *tap != NULL; tap = &(*tap)->ipft_next) - ; - - newtune->ipft_next = NULL; - *tap = newtune; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_delipftune */ -/* Returns: int - 0 == success, else failure */ -/* Parameters: oldtune - pointer to tune struct to remove from the list of */ -/* current dynamic tuneables */ -/* */ -/* Search for the tune structure, by pointer, in the list of those that are */ -/* dynamically added at run time. If found, adjust the list so that this */ -/* structure is no longer part of it. */ -/* ------------------------------------------------------------------------ */ -int fr_delipftune(oldtune) -ipftuneable_t *oldtune; -{ - ipftuneable_t *ta, **tap; - - for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next) - if (ta == oldtune) { - *tap = oldtune->ipft_next; - oldtune->ipft_next = NULL; - return 0; - } - - return ESRCH; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ipftune */ -/* Returns: int - 0 == success, else failure */ -/* Parameters: cmd(I) - ioctl command number */ -/* data(I) - pointer to ioctl data structure */ -/* */ -/* Implement handling of SIOCIPFGETNEXT, SIOCIPFGET and SIOCIPFSET. These */ -/* three ioctls provide the means to access and control global variables */ -/* within IPFilter, allowing (for example) timeouts and table sizes to be */ -/* changed without rebooting, reloading or recompiling. The initialisation */ -/* and 'destruction' routines of the various components of ipfilter are all */ -/* each responsible for handling their own values being too big. */ -/* ------------------------------------------------------------------------ */ -int fr_ipftune(cmd, data) -ioctlcmd_t cmd; -void *data; -{ - ipftuneable_t *ta; - ipftune_t tu; - void *cookie; - int error; - - error = fr_inobj(data, &tu, IPFOBJ_TUNEABLE); - if (error != 0) - return error; - - tu.ipft_name[sizeof(tu.ipft_name) - 1] = '\0'; - cookie = tu.ipft_cookie; - ta = NULL; - - switch (cmd) - { - case SIOCIPFGETNEXT : - /* - * If cookie is non-NULL, assume it to be a pointer to the last - * entry we looked at, so find it (if possible) and return a - * pointer to the next one after it. The last entry in the - * the table is a NULL entry, so when we get to it, set cookie - * to NULL and return that, indicating end of list, erstwhile - * if we come in with cookie set to NULL, we are starting anew - * at the front of the list. - */ - if (cookie != NULL) { - ta = fr_findtunebycookie(cookie, &tu.ipft_cookie); - } else { - ta = ipf_tuneables; - tu.ipft_cookie = ta + 1; - } - if (ta != NULL) { - /* - * Entry found, but does the data pointed to by that - * row fit in what we can return? - */ - if (ta->ipft_sz > sizeof(tu.ipft_un)) - return EINVAL; - - tu.ipft_vlong = 0; - if (ta->ipft_sz == sizeof(u_long)) - tu.ipft_vlong = *ta->ipft_plong; - else if (ta->ipft_sz == sizeof(u_int)) - tu.ipft_vint = *ta->ipft_pint; - else if (ta->ipft_sz == sizeof(u_short)) - tu.ipft_vshort = *ta->ipft_pshort; - else if (ta->ipft_sz == sizeof(u_char)) - tu.ipft_vchar = *ta->ipft_pchar; - - tu.ipft_sz = ta->ipft_sz; - tu.ipft_min = ta->ipft_min; - tu.ipft_max = ta->ipft_max; - tu.ipft_flags = ta->ipft_flags; - bcopy(ta->ipft_name, tu.ipft_name, - MIN(sizeof(tu.ipft_name), - strlen(ta->ipft_name) + 1)); - } - error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE); - break; - - case SIOCIPFGET : - case SIOCIPFSET : - /* - * Search by name or by cookie value for a particular entry - * in the tuning paramter table. - */ - error = ESRCH; - if (cookie != NULL) { - ta = fr_findtunebycookie(cookie, NULL); - if (ta != NULL) - error = 0; - } else if (tu.ipft_name[0] != '\0') { - ta = fr_findtunebyname(tu.ipft_name); - if (ta != NULL) - error = 0; - } - if (error != 0) - break; - - if (cmd == (ioctlcmd_t)SIOCIPFGET) { - /* - * Fetch the tuning parameters for a particular value - */ - tu.ipft_vlong = 0; - if (ta->ipft_sz == sizeof(u_long)) - tu.ipft_vlong = *ta->ipft_plong; - else if (ta->ipft_sz == sizeof(u_int)) - tu.ipft_vint = *ta->ipft_pint; - else if (ta->ipft_sz == sizeof(u_short)) - tu.ipft_vshort = *ta->ipft_pshort; - else if (ta->ipft_sz == sizeof(u_char)) - tu.ipft_vchar = *ta->ipft_pchar; - tu.ipft_sz = ta->ipft_sz; - tu.ipft_min = ta->ipft_min; - tu.ipft_max = ta->ipft_max; - tu.ipft_flags = ta->ipft_flags; - error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE); - - } else if (cmd == (ioctlcmd_t)SIOCIPFSET) { - /* - * Set an internal parameter. The hard part here is - * getting the new value safely and correctly out of - * the kernel (given we only know its size, not type.) - */ - u_long in; - - if (((ta->ipft_flags & IPFT_WRDISABLED) != 0) && - (fr_running > 0)) { - error = EBUSY; - break; - } - - in = tu.ipft_vlong; - if (in < ta->ipft_min || in > ta->ipft_max) { - error = EINVAL; - break; - } - - if (ta->ipft_sz == sizeof(u_long)) { - tu.ipft_vlong = *ta->ipft_plong; - *ta->ipft_plong = in; - } else if (ta->ipft_sz == sizeof(u_int)) { - tu.ipft_vint = *ta->ipft_pint; - *ta->ipft_pint = (u_int)(in & 0xffffffff); - } else if (ta->ipft_sz == sizeof(u_short)) { - tu.ipft_vshort = *ta->ipft_pshort; - *ta->ipft_pshort = (u_short)(in & 0xffff); - } else if (ta->ipft_sz == sizeof(u_char)) { - tu.ipft_vchar = *ta->ipft_pchar; - *ta->ipft_pchar = (u_char)(in & 0xff); - } - error = fr_outobj(data, &tu, IPFOBJ_TUNEABLE); - } - break; - - default : - error = EINVAL; - break; - } - - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_initialise */ -/* Returns: int - 0 == success, < 0 == failure */ -/* Parameters: None. */ -/* */ -/* Call of the initialise functions for all the various subsystems inside */ -/* of IPFilter. If any of them should fail, return immeadiately a failure */ -/* BUT do not try to recover from the error here. */ -/* ------------------------------------------------------------------------ */ -int fr_initialise() -{ - int i; - -#ifdef IPFILTER_LOG - i = fr_loginit(); - if (i < 0) - return -10 + i; -#endif - i = fr_natinit(); - if (i < 0) - return -20 + i; - - i = fr_stateinit(); - if (i < 0) - return -30 + i; - - i = fr_authinit(); - if (i < 0) - return -40 + i; - - i = fr_fraginit(); - if (i < 0) - return -50 + i; - - i = appr_init(); - if (i < 0) - return -60 + i; - -#ifdef IPFILTER_SYNC - i = ipfsync_init(); - if (i < 0) - return -70 + i; -#endif -#ifdef IPFILTER_SCAN - i = ipsc_init(); - if (i < 0) - return -80 + i; -#endif -#ifdef IPFILTER_LOOKUP - i = ip_lookup_init(); - if (i < 0) - return -90 + i; -#endif -#ifdef IPFILTER_COMPILED - ipfrule_add(); -#endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_deinitialise */ -/* Returns: None. */ -/* Parameters: None. */ -/* */ -/* Call all the various subsystem cleanup routines to deallocate memory or */ -/* destroy locks or whatever they've done that they need to now undo. */ -/* The order here IS important as there are some cross references of */ -/* internal data structures. */ -/* ------------------------------------------------------------------------ */ -void fr_deinitialise() -{ - fr_fragunload(); - fr_authunload(); - fr_natunload(); - fr_stateunload(); -#ifdef IPFILTER_SCAN - fr_scanunload(); -#endif - appr_unload(); - -#ifdef IPFILTER_COMPILED - ipfrule_remove(); -#endif - - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE); - (void) frflush(IPL_LOGCOUNT, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - (void) frflush(IPL_LOGCOUNT, 0, FR_INQUE|FR_OUTQUE); - -#ifdef IPFILTER_LOOKUP - ip_lookup_unload(); -#endif - -#ifdef IPFILTER_LOG - fr_logunload(); -#endif -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_zerostats */ -/* Returns: int - 0 = success, else failure */ -/* Parameters: data(O) - pointer to pointer for copying data back to */ -/* */ -/* Copies the current statistics out to userspace and then zero's the */ -/* current ones in the kernel. The lock is only held across the bzero() as */ -/* the copyout may result in paging (ie network activity.) */ -/* ------------------------------------------------------------------------ */ -int fr_zerostats(data) -caddr_t data; -{ - friostat_t fio; - int error; - - fr_getstat(&fio); - error = copyoutptr(&fio, data, sizeof(fio)); - if (error) - return EFAULT; - - WRITE_ENTER(&ipf_mutex); - bzero((char *)frstats, sizeof(*frstats) * 2); - RWLOCK_EXIT(&ipf_mutex); - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_resolvedest */ -/* Returns: Nil */ -/* Parameters: fdp(IO) - pointer to destination information to resolve */ -/* v(I) - IP protocol version to match */ -/* */ -/* Looks up an interface name in the frdest structure pointed to by fdp and */ -/* if a matching name can be found for the particular IP protocol version */ -/* then store the interface pointer in the frdest struct. If no match is */ -/* found, then set the interface pointer to be -1 as NULL is considered to */ -/* indicate there is no information at all in the structure. */ -/* ------------------------------------------------------------------------ */ -void fr_resolvedest(fdp, v) -frdest_t *fdp; -int v; -{ - void *ifp; - - ifp = NULL; - v = v; /* LINT */ - - if (*fdp->fd_ifname != '\0') { - ifp = GETIFP(fdp->fd_ifname, v); - if (ifp == NULL) - ifp = (void *)-1; - } - fdp->fd_ifp = ifp; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_icmp4errortype */ -/* Returns: int - 1 == success, 0 == failure */ -/* Parameters: icmptype(I) - ICMP type number */ -/* */ -/* Tests to see if the ICMP type number passed is an error type or not. */ -/* ------------------------------------------------------------------------ */ -int fr_icmp4errortype(icmptype) -int icmptype; -{ - - switch (icmptype) - { - case ICMP_SOURCEQUENCH : - case ICMP_PARAMPROB : - case ICMP_REDIRECT : - case ICMP_TIMXCEED : - case ICMP_UNREACH : - return 1; - default: - return 0; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_resolvenic */ -/* Returns: void* - NULL = wildcard name, -1 = failed to find NIC, else */ -/* pointer to interface structure for NIC */ -/* Parameters: name(I) - complete interface name */ -/* v(I) - IP protocol version */ -/* */ -/* Look for a network interface structure that firstly has a matching name */ -/* to that passed in and that is also being used for that IP protocol */ -/* version (necessary on some platforms where there are separate listings */ -/* for both IPv4 and IPv6 on the same physical NIC. */ -/* */ -/* One might wonder why name gets terminated with a \0 byte in here. The */ -/* reason is an interface name could get into the kernel structures of ipf */ -/* in any number of ways and so long as they all use the same sized array */ -/* to put the name in, it makes sense to ensure it gets null terminated */ -/* before it is used for its intended purpose - finding its match in the */ -/* kernel's list of configured interfaces. */ -/* */ -/* NOTE: This SHOULD ONLY be used with IPFilter structures that have an */ -/* array for the name that is LIFNAMSIZ bytes (at least) in length. */ -/* ------------------------------------------------------------------------ */ -void *fr_resolvenic(name, v) -char *name; -int v; -{ - void *nic; - - if (name[0] == '\0') - return NULL; - - if ((name[1] == '\0') && ((name[0] == '-') || (name[0] == '*'))) { - return NULL; - } - - name[LIFNAMSIZ - 1] = '\0'; - - nic = GETIFP(name, v); - if (nic == NULL) - nic = (void *)-1; - return nic; -} diff --git a/contrib/ipfilter/fils.c b/contrib/ipfilter/fils.c deleted file mode 100644 index e21af892a577..000000000000 --- a/contrib/ipfilter/fils.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#ifdef __FreeBSD__ -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -#endif -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -# include -#endif -#include -#include -#include -#include -#if defined(STATETOP) -# if defined(_BSDI_VERSION) -# undef STATETOP) -# endif -# if defined(__FreeBSD__) && \ - (!defined(__FreeBSD_version) || (__FreeBSD_version < 430000)) -# undef STATETOP -# endif -# if defined(__NetBSD_Version__) -# if (__NetBSD_Version__ < 105000000) -# undef STATETOP -# else -# include -# define USE_POLL -# endif -# endif -# if defined(sun) -# if defined(__svr4__) || defined(__SVR4) -# include -# else -# undef STATETOP /* NOT supported on SunOS4 */ -# endif -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#if defined(STATETOP) && !defined(linux) -# include -# include -#endif -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "ipf.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "netinet/ip_auth.h" -#ifdef STATETOP -# include "netinet/ipl.h" -# include -# if SOLARIS || defined(__NetBSD__) || defined(_BSDI_VERSION) || \ - defined(__sgi) -# ifdef ERR -# undef ERR -# endif -# include -# else /* SOLARIS */ -# include -# endif /* SOLARIS */ -#endif /* STATETOP */ -#include "kmem.h" -#if defined(__NetBSD__) || (__OpenBSD__) -# include -#endif - -#if !defined(lint) -static const char sccsid[] = "@(#)fils.c 1.21 4/20/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: fils.c,v 2.21.2.45 2004/04/10 11:45:48 darrenr Exp $"; -#endif - -extern char *optarg; -extern int optind; - -#define PRINTF (void)printf -#define FPRINTF (void)fprintf -#define F_IN 0 -#define F_OUT 1 -#define F_ACIN 2 -#define F_ACOUT 3 -static char *filters[4] = { "ipfilter(in)", "ipfilter(out)", - "ipacct(in)", "ipacct(out)" }; - -int opts = 0; -int use_inet6 = 0; -int live_kernel = 1; -int state_fd = -1; -int auth_fd = -1; -int ipf_fd = -1; - -#ifdef STATETOP -#define STSTRSIZE 80 -#define STGROWSIZE 16 -#define HOSTNMLEN 40 - -#define STSORT_PR 0 -#define STSORT_PKTS 1 -#define STSORT_BYTES 2 -#define STSORT_TTL 3 -#define STSORT_SRCIP 4 -#define STSORT_DSTIP 5 -#define STSORT_MAX STSORT_DSTIP -#define STSORT_DEFAULT STSORT_BYTES - - -typedef struct statetop { - union i6addr st_src; - union i6addr st_dst; - u_short st_sport; - u_short st_dport; - u_char st_p; - u_char st_state[2]; - U_QUAD_T st_pkts; - U_QUAD_T st_bytes; - u_long st_age; -} statetop_t; -#endif - -extern int main __P((int, char *[])); -static void showstats __P((friostat_t *, u_32_t)); -static void showfrstates __P((ipfrstat_t *)); -static void showlist __P((friostat_t *)); -static void showipstates __P((ips_stat_t *)); -static void showauthstates __P((fr_authstat_t *)); -static void showgroups __P((friostat_t *)); -static void Usage __P((char *)); -static void printlist __P((frentry_t *)); -static void parse_ipportstr __P((const char *, struct in_addr *, int *)); -static int ipfstate_live __P((char *, friostat_t **, ips_stat_t **, - ipfrstat_t **, fr_authstat_t **, u_32_t *)); -static void ipfstate_dead __P((char *, friostat_t **, ips_stat_t **, - ipfrstat_t **, fr_authstat_t **, u_32_t *)); -#ifdef STATETOP -static void topipstates __P((struct in_addr, struct in_addr, int, int, int, int, int)); -static char *ttl_to_string __P((long)); -static int sort_p __P((const void *, const void *)); -static int sort_pkts __P((const void *, const void *)); -static int sort_bytes __P((const void *, const void *)); -static int sort_ttl __P((const void *, const void *)); -static int sort_srcip __P((const void *, const void *)); -static int sort_dstip __P((const void *, const void *)); -#endif -#if SOLARIS -void showqiflist __P((char *)); -#endif - - -static void Usage(name) -char *name; -{ -#ifdef USE_INET6 - fprintf(stderr, "Usage: %s [-6aAfhIinosv] [-d ]\n", name); -#else - fprintf(stderr, "Usage: %s [-aAfhIinosv] [-d ]\n", name); -#endif - fprintf(stderr, "\t\t[-M corefile] [-N symbol-list]\n"); - fprintf(stderr, " %s -t [-S source address] [-D destination address] [-P protocol] [-T refreshtime] [-C] [-d ]\n", name); - exit(1); -} - - -int main(argc,argv) -int argc; -char *argv[]; -{ - fr_authstat_t frauthst; - fr_authstat_t *frauthstp = &frauthst; - friostat_t fio; - friostat_t *fiop = &fio; - ips_stat_t ipsst; - ips_stat_t *ipsstp = &ipsst; - ipfrstat_t ifrst; - ipfrstat_t *ifrstp = &ifrst; - char *device = IPL_NAME, *memf = NULL; - char *kern = NULL; - int c, myoptind; - struct protoent *proto; - - int protocol = -1; /* -1 = wild card for any protocol */ - int refreshtime = 1; /* default update time */ - int sport = -1; /* -1 = wild card for any source port */ - int dport = -1; /* -1 = wild card for any dest port */ - int topclosed = 0; /* do not show closed tcp sessions */ - struct in_addr saddr, daddr; - u_32_t frf; - - saddr.s_addr = INADDR_ANY; /* default any source addr */ - daddr.s_addr = INADDR_ANY; /* default any dest addr */ - - /* - * Parse these two arguments now lest there be any buffer overflows - * in the parsing of the rest. - */ - myoptind = optind; - while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1) - switch (c) - { - case 'M' : - memf = optarg; - live_kernel = 0; - break; - case 'N' : - kern = optarg; - live_kernel = 0; - break; - } - optind = myoptind; - - if (live_kernel == 1) { - if ((state_fd = open(IPL_STATE, O_RDONLY)) == -1) { - perror("open"); - exit(-1); - } - if ((auth_fd = open(IPL_AUTH, O_RDONLY)) == -1) { - perror("open"); - exit(-1); - } - if ((ipf_fd = open(device, O_RDONLY)) == -1) { - perror("open"); - exit(-1); - } - } - - if (kern != NULL || memf != NULL) - { - (void)setuid(getuid()); - (void)setgid(getgid()); - } - - if (openkmem(kern, memf) == -1) - exit(-1); - - (void)setuid(getuid()); - (void)setgid(getgid()); - - while ((c = getopt(argc, argv, "6aACfghIilnoqstvd:D:M:N:P:S:T:")) != -1) - { - switch (c) - { -#ifdef USE_INET6 - case '6' : - use_inet6 = 1; - break; -#endif - case 'a' : - opts |= OPT_ACCNT|OPT_SHOWLIST; - break; - case 'A' : - device = IPAUTH_NAME; - opts |= OPT_AUTHSTATS; - break; - case 'C' : - topclosed = 1; - break; - case 'd' : - device = optarg; - break; - case 'D' : - parse_ipportstr(optarg, &daddr, &dport); - break; - case 'f' : - opts |= OPT_FRSTATES; - break; - case 'g' : - opts |= OPT_GROUPS; - break; - case 'h' : - opts |= OPT_HITS; - break; - case 'i' : - opts |= OPT_INQUE|OPT_SHOWLIST; - break; - case 'I' : - opts |= OPT_INACTIVE; - break; - case 'l' : - opts |= OPT_SHOWLIST; - break; - case 'M' : - break; - case 'N' : - break; - case 'n' : - opts |= OPT_SHOWLINENO; - break; - case 'o' : - opts |= OPT_OUTQUE|OPT_SHOWLIST; - break; - case 'P' : - if ((proto = getprotobyname(optarg)) != NULL) { - protocol = proto->p_proto; - } else if (!sscanf(optarg, "%ud", &protocol) || - (protocol < 0)) { - fprintf(stderr, "%s : Invalid protocol: %s\n", - argv[0], optarg); - exit(-2); - } - break; - case 'q' : -#if SOLARIS - showqiflist(kern); - exit(0); - break; -#else - fprintf(stderr, "-q only availble on Solaris\n"); - exit(1); - break; -#endif - case 's' : - opts |= OPT_IPSTATES; - break; - case 'S' : - parse_ipportstr(optarg, &saddr, &sport); - break; - case 't' : -#ifdef STATETOP - opts |= OPT_STATETOP; - break; -#else - fprintf(stderr, - "%s : state top facility not compiled in\n", - argv[0]); - exit(-2); -#endif - case 'T' : - if (!sscanf(optarg, "%d", &refreshtime) || - (refreshtime <= 0)) { - fprintf(stderr, - "%s : Invalid refreshtime < 1 : %s\n", - argv[0], optarg); - exit(-2); - } - break; - case 'v' : - opts |= OPT_VERBOSE; - break; - default : - Usage(argv[0]); - break; - } - } - - if (live_kernel == 1) { - bzero((char *)&fio, sizeof(fio)); - bzero((char *)&ipsst, sizeof(ipsst)); - bzero((char *)&ifrst, sizeof(ifrst)); - - ipfstate_live(device, &fiop, &ipsstp, &ifrstp, - &frauthstp, &frf); - } else - ipfstate_dead(kern, &fiop, &ipsstp, &ifrstp, &frauthstp, &frf); - - if (opts & OPT_IPSTATES) { - showipstates(ipsstp); - } else if (opts & OPT_SHOWLIST) { - showlist(fiop); - if ((opts & OPT_OUTQUE) && (opts & OPT_INQUE)){ - opts &= ~OPT_OUTQUE; - showlist(fiop); - } - } else { - if (opts & OPT_FRSTATES) - showfrstates(ifrstp); -#ifdef STATETOP - else if (opts & OPT_STATETOP) - topipstates(saddr, daddr, sport, dport, - protocol, refreshtime, topclosed); -#endif - else if (opts & OPT_AUTHSTATS) - showauthstates(frauthstp); - else if (opts & OPT_GROUPS) - showgroups(fiop); - else - showstats(fiop, frf); - } - return 0; -} - - -/* - * Fill in the stats structures from the live kernel, using a combination - * of ioctl's and copying directly from kernel memory. - */ -int ipfstate_live(device, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) -char *device; -friostat_t **fiopp; -ips_stat_t **ipsstpp; -ipfrstat_t **ifrstpp; -fr_authstat_t **frauthstpp; -u_32_t *frfp; -{ - - if (!(opts & OPT_AUTHSTATS) && ioctl(ipf_fd, SIOCGETFS, fiopp) == -1) { - perror("ioctl(ipf:SIOCGETFS)"); - exit(-1); - } - - if ((opts & OPT_IPSTATES)) { - if ((ioctl(state_fd, SIOCGETFS, ipsstpp) == -1)) { - perror("ioctl(state:SIOCGETFS)"); - exit(-1); - } - } - if ((opts & OPT_FRSTATES) && - (ioctl(ipf_fd, SIOCGFRST, ifrstpp) == -1)) { - perror("ioctl(SIOCGFRST)"); - exit(-1); - } - - if (opts & OPT_VERBOSE) - PRINTF("opts %#x name %s\n", opts, device); - - if ((opts & OPT_AUTHSTATS) && - (ioctl(auth_fd, SIOCATHST, frauthstpp) == -1)) { - perror("ioctl(SIOCATHST)"); - exit(-1); - } - - if (ioctl(ipf_fd, SIOCGETFF, frfp) == -1) - perror("ioctl(SIOCGETFF)"); - - return ipf_fd; -} - - -/* - * Build up the stats structures from data held in the "core" memory. - * This is mainly useful when looking at data in crash dumps and ioctl's - * just won't work any more. - */ -void ipfstate_dead(kernel, fiopp, ipsstpp, ifrstpp, frauthstpp, frfp) -char *kernel; -friostat_t **fiopp; -ips_stat_t **ipsstpp; -ipfrstat_t **ifrstpp; -fr_authstat_t **frauthstpp; -u_32_t *frfp; -{ - static fr_authstat_t frauthst, *frauthstp; - static ips_stat_t ipsst, *ipsstp; - static ipfrstat_t ifrst, *ifrstp; - static friostat_t fio, *fiop; - - void *rules[2][2]; - struct nlist deadlist[42] = { - { "fr_authstats" }, /* 0 */ - { "fae_list" }, - { "ipauth" }, - { "fr_authlist" }, - { "fr_authstart" }, - { "fr_authend" }, /* 5 */ - { "fr_authnext" }, - { "fr_auth" }, - { "fr_authused" }, - { "fr_authsize" }, - { "fr_defaultauthage" }, /* 10 */ - { "fr_authpkts" }, - { "fr_auth_lock" }, - { "frstats" }, - { "ips_stats" }, - { "ips_num" }, /* 15 */ - { "ips_wild" }, - { "ips_list" }, - { "ips_table" }, - { "fr_statemax" }, - { "fr_statesize" }, /* 20 */ - { "fr_state_doflush" }, - { "fr_state_lock" }, - { "ipfr_heads" }, - { "ipfr_nattab" }, - { "ipfr_stats" }, /* 25 */ - { "ipfr_inuse" }, - { "fr_ipfrttl" }, - { "fr_frag_lock" }, - { "ipfr_timer_id" }, - { "fr_nat_lock" }, /* 30 */ - { "ipfilter" }, - { "ipfilter6" }, - { "ipacct" }, - { "ipacct6" }, - { "ipl_frouteok" }, /* 35 */ - { "fr_running" }, - { "ipfgroups" }, - { "fr_active" }, - { "fr_pass" }, - { "fr_flags" }, /* 40 */ - { NULL } - }; - - - frauthstp = &frauthst; - ipsstp = &ipsst; - ifrstp = &ifrst; - fiop = &fio; - - *frfp = 0; - *fiopp = fiop; - *ipsstpp = ipsstp; - *ifrstpp = ifrstp; - *frauthstpp = frauthstp; - - bzero((char *)fiop, sizeof(*fiop)); - bzero((char *)ipsstp, sizeof(*ipsstp)); - bzero((char *)ifrstp, sizeof(*ifrstp)); - bzero((char *)frauthstp, sizeof(*frauthstp)); - - if (nlist(kernel, deadlist) == -1) { - fprintf(stderr, "nlist error\n"); - return; - } - - /* - * This is for SIOCGETFF. - */ - kmemcpy((char *)frfp, (u_long)deadlist[40].n_value, sizeof(*frfp)); - - /* - * f_locks is a combination of the lock variable from each part of - * ipfilter (state, auth, nat, fragments). - */ - kmemcpy((char *)fiop, (u_long)deadlist[13].n_value, sizeof(*fiop)); - kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[22].n_value, - sizeof(fiop->f_locks[0])); - kmemcpy((char *)&fiop->f_locks[0], (u_long)deadlist[30].n_value, - sizeof(fiop->f_locks[1])); - kmemcpy((char *)&fiop->f_locks[2], (u_long)deadlist[28].n_value, - sizeof(fiop->f_locks[2])); - kmemcpy((char *)&fiop->f_locks[3], (u_long)deadlist[12].n_value, - sizeof(fiop->f_locks[3])); - - /* - * Get pointers to each list of rules (active, inactive, in, out) - */ - kmemcpy((char *)&rules, (u_long)deadlist[31].n_value, sizeof(rules)); - fiop->f_fin[0] = rules[0][0]; - fiop->f_fin[1] = rules[0][1]; - fiop->f_fout[0] = rules[1][0]; - fiop->f_fout[1] = rules[1][1]; - - /* - * Same for IPv6, except make them null if support for it is not - * being compiled in. - */ -#ifdef USE_INET6 - kmemcpy((char *)&rules, (u_long)deadlist[32].n_value, sizeof(rules)); - fiop->f_fin6[0] = rules[0][0]; - fiop->f_fin6[1] = rules[0][1]; - fiop->f_fout6[0] = rules[1][0]; - fiop->f_fout6[1] = rules[1][1]; -#else - fiop->f_fin6[0] = NULL; - fiop->f_fin6[1] = NULL; - fiop->f_fout6[0] = NULL; - fiop->f_fout6[1] = NULL; -#endif - - /* - * Now get accounting rules pointers. - */ - kmemcpy((char *)&rules, (u_long)deadlist[33].n_value, sizeof(rules)); - fiop->f_acctin[0] = rules[0][0]; - fiop->f_acctin[1] = rules[0][1]; - fiop->f_acctout[0] = rules[1][0]; - fiop->f_acctout[1] = rules[1][1]; - -#ifdef USE_INET6 - kmemcpy((char *)&rules, (u_long)deadlist[34].n_value, sizeof(rules)); - fiop->f_acctin6[0] = rules[0][0]; - fiop->f_acctin6[1] = rules[0][1]; - fiop->f_acctout6[0] = rules[1][0]; - fiop->f_acctout6[1] = rules[1][1]; -#else - fiop->f_acctin6[0] = NULL; - fiop->f_acctin6[1] = NULL; - fiop->f_acctout6[0] = NULL; - fiop->f_acctout6[1] = NULL; -#endif - - /* - * A collection of "global" variables used inside the kernel which - * are all collected in friostat_t via ioctl. - */ - kmemcpy((char *)&fiop->f_froute, (u_long)deadlist[35].n_value, - sizeof(fiop->f_froute)); - kmemcpy((char *)&fiop->f_running, (u_long)deadlist[36].n_value, - sizeof(fiop->f_running)); - kmemcpy((char *)&fiop->f_groups, (u_long)deadlist[37].n_value, - sizeof(fiop->f_groups)); - kmemcpy((char *)&fiop->f_active, (u_long)deadlist[38].n_value, - sizeof(fiop->f_active)); - kmemcpy((char *)&fiop->f_defpass, (u_long)deadlist[39].n_value, - sizeof(fiop->f_defpass)); - - /* - * Build up the state information stats structure. - */ - kmemcpy((char *)ipsstp, (u_long)deadlist[14].n_value, sizeof(*ipsstp)); - kmemcpy((char *)&ipsstp->iss_active, (u_long)deadlist[15].n_value, - sizeof(ipsstp->iss_active)); - ipsstp->iss_table = (void *)deadlist[18].n_value; - ipsstp->iss_list = (void *)deadlist[17].n_value; - - /* - * Build up the authentiation information stats structure. - */ - kmemcpy((char *)frauthstp, (u_long)deadlist[0].n_value, - sizeof(*frauthstp)); - frauthstp->fas_faelist = (void *)deadlist[1].n_value; - - /* - * Build up the fragment information stats structure. - */ - kmemcpy((char *)ifrstp, (u_long)deadlist[25].n_value, - sizeof(*ifrstp)); - ifrstp->ifs_table = (void *)deadlist[23].n_value; - ifrstp->ifs_nattab = (void *)deadlist[24].n_value; - kmemcpy((char *)&ifrstp->ifs_inuse, (u_long)deadlist[26].n_value, - sizeof(ifrstp->ifs_inuse)); -} - - -/* - * Display the kernel stats for packets blocked and passed and other - * associated running totals which are kept. - */ -static void showstats(fp, frf) -struct friostat *fp; -u_32_t frf; -{ - -#if SOLARIS - PRINTF("dropped packets:\tin %lu\tout %lu\n", - fp->f_st[0].fr_drop, fp->f_st[1].fr_drop); - PRINTF("non-data packets:\tin %lu\tout %lu\n", - fp->f_st[0].fr_notdata, fp->f_st[1].fr_notdata); - PRINTF("no-data packets:\tin %lu\tout %lu\n", - fp->f_st[0].fr_nodata, fp->f_st[1].fr_nodata); - PRINTF("non-ip packets:\t\tin %lu\tout %lu\n", - fp->f_st[0].fr_notip, fp->f_st[1].fr_notip); - PRINTF(" bad packets:\t\tin %lu\tout %lu\n", - fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); - PRINTF("copied messages:\tin %lu\tout %lu\n", - fp->f_st[0].fr_copy, fp->f_st[1].fr_copy); -#endif -#ifdef USE_INET6 - PRINTF(" IPv6 packets:\t\tin %lu out %lu\n", - fp->f_st[0].fr_ipv6[0], fp->f_st[0].fr_ipv6[1]); -#endif - PRINTF(" input packets:\t\tblocked %lu passed %lu nomatch %lu", - fp->f_st[0].fr_block, fp->f_st[0].fr_pass, - fp->f_st[0].fr_nom); - PRINTF(" counted %lu short %lu\n", - fp->f_st[0].fr_acct, fp->f_st[0].fr_short); - PRINTF("output packets:\t\tblocked %lu passed %lu nomatch %lu", - fp->f_st[1].fr_block, fp->f_st[1].fr_pass, - fp->f_st[1].fr_nom); - PRINTF(" counted %lu short %lu\n", - fp->f_st[1].fr_acct, fp->f_st[1].fr_short); - PRINTF(" input packets logged:\tblocked %lu passed %lu\n", - fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); - PRINTF("output packets logged:\tblocked %lu passed %lu\n", - fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); - PRINTF(" packets logged:\tinput %lu output %lu\n", - fp->f_st[0].fr_pkl, fp->f_st[1].fr_pkl); - PRINTF(" log failures:\t\tinput %lu output %lu\n", - fp->f_st[0].fr_skip, fp->f_st[1].fr_skip); - PRINTF("fragment state(in):\tkept %lu\tlost %lu\tnot fragmented %lu\n", - fp->f_st[0].fr_nfr, fp->f_st[0].fr_bnfr, fp->f_st[0].fr_cfr); - PRINTF("fragment state(out):\tkept %lu\tlost %lu\tnot fragmented %lu\n", - fp->f_st[1].fr_nfr, fp->f_st[1].fr_bnfr, fp->f_st[1].fr_cfr); - PRINTF("packet state(in):\tkept %lu\tlost %lu\n", - fp->f_st[0].fr_ads, fp->f_st[0].fr_bads); - PRINTF("packet state(out):\tkept %lu\tlost %lu\n", - fp->f_st[1].fr_ads, fp->f_st[1].fr_bads); - PRINTF("ICMP replies:\t%lu\tTCP RSTs sent:\t%lu\n", - fp->f_st[0].fr_ret, fp->f_st[1].fr_ret); - PRINTF("Invalid source(in):\t%lu\n", fp->f_st[0].fr_badsrc); - PRINTF("Result cache hits(in):\t%lu\t(out):\t%lu\n", - fp->f_st[0].fr_chit, fp->f_st[1].fr_chit); - PRINTF("IN Pullups succeeded:\t%lu\tfailed:\t%lu\n", - fp->f_st[0].fr_pull[0], fp->f_st[0].fr_pull[1]); - PRINTF("OUT Pullups succeeded:\t%lu\tfailed:\t%lu\n", - fp->f_st[1].fr_pull[0], fp->f_st[1].fr_pull[1]); - PRINTF("Fastroute successes:\t%lu\tfailures:\t%lu\n", - fp->f_froute[0], fp->f_froute[1]); - PRINTF("TCP cksum fails(in):\t%lu\t(out):\t%lu\n", - fp->f_st[0].fr_tcpbad, fp->f_st[1].fr_tcpbad); - - PRINTF("Packet log flags set: (%#x)\n", frf); - if (frf & FF_LOGPASS) - PRINTF("\tpackets passed through filter\n"); - if (frf & FF_LOGBLOCK) - PRINTF("\tpackets blocked by filter\n"); - if (frf & FF_LOGNOMATCH) - PRINTF("\tpackets not matched by filter\n"); - if (!frf) - PRINTF("\tnone\n"); -} - - -/* - * Print out a list of rules from the kernel, starting at the one passed. - */ -static void printlist(fp) -frentry_t *fp; -{ - struct frentry fb; - int n; - - for (n = 1; fp; n++) { - if (kmemcpy((char *)&fb, (u_long)fp, sizeof(fb)) == -1) { - perror("kmemcpy"); - return; - } - fp = &fb; - if (opts & OPT_OUTQUE) - fp->fr_flags |= FR_OUTQUE; - if (opts & (OPT_HITS|OPT_VERBOSE)) -#ifdef USE_QUAD_T - PRINTF("%qu ", (unsigned long long) fp->fr_hits); -#else - PRINTF("%lu ", fp->fr_hits); -#endif - if (opts & (OPT_ACCNT|OPT_VERBOSE)) -#ifdef USE_QUAD_T - PRINTF("%qu ", (unsigned long long) fp->fr_bytes); -#else - PRINTF("%lu ", fp->fr_bytes); -#endif - if (opts & OPT_SHOWLINENO) - PRINTF("@%d ", n); - printfr(fp); - if (opts & OPT_VERBOSE) - binprint(fp); - if (fp->fr_grp) - printlist(fp->fr_grp); - fp = fp->fr_next; - } -} - -/* - * print out all of the asked for rule sets, using the stats struct as - * the base from which to get the pointers. - */ -static void showlist(fiop) -struct friostat *fiop; -{ - struct frentry *fp = NULL; - int i, set; - - set = fiop->f_active; - if (opts & OPT_INACTIVE) - set = 1 - set; - if (opts & OPT_ACCNT) { -#ifdef USE_INET6 - if ((use_inet6) && (opts & OPT_OUTQUE)) { - i = F_ACOUT; - fp = (struct frentry *)fiop->f_acctout6[set]; - } else if ((use_inet6) && (opts & OPT_INQUE)) { - i = F_ACIN; - fp = (struct frentry *)fiop->f_acctin6[set]; - } else -#endif - if (opts & OPT_OUTQUE) { - i = F_ACOUT; - fp = (struct frentry *)fiop->f_acctout[set]; - } else if (opts & OPT_INQUE) { - i = F_ACIN; - fp = (struct frentry *)fiop->f_acctin[set]; - } else { - FPRINTF(stderr, "No -i or -o given with -a\n"); - return; - } - } else { -#ifdef USE_INET6 - if ((use_inet6) && (opts & OPT_OUTQUE)) { - i = F_OUT; - fp = (struct frentry *)fiop->f_fout6[set]; - } else if ((use_inet6) && (opts & OPT_INQUE)) { - i = F_IN; - fp = (struct frentry *)fiop->f_fin6[set]; - } else -#endif - if (opts & OPT_OUTQUE) { - i = F_OUT; - fp = (struct frentry *)fiop->f_fout[set]; - } else if (opts & OPT_INQUE) { - i = F_IN; - fp = (struct frentry *)fiop->f_fin[set]; - } else - return; - } - if (opts & OPT_VERBOSE) - FPRINTF(stderr, "showlist:opts %#x i %d\n", opts, i); - - if (opts & OPT_VERBOSE) - PRINTF("fp %p set %d\n", fp, set); - if (fp == NULL) { - FPRINTF(stderr, "empty list for %s%s\n", - (opts & OPT_INACTIVE) ? "inactive " : "", filters[i]); - return; - } - printlist(fp); -} - - -/* - * Display ipfilter stateful filtering information - */ -static void showipstates(ipsp) -ips_stat_t *ipsp; -{ - ipstate_t *istab[IPSTATE_SIZE]; - - /* - * If a list of states hasn't been asked for, only print out stats - */ - if (!(opts & OPT_SHOWLIST)) { - PRINTF("IP states added:\n\t%lu TCP\n\t%lu UDP\n\t%lu ICMP\n", - ipsp->iss_tcp, ipsp->iss_udp, ipsp->iss_icmp); - PRINTF("\t%lu hits\n\t%lu misses\n", ipsp->iss_hits, - ipsp->iss_miss); - PRINTF("\t%lu maximum\n\t%lu no memory\n\t%lu bkts in use\n", - ipsp->iss_max, ipsp->iss_nomem, ipsp->iss_inuse); - PRINTF("\t%lu logged\n\t%lu log failures\n", - ipsp->iss_logged, ipsp->iss_logfail); - PRINTF("\t%lu active\n\t%lu expired\n\t%lu closed\n", - ipsp->iss_active, ipsp->iss_expire, ipsp->iss_fin); - return; - } - - if (kmemcpy((char *)istab, (u_long)ipsp->iss_table, sizeof(istab))) - return; - - /* - * Print out all the state information currently held in the kernel. - */ - while (ipsp->iss_list != NULL) { - ipsp->iss_list = printstate(ipsp->iss_list, opts); - } -} - - -#if SOLARIS -/* - * Displays the list of interfaces of which IPFilter has taken control in - * Solaris. - */ -void showqiflist(kern) -char *kern; -{ - struct nlist qifnlist[2] = { - { "_qif_head" }, - { NULL } - }; - qif_t qif, *qf; - ill_t ill; - - if (kern == NULL) - kern = "/dev/ksyms"; - - if (nlist(kern, qifnlist) == -1) { - fprintf(stderr, "nlist error\n"); - return; - } - - printf("List of interfaces bound by IPFilter:\n"); - if (kmemcpy((char *)&qf, (u_long)qifnlist[0].n_value, sizeof(qf))) - return; - while (qf) { - if (kmemcpy((char *)&qif, (u_long)qf, sizeof(qif))) - break; - if (kmemcpy((char *)&ill, (u_long)qif.qf_ill, sizeof(ill))) - ill.ill_ppa = -1; - printf("Name: %-8s Header Length: %2d SAP: %s (%04x) PPA %d", - qif.qf_name, qif.qf_hl, -#ifdef IP6_DL_SAP - (qif.qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4" -#else - "IPv4" -#endif - , qif.qf_sap, ill.ill_ppa); - printf(" %ld %ld", qif.qf_incnt, qif.qf_outcnt); - qf = qif.qf_next; - putchar('\n'); - } -} -#endif - - -#ifdef STATETOP -static void topipstates(saddr, daddr, sport, dport, protocol, - refreshtime, topclosed) -struct in_addr saddr; -struct in_addr daddr; -int sport; -int dport; -int protocol; -int refreshtime; -int topclosed; -{ - char str1[STSTRSIZE], str2[STSTRSIZE], str3[STSTRSIZE], str4[STSTRSIZE]; - int maxtsentries = 0, reverse = 0, sorting = STSORT_DEFAULT; - int i, j, winx, tsentry, maxx, maxy, redraw = 0; - ipstate_t *istab[IPSTATE_SIZE], ips; - ips_stat_t ipsst, *ipsstp = &ipsst; - statetop_t *tstable = NULL, *tp; - char hostnm[HOSTNMLEN]; - struct protoent *proto; - int c = 0; - time_t t; -#ifdef USE_POLL - struct pollfd set[1]; -#else - struct timeval selecttimeout; - fd_set readfd; -#endif - - /* init ncurses stuff */ - initscr(); - cbreak(); - noecho(); - - /* init hostname */ - gethostname(hostnm, sizeof(hostnm) - 1); - hostnm[sizeof(hostnm) - 1] = '\0'; - - /* repeat until user aborts */ - while ( 1 ) { - - /* get state table */ - bzero((char *)&ipsst, sizeof(&ipsst)); - if ((ioctl(state_fd, SIOCGETFS, &ipsstp) == -1)) { - perror("ioctl(SIOCGETFS)"); - exit(-1); - } - if (kmemcpy((char *)istab, (u_long)ipsstp->iss_table, - sizeof(ips))) - return; - - /* clear the history */ - tsentry = -1; - - /* read the state table and store in tstable */ - while (ipsstp->iss_list) { - if (kmemcpy((char *)&ips, (u_long)ipsstp->iss_list, - sizeof(ips))) - break; - ipsstp->iss_list = ips.is_next; - - if (((saddr.s_addr == INADDR_ANY) || - (saddr.s_addr == ips.is_saddr)) && - ((daddr.s_addr == INADDR_ANY) || - (daddr.s_addr == ips.is_daddr)) && - ((protocol < 0) || (protocol == ips.is_p)) && - (((ips.is_p != IPPROTO_TCP) && - (ips.is_p != IPPROTO_UDP)) || - (((sport < 0) || - (htons(sport) == ips.is_sport)) && - ((dport < 0) || - (htons(dport) == ips.is_dport)))) && - (topclosed || (ips.is_p != IPPROTO_TCP) || - (ips.is_state[0] < TCPS_LAST_ACK) || - (ips.is_state[1] < TCPS_LAST_ACK))) { - /* - * if necessary make room for this state - * entry - */ - tsentry++; - if (!maxtsentries || - (tsentry == maxtsentries)) { - - maxtsentries += STGROWSIZE; - tstable = realloc(tstable, maxtsentries * sizeof(statetop_t)); - if (!tstable) { - perror("malloc"); - exit(-1); - } - } - - /* fill structure */ - tp = tstable + tsentry; - tp->st_src = ips.is_src; - tp->st_dst = ips.is_dst; - tp->st_p = ips.is_p; - tp->st_state[0] = ips.is_state[0]; - tp->st_state[1] = ips.is_state[1]; - tp->st_pkts = ips.is_pkts; - tp->st_bytes = ips.is_bytes; - tp->st_age = ips.is_age; - if ((ips.is_p == IPPROTO_TCP) || - (ips.is_p == IPPROTO_UDP)) { - tp->st_sport = ips.is_sport; - tp->st_dport = ips.is_dport; - } - - } - } - - - /* sort the array */ - if (tsentry != -1) - switch (sorting) - { - case STSORT_PR: - qsort(tstable, tsentry + 1, - sizeof(statetop_t), sort_p); - break; - case STSORT_PKTS: - qsort(tstable, tsentry + 1, - sizeof(statetop_t), sort_pkts); - break; - case STSORT_BYTES: - qsort(tstable, tsentry + 1, - sizeof(statetop_t), sort_bytes); - break; - case STSORT_TTL: - qsort(tstable, tsentry + 1, - sizeof(statetop_t), sort_ttl); - break; - case STSORT_SRCIP: - qsort(tstable, tsentry + 1, - sizeof(statetop_t), sort_srcip); - break; - case STSORT_DSTIP: - qsort(tstable, tsentry + 1, - sizeof(statetop_t), sort_dstip); - break; - default: - break; - } - - /* print title */ - erase(); - getmaxyx(stdscr, maxy, maxx); - attron(A_BOLD); - winx = 0; - move(winx,0); - sprintf(str1, "%s - %s - state top", hostnm, IPL_VERSION); - for (j = 0 ; j < (maxx - 8 - strlen(str1)) / 2; j++) - printw(" "); - printw("%s", str1); - attroff(A_BOLD); - - /* just for fun add a clock */ - move(winx, maxx - 8); - t = time(NULL); - strftime(str1, 80, "%T", localtime(&t)); - printw("%s\n", str1); - - /* - * print the display filters, this is placed in the loop, - * because someday I might add code for changing these - * while the programming is running :-) - */ - if (sport >= 0) - sprintf(str1, "%s,%d", inet_ntoa(saddr), sport); - else - sprintf(str1, "%s", inet_ntoa(saddr)); - - if (dport >= 0) - sprintf(str2, "%s,%d", inet_ntoa(daddr), dport); - else - sprintf(str2, "%s", inet_ntoa(daddr)); - - if (protocol < 0) - strcpy(str3, "any"); - else if ((proto = getprotobynumber(protocol)) != NULL) - sprintf(str3, "%s", proto->p_name); - else - sprintf(str3, "%d", protocol); - - switch (sorting) - { - case STSORT_PR: - sprintf(str4, "proto"); - break; - case STSORT_PKTS: - sprintf(str4, "# pkts"); - break; - case STSORT_BYTES: - sprintf(str4, "# bytes"); - break; - case STSORT_TTL: - sprintf(str4, "ttl"); - break; - case STSORT_SRCIP: - sprintf(str4, "srcip"); - break; - case STSORT_DSTIP: - sprintf(str4, "dstip"); - break; - default: - sprintf(str4, "unknown"); - break; - } - - if (reverse) - strcat(str4, " (reverse)"); - - winx += 2; - move(winx,0); - printw("Src = %s Dest = %s Proto = %s Sorted by = %s\n\n", - str1, str2, str3, str4); - - /* print column description */ - winx += 2; - move(winx,0); - attron(A_BOLD); - printw("%-21s %-21s %3s %4s %7s %9s %9s\n", "Source IP", - "Destination IP", "ST", "PR", "#pkts", "#bytes", "ttl"); - attroff(A_BOLD); - - /* print all the entries */ - tp = tstable; - if (reverse) - tp += tsentry; - - if (tsentry > maxy - 6) - tsentry = maxy - 6; - for (i = 0; i <= tsentry; i++) { - /* print src/dest and port */ - if ((tp->st_p == IPPROTO_TCP) || - (tp->st_p == IPPROTO_UDP)) { - sprintf(str1, "%s,%hu", - inet_ntoa(tp->st_src.in4), - ntohs(tp->st_sport)); - sprintf(str2, "%s,%hu", - inet_ntoa(tp->st_dst.in4), - ntohs(tp->st_dport)); - } else { - sprintf(str1, "%s", inet_ntoa(tp->st_src.in4)); - sprintf(str2, "%s", inet_ntoa(tp->st_dst.in4)); - } - winx++; - move(winx, 0); - printw("%-21s %-21s", str1, str2); - - /* print state */ - sprintf(str1, "%X/%X", tp->st_state[0], - tp->st_state[1]); - printw(" %3s", str1); - - /* print proto */ - proto = getprotobynumber(tp->st_p); - if (proto) { - strncpy(str1, proto->p_name, 4); - str1[4] = '\0'; - } else { - sprintf(str1, "%d", tp->st_p); - } - printw(" %4s", str1); - /* print #pkt/#bytes */ -#ifdef USE_QUAD_T - printw(" %7qu %9qu", (unsigned long long) tp->st_pkts, - (unsigned long long) tp->st_bytes); -#else - printw(" %7lu %9lu", tp->st_pkts, tp->st_bytes); -#endif - printw(" %9s", ttl_to_string(tp->st_age)); - - if (reverse) - tp--; - else - tp++; - } - - /* screen data structure is filled, now update the screen */ - if (redraw) - clearok(stdscr,1); - - refresh(); - if (redraw) { - clearok(stdscr,0); - redraw = 0; - } - - /* wait for key press or a 1 second time out period */ -#ifdef USE_POLL - set[0].fd = 0; - set[0].events = POLLIN; - poll(set, 1, refreshtime * 1000); - - /* if key pressed, read all waiting keys */ - if (set[0].revents & POLLIN) -#else - selecttimeout.tv_sec = refreshtime; - selecttimeout.tv_usec = 0; - FD_ZERO(&readfd); - FD_SET(0, &readfd); - select(1, &readfd, NULL, NULL, &selecttimeout); - - /* if key pressed, read all waiting keys */ - if (FD_ISSET(0, &readfd)) -#endif - - { - c = wgetch(stdscr); - if (c == ERR) - continue; - - if (isalpha(c) && isupper(c)) - c = tolower(c); - if (c == 'l') { - redraw = 1; - } else if (c == 'q') { - break; /* exits while() loop */ - } else if (c == 'r') { - reverse = !reverse; - } else if (c == 's') { - sorting++; - if (sorting > STSORT_MAX) - sorting = 0; - } - } - } /* while */ - - printw("\n"); - nocbreak(); - endwin(); -} -#endif - - -/* - * Show fragment cache information that's held in the kernel. - */ -static void showfrstates(ifsp) -ipfrstat_t *ifsp; -{ - struct ipfr *ipfrtab[IPFT_SIZE], ifr; - frentry_t fr; - int i; - - /* - * print out the numeric statistics - */ - PRINTF("IP fragment states:\n\t%lu new\n\t%lu expired\n\t%lu hits\n", - ifsp->ifs_new, ifsp->ifs_expire, ifsp->ifs_hits); - PRINTF("\t%lu no memory\n\t%lu already exist\n", - ifsp->ifs_nomem, ifsp->ifs_exists); - PRINTF("\t%lu inuse\n", ifsp->ifs_inuse); - if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_table, sizeof(ipfrtab))) - return; - - /* - * Print out the contents (if any) of the fragment cache table. - */ - PRINTF("\n"); - for (i = 0; i < IPFT_SIZE; i++) - while (ipfrtab[i]) { - if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], - sizeof(ifr)) == -1) - break; - PRINTF("%s -> ", hostname(4, &ifr.ipfr_src)); - if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule, - sizeof(fr)) == -1) - break; - PRINTF("%s id %d ttl %d pr %d seen0 %d ifp %p tos %#02x = fl %#x\n", - hostname(4, &ifr.ipfr_dst), ntohs(ifr.ipfr_id), - ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_seen0, - ifr.ipfr_ifp, ifr.ipfr_tos, fr.fr_flags); - ipfrtab[i] = ifr.ipfr_next; - } - if (kmemcpy((char *)ipfrtab, (u_long)ifsp->ifs_nattab,sizeof(ipfrtab))) - return; - for (i = 0; i < IPFT_SIZE; i++) - while (ipfrtab[i]) { - if (kmemcpy((char *)&ifr, (u_long)ipfrtab[i], - sizeof(ifr)) == -1) - break; - PRINTF("NAT: %s -> ", hostname(4, &ifr.ipfr_src)); - if (kmemcpy((char *)&fr, (u_long)ifr.ipfr_rule, - sizeof(fr)) == -1) - break; - PRINTF("%s %d %d %d %#02x = %#x\n", - hostname(4, &ifr.ipfr_dst), ifr.ipfr_id, - ifr.ipfr_ttl, ifr.ipfr_p, ifr.ipfr_tos, - fr.fr_flags); - ipfrtab[i] = ifr.ipfr_next; - } -} - - -/* - * Show stats on how auth within IPFilter has been used - */ -static void showauthstates(asp) -fr_authstat_t *asp; -{ - frauthent_t *frap, fra; - -#ifdef USE_QUAD_T - printf("Authorisation hits: %qu\tmisses %qu\n", - (unsigned long long) asp->fas_hits, - (unsigned long long) asp->fas_miss); -#else - printf("Authorisation hits: %ld\tmisses %ld\n", asp->fas_hits, - asp->fas_miss); -#endif - printf("nospace %ld\nadded %ld\nsendfail %ld\nsendok %ld\n", - asp->fas_nospace, asp->fas_added, asp->fas_sendfail, - asp->fas_sendok); - printf("queok %ld\nquefail %ld\nexpire %ld\n", - asp->fas_queok, asp->fas_quefail, asp->fas_expire); - - frap = asp->fas_faelist; - while (frap) { - if (kmemcpy((char *)&fra, (u_long)frap, sizeof(fra)) == -1) - break; - - printf("age %ld\t", fra.fae_age); - printfr(&fra.fae_fr); - frap = fra.fae_next; - } -} - - -/* - * Display groups used for each of filter rules, accounting rules and - * authentication, separately. - */ -static void showgroups(fiop) -struct friostat *fiop; -{ - static char *gnames[3] = { "Filter", "Accounting", "Authentication" }; - frgroup_t *fp, grp; - int on, off, i; - - on = fiop->f_active; - off = 1 - on; - - for (i = 0; i < 3; i++) { - printf("%s groups (active):\n", gnames[i]); - for (fp = fiop->f_groups[i][on]; fp; fp = grp.fg_next) - if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) - break; - else - printf("%hu\n", grp.fg_num); - printf("%s groups (inactive):\n", gnames[i]); - for (fp = fiop->f_groups[i][off]; fp; fp = grp.fg_next) - if (kmemcpy((char *)&grp, (u_long)fp, sizeof(grp))) - break; - else - printf("%hu\n", grp.fg_num); - } -} - -static void parse_ipportstr(argument, ip, port) -const char *argument; -struct in_addr *ip; -int *port; -{ - - char *s, *comma; - - /* make working copy of argument, Theoretically you must be able - * to write to optarg, but that seems very ugly to me.... - */ - if ((s = malloc(strlen(argument) + 1)) == NULL) - perror("malloc"); - strcpy(s, argument); - - /* get port */ - if ((comma = strchr(s, ',')) != NULL) { - if (!strcasecmp(s, "any")) { - *port = -1; - } else if (!sscanf(comma + 1, "%d", port) || - (*port < 0) || (*port > 65535)) { - fprintf(stderr, "Invalid port specfication in %s\n", - argument); - exit(-2); - } - *comma = '\0'; - } - - - /* get ip address */ - if (!strcasecmp(s, "any")) { - ip->s_addr = INADDR_ANY; - } else if (!inet_aton(s, ip)) { - fprintf(stderr, "Invalid IP address: %s\n", s); - exit(-2); - } - - /* free allocated memory */ - free(s); -} - - -#ifdef STATETOP -static char ttlbuf[STSTRSIZE]; - -static char *ttl_to_string(ttl) -long int ttl; -{ - - int hours, minutes, seconds; - - /* ttl is in half seconds */ - ttl /= 2; - - hours = ttl / 3600; - ttl = ttl % 3600; - minutes = ttl / 60; - seconds = ttl % 60; - - if (hours > 0 ) - sprintf(ttlbuf, "%2d:%02d:%02d", hours, minutes, seconds); - else - sprintf(ttlbuf, "%2d:%02d", minutes, seconds); - return ttlbuf; -} - - -static int sort_pkts(a, b) -const void *a; -const void *b; -{ - - register const statetop_t *ap = a; - register const statetop_t *bp = b; - - if (ap->st_pkts == bp->st_pkts) - return 0; - else if (ap->st_pkts < bp->st_pkts) - return 1; - return -1; -} - - -static int sort_bytes(a, b) -const void *a; -const void *b; -{ - register const statetop_t *ap = a; - register const statetop_t *bp = b; - - if (ap->st_bytes == bp->st_bytes) - return 0; - else if (ap->st_bytes < bp->st_bytes) - return 1; - return -1; -} - - -static int sort_p(a, b) -const void *a; -const void *b; -{ - register const statetop_t *ap = a; - register const statetop_t *bp = b; - - if (ap->st_p == bp->st_p) - return 0; - else if (ap->st_p < bp->st_p) - return 1; - return -1; -} - - -static int sort_ttl(a, b) -const void *a; -const void *b; -{ - register const statetop_t *ap = a; - register const statetop_t *bp = b; - - if (ap->st_age == bp->st_age) - return 0; - else if (ap->st_age < bp->st_age) - return 1; - return -1; -} - -static int sort_srcip(a, b) -const void *a; -const void *b; -{ - register const statetop_t *ap = a; - register const statetop_t *bp = b; - - if (ntohl(ap->st_src.in4.s_addr) == ntohl(bp->st_src.in4.s_addr)) - return 0; - else if (ntohl(ap->st_src.in4.s_addr) > ntohl(bp->st_src.in4.s_addr)) - return 1; - return -1; -} - -static int sort_dstip(a, b) -const void *a; -const void *b; -{ - register const statetop_t *ap = a; - register const statetop_t *bp = b; - - if (ntohl(ap->st_dst.in4.s_addr) == ntohl(bp->st_dst.in4.s_addr)) - return 0; - else if (ntohl(ap->st_dst.in4.s_addr) > ntohl(bp->st_dst.in4.s_addr)) - return 1; - return -1; -} -#endif diff --git a/contrib/ipfilter/inet_addr.c b/contrib/ipfilter/inet_addr.c deleted file mode 100644 index e940280a280a..000000000000 --- a/contrib/ipfilter/inet_addr.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - * ++Copyright++ 1983, 1990, 1993 - * - - * Copyright (c) 1983, 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - - * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies, and that - * the name of Digital Equipment Corporation not be used in advertising or - * publicity pertaining to distribution of the document or software without - * specific, written prior permission. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL - * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT - * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL - * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR - * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS - * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - * - - * --Copyright-- - */ -#ifdef __STDC__ -# ifndef __P -# define __P(x) x -# endif -#else -# undef __P -# define __P(x) () -# undef const -# define const -#endif - -#if !defined(lint) -static const char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93"; -static const char rcsid[] = "@(#)$Id: inet_addr.c,v 2.1.4.2 2002/02/22 15:32:46 darrenr Exp $"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include -#include - -int inet_aton __P((const char *, struct in_addr *)); - -/* - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - */ -int -inet_aton(cp, addr) - register const char *cp; - struct in_addr *addr; -{ - register u_long val; - register int base, n; - register char c; - u_int parts[4]; - register u_int *pp = parts; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, isdigit=decimal. - */ - if (!isdigit(c)) - return (0); - val = 0; base = 10; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') - base = 16, c = *++cp; - else - base = 8; - } - for (;;) { - if (isascii(c) && isdigit(c)) { - val = (val * base) + (c - '0'); - c = *++cp; - } else if (base == 16 && isascii(c) && isxdigit(c)) { - val = (val << 4) | - (c + 10 - (islower(c) ? 'a' : 'A')); - c = *++cp; - } else - break; - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3) - return (0); - *pp++ = val; - c = *++cp; - } else - break; - } - /* - * Check for trailing characters. - */ - if (c != '\0' && (!isascii(c) || !isspace(c))) - return (0); - /* - * Concoct the address according to - * the number of parts specified. - */ - n = pp - parts + 1; - switch (n) { - - case 0: - return (0); /* initial nondigit */ - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffff) - return (0); - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffff) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xff) - return (0); - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - } - if (addr) - addr->s_addr = htonl(val); - return (1); -} - -/* these are compatibility routines, not needed on recent BSD releases */ - -/* - * Ascii internet address interpretation routine. - * The value returned is in network order. - */ -#if (defined(SOLARIS2) && (SOLARIS2 > 5)) || \ - (defined(IRIX) && (IRIX >= 605)) -in_addr_t -#else -u_long -#endif -inet_addr(cp) - register const char *cp; -{ - struct in_addr val; - - if (inet_aton(cp, &val)) - return (val.s_addr); - return (0xffffffff); -} diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c deleted file mode 100644 index b91c2e6245c0..000000000000 --- a/contrib/ipfilter/ip_auth.c +++ /dev/null @@ -1,804 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#include -#if !defined(_KERNEL) -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include -# include -#else -# include -#endif -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) -# include -# if !defined(__SVR4) && !defined(__svr4__) && !defined(linux) -# include -# endif -#endif -#if defined(__SVR4) || defined(__svr4__) -# include -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif -#if (_BSDI_VERSION >= 199802) || (__FreeBSD_version >= 400000) -# include -#endif -#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi) -# include -#endif -#if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -# include -#endif -#include -#ifdef sun -# include -#endif -#include -#include -#include -#include -#if !defined(_KERNEL) && !defined(__osf__) && !defined(__sgi) -# define KERNEL -# define _KERNEL -# define NOT_KERNEL -#endif -#if !defined(linux) -# include -#endif -#ifdef NOT_KERNEL -# undef _KERNEL -# undef KERNEL -#endif -#include -#if defined(IRIX) && (IRIX < 60516) /* IRIX < 6 */ -extern struct ifqueue ipintrq; /* ip packet input queue */ -#else -# if !defined(__hpux) && !defined(linux) -# if __FreeBSD_version >= 300000 -# include -# if __FreeBSD_version >= 500042 -# define IF_QFULL _IF_QFULL -# define IF_DROP _IF_DROP -# endif /* __FreeBSD_version >= 500042 */ -# endif -# include -# include -# endif -#endif -#include -#include -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_auth.h" -#if !defined(MENTAT) && !defined(linux) -# include -# ifdef __FreeBSD__ -# include -# endif -#endif -#if (__FreeBSD_version >= 300000) -# include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include -# include -# endif -#endif -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp"; -#endif - - -#if SOLARIS -extern kcondvar_t ipfauthwait; -#endif /* SOLARIS */ -#if defined(linux) && defined(_KERNEL) -wait_queue_head_t fr_authnext_linux; -#endif - -int fr_authsize = FR_NUMAUTH; -int fr_authused = 0; -int fr_defaultauthage = 600; -int fr_auth_lock = 0; -int fr_auth_init = 0; -fr_authstat_t fr_authstats; -static frauth_t *fr_auth = NULL; -mb_t **fr_authpkts = NULL; -int fr_authstart = 0, fr_authend = 0, fr_authnext = 0; -frauthent_t *fae_list = NULL; -frentry_t *ipauth = NULL, - *fr_authlist = NULL; - - -int fr_authinit() -{ - KMALLOCS(fr_auth, frauth_t *, fr_authsize * sizeof(*fr_auth)); - if (fr_auth != NULL) - bzero((char *)fr_auth, fr_authsize * sizeof(*fr_auth)); - else - return -1; - - KMALLOCS(fr_authpkts, mb_t **, fr_authsize * sizeof(*fr_authpkts)); - if (fr_authpkts != NULL) - bzero((char *)fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); - else - return -2; - - MUTEX_INIT(&ipf_authmx, "ipf auth log mutex"); - RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock"); -#if SOLARIS && defined(_KERNEL) - cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); -#endif -#if defined(linux) && defined(_KERNEL) - init_waitqueue_head(&fr_authnext_linux); -#endif - - fr_auth_init = 1; - - return 0; -} - - -/* - * Check if a packet has authorization. If the packet is found to match an - * authorization result and that would result in a feedback loop (i.e. it - * will end up returning FR_AUTH) then return FR_BLOCK instead. - */ -frentry_t *fr_checkauth(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - frentry_t *fr; - frauth_t *fra; - u_32_t pass; - u_short id; - ip_t *ip; - int i; - - if (fr_auth_lock || !fr_authused) - return NULL; - - ip = fin->fin_ip; - id = ip->ip_id; - - READ_ENTER(&ipf_auth); - for (i = fr_authstart; i != fr_authend; ) { - /* - * index becomes -2 only after an SIOCAUTHW. Check this in - * case the same packet gets sent again and it hasn't yet been - * auth'd. - */ - fra = fr_auth + i; - if ((fra->fra_index == -2) && (id == fra->fra_info.fin_id) && - !bcmp((char *)fin, (char *)&fra->fra_info, FI_CSIZE)) { - /* - * Avoid feedback loop. - */ - if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass))) - pass = FR_BLOCK; - /* - * Create a dummy rule for the stateful checking to - * use and return. Zero out any values we don't - * trust from userland! - */ - if ((pass & FR_KEEPSTATE) || ((pass & FR_KEEPFRAG) && - (fin->fin_flx & FI_FRAG))) { - KMALLOC(fr, frentry_t *); - if (fr) { - bcopy((char *)fra->fra_info.fin_fr, - (char *)fr, sizeof(*fr)); - fr->fr_grp = NULL; - fr->fr_ifa = fin->fin_ifp; - fr->fr_func = NULL; - fr->fr_ref = 1; - fr->fr_flags = pass; - fr->fr_ifas[1] = NULL; - fr->fr_ifas[2] = NULL; - fr->fr_ifas[3] = NULL; - } - } else - fr = fra->fra_info.fin_fr; - fin->fin_fr = fr; - RWLOCK_EXIT(&ipf_auth); - WRITE_ENTER(&ipf_auth); - if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) { - fr->fr_next = fr_authlist; - fr_authlist = fr; - } - fr_authstats.fas_hits++; - fra->fra_index = -1; - fr_authused--; - if (i == fr_authstart) { - while (fra->fra_index == -1) { - i++; - fra++; - if (i == fr_authsize) { - i = 0; - fra = fr_auth; - } - fr_authstart = i; - if (i == fr_authend) - break; - } - if (fr_authstart == fr_authend) { - fr_authnext = 0; - fr_authstart = fr_authend = 0; - } - } - RWLOCK_EXIT(&ipf_auth); - if (passp != NULL) - *passp = pass; - ATOMIC_INC64(fr_authstats.fas_hits); - return fr; - } - i++; - if (i == fr_authsize) - i = 0; - } - fr_authstats.fas_miss++; - RWLOCK_EXIT(&ipf_auth); - ATOMIC_INC64(fr_authstats.fas_miss); - return NULL; -} - - -/* - * Check if we have room in the auth array to hold details for another packet. - * If we do, store it and wake up any user programs which are waiting to - * hear about these events. - */ -int fr_newauth(m, fin) -mb_t *m; -fr_info_t *fin; -{ -#if defined(_KERNEL) && defined(MENTAT) - qpktinfo_t *qpi = fin->fin_qpi; -#endif - frauth_t *fra; -#if !defined(sparc) && !defined(m68k) - ip_t *ip; -#endif - int i; - - if (fr_auth_lock) - return 0; - - WRITE_ENTER(&ipf_auth); - if (fr_authstart > fr_authend) { - fr_authstats.fas_nospace++; - RWLOCK_EXIT(&ipf_auth); - return 0; - } else { - if (fr_authused == fr_authsize) { - fr_authstats.fas_nospace++; - RWLOCK_EXIT(&ipf_auth); - return 0; - } - } - - fr_authstats.fas_added++; - fr_authused++; - i = fr_authend++; - if (fr_authend == fr_authsize) - fr_authend = 0; - RWLOCK_EXIT(&ipf_auth); - - fra = fr_auth + i; - fra->fra_index = i; - fra->fra_pass = 0; - fra->fra_age = fr_defaultauthage; - bcopy((char *)fin, (char *)&fra->fra_info, sizeof(*fin)); -#if !defined(sparc) && !defined(m68k) - /* - * No need to copyback here as we want to undo the changes, not keep - * them. - */ - ip = fin->fin_ip; -# if defined(MENTAT) && defined(_KERNEL) - if ((ip == (ip_t *)m->b_rptr) && (fin->fin_v == 4)) -# endif - { - register u_short bo; - - bo = ip->ip_len; - ip->ip_len = htons(bo); - bo = ip->ip_off; - ip->ip_off = htons(bo); - } -#endif -#if SOLARIS && defined(_KERNEL) - m->b_rptr -= qpi->qpi_off; - fr_authpkts[i] = *(mblk_t **)fin->fin_mp; - fra->fra_q = qpi->qpi_q; /* The queue can disappear! */ - cv_signal(&ipfauthwait); -#else -# if defined(BSD) && !defined(sparc) && (BSD >= 199306) - if (!fin->fin_out) { - ip->ip_len = htons(ip->ip_len); - ip->ip_off = htons(ip->ip_off); - } -# endif - fr_authpkts[i] = m; - WAKEUP(&fr_authnext,0); -#endif - return 1; -} - - -int fr_auth_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - mb_t *m; -#if defined(_KERNEL) && !defined(MENTAT) && !defined(linux) && \ - (!defined(__FreeBSD_version) || (__FreeBSD_version < 501000)) - struct ifqueue *ifq; -# ifdef USE_SPL - int s; -# endif /* USE_SPL */ -#endif - frauth_t auth, *au = &auth, *fra; - int i, error = 0, len; - char *t; - - switch (cmd) - { - case SIOCSTLCK : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - fr_lock(data, &fr_auth_lock); - break; - - case SIOCATHST: - fr_authstats.fas_faelist = fae_list; - error = fr_outobj(data, &fr_authstats, IPFOBJ_AUTHSTAT); - break; - - case SIOCIPFFL: - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - i = fr_authflush(); - RWLOCK_EXIT(&ipf_auth); - SPL_X(s); - error = copyoutptr((char *)&i, data, sizeof(i)); - break; - - case SIOCAUTHW: -fr_authioctlloop: - error = fr_inobj(data, au, IPFOBJ_FRAUTH); - READ_ENTER(&ipf_auth); - if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) { - error = fr_outobj(data, &fr_auth[fr_authnext], - IPFOBJ_FRAUTH); - if (auth.fra_len != 0 && auth.fra_buf != NULL) { - /* - * Copy packet contents out to user space if - * requested. Bail on an error. - */ - m = fr_authpkts[fr_authnext]; - len = MSGDSIZE(m); - if (len > auth.fra_len) - len = auth.fra_len; - auth.fra_len = len; - for (t = auth.fra_buf; m && (len > 0); ) { - i = MIN(M_LEN(m), len); - error = copyoutptr(MTOD(m, char *), - t, i); - len -= i; - t += i; - if (error != 0) - break; - } - } - RWLOCK_EXIT(&ipf_auth); - if (error != 0) - break; - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - fr_authnext++; - if (fr_authnext == fr_authsize) - fr_authnext = 0; - RWLOCK_EXIT(&ipf_auth); - SPL_X(s); - return 0; - } - RWLOCK_EXIT(&ipf_auth); - /* - * We exit ipf_global here because a program that enters in - * here will have a lock on it and goto sleep having this lock. - * If someone were to do an 'ipf -D' the system would then - * deadlock. The catch with releasing it here is that the - * caller of this function expects it to be held when we - * return so we have to reacquire it in here. - */ - RWLOCK_EXIT(&ipf_global); - - MUTEX_ENTER(&ipf_authmx); -#ifdef _KERNEL -# if SOLARIS - error = 0; - if (!cv_wait_sig(&ipfauthwait, &ipf_authmx.ipf_lk)) - error = EINTR; -# else /* SOLARIS */ -# ifdef __hpux - { - lock_t *l; - - l = get_sleep_lock(&fr_authnext); - error = sleep(&fr_authnext, PZERO+1); - spinunlock(l); - } -# else -# ifdef __osf__ - error = mpsleep(&fr_authnext, PSUSP|PCATCH, "fr_authnext", 0, - &ipf_authmx, MS_LOCK_SIMPLE); -# else - error = SLEEP(&fr_authnext, "fr_authnext"); -# endif /* __osf__ */ -# endif /* __hpux */ -# endif /* SOLARIS */ -#endif - MUTEX_EXIT(&ipf_authmx); - READ_ENTER(&ipf_global); - if (error == 0) { - READ_ENTER(&ipf_auth); - goto fr_authioctlloop; - } - break; - - case SIOCAUTHR: - error = fr_inobj(data, &auth, IPFOBJ_FRAUTH); - if (error != 0) - return error; - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - i = au->fra_index; - fra = fr_auth + i; - if ((i < 0) || (i >= fr_authsize) || - (fra->fra_info.fin_id != au->fra_info.fin_id)) { - RWLOCK_EXIT(&ipf_auth); - SPL_X(s); - return ESRCH; - } - m = fr_authpkts[i]; - fra->fra_index = -2; - fra->fra_pass = au->fra_pass; - fr_authpkts[i] = NULL; - RWLOCK_EXIT(&ipf_auth); -#ifdef _KERNEL - if ((m != NULL) && (au->fra_info.fin_out != 0)) { -# ifdef MENTAT - error = !putq(fra->fra_q, m); -# else /* MENTAT */ -# ifdef linux -# else -# if (_BSDI_VERSION >= 199802) || defined(__OpenBSD__) || \ - (defined(__sgi) && (IRIX >= 60500) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 470102))) - error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, - NULL); -# else - error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); -# endif -# endif /* Linux */ -# endif /* MENTAT */ - if (error != 0) - fr_authstats.fas_sendfail++; - else - fr_authstats.fas_sendok++; - } else if (m) { -# ifdef MENTAT - error = !putq(fra->fra_q, m); -# else /* MENTAT */ -# ifdef linux -# else -# if __FreeBSD_version >= 501000 - netisr_dispatch(NETISR_IP, m); -# else -# if IRIX >= 60516 - ifq = &((struct ifnet *)fra->fra_info.fin_ifp)->if_snd; -# else - ifq = &ipintrq; -# endif - if (IF_QFULL(ifq)) { - IF_DROP(ifq); - FREE_MB_T(m); - error = ENOBUFS; - } else { - IF_ENQUEUE(ifq, m); -# if IRIX < 60500 - schednetisr(NETISR_IP); -# endif - } -# endif -# endif /* Linux */ -# endif /* MENTAT */ - if (error != 0) - fr_authstats.fas_quefail++; - else - fr_authstats.fas_queok++; - } else - error = EINVAL; -# ifdef MENTAT - if (error != 0) - error = EINVAL; -# else /* MENTAT */ - /* - * If we experience an error which will result in the packet - * not being processed, make sure we advance to the next one. - */ - if (error == ENOBUFS) { - fr_authused--; - fra->fra_index = -1; - fra->fra_pass = 0; - if (i == fr_authstart) { - while (fra->fra_index == -1) { - i++; - if (i == fr_authsize) - i = 0; - fr_authstart = i; - if (i == fr_authend) - break; - } - if (fr_authstart == fr_authend) { - fr_authnext = 0; - fr_authstart = fr_authend = 0; - } - } - } -# endif /* MENTAT */ -#endif /* _KERNEL */ - SPL_X(s); - break; - - default : - error = EINVAL; - break; - } - return error; -} - - -/* - * Free all network buffer memory used to keep saved packets. - */ -void fr_authunload() -{ - register int i; - register frauthent_t *fae, **faep; - frentry_t *fr, **frp; - mb_t *m; - - if (fr_auth != NULL) { - KFREES(fr_auth, fr_authsize * sizeof(*fr_auth)); - fr_auth = NULL; - } - - if (fr_authpkts != NULL) { - for (i = 0; i < fr_authsize; i++) { - m = fr_authpkts[i]; - if (m != NULL) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - } - } - KFREES(fr_authpkts, fr_authsize * sizeof(*fr_authpkts)); - fr_authpkts = NULL; - } - - faep = &fae_list; - while ((fae = *faep) != NULL) { - *faep = fae->fae_next; - KFREE(fae); - } - ipauth = NULL; - - if (fr_authlist != NULL) { - for (frp = &fr_authlist; ((fr = *frp) != NULL); ) { - if (fr->fr_ref == 1) { - *frp = fr->fr_next; - KFREE(fr); - } else - frp = &fr->fr_next; - } - } - - if (fr_auth_init == 1) { -# if SOLARIS && defined(_KERNEL) - cv_destroy(&ipfauthwait); -# endif - MUTEX_DESTROY(&ipf_authmx); - RW_DESTROY(&ipf_auth); - - fr_auth_init = 0; - } -} - - -/* - * Slowly expire held auth records. Timeouts are set - * in expectation of this being called twice per second. - */ -void fr_authexpire() -{ - register int i; - register frauth_t *fra; - register frauthent_t *fae, **faep; - register frentry_t *fr, **frp; - mb_t *m; -# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL) - int s; -# endif - - if (fr_auth_lock) - return; - - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - for (i = 0, fra = fr_auth; i < fr_authsize; i++, fra++) { - fra->fra_age--; - if ((fra->fra_age == 0) && (m = fr_authpkts[i])) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - fr_auth[i].fra_index = -1; - fr_authstats.fas_expire++; - fr_authused--; - } - } - - for (faep = &fae_list; ((fae = *faep) != NULL); ) { - fae->fae_age--; - if (fae->fae_age == 0) { - *faep = fae->fae_next; - KFREE(fae); - fr_authstats.fas_expire++; - } else - faep = &fae->fae_next; - } - if (fae_list != NULL) - ipauth = &fae_list->fae_fr; - else - ipauth = NULL; - - for (frp = &fr_authlist; ((fr = *frp) != NULL); ) { - if (fr->fr_ref == 1) { - *frp = fr->fr_next; - KFREE(fr); - } else - frp = &fr->fr_next; - } - RWLOCK_EXIT(&ipf_auth); - SPL_X(s); -} - -int fr_preauthcmd(cmd, fr, frptr) -ioctlcmd_t cmd; -frentry_t *fr, **frptr; -{ - frauthent_t *fae, **faep; - int error = 0; -# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL) - int s; -#endif - - if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) - return EIO; - - for (faep = &fae_list; ((fae = *faep) != NULL); ) { - if (&fae->fae_fr == fr) - break; - else - faep = &fae->fae_next; - } - - if (cmd == (ioctlcmd_t)SIOCRMAFR) { - if (fr == NULL || frptr == NULL) - error = EINVAL; - else if (fae == NULL) - error = ESRCH; - else { - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - *faep = fae->fae_next; - if (ipauth == &fae->fae_fr) - ipauth = fae_list ? &fae_list->fae_fr : NULL; - RWLOCK_EXIT(&ipf_auth); - SPL_X(s); - - KFREE(fae); - } - } else if (fr != NULL && frptr != NULL) { - KMALLOC(fae, frauthent_t *); - if (fae != NULL) { - bcopy((char *)fr, (char *)&fae->fae_fr, - sizeof(*fr)); - SPL_NET(s); - WRITE_ENTER(&ipf_auth); - fae->fae_age = fr_defaultauthage; - fae->fae_fr.fr_hits = 0; - fae->fae_fr.fr_next = *frptr; - *frptr = &fae->fae_fr; - fae->fae_next = *faep; - *faep = fae; - ipauth = &fae_list->fae_fr; - RWLOCK_EXIT(&ipf_auth); - SPL_X(s); - } else - error = ENOMEM; - } else - error = EINVAL; - return error; -} - - -/* - * Flush held packets. - * Must already be properly SPL'ed and Locked on &ipf_auth. - * - */ -int fr_authflush() -{ - register int i, num_flushed; - mb_t *m; - - if (fr_auth_lock) - return -1; - - num_flushed = 0; - - for (i = 0 ; i < fr_authsize; i++) { - m = fr_authpkts[i]; - if (m != NULL) { - FREE_MB_T(m); - fr_authpkts[i] = NULL; - fr_auth[i].fra_index = -1; - /* perhaps add & use a flush counter inst.*/ - fr_authstats.fas_expire++; - fr_authused--; - num_flushed++; - } - } - - fr_authstart = 0; - fr_authend = 0; - fr_authnext = 0; - - return num_flushed; -} diff --git a/contrib/ipfilter/ip_auth.h b/contrib/ipfilter/ip_auth.h deleted file mode 100644 index a39e7fd823f1..000000000000 --- a/contrib/ipfilter/ip_auth.h +++ /dev/null @@ -1,66 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1997-2001 by Darren Reed & Guido Van Rooij. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp - * - */ -#ifndef __IP_AUTH_H__ -#define __IP_AUTH_H__ - -#define FR_NUMAUTH 32 - -typedef struct frauth { - int fra_age; - int fra_len; - int fra_index; - u_32_t fra_pass; - fr_info_t fra_info; - char *fra_buf; -#ifdef MENTAT - queue_t *fra_q; -#endif -} frauth_t; - -typedef struct frauthent { - struct frentry fae_fr; - struct frauthent *fae_next; - u_long fae_age; -} frauthent_t; - -typedef struct fr_authstat { - U_QUAD_T fas_hits; - U_QUAD_T fas_miss; - u_long fas_nospace; - u_long fas_added; - u_long fas_sendfail; - u_long fas_sendok; - u_long fas_queok; - u_long fas_quefail; - u_long fas_expire; - frauthent_t *fas_faelist; -} fr_authstat_t; - - -extern frentry_t *ipauth; -extern struct fr_authstat fr_authstats; -extern int fr_defaultauthage; -extern int fr_authstart; -extern int fr_authend; -extern int fr_authsize; -extern int fr_authused; -extern int fr_auth_lock; -extern frentry_t *fr_checkauth __P((fr_info_t *, u_32_t *)); -extern void fr_authexpire __P((void)); -extern int fr_authinit __P((void)); -extern void fr_authunload __P((void)); -extern int fr_authflush __P((void)); -extern mb_t **fr_authpkts; -extern int fr_newauth __P((mb_t *, fr_info_t *)); -extern int fr_preauthcmd __P((ioctlcmd_t, frentry_t *, frentry_t **)); -extern int fr_auth_ioctl __P((caddr_t, ioctlcmd_t, int)); - -#endif /* __IP_AUTH_H__ */ diff --git a/contrib/ipfilter/ip_compat.h b/contrib/ipfilter/ip_compat.h deleted file mode 100644 index 6ea3f709a558..000000000000 --- a/contrib/ipfilter/ip_compat.h +++ /dev/null @@ -1,2295 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_compat.h 1.8 1/14/96 - * Id: ip_compat.h,v 2.142.2.25 2005/03/28 09:33:36 darrenr Exp - */ - -#ifndef __IP_COMPAT_H__ -#define __IP_COMPAT_H__ - -#ifndef __P -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# endif -#endif -#ifndef __STDC__ -# undef const -# define const -#endif - -#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__) -# undef KERNEL -# undef _KERNEL -# undef __KERNEL__ -# define KERNEL -# define _KERNEL -# define __KERNEL__ -#endif - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif -#if SOLARIS2 >= 8 -# ifndef USE_INET6 -# define USE_INET6 -# endif -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \ - !defined(_KERNEL) && !defined(USE_INET6) && !defined(NOINET6) -# define USE_INET6 -#endif -#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000) && \ - !defined(_KERNEL) && !defined(USE_INET6) -# define USE_INET6 -# define IPFILTER_M_IPFILTER -#endif -#if defined(OpenBSD) && (OpenBSD >= 200206) && \ - !defined(_KERNEL) && !defined(USE_INET6) -# define USE_INET6 -#endif -#if defined(__osf__) -# define USE_INET6 -#endif -#if defined(linux) && (!defined(_KERNEL) || defined(CONFIG_IPV6)) -# define USE_INET6 -#endif -#if defined(HPUXREV) && (HPUXREV >= 1111) -# define USE_INET6 -#endif - -#if defined(BSD) && (BSD < 199103) && defined(__osf__) -# undef BSD -# define BSD 199103 -#endif - -#if defined(__SVR4) || defined(__svr4__) || defined(__sgi) -# define index strchr -# if !defined(_KERNEL) -# define bzero(a,b) memset(a,0,b) -# define bcmp memcmp -# define bcopy(a,b,c) memmove(b,a,c) -# endif -#endif - -#ifndef LIFNAMSIZ -# ifdef IF_NAMESIZE -# define LIFNAMSIZ IF_NAMESIZE -# else -# ifdef IFNAMSIZ -# define LIFNAMSIZ IFNAMSIZ -# else -# define LIFNAMSIZ 16 -# endif -# endif -#endif - -#if defined(__sgi) || defined(bsdi) || defined(__hpux) || defined(hpux) -struct ether_addr { - u_char ether_addr_octet[6]; -}; -#endif - -#if defined(__sgi) && !defined(IPFILTER_LKM) -# ifdef __STDC__ -# define IPL_EXTERN(ep) ipfilter##ep -# else -# define IPL_EXTERN(ep) ipfilter/**/ep -# endif -#else -# ifdef __STDC__ -# define IPL_EXTERN(ep) ipl##ep -# else -# define IPL_EXTERN(ep) ipl/**/ep -# endif -#endif - -/* - * This is a workaround for troubles on FreeBSD and OpenBSD. - */ -#ifndef linux -# ifndef _KERNEL -# define ADD_KERNEL -# define _KERNEL -# define KERNEL -# endif -# ifdef __OpenBSD__ -struct file; -# endif -# include -# ifdef ADD_KERNEL -# undef _KERNEL -# undef KERNEL -# endif -#endif - - -/* ----------------------------------------------------------------------- */ -/* S O L A R I S */ -/* ----------------------------------------------------------------------- */ -#if SOLARIS -# define MENTAT 1 -# include -# include -# include -# include -# include -# include -# if SOLARIS2 >= 10 -# include -# include -# include -# include -# endif -/* - * because Solaris 2 defines these in two places :-/ - */ -# ifndef KERNEL -# define _KERNEL -# undef RES_INIT -# endif /* _KERNEL */ - -# if SOLARIS2 >= 8 -# include -# include -# endif - -# include -/* These 5 are defined in and */ -# undef IPOPT_EOL -# undef IPOPT_NOP -# undef IPOPT_LSRR -# undef IPOPT_RR -# undef IPOPT_SSRR -# ifdef i386 -# define _SYS_PROMIF_H -# endif -# include -# undef COPYOUT -# include -# ifndef KERNEL -# undef _KERNEL -# endif -# if SOLARIS2 >= 8 -# define SNPRINTF snprintf - -# include -# define ipif_local_addr ipif_lcl_addr -/* Only defined in private include file */ -# ifndef V4_PART_OF_V6 -# define V4_PART_OF_V6(v6) v6.s6_addr32[3] -# endif -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; -# endif /* SOLARIS2 >= 8 */ - -# if SOLARIS2 >= 6 -# include -typedef uint32_t u_32_t; -# else -typedef unsigned int u_32_t; -# endif -# define U_32_T 1 - -# ifdef _KERNEL -# define KRWLOCK_T krwlock_t -# define KMUTEX_T kmutex_t -# include "qif.h" -# include "pfil.h" -# if SOLARIS2 >= 6 -# if SOLARIS2 == 6 -# define ATOMIC_INCL(x) atomic_add_long((uint32_t*)&(x), 1) -# define ATOMIC_DECL(x) atomic_add_long((uint32_t*)&(x), -1) -# else -# define ATOMIC_INCL(x) atomic_add_long(&(x), 1) -# define ATOMIC_DECL(x) atomic_add_long(&(x), -1) -# endif /* SOLARIS2 == 6 */ -# define ATOMIC_INC64(x) atomic_add_64((uint64_t*)&(x), 1) -# define ATOMIC_INC32(x) atomic_add_32((uint32_t*)&(x), 1) -# define ATOMIC_INC16(x) atomic_add_16((uint16_t*)&(x), 1) -# define ATOMIC_DEC64(x) atomic_add_64((uint64_t*)&(x), -1) -# define ATOMIC_DEC32(x) atomic_add_32((uint32_t*)&(x), -1) -# define ATOMIC_DEC16(x) atomic_add_16((uint16_t*)&(x), -1) -# else -# define ATOMIC_INC(x) { mutex_enter(&ipf_rw); (x)++; \ - mutex_exit(&ipf_rw); } -# define ATOMIC_DEC(x) { mutex_enter(&ipf_rw); (x)--; \ - mutex_exit(&ipf_rw); } -# endif /* SOLARIS2 >= 6 */ -# define USE_MUTEXES -# define MUTEX_ENTER(x) mutex_enter(&(x)->ipf_lk) -# define READ_ENTER(x) rw_enter(&(x)->ipf_lk, RW_READER) -# define WRITE_ENTER(x) rw_enter(&(x)->ipf_lk, RW_WRITER) -# define MUTEX_DOWNGRADE(x) rw_downgrade(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) rw_init(&(x)->ipf_lk, (y), \ - RW_DRIVER, NULL) -# define RWLOCK_EXIT(x) rw_exit(&(x)->ipf_lk) -# define RW_DESTROY(x) rw_destroy(&(x)->ipf_lk) -# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, (y), \ - MUTEX_DRIVER, NULL) -# define MUTEX_DESTROY(x) mutex_destroy(&(x)->ipf_lk) -# define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) -# define MUTEX_EXIT(x) mutex_exit(&(x)->ipf_lk) -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYIN(a,b,c) (void) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) (void) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -# ifdef sparc -# define ntohs(x) (x) -# define ntohl(x) (x) -# define htons(x) (x) -# define htonl(x) (x) -# endif /* sparc */ -# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP) -# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP) -# define GET_MINOR(x) getminor(x) -extern void *get_unit __P((char *, int)); -# define GETIFP(n, v) get_unit(n, v) -# define IFNAME(x) ((qif_t *)x)->qf_name -# define COPYIFNAME(x, b) \ - (void) strncpy(b, ((qif_t *)x)->qf_name, \ - LIFNAMSIZ) -# define GETKTIME(x) uniqtime((struct timeval *)x) -# define MSGDSIZE(x) msgdsize(x) -# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr) -# define M_DUPLICATE(x) dupmsg((x)) -# define MTOD(m,t) ((t)((m)->b_rptr)) -# define MTYPE(m) ((m)->b_datap->db_type) -# define FREE_MB_T(m) freemsg(m) -# define m_next b_cont -# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7) -# define IPF_PANIC(x,y) if (x) { printf y; cmn_err(CE_PANIC, "ipf_panic"); } -typedef mblk_t mb_t; -# endif /* _KERNEL */ - -# if (SOLARIS2 >= 7) -# ifdef lint -# define ALIGN32(ptr) (ptr ? 0L : 0L) -# define ALIGN16(ptr) (ptr ? 0L : 0L) -# else -# define ALIGN32(ptr) (ptr) -# define ALIGN16(ptr) (ptr) -# endif -# endif - -# if SOLARIS2 < 6 -typedef struct uio uio_t; -# endif -typedef int ioctlcmd_t; - -# define OS_RECOGNISED 1 - -#endif /* SOLARIS */ - -/* ----------------------------------------------------------------------- */ -/* H P U X */ -/* ----------------------------------------------------------------------- */ -#ifdef __hpux -# define MENTAT 1 -# include -# include -# include -# include -# ifdef USE_INET6 -# include -# include -# include -typedef struct ip6_hdr ip6_t; -# endif - -# ifdef _KERNEL -# define SNPRINTF sprintf -# if (HPUXREV >= 1111) -# define IPL_SELECT -# ifdef IPL_SELECT -# include -# include -# define READ_COLLISION 0x01 - -typedef struct iplog_select_s { - kthread_t *read_waiter; - int state; -} iplog_select_t; -# endif -# endif - -# define GETKTIME(x) uniqtime((struct timeval *)x) - -# if HPUXREV == 1111 -# include "kern_svcs.h" -# else -# include -# endif -# undef ti_flags -# undef TCP_NODELAY -# undef TCP_MAXSEG -# include -# include "../netinet/ip_info.h" -/* - * According to /usr/include/sys/spinlock.h on HP-UX 11.00, these functions - * are available. Attempting to use them actually results in unresolved - * symbols when it comes time to load the module. - * This has been fixed! Yipee! - */ -# if 1 -# ifdef __LP64__ -# define ATOMIC_INCL(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_DECL(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), -1) -# else -# define ATOMIC_INCL(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_DECL(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), -1) -# endif -# define ATOMIC_INC64(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_INC32(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_INC16(x) lock_and_incr_int16(&ipf_rw.ipf_lk, &(x), 1) -# define ATOMIC_DEC64(x) lock_and_incr_int64(&ipf_rw.ipf_lk, &(x), -1) -# define ATOMIC_DEC32(x) lock_and_incr_int32(&ipf_rw.ipf_lk, &(x), -1) -# define ATOMIC_DEC16(x) lock_and_incr_int16(&ipf_rw.ipf_lk, &(x), -1) -# else /* 0 */ -# define ATOMIC_INC64(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC64(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INC32(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC32(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INCL(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DECL(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw); } -# endif -# define ip_cksum ip_csuma -# define memcpy(a,b,c) bcopy((caddr_t)b, (caddr_t)a, c) -# define USE_MUTEXES -# define MUTEX_INIT(x, y) initlock(&(x)->ipf_lk, 0, 0, (y)) -# define MUTEX_ENTER(x) spinlock(&(x)->ipf_lk) -# define MUTEX_EXIT(x) spinunlock(&(x)->ipf_lk); -# define MUTEX_DESTROY(x) -# define MUTEX_NUKE(x) bzero((char *)(x), sizeof(*(x))) -# define KMUTEX_T lock_t -# define kmutex_t lock_t /* for pfil.h */ -# define krwlock_t lock_t /* for pfil.h */ -/* - * The read-write lock implementation in HP-UX 11.0 is crippled - it can - * only be used by threads working in a user context! - * This has been fixed! Yipee! (Or at least it does in 11.00, not 11.11..) - */ -# if HPUXREV < 1111 -# define MUTEX_DOWNGRADE(x) lock_write_to_read(x) -# define KRWLOCK_T struct rw_lock -# define READ_ENTER(x) lock_read(&(x)->ipf_lk) -# define WRITE_ENTER(x) lock_write(&(x)->ipf_lk) -# if HPUXREV >= 1111 -# define RWLOCK_INIT(x, y) rwlock_init4(&(x)->ipf_lk, 0, RWLCK_CANSLEEP, 0, y) -# else -# define RWLOCK_INIT(x, y) lock_init3(&(x)->ipf_lk, 0, 1, 0, 0, y) -# endif -# define RWLOCK_EXIT(x) lock_done(&(x)->ipf_lk) -# else -# define KRWLOCK_T lock_t -# define KMUTEX_T lock_t -# define READ_ENTER(x) MUTEX_ENTER(x) -# define WRITE_ENTER(x) MUTEX_ENTER(x) -# define MUTEX_DOWNGRADE(x) -# define RWLOCK_INIT(x, y) initlock(&(x)->ipf_lk, 0, 0, y) -# define RWLOCK_EXIT(x) MUTEX_EXIT(x) -# endif -# define RW_DESTROY(x) -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# if HPUXREV >= 1111 -# define BCOPYIN(a,b,c) 0; bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) 0; bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# else -# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# endif -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -extern void *get_unit __P((char *, int)); -# define GETIFP(n, v) get_unit(n, v) -# define IFNAME(x, b) ((ill_t *)x)->ill_name -# define COPYIFNAME(x, b) \ - (void) strncpy(b, ((qif_t *)x)->qf_name, \ - LIFNAMSIZ) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define SLEEP(id, n) { lock_t *_l = get_sleep_lock((caddr_t)id); \ - sleep(id, PZERO+1); \ - spinunlock(_l); \ - } -# define WAKEUP(id,x) { lock_t *_l = get_sleep_lock((caddr_t)id); \ - wakeup(id + x); \ - spinunlock(_l); \ - } -# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_IOSYS, M_NOWAIT) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_IOSYS, M_NOWAIT) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define MSGDSIZE(x) msgdsize(x) -# define M_LEN(x) ((x)->b_wptr - (x)->b_rptr) -# define M_DUPLICATE(x) dupmsg((x)) -# define MTOD(m,t) ((t)((m)->b_rptr)) -# define MTYPE(m) ((m)->b_datap->db_type) -# define FREE_MB_T(m) freemsg(m) -# define m_next b_cont -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef mblk_t mb_t; - -# define CACHE_HASH(x) (((qpktinfo_t *)(x)->fin_qpi)->qpi_num & 7) - -# include "qif.h" -# include "pfil.h" - -# else /* _KERNEL */ - -typedef unsigned char uchar_t; - -# ifndef _SYS_STREAM_INCLUDED -typedef char * mblk_t; -typedef void * queue_t; -typedef u_long ulong; -# endif -# include - -# endif /* _KERNEL */ - -# ifdef lint -# define ALIGN32(ptr) (ptr ? 0L : 0L) -# define ALIGN16(ptr) (ptr ? 0L : 0L) -# else -# define ALIGN32(ptr) (ptr) -# define ALIGN16(ptr) (ptr) -# endif - -typedef struct uio uio_t; -typedef int ioctlcmd_t; -typedef int minor_t; -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 - -#endif /* __hpux */ - -/* ----------------------------------------------------------------------- */ -/* I R I X */ -/* ----------------------------------------------------------------------- */ -#ifdef __sgi -# undef MENTAT -# if IRIX < 60500 -typedef struct uio uio_t; -# endif -typedef int ioctlcmd_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# ifdef INET6 -# define USE_INET6 -# endif - -# define hz HZ -# include -# define IPF_LOCK_PL plhi -# include -# undef kmutex_t -typedef struct { - lock_t *l; - int pl; -} kmutex_t; - -# ifdef MUTEX_INIT -# define KMUTEX_T mutex_t -# else -# define KMUTEX_T kmutex_t -# define KRWLOCK_T kmutex_t -# endif - -# ifdef _KERNEL -# define ATOMIC_INC(x) { MUTEX_ENTER(&ipf_rw); \ - (x)++; MUTEX_EXIT(&ipf_rw); } -# define ATOMIC_DEC(x) { MUTEX_ENTER(&ipf_rw); \ - (x)--; MUTEX_EXIT(&ipf_rw); } -# define USE_MUTEXES -# ifdef MUTEX_INIT -# include -# define ATOMIC_INCL(x) atomicAddUlong(&(x), 1) -# define ATOMIC_INC64(x) atomicAddUint64(&(x), 1) -# define ATOMIC_INC32(x) atomicAddUint(&(x), 1) -# define ATOMIC_INC16 ATOMIC_INC -# define ATOMIC_DECL(x) atomicAddUlong(&(x), -1) -# define ATOMIC_DEC64(x) atomicAddUint64(&(x), -1) -# define ATOMIC_DEC32(x) atomicAddUint(&(x), -1) -# define ATOMIC_DEC16 ATOMIC_DEC -# undef MUTEX_INIT -# define MUTEX_INIT(x, y) mutex_init(&(x)->ipf_lk, \ - MUTEX_DEFAULT, y) -# undef MUTEX_ENTER -# define MUTEX_ENTER(x) mutex_lock(&(x)->ipf_lk, 0) -# undef MUTEX_EXIT -# define MUTEX_EXIT(x) mutex_unlock(&(x)->ipf_lk) -# undef MUTEX_DESTROY -# define MUTEX_DESTROY(x) mutex_destroy(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) mrdemote(&(x)->ipf_lk) -# define KRWLOCK_T mrlock_t -# define RWLOCK_INIT(x, y) mrinit(&(x)->ipf_lk, y) -# undef RW_DESTROY -# define RW_DESTROY(x) mrfree(&(x)->ipf_lk) -# define READ_ENTER(x) RW_RDLOCK(&(x)->ipf_lk) -# define WRITE_ENTER(x) RW_WRLOCK(&(x)->ipf_lk) -# define RWLOCK_EXIT(x) RW_UNLOCK(&(x)->ipf_lk) -# else -# define READ_ENTER(x) MUTEX_ENTER(&(x)->ipf_lk) -# define WRITE_ENTER(x) MUTEX_ENTER(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) ; -# define RWLOCK_EXIT(x) MUTEX_EXIT(&(x)->ipf_lk) -# define MUTEX_EXIT(x) UNLOCK((x)->ipf_lk.l, (x)->ipf_lk.pl); -# define MUTEX_INIT(x,y) (x)->ipf_lk.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP) -# define MUTEX_DESTROY(x) LOCK_DEALLOC((x)->ipf_lk.l) -# define MUTEX_ENTER(x) (x)->ipf_lk.pl = LOCK((x)->ipf_lk.l, \ - IPF_LOCK_PL); -# endif -# define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) -# define FREE_MB_T(m) m_freem(m) -# define MTOD(m,t) mtod(m,t) -# define COPYIN(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define COPYOUT(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define BCOPYIN(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define BCOPYOUT(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define SLEEP(id, n) sleep((id), PZERO+1) -# define WAKEUP(id,x) wakeup(id+x) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define GETIFP(n,v) ifunit(n) -# include -# include -# define KMALLOC(a,b) (a) = (b)kmem_alloc(sizeof(*(a)), KM_NOSLEEP) -# define KMALLOCS(a,b,c) (a) = (b)kmem_alloc((c), KM_NOSLEEP) -# define GET_MINOR(x) getminor(x) -# define USE_SPL 1 -# define SPL_IMP(x) (x) = splimp() -# define SPL_NET(x) (x) = splnet() -# define SPL_X(x) (void) splx(x) -extern void m_copydata __P((struct mbuf *, int, int, caddr_t)); -extern void m_copyback __P((struct mbuf *, int, int, caddr_t)); -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) microtime((struct timeval *)x) -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# else -# undef RW_DESTROY -# undef MUTEX_INIT -# undef MUTEX_DESTROY -# endif /* _KERNEL */ - -# define OS_RECOGNISED 1 - -#endif /* __sgi */ - -/* ----------------------------------------------------------------------- */ -/* T R U 6 4 */ -/* ----------------------------------------------------------------------- */ -#ifdef __osf__ -# undef MENTAT - -# include -# include - -# ifdef _KERNEL -# define KMUTEX_T simple_lock_data_t -# define KRWLOCK_T lock_data_t -# include -# define USE_MUTEXES -# define READ_ENTER(x) lock_read(&(x)->ipf_lk) -# define WRITE_ENTER(x) lock_write(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) lock_write_to_read(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) lock_init(&(x)->ipf_lk, TRUE) -# define RWLOCK_EXIT(x) lock_done(&(x)->ipf_lk) -# define RW_DESTROY(x) lock_terminate(&(x)->ipf_lk) -# define MUTEX_ENTER(x) simple_lock(&(x)->ipf_lk) -# define MUTEX_INIT(x, y) simple_lock_init(&(x)->ipf_lk) -# define MUTEX_DESTROY(x) simple_lock_terminate(&(x)->ipf_lk) -# define MUTEX_EXIT(x) simple_unlock(&(x)->ipf_lk) -# define MUTEX_NUKE(x) bzero(x, sizeof(*(x))) -# define ATOMIC_INC64(x) atomic_incq((uint64_t*)&(x)) -# define ATOMIC_DEC64(x) atomic_decq((uint64_t*)&(x)) -# define ATOMIC_INC32(x) atomic_incl((uint32_t*)&(x)) -# define ATOMIC_DEC32(x) atomic_decl((uint32_t*)&(x)) -# define ATOMIC_INC16(x) { simple_lock(&ipf_rw); (x)++; \ - simple_unlock(&ipf_rw); } -# define ATOMIC_DEC16(x) { simple_lock(&ipf_rw); (x)--; \ - simple_unlock(&ipf_rw); } -# define ATOMIC_INCL(x) atomic_incl((uint32_t*)&(x)) -# define ATOMIC_DECL(x) atomic_decl((uint32_t*)&(x)) -# define ATOMIC_INC(x) { simple_lock(&ipf_rw); (x)++; \ - simple_unlock(&ipf_rw); } -# define ATOMIC_DEC(x) { simple_lock(&ipf_rw); (x)--; \ - simple_unlock(&ipf_rw); } -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# undef SPL_X -# define SPL_X(x) ; -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a, b, d) -# define FREE_MB_T(m) m_freem(m) -# define MTOD(m,t) mtod(m,t) -# define GETIFP(n, v) ifunit(n) -# define GET_MINOR getminor -# define WAKEUP(id,x) wakeup(id + x) -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), M_PFILT, M_NOWAIT) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), M_PFILT, \ - ((c) > 4096) ? M_WAITOK : M_NOWAIT) -# define KFREE(x) FREE((x), M_PFILT) -# define KFREES(x,s) FREE((x), M_PFILT) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) microtime((struct timeval *)x) -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# endif /* _KERNEL */ - -# if (defined(_KERNEL) || defined(_NO_BITFIELDS) || (__STDC__ == 1)) -# define IP_V(x) ((x)->ip_vhl >> 4) -# define IP_HL(x) ((x)->ip_vhl & 0xf) -# define IP_V_A(x,y) (x)->ip_vhl |= (((y) << 4) & 0xf0) -# define IP_HL_A(x,y) (x)->ip_vhl |= ((y) & 0xf) -# define TCP_X2(x) ((x)->th_xoff & 0xf) -# define TCP_X2_A(x,y) (x)->th_xoff |= ((y) & 0xf) -# define TCP_OFF(x) ((x)->th_xoff >> 4) -# define TCP_OFF_A(x,y) (x)->th_xoff |= (((y) << 4) & 0xf0) -# endif - -/* - * These are from's Solaris' #defines for little endian. - */ -#define IP6F_MORE_FRAG 0x0100 -#define IP6F_RESERVED_MASK 0x0600 -#define IP6F_OFF_MASK 0xf8ff - -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; - -typedef int ioctlcmd_t; -/* - * Really, any arch where sizeof(long) != sizeof(int). - */ -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __osf__ */ - -/* ----------------------------------------------------------------------- */ -/* N E T B S D */ -/* ----------------------------------------------------------------------- */ -#ifdef __NetBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include "bpfilter.h" -# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 104110000) -# include "opt_inet.h" -# endif -# ifdef INET6 -# define USE_INET6 -# endif -# if (__NetBSD_Version__ >= 105000000) -# define HAVE_M_PULLDOWN 1 -# endif -# endif - -# ifdef _KERNEL -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define GETKTIME(x) microtime((struct timeval *)x) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -typedef struct mbuf mb_t; -# endif /* _KERNEL */ -# if (NetBSD <= 1991011) && (NetBSD >= 199606) -# define IFNAME(x) ((struct ifnet *)x)->if_xname -# define COPYIFNAME(x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) -# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7) -# else -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif - -typedef struct uio uio_t; -typedef u_long ioctlcmd_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __NetBSD__ */ - - -/* ----------------------------------------------------------------------- */ -/* F R E E B S D */ -/* ----------------------------------------------------------------------- */ -#ifdef __FreeBSD__ -# if defined(_KERNEL) && !defined(IPFILTER_LKM) && !defined(KLD_MODULE) -# if (__FreeBSD_version >= 500000) -# include "opt_bpf.h" -# else -# include "bpf.h" -# endif -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) -# include "opt_inet6.h" -# endif -# if defined(INET6) && !defined(USE_INET6) -# define USE_INET6 -# endif -# endif - -# if defined(_KERNEL) -# if (__FreeBSD_version >= 400000) -/* - * When #define'd, the 5.2.1 kernel panics when used with the ftp proxy. - * There may be other, safe, kernels but this is not extensively tested yet. - */ -# define HAVE_M_PULLDOWN -# endif -# if !defined(IPFILTER_LKM) && (__FreeBSD_version >= 300000) -# include "opt_ipfilter.h" -# endif -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) - -# if (__FreeBSD_version >= 500043) -# define NETBSD_PF -# endif -# endif /* _KERNEL */ - -# if (__FreeBSD_version >= 500043) -# include -# include -/* - * Whilst the sx(9) locks on FreeBSD have the right semantics and interface - * for what we want to use them for, despite testing showing they work - - * with a WITNESS kernel, it generates LOR messages. - */ -# define KMUTEX_T struct mtx -# if 1 -# define KRWLOCK_T struct mtx -# else -# define KRWLOCK_T struct sx -# endif -# endif - -# if (__FreeBSD_version >= 501113) -# include -# define IFNAME(x) ((struct ifnet *)x)->if_xname -# define COPYIFNAME(x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) -# endif -# if (__FreeBSD_version >= 500043) -# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index) & 7) -# else -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif - -# ifdef _KERNEL -# define GETKTIME(x) microtime((struct timeval *)x) - -# if (__FreeBSD_version >= 500002) -# include -# include -# include -# endif - -# if (__FreeBSD_version >= 500043) -# define USE_MUTEXES -# define MUTEX_ENTER(x) mtx_lock(&(x)->ipf_lk) -# define MUTEX_EXIT(x) mtx_unlock(&(x)->ipf_lk) -# define MUTEX_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\ - MTX_DEF) -# define MUTEX_DESTROY(x) mtx_destroy(&(x)->ipf_lk) -# define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) -/* - * Whilst the sx(9) locks on FreeBSD have the right semantics and interface - * for what we want to use them for, despite testing showing they work - - * with a WITNESS kernel, it generates LOR messages. - */ -# if 1 -# define READ_ENTER(x) mtx_lock(&(x)->ipf_lk) -# define WRITE_ENTER(x) mtx_lock(&(x)->ipf_lk) -# define RWLOCK_EXIT(x) mtx_unlock(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) ; -# define RWLOCK_INIT(x,y) mtx_init(&(x)->ipf_lk, (y), NULL,\ - MTX_DEF) -# define RW_DESTROY(x) mtx_destroy(&(x)->ipf_lk) -# else -# define READ_ENTER(x) sx_slock(&(x)->ipf_lk) -# define WRITE_ENTER(x) sx_xlock(&(x)->ipf_lk) -# define MUTEX_DOWNGRADE(x) sx_downgrade(&(x)->ipf_lk) -# define RWLOCK_INIT(x, y) sx_init(&(x)->ipf_lk, (y)) -# define RW_DESTROY(x) sx_destroy(&(x)->ipf_lk) -# ifdef sx_unlock -# define RWLOCK_EXIT(x) sx_unlock(x) -# else -# define RWLOCK_EXIT(x) do { \ - if ((x)->ipf_lk.sx_cnt < 0) \ - sx_xunlock(&(x)->ipf_lk); \ - else \ - sx_sunlock(&(x)->ipf_lk); \ - } while (0) -# endif -# endif -# include -# define ATOMIC_INC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)++; \ - mtx_unlock(&ipf_rw.ipf_lk); } -# define ATOMIC_DEC(x) { mtx_lock(&ipf_rw.ipf_lk); (x)--; \ - mtx_unlock(&ipf_rw.ipf_lk); } -# define ATOMIC_INCL(x) atomic_add_long(&(x), 1) -# define ATOMIC_INC64(x) ATOMIC_INC(x) -# define ATOMIC_INC32(x) atomic_add_32(&(x), 1) -# define ATOMIC_INC16(x) atomic_add_16(&(x), 1) -# define ATOMIC_DECL(x) atomic_add_long(&(x), -1) -# define ATOMIC_DEC64(x) ATOMIC_DEC(x) -# define ATOMIC_DEC32(x) atomic_add_32(&(x), -1) -# define ATOMIC_DEC16(x) atomic_add_16(&(x), -1) -# define SPL_X(x) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -extern int in_cksum __P((struct mbuf *, int)); -# endif /* __FreeBSD_version >= 500043 */ -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# endif /* _KERNEL */ - -# if __FreeBSD__ < 3 -# include -# else -# if __FreeBSD__ == 3 -# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL) -# define ACTUALLY_LKM_NOT_KERNEL -# endif -# endif -# endif - -# if (__FreeBSD_version >= 300000) -typedef u_long ioctlcmd_t; -# else -typedef int ioctlcmd_t; -# endif -typedef struct uio uio_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __FreeBSD__ */ - - -/* ----------------------------------------------------------------------- */ -/* O P E N B S D */ -/* ----------------------------------------------------------------------- */ -#ifdef __OpenBSD__ -# ifdef INET6 -# define USE_INET6 -# endif - -# ifdef _KERNEL -# if !defined(IPFILTER_LKM) -# include "bpfilter.h" -# endif -# if (OpenBSD >= 200311) -# define SNPRINTF snprintf -# if defined(USE_INET6) -# include "netinet6/in6_var.h" -# include "netinet6/nd6.h" -# endif -# endif -# if (OpenBSD >= 200012) -# define HAVE_M_PULLDOWN 1 -# endif -# define COPYIN(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYOUT(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define GETKTIME(x) microtime((struct timeval *)x) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -typedef struct mbuf mb_t; -# endif /* _KERNEL */ -# if (OpenBSD >= 199603) -# define IFNAME(x, b) ((struct ifnet *)x)->if_xname -# define COPYIFNAME(x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) -# define CACHE_HASH(x) ((((struct ifnet *)fin->fin_ifp)->if_index)&7) -# else -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif - -typedef struct uio uio_t; -typedef u_long ioctlcmd_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 -#endif /* __OpenBSD__ */ - - -/* ----------------------------------------------------------------------- */ -/* B S D O S */ -/* ----------------------------------------------------------------------- */ -#ifdef _BSDI_VERSION -# ifdef INET6 -# define USE_INET6 -# endif - -# ifdef _KERNEL -# define GETKTIME(x) microtime((struct timeval *)x) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -typedef struct mbuf mb_t; -# endif /* _KERNEL */ - -# if (_BSDI_VERSION >= 199701) -typedef u_long ioctlcmd_t; -# else -typedef int ioctlcmd_t; -# endif -typedef u_int32_t u_32_t; -# define U_32_T 1 - -#endif /* _BSDI_VERSION */ - - -/* ----------------------------------------------------------------------- */ -/* S U N O S 4 */ -/* ----------------------------------------------------------------------- */ -#if defined(sun) && !defined(OS_RECOGNISED) /* SunOS4 */ -# ifdef _KERNEL -# include -# define GETKTIME(x) uniqtime((struct timeval *)x) -# define MSGDSIZE(x) mbufchainlen(x) -# define M_LEN(x) (x)->m_len -# define M_DUPLICATE(x) m_copy((x), 0, M_COPYALL) -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# define GETIFP(n, v) ifunit(n, IFNAMSIZ) -# define KFREE(x) kmem_free((char *)(x), sizeof(*(x))) -# define KFREES(x,s) kmem_free((char *)(x), (s)) -# define SLEEP(id, n) sleep((id), PZERO+1) -# define WAKEUP(id,x) wakeup(id + x) -# define UIOMOVE(a,b,c,d) uiomove((caddr_t)a,b,c,d) -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } - -extern void m_copydata __P((struct mbuf *, int, int, caddr_t)); -extern void m_copyback __P((struct mbuf *, int, int, caddr_t)); - -typedef struct mbuf mb_t; -# endif - -typedef struct uio uio_t; -typedef int ioctlcmd_t; -typedef int minor_t; -typedef unsigned int u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 - -#endif /* SunOS 4 */ - -/* ----------------------------------------------------------------------- */ -/* L I N U X */ -/* ----------------------------------------------------------------------- */ -#if defined(linux) && !defined(OS_RECOGNISED) -#include -#include -# if LINUX >= 20600 -# define HDR_T_PRIVATE 1 -# endif -# undef USE_INET6 -# ifdef USE_INET6 -struct ip6_ext { - u_char ip6e_nxt; - u_char ip6e_len; -}; -# endif - -# ifdef _KERNEL -# define IPF_PANIC(x,y) if (x) { printf y; panic("ipf_panic"); } -# define BCOPYIN(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define BCOPYOUT(a,b,c) bcopy((caddr_t)(a), (caddr_t)(b), (c)) -# define COPYIN(a,b,c) copy_from_user((caddr_t)(b), (caddr_t)(a), (c)) -# define COPYOUT(a,b,c) copy_to_user((caddr_t)(b), (caddr_t)(a), (c)) -# define FREE_MB_T(m) kfree_skb(m) -# define GETKTIME(x) do_gettimeofday((struct timeval *)x) -# define SLEEP(x,s) 0, interruptible_sleep_on(x##_linux) -# define WAKEUP(x,y) wake_up(x##_linux + y) -# define UIOMOVE(a,b,c,d) uiomove(a,b,c,d) -# define USE_MUTEXES -# define KRWLOCK_T rwlock_t -# define KMUTEX_T spinlock_t -# define MUTEX_INIT(x,y) spin_lock_init(&(x)->ipf_lk) -# define MUTEX_ENTER(x) spin_lock(&(x)->ipf_lk) -# define MUTEX_EXIT(x) spin_unlock(&(x)->ipf_lk) -# define MUTEX_DESTROY(x) do { } while (0) -# define MUTEX_NUKE(x) bzero(&(x)->ipf_lk, sizeof((x)->ipf_lk)) -# define READ_ENTER(x) ipf_read_enter(x) -# define WRITE_ENTER(x) ipf_write_enter(x) -# define RWLOCK_INIT(x,y) rwlock_init(&(x)->ipf_lk) -# define RW_DESTROY(x) do { } while (0) -# define RWLOCK_EXIT(x) ipf_rw_exit(x) -# define MUTEX_DOWNGRADE(x) ipf_rw_downgrade(x) -# define ATOMIC_INCL(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DECL(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_INC64(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_INC32(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_INC16(x) MUTEX_ENTER(&ipf_rw); (x)++; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DEC64(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DEC32(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define ATOMIC_DEC16(x) MUTEX_ENTER(&ipf_rw); (x)--; \ - MUTEX_EXIT(&ipf_rw) -# define SPL_IMP(x) do { } while (0) -# define SPL_NET(x) do { } while (0) -# define SPL_X(x) do { } while (0) -# define IFNAME(x) ((struct net_device*)x)->name -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct net_device *)fin->fin_ifp)->ifindex) & 7) -typedef struct sk_buff mb_t; -extern void m_copydata __P((mb_t *, int, int, caddr_t)); -extern void m_copyback __P((mb_t *, int, int, caddr_t)); -extern void m_adj __P((mb_t *, int)); -extern mb_t *m_pullup __P((mb_t *, int)); -# define mbuf sk_buff - -# define mtod(m, t) ((t)(m)->data) -# define m_len len -# define m_next next -# define M_DUPLICATE(m) skb_clone((m), in_interrupt() ? GFP_ATOMIC : \ - GFP_KERNEL) -# define MSGDSIZE(m) (m)->len -# define M_LEN(m) (m)->len - -# define splnet(x) ; -# define printf printk -# define bcopy(s,d,z) memmove(d, s, z) -# define bzero(s,z) memset(s, 0, z) -# define bcmp(a,b,z) memcmp(a, b, z) - -# define ifnet net_device -# define if_xname name -# define if_unit ifindex - -# define KMALLOC(x,t) (x) = (t)kmalloc(sizeof(*(x)), \ - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -# define KFREE(x) kfree(x) -# define KMALLOCS(x,t,s) (x) = (t)kmalloc((s), \ - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL) -# define KFREES(x,s) kfree(x) - -# define GETIFP(n,v) dev_get_by_name(n) - -# else -# include - -struct mbuf { -}; - -# ifndef _NET_ROUTE_H -struct rtentry { -}; -# endif - -struct ifnet { - char if_xname[IFNAMSIZ]; - int if_unit; - int (* if_output) __P((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *)); - struct ifaddr *if_addrlist; -}; -# define IFNAME(x) ((struct ifnet *)x)->if_xname - -# endif /* _KERNEL */ - -# define COPYIFNAME(x, b) \ - (void) strncpy(b, \ - ((struct ifnet *)x)->if_xname, \ - LIFNAMSIZ) - -# include -# define FWRITE FMODE_WRITE -# define FREAD FMODE_READ - -# define __USE_MISC 1 -# define __FAVOR_BSD 1 - -typedef struct uio { - struct iovec *uio_iov; - void *uio_file; - char *uio_buf; - int uio_iovcnt; - int uio_offset; - size_t uio_resid; - int uio_rw; -} uio_t; - -extern int uiomove __P((caddr_t, size_t, int, struct uio *)); - -# define UIO_READ 1 -# define UIO_WRITE 2 - -typedef u_long ioctlcmd_t; -typedef int minor_t; -typedef u_int32_t u_32_t; -# define U_32_T 1 - -# define OS_RECOGNISED 1 - -#endif - - -#ifndef OS_RECOGNISED -#error ip_compat.h does not recognise this platform/OS. -#endif - - -/* ----------------------------------------------------------------------- */ -/* G E N E R I C */ -/* ----------------------------------------------------------------------- */ -#ifndef OS_RECOGNISED -#endif - -/* - * For BSD kernels, if bpf is in the kernel, enable ipfilter to use bpf in - * filter rules. - */ -#if !defined(IPFILTER_BPF) && ((NBPF > 0) || (NBPFILTER > 0)) -# define IPFILTER_BPF -#endif - -/* - * Userland locking primitives - */ -typedef struct { - char *eMm_owner; - char *eMm_heldin; - u_int eMm_magic; - int eMm_held; - int eMm_heldat; -#ifdef __hpux - char eMm_fill[8]; -#endif -} eMmutex_t; - -typedef struct { - char *eMrw_owner; - char *eMrw_heldin; - u_int eMrw_magic; - short eMrw_read; - short eMrw_write; - int eMrw_heldat; -#ifdef __hpux - char eMm_fill[24]; -#endif -} eMrwlock_t; - -typedef union { -#ifdef KMUTEX_T - struct { - KMUTEX_T ipf_slk; - char *ipf_lname; - } ipf_lkun_s; -#endif - eMmutex_t ipf_emu; -} ipfmutex_t; - -typedef union { -#ifdef KRWLOCK_T - struct { - KRWLOCK_T ipf_slk; - char *ipf_lname; - int ipf_sr; - int ipf_sw; - u_int ipf_magic; - } ipf_lkun_s; -#endif - eMrwlock_t ipf_emu; -} ipfrwlock_t; - -#define ipf_lk ipf_lkun_s.ipf_slk -#define ipf_lname ipf_lkun_s.ipf_lname -#define ipf_isr ipf_lkun_s.ipf_sr -#define ipf_isw ipf_lkun_s.ipf_sw -#define ipf_magic ipf_lkun_s.ipf_magic - -#if !defined(__GNUC__) || \ - (defined(__FreeBSD_version) && (__FreeBSD_version >= 503000)) -# ifndef INLINE -# define INLINE -# endif -#else -# define INLINE __inline__ -#endif - -#if defined(linux) && defined(_KERNEL) -extern INLINE void ipf_read_enter __P((ipfrwlock_t *)); -extern INLINE void ipf_write_enter __P((ipfrwlock_t *)); -extern INLINE void ipf_rw_exit __P((ipfrwlock_t *)); -extern INLINE void ipf_rw_downgrade __P((ipfrwlock_t *)); -#endif - -/* - * In a non-kernel environment, there are a lot of macros that need to be - * filled in to be null-ops or to point to some compatibility function, - * somewhere in userland. - */ -#ifndef _KERNEL -typedef struct mb_s { - struct mb_s *mb_next; - int mb_len; - u_long mb_buf[2048]; -} mb_t; -# undef m_next -# define m_next mb_next -# define MSGDSIZE(x) (x)->mb_len /* XXX - from ipt.c */ -# define M_LEN(x) (x)->mb_len -# define M_DUPLICATE(x) (x) -# define GETKTIME(x) gettimeofday((struct timeval *)(x), NULL) -# define MTOD(m, t) ((t)(m)->mb_buf) -# define FREE_MB_T(x) -# define SLEEP(x,y) 1; -# define WAKEUP(x,y) ; -# define IPF_PANIC(x,y) ; -# define PANIC(x,y) ; -# define SPL_NET(x) ; -# define SPL_IMP(x) ; -# define SPL_X(x) ; -# define KMALLOC(a,b) (a) = (b)malloc(sizeof(*a)) -# define KMALLOCS(a,b,c) (a) = (b)malloc(c) -# define KFREE(x) free(x) -# define KFREES(x,s) free(x) -# define GETIFP(x, v) get_unit(x,v) -# define COPYIN(a,b,c) (bcopy((a), (b), (c)), 0) -# define COPYOUT(a,b,c) (bcopy((a), (b), (c)), 0) -# define BCOPYIN(a,b,c) (bcopy((a), (b), (c)), 0) -# define BCOPYOUT(a,b,c) (bcopy((a), (b), (c)), 0) -# define COPYDATA(m, o, l, b) bcopy(MTOD((mb_t *)m, char *) + (o), \ - (b), (l)) -# define COPYBACK(m, o, l, b) bcopy((b), \ - MTOD((mb_t *)m, char *) + (o), \ - (l)) -# define UIOMOVE(a,b,c,d) ipfuiomove(a,b,c,d) -extern void m_copydata __P((mb_t *, int, int, caddr_t)); -extern int ipfuiomove __P((caddr_t, int, int, struct uio *)); -# ifndef CACHE_HASH -# define CACHE_HASH(x) ((IFNAME(fin->fin_ifp)[0] + \ - ((struct ifnet *)fin->fin_ifp)->if_unit) & 7) -# endif - -# define MUTEX_DESTROY(x) eMmutex_destroy(&(x)->ipf_emu) -# define MUTEX_ENTER(x) eMmutex_enter(&(x)->ipf_emu, \ - __FILE__, __LINE__) -# define MUTEX_EXIT(x) eMmutex_exit(&(x)->ipf_emu) -# define MUTEX_INIT(x,y) eMmutex_init(&(x)->ipf_emu, y) -# define MUTEX_NUKE(x) bzero((x), sizeof(*(x))) - -# define MUTEX_DOWNGRADE(x) eMrwlock_downgrade(&(x)->ipf_emu, \ - __FILE__, __LINE__) -# define READ_ENTER(x) eMrwlock_read_enter(&(x)->ipf_emu, \ - __FILE__, __LINE__) -# define RWLOCK_INIT(x, y) eMrwlock_init(&(x)->ipf_emu, y) -# define RWLOCK_EXIT(x) eMrwlock_exit(&(x)->ipf_emu) -# define RW_DESTROY(x) eMrwlock_destroy(&(x)->ipf_emu) -# define WRITE_ENTER(x) eMrwlock_write_enter(&(x)->ipf_emu, \ - __FILE__, \ - __LINE__) - -# define USE_MUTEXES 1 - -extern void eMmutex_destroy __P((eMmutex_t *)); -extern void eMmutex_enter __P((eMmutex_t *, char *, int)); -extern void eMmutex_exit __P((eMmutex_t *)); -extern void eMmutex_init __P((eMmutex_t *, char *)); -extern void eMrwlock_destroy __P((eMrwlock_t *)); -extern void eMrwlock_exit __P((eMrwlock_t *)); -extern void eMrwlock_init __P((eMrwlock_t *, char *)); -extern void eMrwlock_read_enter __P((eMrwlock_t *, char *, int)); -extern void eMrwlock_write_enter __P((eMrwlock_t *, char *, int)); -extern void eMrwlock_downgrade __P((eMrwlock_t *, char *, int)); - -#endif - -#define MAX_IPV4HDR ((0xf << 2) + sizeof(struct icmp) + sizeof(ip_t) + 8) - -#ifndef IP_OFFMASK -# define IP_OFFMASK 0x1fff -#endif - - -/* - * On BSD's use quad_t as a guarantee for getting at least a 64bit sized - * object. - */ -#if BSD > 199306 -# define USE_QUAD_T -# define U_QUAD_T u_quad_t -# define QUAD_T quad_t -#else /* BSD > 199306 */ -# define U_QUAD_T u_long -# define QUAD_T long -#endif /* BSD > 199306 */ - - -#ifdef USE_INET6 -# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \ - defined(__osf__) || defined(linux) -# include -# include -# if !defined(linux) -# if defined(_KERNEL) && !defined(__osf__) -# include -# endif -# endif -typedef struct ip6_hdr ip6_t; -# endif -#endif - -#ifndef MAX -# define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#if defined(_KERNEL) -# ifdef MENTAT -# define COPYDATA mb_copydata -# define COPYBACK mb_copyback -# else -# define COPYDATA m_copydata -# define COPYBACK m_copyback -# endif -# if (BSD >= 199306) || defined(__FreeBSD__) -# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105180000)) || \ - defined(__FreeBSD__) || (defined(OpenBSD) && (OpenBSD < 200206)) || \ - defined(_BSDI_VERSION) -# include -# endif -# if !defined(__FreeBSD__) || (defined (__FreeBSD_version) && \ - (__FreeBSD_version >= 300000)) -# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \ - (defined(OpenBSD) && (OpenBSD >= 200111)) -# include -# else -# include -extern vm_map_t kmem_map; -# endif -# include -# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD_version >= 300000) */ -# include -# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD_version >= 300000) */ - -# ifdef IPFILTER_M_IPFILTER -# include -MALLOC_DECLARE(M_IPFILTER); -# define _M_IPF M_IPFILTER -# else /* IPFILTER_M_IPFILTER */ -# ifdef M_PFIL -# define _M_IPF M_PFIL -# else -# ifdef M_IPFILTER -# define _M_IPF M_IPFILTER -# else -# define _M_IPF M_TEMP -# endif /* M_IPFILTER */ -# endif /* M_PFIL */ -# endif /* IPFILTER_M_IPFILTER */ -# define KMALLOC(a, b) MALLOC((a), b, sizeof(*(a)), _M_IPF, M_NOWAIT) -# define KMALLOCS(a, b, c) MALLOC((a), b, (c), _M_IPF, M_NOWAIT) -# define KFREE(x) FREE((x), _M_IPF) -# define KFREES(x,s) FREE((x), _M_IPF) -# define UIOMOVE(a,b,c,d) uiomove(a,b,d) -# define SLEEP(id, n) tsleep((id), PPAUSE|PCATCH, n, 0) -# define WAKEUP(id,x) wakeup(id+x) -# define GETIFP(n, v) ifunit(n) -# endif /* (Free)BSD */ - -# if !defined(USE_MUTEXES) && !defined(SPL_NET) -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199407)) || \ - (defined(OpenBSD) && (OpenBSD >= 200006)) -# define SPL_NET(x) x = splsoftnet() -# else -# define SPL_IMP(x) x = splimp() -# define SPL_NET(x) x = splnet() -# endif /* NetBSD && (NetBSD <= 1991011) && (NetBSD >= 199407) */ -# define SPL_X(x) (void) splx(x) -# endif /* !USE_MUTEXES */ - -# ifndef FREE_MB_T -# define FREE_MB_T(m) m_freem(m) -# endif - -# ifndef MTOD -# define MTOD(m,t) mtod(m,t) -# endif - -# ifndef COPYIN -# define COPYIN(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define COPYOUT(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define BCOPYIN(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# define BCOPYOUT(a,b,c) (bcopy((caddr_t)(a), (caddr_t)(b), (c)), 0) -# endif - -# ifndef KMALLOC -# define KMALLOC(a,b) (a) = (b)new_kmem_alloc(sizeof(*(a)), \ - KMEM_NOSLEEP) -# define KMALLOCS(a,b,c) (a) = (b)new_kmem_alloc((c), KMEM_NOSLEEP) -# endif - -# ifndef GET_MINOR -# define GET_MINOR(x) minor(x) -# endif -# define PANIC(x,y) if (x) panic y -#endif /* _KERNEL */ - -#ifndef IFNAME -# define IFNAME(x) ((struct ifnet *)x)->if_name -#endif -#ifndef COPYIFNAME -# define NEED_FRGETIFNAME -extern char *fr_getifname __P((struct ifnet *, char *)); -# define COPYIFNAME(x, b) \ - fr_getifname((struct ifnet *)x, b) -#endif - -#ifndef ASSERT -# define ASSERT(x) -#endif - -/* - * Because the ctype(3) posix definition, if used "safely" in code everywhere, - * would mean all normal code that walks through strings needed casts. Yuck. - */ -#define ISALNUM(x) isalnum((u_char)(x)) -#define ISALPHA(x) isalpha((u_char)(x)) -#define ISASCII(x) isascii((u_char)(x)) -#define ISDIGIT(x) isdigit((u_char)(x)) -#define ISPRINT(x) isprint((u_char)(x)) -#define ISSPACE(x) isspace((u_char)(x)) -#define ISUPPER(x) isupper((u_char)(x)) -#define ISXDIGIT(x) isxdigit((u_char)(x)) -#define ISLOWER(x) islower((u_char)(x)) -#define TOUPPER(x) toupper((u_char)(x)) -#define TOLOWER(x) tolower((u_char)(x)) - -/* - * If mutexes aren't being used, turn all the mutex functions into null-ops. - */ -#if !defined(USE_MUTEXES) -# define USE_SPL 1 -# undef RW_DESTROY -# undef MUTEX_INIT -# undef MUTEX_NUKE -# undef MUTEX_DESTROY -# define MUTEX_ENTER(x) ; -# define READ_ENTER(x) ; -# define WRITE_ENTER(x) ; -# define MUTEX_DOWNGRADE(x) ; -# define RWLOCK_INIT(x, y) ; -# define RWLOCK_EXIT(x) ; -# define RW_DESTROY(x) ; -# define MUTEX_EXIT(x) ; -# define MUTEX_INIT(x,y) ; -# define MUTEX_DESTROY(x) ; -# define MUTEX_NUKE(x) ; -#endif /* !USE_MUTEXES */ -#ifndef ATOMIC_INC -# define ATOMIC_INC(x) (x)++ -# define ATOMIC_DEC(x) (x)-- -#endif - -/* - * If there are no atomic operations for bit sizes defined, define them to all - * use a generic one that works for all sizes. - */ -#ifndef ATOMIC_INCL -# define ATOMIC_INCL ATOMIC_INC -# define ATOMIC_INC64 ATOMIC_INC -# define ATOMIC_INC32 ATOMIC_INC -# define ATOMIC_INC16 ATOMIC_INC -# define ATOMIC_DECL ATOMIC_DEC -# define ATOMIC_DEC64 ATOMIC_DEC -# define ATOMIC_DEC32 ATOMIC_DEC -# define ATOMIC_DEC16 ATOMIC_DEC -#endif - -#ifndef HDR_T_PRIVATE -typedef struct tcphdr tcphdr_t; -typedef struct udphdr udphdr_t; -#endif -typedef struct icmp icmphdr_t; -typedef struct ip ip_t; -typedef struct ether_header ether_header_t; -typedef struct tcpiphdr tcpiphdr_t; - -#ifndef FR_GROUPLEN -# define FR_GROUPLEN 16 -#endif - -#ifdef offsetof -# undef offsetof -#endif -#ifndef offsetof -# define offsetof(t,m) (int)((&((t *)0L)->m)) -#endif - -/* - * This set of macros has been brought about because on Tru64 it is not - * possible to easily assign or examine values in a structure that are - * bit fields. - */ -#ifndef IP_V -# define IP_V(x) (x)->ip_v -#endif -#ifndef IP_V_A -# define IP_V_A(x,y) (x)->ip_v = (y) -#endif -#ifndef IP_HL -# define IP_HL(x) (x)->ip_hl -#endif -#ifndef IP_HL_A -# define IP_HL_A(x,y) (x)->ip_hl = (y) -#endif -#ifndef TCP_X2 -# define TCP_X2(x) (x)->th_x2 -#endif -#ifndef TCP_X2_A -# define TCP_X2_A(x,y) (x)->th_x2 = (y) -#endif -#ifndef TCP_OFF -# define TCP_OFF(x) (x)->th_off -#endif -#ifndef TCP_OFF_A -# define TCP_OFF_A(x,y) (x)->th_off = (y) -#endif -#define IPMINLEN(i, h) ((i)->ip_len >= (IP_HL(i) * 4 + sizeof(struct h))) - - -/* - * XXX - This is one of those *awful* hacks which nobody likes - */ -#ifdef ultrix -#define A_A -#else -#define A_A & -#endif - -#define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|\ - TH_ECN|TH_CWR) - -#if (BSD >= 199306) && !defined(m_act) -# define m_act m_nextpkt -#endif - -/* - * Security Options for Intenet Protocol (IPSO) as defined in RFC 1108. - * - * Basic Option - * - * 00000001 - (Reserved 4) - * 00111101 - Top Secret - * 01011010 - Secret - * 10010110 - Confidential - * 01100110 - (Reserved 3) - * 11001100 - (Reserved 2) - * 10101011 - Unclassified - * 11110001 - (Reserved 1) - */ -#define IPSO_CLASS_RES4 0x01 -#define IPSO_CLASS_TOPS 0x3d -#define IPSO_CLASS_SECR 0x5a -#define IPSO_CLASS_CONF 0x96 -#define IPSO_CLASS_RES3 0x66 -#define IPSO_CLASS_RES2 0xcc -#define IPSO_CLASS_UNCL 0xab -#define IPSO_CLASS_RES1 0xf1 - -#define IPSO_AUTH_GENSER 0x80 -#define IPSO_AUTH_ESI 0x40 -#define IPSO_AUTH_SCI 0x20 -#define IPSO_AUTH_NSA 0x10 -#define IPSO_AUTH_DOE 0x08 -#define IPSO_AUTH_UN 0x06 -#define IPSO_AUTH_FTE 0x01 - -/* - * IP option #defines - */ -#undef IPOPT_RR -#define IPOPT_RR 7 -#undef IPOPT_ZSU -#define IPOPT_ZSU 10 /* ZSU */ -#undef IPOPT_MTUP -#define IPOPT_MTUP 11 /* MTUP */ -#undef IPOPT_MTUR -#define IPOPT_MTUR 12 /* MTUR */ -#undef IPOPT_ENCODE -#define IPOPT_ENCODE 15 /* ENCODE */ -#undef IPOPT_TS -#define IPOPT_TS 68 -#undef IPOPT_TR -#define IPOPT_TR 82 /* TR */ -#undef IPOPT_SECURITY -#define IPOPT_SECURITY 130 -#undef IPOPT_LSRR -#define IPOPT_LSRR 131 -#undef IPOPT_E_SEC -#define IPOPT_E_SEC 133 /* E-SEC */ -#undef IPOPT_CIPSO -#define IPOPT_CIPSO 134 /* CIPSO */ -#undef IPOPT_SATID -#define IPOPT_SATID 136 -#ifndef IPOPT_SID -# define IPOPT_SID IPOPT_SATID -#endif -#undef IPOPT_SSRR -#define IPOPT_SSRR 137 -#undef IPOPT_ADDEXT -#define IPOPT_ADDEXT 147 /* ADDEXT */ -#undef IPOPT_VISA -#define IPOPT_VISA 142 /* VISA */ -#undef IPOPT_IMITD -#define IPOPT_IMITD 144 /* IMITD */ -#undef IPOPT_EIP -#define IPOPT_EIP 145 /* EIP */ -#undef IPOPT_RTRALRT -#define IPOPT_RTRALRT 148 /* RTRALRT */ -#undef IPOPT_SDB -#define IPOPT_SDB 149 -#undef IPOPT_NSAPA -#define IPOPT_NSAPA 150 -#undef IPOPT_DPS -#define IPOPT_DPS 151 -#undef IPOPT_UMP -#define IPOPT_UMP 152 -#undef IPOPT_FINN -#define IPOPT_FINN 205 /* FINN */ - -#ifndef TCPOPT_EOL -# define TCPOPT_EOL 0 -#endif -#ifndef TCPOPT_NOP -# define TCPOPT_NOP 1 -#endif -#ifndef TCPOPT_MAXSEG -# define TCPOPT_MAXSEG 2 -#endif -#ifndef TCPOLEN_MAXSEG -# define TCPOLEN_MAXSEG 4 -#endif -#ifndef TCPOPT_WINDOW -# define TCPOPT_WINDOW 3 -#endif -#ifndef TCPOLEN_WINDOW -# define TCPOLEN_WINDOW 3 -#endif -#ifndef TCPOPT_SACK_PERMITTED -# define TCPOPT_SACK_PERMITTED 4 -#endif -#ifndef TCPOLEN_SACK_PERMITTED -# define TCPOLEN_SACK_PERMITTED 2 -#endif -#ifndef TCPOPT_SACK -# define TCPOPT_SACK 5 -#endif -#ifndef TCPOPT_TIMESTAMP -# define TCPOPT_TIMESTAMP 8 -#endif - -#ifndef ICMP_MINLEN -# define ICMP_MINLEN 8 -#endif -#ifndef ICMP_ECHOREPLY -# define ICMP_ECHOREPLY 0 -#endif -#ifndef ICMP_UNREACH -# define ICMP_UNREACH 3 -#endif -#ifndef ICMP_UNREACH_NET -# define ICMP_UNREACH_NET 0 -#endif -#ifndef ICMP_UNREACH_HOST -# define ICMP_UNREACH_HOST 1 -#endif -#ifndef ICMP_UNREACH_PROTOCOL -# define ICMP_UNREACH_PROTOCOL 2 -#endif -#ifndef ICMP_UNREACH_PORT -# define ICMP_UNREACH_PORT 3 -#endif -#ifndef ICMP_UNREACH_NEEDFRAG -# define ICMP_UNREACH_NEEDFRAG 4 -#endif -#ifndef ICMP_UNREACH_SRCFAIL -# define ICMP_UNREACH_SRCFAIL 5 -#endif -#ifndef ICMP_UNREACH_NET_UNKNOWN -# define ICMP_UNREACH_NET_UNKNOWN 6 -#endif -#ifndef ICMP_UNREACH_HOST_UNKNOWN -# define ICMP_UNREACH_HOST_UNKNOWN 7 -#endif -#ifndef ICMP_UNREACH_ISOLATED -# define ICMP_UNREACH_ISOLATED 8 -#endif -#ifndef ICMP_UNREACH_NET_PROHIB -# define ICMP_UNREACH_NET_PROHIB 9 -#endif -#ifndef ICMP_UNREACH_HOST_PROHIB -# define ICMP_UNREACH_HOST_PROHIB 10 -#endif -#ifndef ICMP_UNREACH_TOSNET -# define ICMP_UNREACH_TOSNET 11 -#endif -#ifndef ICMP_UNREACH_TOSHOST -# define ICMP_UNREACH_TOSHOST 12 -#endif -#ifndef ICMP_UNREACH_ADMIN_PROHIBIT -# define ICMP_UNREACH_ADMIN_PROHIBIT 13 -#endif -#ifndef ICMP_UNREACH_FILTER -# define ICMP_UNREACH_FILTER 13 -#endif -#ifndef ICMP_UNREACH_HOST_PRECEDENCE -# define ICMP_UNREACH_HOST_PRECEDENCE 14 -#endif -#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF -# define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 -#endif -#ifndef ICMP_SOURCEQUENCH -# define ICMP_SOURCEQUENCH 4 -#endif -#ifndef ICMP_REDIRECT_NET -# define ICMP_REDIRECT_NET 0 -#endif -#ifndef ICMP_REDIRECT_HOST -# define ICMP_REDIRECT_HOST 1 -#endif -#ifndef ICMP_REDIRECT_TOSNET -# define ICMP_REDIRECT_TOSNET 2 -#endif -#ifndef ICMP_REDIRECT_TOSHOST -# define ICMP_REDIRECT_TOSHOST 3 -#endif -#ifndef ICMP_ALTHOSTADDR -# define ICMP_ALTHOSTADDR 6 -#endif -#ifndef ICMP_TIMXCEED -# define ICMP_TIMXCEED 11 -#endif -#ifndef ICMP_TIMXCEED_INTRANS -# define ICMP_TIMXCEED_INTRANS 0 -#endif -#ifndef ICMP_TIMXCEED_REASS -# define ICMP_TIMXCEED_REASS 1 -#endif -#ifndef ICMP_PARAMPROB -# define ICMP_PARAMPROB 12 -#endif -#ifndef ICMP_PARAMPROB_ERRATPTR -# define ICMP_PARAMPROB_ERRATPTR 0 -#endif -#ifndef ICMP_PARAMPROB_OPTABSENT -# define ICMP_PARAMPROB_OPTABSENT 1 -#endif -#ifndef ICMP_PARAMPROB_LENGTH -# define ICMP_PARAMPROB_LENGTH 2 -#endif -#ifndef ICMP_TSTAMP -# define ICMP_TSTAMP 13 -#endif -#ifndef ICMP_TSTAMPREPLY -# define ICMP_TSTAMPREPLY 14 -#endif -#ifndef ICMP_IREQ -# define ICMP_IREQ 15 -#endif -#ifndef ICMP_IREQREPLY -# define ICMP_IREQREPLY 16 -#endif -#ifndef ICMP_MASKREQ -# define ICMP_MASKREQ 17 -#endif -#ifndef ICMP_MASKREPLY -# define ICMP_MASKREPLY 18 -#endif -#ifndef ICMP_TRACEROUTE -# define ICMP_TRACEROUTE 30 -#endif -#ifndef ICMP_DATACONVERR -# define ICMP_DATACONVERR 31 -#endif -#ifndef ICMP_MOBILE_REDIRECT -# define ICMP_MOBILE_REDIRECT 32 -#endif -#ifndef ICMP_IPV6_WHEREAREYOU -# define ICMP_IPV6_WHEREAREYOU 33 -#endif -#ifndef ICMP_IPV6_IAMHERE -# define ICMP_IPV6_IAMHERE 34 -#endif -#ifndef ICMP_MOBILE_REGREQUEST -# define ICMP_MOBILE_REGREQUEST 35 -#endif -#ifndef ICMP_MOBILE_REGREPLY -# define ICMP_MOBILE_REGREPLY 36 -#endif -#ifndef ICMP_SKIP -# define ICMP_SKIP 39 -#endif -#ifndef ICMP_PHOTURIS -# define ICMP_PHOTURIS 40 -#endif -#ifndef ICMP_PHOTURIS_UNKNOWN_INDEX -# define ICMP_PHOTURIS_UNKNOWN_INDEX 1 -#endif -#ifndef ICMP_PHOTURIS_AUTH_FAILED -# define ICMP_PHOTURIS_AUTH_FAILED 2 -#endif -#ifndef ICMP_PHOTURIS_DECRYPT_FAILED -# define ICMP_PHOTURIS_DECRYPT_FAILED 3 -#endif -#ifndef IPVERSION -# define IPVERSION 4 -#endif -#ifndef IPOPT_MINOFF -# define IPOPT_MINOFF 4 -#endif -#ifndef IPOPT_COPIED -# define IPOPT_COPIED(x) ((x)&0x80) -#endif -#ifndef IPOPT_EOL -# define IPOPT_EOL 0 -#endif -#ifndef IPOPT_NOP -# define IPOPT_NOP 1 -#endif -#ifndef IP_MF -# define IP_MF ((u_short)0x2000) -#endif -#ifndef ETHERTYPE_IP -# define ETHERTYPE_IP ((u_short)0x0800) -#endif -#ifndef TH_FIN -# define TH_FIN 0x01 -#endif -#ifndef TH_SYN -# define TH_SYN 0x02 -#endif -#ifndef TH_RST -# define TH_RST 0x04 -#endif -#ifndef TH_PUSH -# define TH_PUSH 0x08 -#endif -#ifndef TH_ACK -# define TH_ACK 0x10 -#endif -#ifndef TH_URG -# define TH_URG 0x20 -#endif -#undef TH_ACKMASK -#define TH_ACKMASK (TH_FIN|TH_SYN|TH_RST|TH_ACK) - -#ifndef IPOPT_EOL -# define IPOPT_EOL 0 -#endif -#ifndef IPOPT_NOP -# define IPOPT_NOP 1 -#endif -#ifndef IPOPT_RR -# define IPOPT_RR 7 -#endif -#ifndef IPOPT_TS -# define IPOPT_TS 68 -#endif -#ifndef IPOPT_SECURITY -# define IPOPT_SECURITY 130 -#endif -#ifndef IPOPT_LSRR -# define IPOPT_LSRR 131 -#endif -#ifndef IPOPT_SATID -# define IPOPT_SATID 136 -#endif -#ifndef IPOPT_SSRR -# define IPOPT_SSRR 137 -#endif -#ifndef IPOPT_SECUR_UNCLASS -# define IPOPT_SECUR_UNCLASS ((u_short)0x0000) -#endif -#ifndef IPOPT_SECUR_CONFID -# define IPOPT_SECUR_CONFID ((u_short)0xf135) -#endif -#ifndef IPOPT_SECUR_EFTO -# define IPOPT_SECUR_EFTO ((u_short)0x789a) -#endif -#ifndef IPOPT_SECUR_MMMM -# define IPOPT_SECUR_MMMM ((u_short)0xbc4d) -#endif -#ifndef IPOPT_SECUR_RESTR -# define IPOPT_SECUR_RESTR ((u_short)0xaf13) -#endif -#ifndef IPOPT_SECUR_SECRET -# define IPOPT_SECUR_SECRET ((u_short)0xd788) -#endif -#ifndef IPOPT_SECUR_TOPSECRET -# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5) -#endif -#ifndef IPOPT_OLEN -# define IPOPT_OLEN 1 -#endif -#ifndef IPPROTO_HOPOPTS -# define IPPROTO_HOPOPTS 0 -#endif -#ifndef IPPROTO_ENCAP -# define IPPROTO_ENCAP 4 -#endif -#ifndef IPPROTO_IPV6 -# define IPPROTO_IPV6 41 -#endif -#ifndef IPPROTO_ROUTING -# define IPPROTO_ROUTING 43 -#endif -#ifndef IPPROTO_FRAGMENT -# define IPPROTO_FRAGMENT 44 -#endif -#ifndef IPPROTO_GRE -# define IPPROTO_GRE 47 /* GRE encaps RFC 1701 */ -#endif -#ifndef IPPROTO_ESP -# define IPPROTO_ESP 50 -#endif -#ifndef IPPROTO_AH -# define IPPROTO_AH 51 -#endif -#ifndef IPPROTO_ICMPV6 -# define IPPROTO_ICMPV6 58 -#endif -#ifndef IPPROTO_NONE -# define IPPROTO_NONE 59 -#endif -#ifndef IPPROTO_DSTOPTS -# define IPPROTO_DSTOPTS 60 -#endif -#ifndef IPPROTO_FRAGMENT -# define IPPROTO_FRAGMENT 44 -#endif -#ifndef ICMP_ROUTERADVERT -# define ICMP_ROUTERADVERT 9 -#endif -#ifndef ICMP_ROUTERSOLICIT -# define ICMP_ROUTERSOLICIT 10 -#endif -#ifndef ICMP6_DST_UNREACH -# define ICMP6_DST_UNREACH 1 -#endif -#ifndef ICMP6_PACKET_TOO_BIG -# define ICMP6_PACKET_TOO_BIG 2 -#endif -#ifndef ICMP6_TIME_EXCEEDED -# define ICMP6_TIME_EXCEEDED 3 -#endif -#ifndef ICMP6_PARAM_PROB -# define ICMP6_PARAM_PROB 4 -#endif - -#ifndef ICMP6_ECHO_REQUEST -# define ICMP6_ECHO_REQUEST 128 -#endif -#ifndef ICMP6_ECHO_REPLY -# define ICMP6_ECHO_REPLY 129 -#endif -#ifndef ICMP6_MEMBERSHIP_QUERY -# define ICMP6_MEMBERSHIP_QUERY 130 -#endif -#ifndef MLD6_LISTENER_QUERY -# define MLD6_LISTENER_QUERY 130 -#endif -#ifndef ICMP6_MEMBERSHIP_REPORT -# define ICMP6_MEMBERSHIP_REPORT 131 -#endif -#ifndef MLD6_LISTENER_REPORT -# define MLD6_LISTENER_REPORT 131 -#endif -#ifndef ICMP6_MEMBERSHIP_REDUCTION -# define ICMP6_MEMBERSHIP_REDUCTION 132 -#endif -#ifndef MLD6_LISTENER_DONE -# define MLD6_LISTENER_DONE 132 -#endif -#ifndef ND_ROUTER_SOLICIT -# define ND_ROUTER_SOLICIT 133 -#endif -#ifndef ND_ROUTER_ADVERT -# define ND_ROUTER_ADVERT 134 -#endif -#ifndef ND_NEIGHBOR_SOLICIT -# define ND_NEIGHBOR_SOLICIT 135 -#endif -#ifndef ND_NEIGHBOR_ADVERT -# define ND_NEIGHBOR_ADVERT 136 -#endif -#ifndef ND_REDIRECT -# define ND_REDIRECT 137 -#endif -#ifndef ICMP6_ROUTER_RENUMBERING -# define ICMP6_ROUTER_RENUMBERING 138 -#endif -#ifndef ICMP6_WRUREQUEST -# define ICMP6_WRUREQUEST 139 -#endif -#ifndef ICMP6_WRUREPLY -# define ICMP6_WRUREPLY 140 -#endif -#ifndef ICMP6_FQDN_QUERY -# define ICMP6_FQDN_QUERY 139 -#endif -#ifndef ICMP6_FQDN_REPLY -# define ICMP6_FQDN_REPLY 140 -#endif -#ifndef ICMP6_NI_QUERY -# define ICMP6_NI_QUERY 139 -#endif -#ifndef ICMP6_NI_REPLY -# define ICMP6_NI_REPLY 140 -#endif -#ifndef MLD6_MTRACE_RESP -# define MLD6_MTRACE_RESP 200 -#endif -#ifndef MLD6_MTRACE -# define MLD6_MTRACE 201 -#endif -#ifndef ICMP6_HADISCOV_REQUEST -# define ICMP6_HADISCOV_REQUEST 202 -#endif -#ifndef ICMP6_HADISCOV_REPLY -# define ICMP6_HADISCOV_REPLY 203 -#endif -#ifndef ICMP6_MOBILEPREFIX_SOLICIT -# define ICMP6_MOBILEPREFIX_SOLICIT 204 -#endif -#ifndef ICMP6_MOBILEPREFIX_ADVERT -# define ICMP6_MOBILEPREFIX_ADVERT 205 -#endif -#ifndef ICMP6_MAXTYPE -# define ICMP6_MAXTYPE 205 -#endif - -#ifndef ICMP6_DST_UNREACH_NOROUTE -# define ICMP6_DST_UNREACH_NOROUTE 0 -#endif -#ifndef ICMP6_DST_UNREACH_ADMIN -# define ICMP6_DST_UNREACH_ADMIN 1 -#endif -#ifndef ICMP6_DST_UNREACH_NOTNEIGHBOR -# define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 -#endif -#ifndef ICMP6_DST_UNREACH_BEYONDSCOPE -# define ICMP6_DST_UNREACH_BEYONDSCOPE 2 -#endif -#ifndef ICMP6_DST_UNREACH_ADDR -# define ICMP6_DST_UNREACH_ADDR 3 -#endif -#ifndef ICMP6_DST_UNREACH_NOPORT -# define ICMP6_DST_UNREACH_NOPORT 4 -#endif -#ifndef ICMP6_TIME_EXCEED_TRANSIT -# define ICMP6_TIME_EXCEED_TRANSIT 0 -#endif -#ifndef ICMP6_TIME_EXCEED_REASSEMBLY -# define ICMP6_TIME_EXCEED_REASSEMBLY 1 -#endif - -#ifndef ICMP6_NI_SUCCESS -# define ICMP6_NI_SUCCESS 0 -#endif -#ifndef ICMP6_NI_REFUSED -# define ICMP6_NI_REFUSED 1 -#endif -#ifndef ICMP6_NI_UNKNOWN -# define ICMP6_NI_UNKNOWN 2 -#endif - -#ifndef ICMP6_ROUTER_RENUMBERING_COMMAND -# define ICMP6_ROUTER_RENUMBERING_COMMAND 0 -#endif -#ifndef ICMP6_ROUTER_RENUMBERING_RESULT -# define ICMP6_ROUTER_RENUMBERING_RESULT 1 -#endif -#ifndef ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET -# define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 -#endif - -#ifndef ICMP6_PARAMPROB_HEADER -# define ICMP6_PARAMPROB_HEADER 0 -#endif -#ifndef ICMP6_PARAMPROB_NEXTHEADER -# define ICMP6_PARAMPROB_NEXTHEADER 1 -#endif -#ifndef ICMP6_PARAMPROB_OPTION -# define ICMP6_PARAMPROB_OPTION 2 -#endif - -#ifndef ICMP6_NI_SUBJ_IPV6 -# define ICMP6_NI_SUBJ_IPV6 0 -#endif -#ifndef ICMP6_NI_SUBJ_FQDN -# define ICMP6_NI_SUBJ_FQDN 1 -#endif -#ifndef ICMP6_NI_SUBJ_IPV4 -# define ICMP6_NI_SUBJ_IPV4 2 -#endif - -/* - * ECN is a new addition to TCP - RFC 2481 - */ -#ifndef TH_ECN -# define TH_ECN 0x40 -#endif -#ifndef TH_CWR -# define TH_CWR 0x80 -#endif -#define TH_ECNALL (TH_ECN|TH_CWR) - -/* - * TCP States - */ -#define IPF_TCPS_CLOSED 0 /* closed */ -#define IPF_TCPS_LISTEN 1 /* listening for connection */ -#define IPF_TCPS_SYN_SENT 2 /* active, have sent syn */ -#define IPF_TCPS_SYN_RECEIVED 3 /* have send and received syn */ -#define IPF_TCPS_HALF_ESTAB 4 /* for connections not fully "up" */ -/* states < IPF_TCPS_ESTABLISHED are those where connections not established */ -#define IPF_TCPS_ESTABLISHED 5 /* established */ -#define IPF_TCPS_CLOSE_WAIT 6 /* rcvd fin, waiting for close */ -/* states > IPF_TCPS_CLOSE_WAIT are those where user has closed */ -#define IPF_TCPS_FIN_WAIT_1 7 /* have closed, sent fin */ -#define IPF_TCPS_CLOSING 8 /* closed xchd FIN; await FIN ACK */ -#define IPF_TCPS_LAST_ACK 9 /* had fin and close; await FIN ACK */ -/* states > IPF_TCPS_CLOSE_WAIT && < IPF_TCPS_FIN_WAIT_2 await ACK of FIN */ -#define IPF_TCPS_FIN_WAIT_2 10 /* have closed, fin is acked */ -#define IPF_TCPS_TIME_WAIT 11 /* in 2*msl quiet wait after close */ -#define IPF_TCP_NSTATES 12 - -#define TCP_MSL 120 - -#undef ICMP_MAX_UNREACH -#define ICMP_MAX_UNREACH 14 -#undef ICMP_MAXTYPE -#define ICMP_MAXTYPE 18 - -#ifndef IFNAMSIZ -#define IFNAMSIZ 16 -#endif - -#ifndef LOG_FTP -# define LOG_FTP (11<<3) -#endif -#ifndef LOG_AUTHPRIV -# define LOG_AUTHPRIV (10<<3) -#endif -#ifndef LOG_AUDIT -# define LOG_AUDIT (13<<3) -#endif -#ifndef LOG_NTP -# define LOG_NTP (12<<3) -#endif -#ifndef LOG_SECURITY -# define LOG_SECURITY (13<<3) -#endif -#ifndef LOG_LFMT -# define LOG_LFMT (14<<3) -#endif -#ifndef LOG_CONSOLE -# define LOG_CONSOLE (14<<3) -#endif - -/* - * ICMP error replies have an IP header (20 bytes), 8 bytes of ICMP data, - * another IP header and then 64 bits of data, totalling 56. Of course, - * the last 64 bits is dependant on that being available. - */ -#define ICMPERR_ICMPHLEN 8 -#define ICMPERR_IPICMPHLEN (20 + 8) -#define ICMPERR_MINPKTLEN (20 + 8 + 20) -#define ICMPERR_MAXPKTLEN (20 + 8 + 20 + 8) -#define ICMP6ERR_MINPKTLEN (40 + 8) -#define ICMP6ERR_IPICMPHLEN (40 + 8 + 40) - -#ifndef MIN -# define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - -#ifdef IPF_DEBUG -# define DPRINT(x) printf x -#else -# define DPRINT(x) -#endif - -#endif /* __IP_COMPAT_H__ */ diff --git a/contrib/ipfilter/ip_fil.h b/contrib/ipfilter/ip_fil.h deleted file mode 100644 index 2aacb3f0af78..000000000000 --- a/contrib/ipfilter/ip_fil.h +++ /dev/null @@ -1,1368 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_fil.h 1.35 6/5/96 - * Id: ip_fil.h,v 2.170.2.18 2005/03/28 10:47:52 darrenr Exp - */ - -#ifndef __IP_FIL_H__ -#define __IP_FIL_H__ - -#ifndef SOLARIS -# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#ifndef __P -# ifdef __STDC__ -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - -#if defined(__STDC__) || defined(__GNUC__) -# define SIOCADAFR _IOW('r', 60, struct ipfobj) -# define SIOCRMAFR _IOW('r', 61, struct ipfobj) -# define SIOCSETFF _IOW('r', 62, u_int) -# define SIOCGETFF _IOR('r', 63, u_int) -# define SIOCGETFS _IOWR('r', 64, struct ipfobj) -# define SIOCIPFFL _IOWR('r', 65, int) -# define SIOCIPFFB _IOR('r', 66, int) -# define SIOCADIFR _IOW('r', 67, struct ipfobj) -# define SIOCRMIFR _IOW('r', 68, struct ipfobj) -# define SIOCSWAPA _IOR('r', 69, u_int) -# define SIOCINAFR _IOW('r', 70, struct ipfobj) -# define SIOCINIFR _IOW('r', 71, struct ipfobj) -# define SIOCFRENB _IOW('r', 72, u_int) -# define SIOCFRSYN _IOW('r', 73, u_int) -# define SIOCFRZST _IOWR('r', 74, struct ipfobj) -# define SIOCZRLST _IOWR('r', 75, struct ipfobj) -# define SIOCAUTHW _IOWR('r', 76, struct ipfobj) -# define SIOCAUTHR _IOWR('r', 77, struct ipfobj) -# define SIOCATHST _IOWR('r', 78, struct ipfobj) -# define SIOCSTLCK _IOWR('r', 79, u_int) -# define SIOCSTPUT _IOWR('r', 80, struct ipfobj) -# define SIOCSTGET _IOWR('r', 81, struct ipfobj) -# define SIOCSTGSZ _IOWR('r', 82, struct ipfobj) -# define SIOCGFRST _IOWR('r', 83, struct ipfobj) -# define SIOCSETLG _IOWR('r', 84, int) -# define SIOCGETLG _IOWR('r', 85, int) -# define SIOCFUNCL _IOWR('r', 86, struct ipfunc_resolve) -# define SIOCIPFGETNEXT _IOWR('r', 87, struct ipfobj) -# define SIOCIPFGET _IOWR('r', 88, struct ipfobj) -# define SIOCIPFSET _IOWR('r', 89, struct ipfobj) -# define SIOCIPFL6 _IOWR('r', 90, int) -#else -# define SIOCADAFR _IOW(r, 60, struct ipfobj) -# define SIOCRMAFR _IOW(r, 61, struct ipfobj) -# define SIOCSETFF _IOW(r, 62, u_int) -# define SIOCGETFF _IOR(r, 63, u_int) -# define SIOCGETFS _IOWR(r, 64, struct ipfobj) -# define SIOCIPFFL _IOWR(r, 65, int) -# define SIOCIPFFB _IOR(r, 66, int) -# define SIOCADIFR _IOW(r, 67, struct ipfobj) -# define SIOCRMIFR _IOW(r, 68, struct ipfobj) -# define SIOCSWAPA _IOR(r, 69, u_int) -# define SIOCINAFR _IOW(r, 70, struct ipfobj) -# define SIOCINIFR _IOW(r, 71, struct ipfobj) -# define SIOCFRENB _IOW(r, 72, u_int) -# define SIOCFRSYN _IOW(r, 73, u_int) -# define SIOCFRZST _IOWR(r, 74, struct ipfobj) -# define SIOCZRLST _IOWR(r, 75, struct ipfobj) -# define SIOCAUTHW _IOWR(r, 76, struct ipfobj) -# define SIOCAUTHR _IOWR(r, 77, struct ipfobj) -# define SIOCATHST _IOWR(r, 78, struct ipfobj) -# define SIOCSTLCK _IOWR(r, 79, u_int) -# define SIOCSTPUT _IOWR(r, 80, struct ipfobj) -# define SIOCSTGET _IOWR(r, 81, struct ipfobj) -# define SIOCSTGSZ _IOWR(r, 82, struct ipfobj) -# define SIOCGFRST _IOWR(r, 83, struct ipfobj) -# define SIOCSETLG _IOWR(r, 84, int) -# define SIOCGETLG _IOWR(r, 85, int) -# define SIOCFUNCL _IOWR(r, 86, struct ipfunc_resolve) -# define SIOCIPFGETNEXT _IOWR(r, 87, struct ipfobj) -# define SIOCIPFGET _IOWR(r, 88, struct ipfobj) -# define SIOCIPFSET _IOWR(r, 89, struct ipfobj) -# define SIOCIPFL6 _IOWR(r, 90, int) -#endif -#define SIOCADDFR SIOCADAFR -#define SIOCDELFR SIOCRMAFR -#define SIOCINSFR SIOCINAFR - - -struct ipscan; -struct ifnet; - - -typedef int (* lookupfunc_t) __P((void *, int, void *)); - -/* - * i6addr is used as a container for both IPv4 and IPv6 addresses, as well - * as other types of objects, depending on its qualifier. - */ -#ifdef USE_INET6 -typedef union i6addr { - u_32_t i6[4]; - struct in_addr in4; - struct in6_addr in6; - void *vptr[2]; - lookupfunc_t lptr[2]; -} i6addr_t; -#else -typedef union i6addr { - u_32_t i6[4]; - struct in_addr in4; - void *vptr[2]; - lookupfunc_t lptr[2]; -} i6addr_t; -#endif - -#define in4_addr in4.s_addr -#define iplookupnum i6[0] -#define iplookuptype i6[1] -/* - * NOTE: These DO overlap the above on 64bit systems and this IS recognised. - */ -#define iplookupptr vptr[0] -#define iplookupfunc lptr[1] - -#define I60(x) (((i6addr_t *)(x))->i6[0]) -#define I61(x) (((i6addr_t *)(x))->i6[1]) -#define I62(x) (((i6addr_t *)(x))->i6[2]) -#define I63(x) (((i6addr_t *)(x))->i6[3]) -#define HI60(x) ntohl(((i6addr_t *)(x))->i6[0]) -#define HI61(x) ntohl(((i6addr_t *)(x))->i6[1]) -#define HI62(x) ntohl(((i6addr_t *)(x))->i6[2]) -#define HI63(x) ntohl(((i6addr_t *)(x))->i6[3]) - -#define IP6_EQ(a,b) ((I63(a) == I63(b)) && (I62(a) == I62(b)) && \ - (I61(a) == I61(b)) && (I60(a) == I60(b))) -#define IP6_NEQ(a,b) ((I63(a) != I63(b)) || (I62(a) != I62(b)) || \ - (I61(a) != I61(b)) || (I60(a) != I60(b))) -#define IP6_ISZERO(a) ((I60(a) | I61(a) | I62(a) | I63(a)) == 0) -#define IP6_NOTZERO(a) ((I60(a) | I61(a) | I62(a) | I63(a)) != 0) -#define IP6_GT(a,b) (HI60(a) > HI60(b) || (HI60(a) == HI60(b) && \ - (HI61(a) > HI61(b) || (HI61(a) == HI61(b) && \ - (HI62(a) > HI62(b) || (HI62(a) == HI62(b) && \ - HI63(a) > HI63(b))))))) -#define IP6_LT(a,b) (HI60(a) < HI60(b) || (HI60(a) == HI60(b) && \ - (HI61(a) < HI61(b) || (HI61(a) == HI61(b) && \ - (HI62(a) < HI62(b) || (HI62(a) == HI62(b) && \ - HI63(a) < HI63(b))))))) -#define NLADD(n,x) htonl(ntohl(n) + (x)) -#define IP6_INC(a) \ - { i6addr_t *_i6 = (i6addr_t *)(a); \ - _i6->i6[0] = NLADD(_i6->i6[0], 1); \ - if (_i6->i6[0] == 0) { \ - _i6->i6[0] = NLADD(_i6->i6[1], 1); \ - if (_i6->i6[1] == 0) { \ - _i6->i6[0] = NLADD(_i6->i6[2], 1); \ - if (_i6->i6[2] == 0) { \ - _i6->i6[0] = NLADD(_i6->i6[3], 1); \ - } \ - } \ - } \ - } -#define IP6_ADD(a,x,d) \ - { i6addr_t *_s = (i6addr_t *)(a); \ - i6addr_t *_d = (i6addr_t *)(d); \ - _d->i6[0] = NLADD(_s->i6[0], x); \ - if (ntohl(_d->i6[0]) < ntohl(_s->i6[0])) { \ - _d->i6[1] = NLADD(_d->i6[1], 1); \ - if (ntohl(_d->i6[1]) < ntohl(_s->i6[1])) { \ - _d->i6[2] = NLADD(_d->i6[2], 1); \ - if (ntohl(_d->i6[2]) < ntohl(_s->i6[2])) { \ - _d->i6[3] = NLADD(_d->i6[3], 1); \ - } \ - } \ - } \ - } -#define IP6_AND(a,b,d) { i6addr_t *_s1 = (i6addr_t *)(a); \ - i6addr_t *_s2 = (i6addr_t *)(d); \ - i6addr_t *_d = (i6addr_t *)(d); \ - _d->i6[0] = _s1->i6[0] & _s2->i6[0]; \ - _d->i6[1] = _s1->i6[1] & _s2->i6[1]; \ - _d->i6[2] = _s1->i6[2] & _s2->i6[2]; \ - _d->i6[3] = _s1->i6[3] & _s2->i6[3]; \ - } -#define IP6_MERGE(a,b,c) \ - { i6addr_t *_d, *_s1, *_s2; \ - _d = (i6addr_t *)(a); \ - _s1 = (i6addr_t *)(b); \ - _s2 = (i6addr_t *)(c); \ - _d->i6[0] |= _s1->i6[0] & ~_s2->i6[0]; \ - _d->i6[1] |= _s1->i6[1] & ~_s2->i6[1]; \ - _d->i6[2] |= _s1->i6[2] & ~_s2->i6[2]; \ - _d->i6[2] |= _s1->i6[3] & ~_s2->i6[3]; \ - } - - -typedef struct fr_ip { - u_32_t fi_v:4; /* IP version */ - u_32_t fi_xx:4; /* spare */ - u_32_t fi_tos:8; /* IP packet TOS */ - u_32_t fi_ttl:8; /* IP packet TTL */ - u_32_t fi_p:8; /* IP packet protocol */ - u_32_t fi_optmsk; /* bitmask composed from IP options */ - i6addr_t fi_src; /* source address from packet */ - i6addr_t fi_dst; /* destination address from packet */ - u_short fi_secmsk; /* bitmask composed from IP security options */ - u_short fi_auth; /* authentication code from IP sec. options */ - u_32_t fi_flx; /* packet flags */ - u_32_t fi_tcpmsk; /* TCP options set/reset */ - u_32_t fi_res1; /* RESERVED */ -} fr_ip_t; - -/* - * For use in fi_flx - */ -#define FI_TCPUDP 0x0001 /* TCP/UCP implied comparison*/ -#define FI_OPTIONS 0x0002 -#define FI_FRAG 0x0004 -#define FI_SHORT 0x0008 -#define FI_NATED 0x0010 -#define FI_MULTICAST 0x0020 -#define FI_BROADCAST 0x0040 -#define FI_MBCAST 0x0080 -#define FI_STATE 0x0100 -#define FI_BADNAT 0x0200 -#define FI_BAD 0x0400 -#define FI_OOW 0x0800 /* Out of state window, else match */ -#define FI_ICMPERR 0x1000 -#define FI_FRAGBODY 0x2000 -#define FI_BADSRC 0x4000 -#define FI_LOWTTL 0x8000 -#define FI_CMP 0xcfe3 /* Not FI_FRAG,FI_NATED,FI_FRAGTAIL */ -#define FI_ICMPCMP 0x0003 /* Flags we can check for ICMP error packets */ -#define FI_WITH 0xeffe /* Not FI_TCPUDP */ -#define FI_V6EXTHDR 0x10000 -#define FI_COALESCE 0x20000 -#define FI_NOCKSUM 0x20000000 /* don't do a L4 checksum validation */ -#define FI_DONTCACHE 0x40000000 /* don't cache the result */ -#define FI_IGNORE 0x80000000 - -#define fi_saddr fi_src.in4.s_addr -#define fi_daddr fi_dst.in4.s_addr -#define fi_srcnum fi_src.iplookupnum -#define fi_dstnum fi_dst.iplookupnum -#define fi_srctype fi_src.iplookuptype -#define fi_dsttype fi_dst.iplookuptype -#define fi_srcptr fi_src.iplookupptr -#define fi_dstptr fi_dst.iplookupptr -#define fi_srcfunc fi_src.iplookupfunc -#define fi_dstfunc fi_dst.iplookupfunc - - -/* - * These are both used by the state and NAT code to indicate that one port or - * the other should be treated as a wildcard. - * NOTE: When updating, check bit masks in ip_state.h and update there too. - */ -#define SI_W_SPORT 0x00000100 -#define SI_W_DPORT 0x00000200 -#define SI_WILDP (SI_W_SPORT|SI_W_DPORT) -#define SI_W_SADDR 0x00000400 -#define SI_W_DADDR 0x00000800 -#define SI_WILDA (SI_W_SADDR|SI_W_DADDR) -#define SI_NEWFR 0x00001000 -#define SI_CLONE 0x00002000 -#define SI_CLONED 0x00004000 - - -typedef struct fr_info { - void *fin_ifp; /* interface packet is `on' */ - fr_ip_t fin_fi; /* IP Packet summary */ - union { - u_short fid_16[2]; /* TCP/UDP ports, ICMP code/type */ - u_32_t fid_32; - } fin_dat; - int fin_out; /* in or out ? 1 == out, 0 == in */ - int fin_rev; /* state only: 1 = reverse */ - u_short fin_hlen; /* length of IP header in bytes */ - u_char fin_tcpf; /* TCP header flags (SYN, ACK, etc) */ - u_char fin_icode; /* ICMP error to return */ - u_32_t fin_rule; /* rule # last matched */ - char fin_group[FR_GROUPLEN]; /* group number, -1 for none */ - struct frentry *fin_fr; /* last matching rule */ - void *fin_dp; /* start of data past IP header */ - int fin_dlen; /* length of data portion of packet */ - int fin_plen; - int fin_ipoff; /* # bytes from buffer start to hdr */ - u_short fin_id; /* IP packet id field */ - u_short fin_off; - int fin_depth; /* Group nesting depth */ - int fin_error; /* Error code to return */ - void *fin_nat; - void *fin_state; - void *fin_nattag; - ip_t *fin_ip; - mb_t **fin_mp; /* pointer to pointer to mbuf */ - mb_t *fin_m; /* pointer to mbuf */ -#ifdef MENTAT - mb_t *fin_qfm; /* pointer to mblk where pkt starts */ - void *fin_qpi; -#endif -#ifdef __sgi - void *fin_hbuf; -#endif -} fr_info_t; - -#define fin_v fin_fi.fi_v -#define fin_p fin_fi.fi_p -#define fin_flx fin_fi.fi_flx -#define fin_optmsk fin_fi.fi_optmsk -#define fin_secmsk fin_fi.fi_secmsk -#define fin_auth fin_fi.fi_auth -#define fin_src fin_fi.fi_src.in4 -#define fin_src6 fin_fi.fi_src.in6 -#define fin_saddr fin_fi.fi_saddr -#define fin_dst fin_fi.fi_dst.in4 -#define fin_dst6 fin_fi.fi_dst.in6 -#define fin_daddr fin_fi.fi_daddr -#define fin_data fin_dat.fid_16 -#define fin_sport fin_dat.fid_16[0] -#define fin_dport fin_dat.fid_16[1] -#define fin_ports fin_dat.fid_32 - -#define IPF_IN 0 -#define IPF_OUT 1 - -typedef struct frentry *(*ipfunc_t) __P((fr_info_t *, u_32_t *)); -typedef int (*ipfuncinit_t) __P((struct frentry *)); - -typedef struct ipfunc_resolve { - char ipfu_name[32]; - ipfunc_t ipfu_addr; - ipfuncinit_t ipfu_init; -} ipfunc_resolve_t; - -/* - * Size for compares on fr_info structures - */ -#define FI_CSIZE offsetof(fr_info_t, fin_icode) -#define FI_LCSIZE offsetof(fr_info_t, fin_dp) - -/* - * Size for copying cache fr_info structure - */ -#define FI_COPYSIZE offsetof(fr_info_t, fin_dp) - -/* - * Structure for holding IPFilter's tag information - */ -#define IPFTAG_LEN 16 -typedef struct { - union { - u_32_t iptu_num[4]; - char iptu_tag[IPFTAG_LEN]; - } ipt_un; - int ipt_not; -} ipftag_t; - -#define ipt_tag ipt_un.iptu_tag -#define ipt_num ipt_un.iptu_num - - -/* - * This structure is used to hold information about the next hop for where - * to forward a packet. - */ -typedef struct frdest { - void *fd_ifp; - i6addr_t fd_ip6; - char fd_ifname[LIFNAMSIZ]; -} frdest_t; - -#define fd_ip fd_ip6.in4 - - -/* - * This structure holds information about a port comparison. - */ -typedef struct frpcmp { - int frp_cmp; /* data for port comparisons */ - u_short frp_port; /* top port for <> and >< */ - u_short frp_top; /* top port for <> and >< */ -} frpcmp_t; - -#define FR_NONE 0 -#define FR_EQUAL 1 -#define FR_NEQUAL 2 -#define FR_LESST 3 -#define FR_GREATERT 4 -#define FR_LESSTE 5 -#define FR_GREATERTE 6 -#define FR_OUTRANGE 7 -#define FR_INRANGE 8 -#define FR_INCRANGE 9 - -/* - * Structure containing all the relevant TCP things that can be checked in - * a filter rule. - */ -typedef struct frtuc { - u_char ftu_tcpfm; /* tcp flags mask */ - u_char ftu_tcpf; /* tcp flags */ - frpcmp_t ftu_src; - frpcmp_t ftu_dst; -} frtuc_t; - -#define ftu_scmp ftu_src.frp_cmp -#define ftu_dcmp ftu_dst.frp_cmp -#define ftu_sport ftu_src.frp_port -#define ftu_dport ftu_dst.frp_port -#define ftu_stop ftu_src.frp_top -#define ftu_dtop ftu_dst.frp_top - -#define FR_TCPFMAX 0x3f - -/* - * This structure makes up what is considered to be the IPFilter specific - * matching components of a filter rule, as opposed to the data structures - * used to define the result which are in frentry_t and not here. - */ -typedef struct fripf { - fr_ip_t fri_ip; - fr_ip_t fri_mip; /* mask structure */ - - u_short fri_icmpm; /* data for ICMP packets (mask) */ - u_short fri_icmp; - - frtuc_t fri_tuc; - int fri_satype; /* addres type */ - int fri_datype; /* addres type */ - int fri_sifpidx; /* doing dynamic addressing */ - int fri_difpidx; /* index into fr_ifps[] to use when */ -} fripf_t; - -#define fri_dstnum fri_ip.fi_dstnum -#define fri_srcnum fri_mip.fi_srcnum -#define fri_dstptr fri_ip.fi_dstptr -#define fri_srcptr fri_mip.fi_srcptr - -#define FRI_NORMAL 0 /* Normal address */ -#define FRI_DYNAMIC 1 /* dynamic address */ -#define FRI_LOOKUP 2 /* address is a pool # */ -#define FRI_RANGE 3 /* address/mask is a range */ -#define FRI_NETWORK 4 /* network address from if */ -#define FRI_BROADCAST 5 /* broadcast address from if */ -#define FRI_PEERADDR 6 /* Peer address for P-to-P */ -#define FRI_NETMASKED 7 /* network address with netmask from if */ - - -typedef struct frentry * (* frentfunc_t) __P((fr_info_t *)); - -typedef struct frentry { - ipfmutex_t fr_lock; - struct frentry *fr_next; - struct frentry **fr_grp; - struct ipscan *fr_isc; - void *fr_ifas[4]; - void *fr_ptr; /* for use with fr_arg */ - char *fr_comment; /* text comment for rule */ - int fr_ref; /* reference count - for grouping */ - int fr_statecnt; /* state count - for limit rules */ - /* - * These are only incremented when a packet matches this rule and - * it is the last match - */ - U_QUAD_T fr_hits; - U_QUAD_T fr_bytes; - - /* - * For PPS rate limiting - */ - struct timeval fr_lastpkt; - int fr_curpps; - - union { - void *fru_data; - caddr_t fru_caddr; - fripf_t *fru_ipf; - frentfunc_t fru_func; - } fr_dun; - - /* - * Fields after this may not change whilst in the kernel. - */ - ipfunc_t fr_func; /* call this function */ - int fr_dsize; - int fr_pps; - int fr_statemax; /* max reference count */ - int fr_flineno; /* line number from conf file */ - u_32_t fr_type; - u_32_t fr_flags; /* per-rule flags && options (see below) */ - u_32_t fr_logtag; /* user defined log tag # */ - u_32_t fr_collect; /* collection number */ - u_int fr_arg; /* misc. numeric arg for rule */ - u_int fr_loglevel; /* syslog log facility + priority */ - u_int fr_age[2]; /* non-TCP timeouts */ - u_char fr_v; - u_char fr_icode; /* return ICMP code */ - char fr_group[FR_GROUPLEN]; /* group to which this rule belongs */ - char fr_grhead[FR_GROUPLEN]; /* group # which this rule starts */ - ipftag_t fr_nattag; - char fr_ifnames[4][LIFNAMSIZ]; - char fr_isctag[16]; - frdest_t fr_tifs[2]; /* "to"/"reply-to" interface */ - frdest_t fr_dif; /* duplicate packet interface */ - /* - * This must be last and will change after loaded into the kernel. - */ - u_int fr_cksum; /* checksum on filter rules for performance */ -} frentry_t; - -#define fr_caddr fr_dun.fru_caddr -#define fr_data fr_dun.fru_data -#define fr_dfunc fr_dun.fru_func -#define fr_ipf fr_dun.fru_ipf -#define fr_ip fr_ipf->fri_ip -#define fr_mip fr_ipf->fri_mip -#define fr_icmpm fr_ipf->fri_icmpm -#define fr_icmp fr_ipf->fri_icmp -#define fr_tuc fr_ipf->fri_tuc -#define fr_satype fr_ipf->fri_satype -#define fr_datype fr_ipf->fri_datype -#define fr_sifpidx fr_ipf->fri_sifpidx -#define fr_difpidx fr_ipf->fri_difpidx -#define fr_proto fr_ip.fi_p -#define fr_mproto fr_mip.fi_p -#define fr_ttl fr_ip.fi_ttl -#define fr_mttl fr_mip.fi_ttl -#define fr_tos fr_ip.fi_tos -#define fr_mtos fr_mip.fi_tos -#define fr_tcpfm fr_tuc.ftu_tcpfm -#define fr_tcpf fr_tuc.ftu_tcpf -#define fr_scmp fr_tuc.ftu_scmp -#define fr_dcmp fr_tuc.ftu_dcmp -#define fr_dport fr_tuc.ftu_dport -#define fr_sport fr_tuc.ftu_sport -#define fr_stop fr_tuc.ftu_stop -#define fr_dtop fr_tuc.ftu_dtop -#define fr_dst fr_ip.fi_dst.in4 -#define fr_daddr fr_ip.fi_dst.in4.s_addr -#define fr_src fr_ip.fi_src.in4 -#define fr_saddr fr_ip.fi_src.in4.s_addr -#define fr_dmsk fr_mip.fi_dst.in4 -#define fr_dmask fr_mip.fi_dst.in4.s_addr -#define fr_smsk fr_mip.fi_src.in4 -#define fr_smask fr_mip.fi_src.in4.s_addr -#define fr_dstnum fr_ip.fi_dstnum -#define fr_srcnum fr_ip.fi_srcnum -#define fr_dsttype fr_ip.fi_dsttype -#define fr_srctype fr_ip.fi_srctype -#define fr_dstptr fr_mip.fi_dstptr -#define fr_srcptr fr_mip.fi_srcptr -#define fr_dstfunc fr_mip.fi_dstfunc -#define fr_srcfunc fr_mip.fi_srcfunc -#define fr_optbits fr_ip.fi_optmsk -#define fr_optmask fr_mip.fi_optmsk -#define fr_secbits fr_ip.fi_secmsk -#define fr_secmask fr_mip.fi_secmsk -#define fr_authbits fr_ip.fi_auth -#define fr_authmask fr_mip.fi_auth -#define fr_flx fr_ip.fi_flx -#define fr_mflx fr_mip.fi_flx -#define fr_ifname fr_ifnames[0] -#define fr_oifname fr_ifnames[2] -#define fr_ifa fr_ifas[0] -#define fr_oifa fr_ifas[2] -#define fr_tif fr_tifs[0] -#define fr_rif fr_tifs[1] - -#define FR_NOLOGTAG 0 - -#ifndef offsetof -#define offsetof(t,m) (int)((&((t *)0L)->m)) -#endif -#define FR_CMPSIZ (sizeof(struct frentry) - \ - offsetof(struct frentry, fr_func)) - -/* - * fr_type - */ -#define FR_T_NONE 0 -#define FR_T_IPF 1 /* IPF structures */ -#define FR_T_BPFOPC 2 /* BPF opcode */ -#define FR_T_CALLFUNC 3 /* callout to function in fr_func only */ -#define FR_T_COMPIPF 4 /* compiled C code */ -#define FR_T_BUILTIN 0x80000000 /* rule is in kernel space */ - -/* - * fr_flags - */ -#define FR_CALL 0x00000 /* call rule */ -#define FR_BLOCK 0x00001 /* do not allow packet to pass */ -#define FR_PASS 0x00002 /* allow packet to pass */ -#define FR_AUTH 0x00003 /* use authentication */ -#define FR_PREAUTH 0x00004 /* require preauthentication */ -#define FR_ACCOUNT 0x00005 /* Accounting rule */ -#define FR_SKIP 0x00006 /* skip rule */ -#define FR_DIVERT 0x00007 /* divert rule */ -#define FR_CMDMASK 0x0000f -#define FR_LOG 0x00010 /* Log */ -#define FR_LOGB 0x00011 /* Log-fail */ -#define FR_LOGP 0x00012 /* Log-pass */ -#define FR_LOGMASK (FR_LOG|FR_CMDMASK) -#define FR_CALLNOW 0x00020 /* call another function (fr_func) if matches */ -#define FR_NOTSRCIP 0x00040 -#define FR_NOTDSTIP 0x00080 -#define FR_QUICK 0x00100 /* match & stop processing list */ -#define FR_KEEPFRAG 0x00200 /* keep fragment information */ -#define FR_KEEPSTATE 0x00400 /* keep `connection' state information */ -#define FR_FASTROUTE 0x00800 /* bypass normal routing */ -#define FR_RETRST 0x01000 /* Return TCP RST packet - reset connection */ -#define FR_RETICMP 0x02000 /* Return ICMP unreachable packet */ -#define FR_FAKEICMP 0x03000 /* Return ICMP unreachable with fake source */ -#define FR_OUTQUE 0x04000 /* outgoing packets */ -#define FR_INQUE 0x08000 /* ingoing packets */ -#define FR_LOGBODY 0x10000 /* Log the body */ -#define FR_LOGFIRST 0x20000 /* Log the first byte if state held */ -#define FR_LOGORBLOCK 0x40000 /* block the packet if it can't be logged */ -#define FR_DUP 0x80000 /* duplicate packet */ -#define FR_FRSTRICT 0x100000 /* strict frag. cache */ -#define FR_STSTRICT 0x200000 /* strict keep state */ -#define FR_NEWISN 0x400000 /* new ISN for outgoing TCP */ -#define FR_NOICMPERR 0x800000 /* do not match ICMP errors in state */ -#define FR_STATESYNC 0x1000000 /* synchronize state to slave */ -#define FR_NOMATCH 0x8000000 /* no match occured */ - /* 0x10000000 FF_LOGPASS */ - /* 0x20000000 FF_LOGBLOCK */ - /* 0x40000000 FF_LOGNOMATCH */ - /* 0x80000000 FF_BLOCKNONIP */ -#define FR_COPIED 0x40000000 /* copied from user space */ -#define FR_INACTIVE 0x80000000 /* only used when flush'ing rules */ - -#define FR_RETMASK (FR_RETICMP|FR_RETRST|FR_FAKEICMP) -#define FR_ISBLOCK(x) (((x) & FR_CMDMASK) == FR_BLOCK) -#define FR_ISPASS(x) (((x) & FR_CMDMASK) == FR_PASS) -#define FR_ISAUTH(x) (((x) & FR_CMDMASK) == FR_AUTH) -#define FR_ISPREAUTH(x) (((x) & FR_CMDMASK) == FR_PREAUTH) -#define FR_ISACCOUNT(x) (((x) & FR_CMDMASK) == FR_ACCOUNT) -#define FR_ISSKIP(x) (((x) & FR_CMDMASK) == FR_SKIP) -#define FR_ISNOMATCH(x) ((x) & FR_NOMATCH) -#define FR_INOUT (FR_INQUE|FR_OUTQUE) - -/* - * recognized flags for SIOCGETFF and SIOCSETFF, and get put in fr_flags - */ -#define FF_LOGPASS 0x10000000 -#define FF_LOGBLOCK 0x20000000 -#define FF_LOGNOMATCH 0x40000000 -#define FF_LOGGING (FF_LOGPASS|FF_LOGBLOCK|FF_LOGNOMATCH) -#define FF_BLOCKNONIP 0x80000000 /* Solaris2 Only */ - - -/* - * Structure that passes information on what/how to flush to the kernel. - */ -typedef struct ipfflush { - int ipflu_how; - int ipflu_arg; -} ipfflush_t; - - -/* - * - */ -typedef struct ipfgetctl { - u_int ipfg_min; /* min value */ - u_int ipfg_current; /* current value */ - u_int ipfg_max; /* max value */ - u_int ipfg_default; /* default value */ - u_int ipfg_steps; /* value increments */ - char ipfg_name[40]; /* tag name for this control */ -} ipfgetctl_t; - -typedef struct ipfsetctl { - int ipfs_which; /* 0 = min 1 = current 2 = max 3 = default */ - u_int ipfs_value; /* min value */ - char ipfs_name[40]; /* tag name for this control */ -} ipfsetctl_t; - - -/* - * Some of the statistics below are in their own counters, but most are kept - * in this single structure so that they can all easily be collected and - * copied back as required. - */ -typedef struct filterstats { - u_long fr_pass; /* packets allowed */ - u_long fr_block; /* packets denied */ - u_long fr_nom; /* packets which don't match any rule */ - u_long fr_short; /* packets which are short */ - u_long fr_ppkl; /* packets allowed and logged */ - u_long fr_bpkl; /* packets denied and logged */ - u_long fr_npkl; /* packets unmatched and logged */ - u_long fr_pkl; /* packets logged */ - u_long fr_skip; /* packets to be logged but buffer full */ - u_long fr_ret; /* packets for which a return is sent */ - u_long fr_acct; /* packets for which counting was performed */ - u_long fr_bnfr; /* bad attempts to allocate fragment state */ - u_long fr_nfr; /* new fragment state kept */ - u_long fr_cfr; /* add new fragment state but complete pkt */ - u_long fr_bads; /* bad attempts to allocate packet state */ - u_long fr_ads; /* new packet state kept */ - u_long fr_chit; /* cached hit */ - u_long fr_tcpbad; /* TCP checksum check failures */ - u_long fr_pull[2]; /* good and bad pullup attempts */ - u_long fr_badsrc; /* source received doesn't match route */ - u_long fr_badttl; /* TTL in packet doesn't reach minimum */ - u_long fr_bad; /* bad IP packets to the filter */ - u_long fr_ipv6; /* IPv6 packets in/out */ - u_long fr_ppshit; /* dropped because of pps ceiling */ - u_long fr_ipud; /* IP id update failures */ -} filterstats_t; - -/* - * Log structure. Each packet header logged is prepended by one of these. - * Following this in the log records read from the device will be an ipflog - * structure which is then followed by any packet data. - */ -typedef struct iplog { - u_32_t ipl_magic; - u_int ipl_count; - struct timeval ipl_time; - size_t ipl_dsize; - struct iplog *ipl_next; -} iplog_t; - -#define ipl_sec ipl_time.tv_sec -#define ipl_usec ipl_time.tv_usec - -#define IPL_MAGIC 0x49504c4d /* 'IPLM' */ -#define IPL_MAGIC_NAT 0x49504c4e /* 'IPLN' */ -#define IPL_MAGIC_STATE 0x49504c53 /* 'IPLS' */ -#define IPLOG_SIZE sizeof(iplog_t) - -typedef struct ipflog { -#if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) -#else - u_int fl_unit; -#endif - u_32_t fl_rule; - u_32_t fl_flags; - u_32_t fl_lflags; - u_32_t fl_logtag; - ipftag_t fl_nattag; - u_short fl_plen; /* extra data after hlen */ - u_short fl_loglevel; /* syslog log level */ - char fl_group[FR_GROUPLEN]; - u_char fl_hlen; /* length of IP headers saved */ - u_char fl_dir; - u_char fl_xxx[2]; /* pad */ - char fl_ifname[LIFNAMSIZ]; -} ipflog_t; - -#ifndef IPF_LOGGING -# define IPF_LOGGING 0 -#endif -#ifndef IPF_DEFAULT_PASS -# define IPF_DEFAULT_PASS FR_PASS -#endif - -#define DEFAULT_IPFLOGSIZE 8192 -#ifndef IPFILTER_LOGSIZE -# define IPFILTER_LOGSIZE DEFAULT_IPFLOGSIZE -#else -# if IPFILTER_LOGSIZE < DEFAULT_IPFLOGSIZE -# error IPFILTER_LOGSIZE too small. Must be >= DEFAULT_IPFLOGSIZE -# endif -#endif - -#define IPF_OPTCOPY 0x07ff00 /* bit mask of copied options */ - -/* - * Device filenames for reading log information. Use ipf on Solaris2 because - * ipl is already a name used by something else. - */ -#ifndef IPL_NAME -# if SOLARIS -# define IPL_NAME "/dev/ipf" -# else -# define IPL_NAME "/dev/ipl" -# endif -#endif -/* - * Pathnames for various IP Filter control devices. Used by LKM - * and userland, so defined here. - */ -#define IPNAT_NAME "/dev/ipnat" -#define IPSTATE_NAME "/dev/ipstate" -#define IPAUTH_NAME "/dev/ipauth" -#define IPSYNC_NAME "/dev/ipsync" -#define IPSCAN_NAME "/dev/ipscan" -#define IPLOOKUP_NAME "/dev/iplookup" - -#define IPL_LOGIPF 0 /* Minor device #'s for accessing logs */ -#define IPL_LOGNAT 1 -#define IPL_LOGSTATE 2 -#define IPL_LOGAUTH 3 -#define IPL_LOGSYNC 4 -#define IPL_LOGSCAN 5 -#define IPL_LOGLOOKUP 6 -#define IPL_LOGCOUNT 7 -#define IPL_LOGMAX 7 -#define IPL_LOGSIZE IPL_LOGMAX + 1 -#define IPL_LOGALL -1 -#define IPL_LOGNONE -2 - -/* - * For SIOCGETFS - */ -typedef struct friostat { - struct filterstats f_st[2]; - struct frentry *f_ipf[2][2]; - struct frentry *f_acct[2][2]; - struct frentry *f_ipf6[2][2]; - struct frentry *f_acct6[2][2]; - struct frentry *f_auth; - struct frgroup *f_groups[IPL_LOGSIZE][2]; - u_long f_froute[2]; - u_long f_ticks; - int f_locks[IPL_LOGMAX]; - size_t f_kmutex_sz; - size_t f_krwlock_sz; - int f_defpass; /* default pass - from fr_pass */ - int f_active; /* 1 or 0 - active rule set */ - int f_running; /* 1 if running, else 0 */ - int f_logging; /* 1 if enabled, else 0 */ - int f_features; - char f_version[32]; /* version string */ -} friostat_t; - -#define f_fin f_ipf[0] -#define f_fin6 f_ipf6[0] -#define f_fout f_ipf[1] -#define f_fout6 f_ipf6[1] -#define f_acctin f_acct[0] -#define f_acctin6 f_acct6[0] -#define f_acctout f_acct[1] -#define f_acctout6 f_acct6[1] - -#define IPF_FEAT_LKM 0x001 -#define IPF_FEAT_LOG 0x002 -#define IPF_FEAT_LOOKUP 0x004 -#define IPF_FEAT_BPF 0x008 -#define IPF_FEAT_COMPILED 0x010 -#define IPF_FEAT_CKSUM 0x020 -#define IPF_FEAT_SYNC 0x040 -#define IPF_FEAT_SCAN 0x080 -#define IPF_FEAT_IPV6 0x100 - -typedef struct optlist { - u_short ol_val; - int ol_bit; -} optlist_t; - - -/* - * Group list structure. - */ -typedef struct frgroup { - struct frgroup *fg_next; - struct frentry *fg_head; - struct frentry *fg_start; - u_32_t fg_flags; - int fg_ref; - char fg_name[FR_GROUPLEN]; -} frgroup_t; - -#define FG_NAME(g) (*(g)->fg_name == '\0' ? "" : (g)->fg_name) - - -/* - * Used by state and NAT tables - */ -typedef struct icmpinfo { - u_short ici_id; - u_short ici_seq; - u_char ici_type; -} icmpinfo_t; - -typedef struct udpinfo { - u_short us_sport; - u_short us_dport; -} udpinfo_t; - - -typedef struct tcpdata { - u_32_t td_end; - u_32_t td_maxend; - u_32_t td_maxwin; - u_32_t td_winscale; - u_32_t td_maxseg; - int td_winflags; -} tcpdata_t; - -#define TCP_WSCALE_MAX 14 - -#define TCP_WSCALE_SEEN 0x00000001 -#define TCP_WSCALE_FIRST 0x00000002 - - -typedef struct tcpinfo { - u_short ts_sport; - u_short ts_dport; - tcpdata_t ts_data[2]; -} tcpinfo_t; - - -struct grebits { - u_32_t grb_C:1; - u_32_t grb_R:1; - u_32_t grb_K:1; - u_32_t grb_S:1; - u_32_t grb_s:1; - u_32_t grb_recur:1; - u_32_t grb_A:1; - u_32_t grb_flags:3; - u_32_t grb_ver:3; - u_short grb_ptype; -}; - -typedef struct grehdr { - union { - struct grebits gru_bits; - u_short gru_flags; - } gr_un; - u_short gr_len; - u_short gr_call; -} grehdr_t; - -#define gr_flags gr_un.gru_flags -#define gr_bits gr_un.gru_bits -#define gr_ptype gr_bits.grb_ptype -#define gr_C gr_bits.grb_C -#define gr_R gr_bits.grb_R -#define gr_K gr_bits.grb_K -#define gr_S gr_bits.grb_S -#define gr_s gr_bits.grb_s -#define gr_recur gr_bits.grb_recur -#define gr_A gr_bits.grb_A -#define gr_ver gr_bits.grb_ver - - -typedef struct greinfo { - u_short gs_call[2]; - u_short gs_flags; - u_short gs_ptype; -} greinfo_t; - -#define GRE_REV(x) ((ntohs(x) >> 13) & 7) - - -/* - * Timeout tail queue list member - */ -typedef struct ipftqent { - struct ipftqent **tqe_pnext; - struct ipftqent *tqe_next; - struct ipftq *tqe_ifq; - void *tqe_parent; /* pointer back to NAT/state struct */ - u_long tqe_die; /* when this entriy is to die */ - u_long tqe_touched; - int tqe_flags; - int tqe_state[2]; /* current state of this entry */ -} ipftqent_t; - -#define TQE_RULEBASED 0x00000001 - - -/* - * Timeout tail queue head for IPFilter - */ -typedef struct ipftq { - ipfmutex_t ifq_lock; - u_int ifq_ttl; - ipftqent_t *ifq_head; - ipftqent_t **ifq_tail; - struct ipftq *ifq_next; - struct ipftq **ifq_pnext; - int ifq_ref; - u_int ifq_flags; -} ipftq_t; - -#define IFQF_USER 0x01 /* User defined aging */ -#define IFQF_DELETE 0x02 /* Marked for deletion */ -#define IFQF_PROXY 0x04 /* Timeout queue in use by a proxy */ - -#define IPF_HZ_MULT 1 -#define IPF_HZ_DIVIDE 2 /* How many times a second ipfilter */ - /* checks its timeout queues. */ -#define IPF_TTLVAL(x) (((x) / IPF_HZ_MULT) * IPF_HZ_DIVIDE) - -/* - * Structure to define address for pool lookups. - */ -typedef struct { - u_char adf_len; - i6addr_t adf_addr; -} addrfamily_t; - - -/* - * Object structure description. For passing through in ioctls. - */ -typedef struct ipfobj { - u_32_t ipfo_rev; /* IPFilter version number */ - u_32_t ipfo_size; /* size of object at ipfo_ptr */ - void *ipfo_ptr; /* pointer to object */ - int ipfo_type; /* type of object being pointed to */ - int ipfo_offset; /* bytes from ipfo_ptr where to start */ - u_char ipfo_xxxpad[32]; /* reserved for future use */ -} ipfobj_t; - -#define IPFOBJ_FRENTRY 0 /* struct frentry */ -#define IPFOBJ_IPFSTAT 1 /* struct friostat */ -#define IPFOBJ_IPFINFO 2 /* struct fr_info */ -#define IPFOBJ_AUTHSTAT 3 /* struct fr_authstat */ -#define IPFOBJ_FRAGSTAT 4 /* struct ipfrstat */ -#define IPFOBJ_IPNAT 5 /* struct ipnat */ -#define IPFOBJ_NATSTAT 6 /* struct natstat */ -#define IPFOBJ_STATESAVE 7 /* struct ipstate_save */ -#define IPFOBJ_NATSAVE 8 /* struct nat_save */ -#define IPFOBJ_NATLOOKUP 9 /* struct natlookup */ -#define IPFOBJ_IPSTATE 10 /* struct ipstate */ -#define IPFOBJ_STATESTAT 11 /* struct ips_stat */ -#define IPFOBJ_FRAUTH 12 /* struct frauth */ -#define IPFOBJ_TUNEABLE 13 /* struct ipftune */ - - -typedef union ipftunevalptr { - void *ipftp_void; - u_long *ipftp_long; - u_int *ipftp_int; - u_short *ipftp_short; - u_char *ipftp_char; -} ipftunevalptr_t; - -typedef struct ipftuneable { - ipftunevalptr_t ipft_una; - char *ipft_name; - u_long ipft_min; - u_long ipft_max; - int ipft_sz; - int ipft_flags; - struct ipftuneable *ipft_next; -} ipftuneable_t; - -#define ipft_addr ipft_una.ipftp_void -#define ipft_plong ipft_una.ipftp_long -#define ipft_pint ipft_una.ipftp_int -#define ipft_pshort ipft_una.ipftp_short -#define ipft_pchar ipft_una.ipftp_char - -#define IPFT_RDONLY 1 /* read-only */ -#define IPFT_WRDISABLED 2 /* write when disabled only */ - -typedef union ipftuneval { - u_long ipftu_long; - u_int ipftu_int; - u_short ipftu_short; - u_char ipftu_char; -} ipftuneval_t; - -typedef struct ipftune { - void *ipft_cookie; - ipftuneval_t ipft_un; - u_long ipft_min; - u_long ipft_max; - int ipft_sz; - int ipft_flags; - char ipft_name[80]; -} ipftune_t; - -#define ipft_vlong ipft_un.ipftu_long -#define ipft_vint ipft_un.ipftu_int -#define ipft_vshort ipft_un.ipftu_short -#define ipft_vchar ipft_un.ipftu_char - - -/* -** HPUX Port -*/ -#ifdef __hpux -/* HP-UX locking sequence deadlock detection module lock MAJOR ID */ -# define IPF_SMAJ 0 /* temp assignment XXX, not critical */ -#endif - -#if !defined(CDEV_MAJOR) && defined (__FreeBSD_version) && \ - (__FreeBSD_version >= 220000) -# define CDEV_MAJOR 79 -#endif - -/* - * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns - * on those hooks. We don't need any special mods in non-IP Filter code - * with this! - */ -#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ - (defined(NetBSD1_2) && NetBSD1_2 > 1) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 500043)) -# if (NetBSD >= 199905) -# define PFIL_HOOKS -# endif -# ifdef PFIL_HOOKS -# define NETBSD_PF -# endif -#endif - -#ifndef _KERNEL -extern int fr_check __P((struct ip *, int, void *, int, mb_t **)); -extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **)); -extern int ipf_log __P((void)); -extern struct ifnet *get_unit __P((char *, int)); -extern char *get_ifname __P((struct ifnet *)); -# if defined(__NetBSD__) || defined(__OpenBSD__) || \ - (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000) -extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int)); -# else -extern int iplioctl __P((int, ioctlcmd_t, caddr_t, int)); -# endif -extern int iplopen __P((dev_t, int)); -extern int iplclose __P((dev_t, int)); -extern void m_freem __P((mb_t *)); -#else /* #ifndef _KERNEL */ -# if defined(__NetBSD__) && defined(PFIL_HOOKS) -extern void ipfilterattach __P((int)); -# endif -extern int ipl_enable __P((void)); -extern int ipl_disable __P((void)); -# ifdef MENTAT -extern int fr_check __P((struct ip *, int, void *, int, void *, - mblk_t **)); -# if SOLARIS -# if SOLARIS2 >= 7 -extern int iplioctl __P((dev_t, int, intptr_t, int, cred_t *, int *)); -# else -extern int iplioctl __P((dev_t, int, int *, int, cred_t *, int *)); -# endif -extern int iplopen __P((dev_t *, int, int, cred_t *)); -extern int iplclose __P((dev_t, int, int, cred_t *)); -extern int iplread __P((dev_t, uio_t *, cred_t *)); -extern int iplwrite __P((dev_t, uio_t *, cred_t *)); -# endif -# ifdef __hpux -extern int iplopen __P((dev_t, int, intptr_t, int)); -extern int iplclose __P((dev_t, int, int)); -extern int iplioctl __P((dev_t, int, caddr_t, int)); -extern int iplread __P((dev_t, uio_t *)); -extern int iplwrite __P((dev_t, uio_t *)); -extern int iplselect __P((dev_t, int)); -# endif -extern int ipfsync __P((void)); -extern int fr_qout __P((queue_t *, mblk_t *)); -# else /* MENTAT */ -extern int fr_check __P((struct ip *, int, void *, int, mb_t **)); -extern int (*fr_checkp) __P((ip_t *, int, void *, int, mb_t **)); -extern size_t mbufchainlen __P((mb_t *)); -# ifdef __sgi -# include -extern int iplioctl __P((dev_t, int, caddr_t, int, cred_t *, int *)); -extern int iplopen __P((dev_t *, int, int, cred_t *)); -extern int iplclose __P((dev_t, int, int, cred_t *)); -extern int iplread __P((dev_t, uio_t *, cred_t *)); -extern int iplwrite __P((dev_t, uio_t *, cred_t *)); -extern int ipfsync __P((void)); -extern int ipfilter_sgi_attach __P((void)); -extern void ipfilter_sgi_detach __P((void)); -extern void ipfilter_sgi_intfsync __P((void)); -# else -# ifdef IPFILTER_LKM -extern int iplidentify __P((char *)); -# endif -# if (_BSDI_VERSION >= 199510) || (__FreeBSD_version >= 220000) || \ - (NetBSD >= 199511) || defined(__OpenBSD__) -# if defined(__NetBSD__) || (_BSDI_VERSION >= 199701) || \ - defined(__OpenBSD__) || (__FreeBSD_version >= 300000) -# if (__FreeBSD_version >= 500024) -# if (__FreeBSD_version >= 502116) -extern int iplioctl __P((struct cdev*, u_long, caddr_t, int, struct thread *)); -# else -extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct thread *)); -# endif /* __FreeBSD_version >= 502116 */ -# else -extern int iplioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); -# endif /* __FreeBSD_version >= 500024 */ -# else -extern int iplioctl __P((dev_t, int, caddr_t, int, struct proc *)); -# endif -# if (__FreeBSD_version >= 500024) -# if (__FreeBSD_version >= 502116) -extern int iplopen __P((struct cdev*, int, int, struct thread *)); -extern int iplclose __P((struct cdev*, int, int, struct thread *)); -# else -extern int iplopen __P((dev_t, int, int, struct thread *)); -extern int iplclose __P((dev_t, int, int, struct thread *)); -# endif /* __FreeBSD_version >= 502116 */ -# else -extern int iplopen __P((dev_t, int, int, struct proc *)); -extern int iplclose __P((dev_t, int, int, struct proc *)); -# endif /* __FreeBSD_version >= 500024 */ -# else -# ifdef linux -extern int iplioctl __P((struct inode *, struct file *, u_int, u_long)); -# else -extern int iplopen __P((dev_t, int)); -extern int iplclose __P((dev_t, int)); -extern int iplioctl __P((dev_t, int, caddr_t, int)); -# endif -# endif /* (_BSDI_VERSION >= 199510) */ -# if BSD >= 199306 -# if (__FreeBSD_version >= 502116) -extern int iplread __P((struct cdev*, struct uio *, int)); -extern int iplwrite __P((struct cdev*, struct uio *, int)); -# else -extern int iplread __P((dev_t, struct uio *, int)); -extern int iplwrite __P((dev_t, struct uio *, int)); -# endif /* __FreeBSD_version >= 502116 */ -# else -# ifndef linux -extern int iplread __P((dev_t, struct uio *)); -extern int iplwrite __P((dev_t, struct uio *)); -# endif -# endif /* BSD >= 199306 */ -# endif /* __ sgi */ -# endif /* MENTAT */ - -#endif /* #ifndef _KERNEL */ - -extern ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_hostmap; -extern ipfmutex_t ipf_timeoutlock, ipf_stinsert, ipf_natio, ipf_nat_new; -extern ipfrwlock_t ipf_mutex, ipf_global, ip_poolrw, ipf_ipidfrag; -extern ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; - -extern char *memstr __P((char *, char *, int, int)); -extern int count4bits __P((u_32_t)); -extern int frrequest __P((int, ioctlcmd_t, caddr_t, int, int)); -extern char *getifname __P((struct ifnet *)); -extern int iplattach __P((void)); -extern int ipldetach __P((void)); -extern u_short ipf_cksum __P((u_short *, int)); -extern int copyinptr __P((void *, void *, size_t)); -extern int copyoutptr __P((void *, void *, size_t)); -extern int fr_fastroute __P((mb_t *, mb_t **, fr_info_t *, frdest_t *)); -extern int fr_inobj __P((void *, void *, int)); -extern int fr_inobjsz __P((void *, void *, int, int)); -extern int fr_ioctlswitch __P((int, void *, ioctlcmd_t, int)); -extern int fr_ipftune __P((ioctlcmd_t, void *)); -extern int fr_outobj __P((void *, void *, int)); -extern int fr_outobjsz __P((void *, void *, int, int)); -extern void *fr_pullup __P((mb_t *, fr_info_t *, int)); -extern void fr_resolvedest __P((struct frdest *, int)); -extern int fr_resolvefunc __P((void *)); -extern void *fr_resolvenic __P((char *, int)); -extern int fr_send_icmp_err __P((int, fr_info_t *, int)); -extern int fr_send_reset __P((fr_info_t *)); -#if (__FreeBSD_version < 490000) || !defined(_KERNEL) -extern int ppsratecheck __P((struct timeval *, int *, int)); -#endif -extern ipftq_t *fr_addtimeoutqueue __P((ipftq_t **, u_int)); -extern void fr_deletequeueentry __P((ipftqent_t *)); -extern int fr_deletetimeoutqueue __P((ipftq_t *)); -extern void fr_freetimeoutqueue __P((ipftq_t *)); -extern void fr_movequeue __P((ipftqent_t *, ipftq_t *, ipftq_t *)); -extern void fr_queueappend __P((ipftqent_t *, ipftq_t *, void *)); -extern void fr_queueback __P((ipftqent_t *)); -extern void fr_queuefront __P((ipftqent_t *)); -extern void fr_checkv4sum __P((fr_info_t *)); -extern int fr_checkl4sum __P((fr_info_t *)); -extern int fr_ifpfillv4addr __P((int, struct sockaddr_in *, - struct sockaddr_in *, struct in_addr *, - struct in_addr *)); -extern int fr_coalesce __P((fr_info_t *)); -#ifdef USE_INET6 -extern void fr_checkv6sum __P((fr_info_t *)); -extern int fr_ifpfillv6addr __P((int, struct sockaddr_in6 *, - struct sockaddr_in6 *, struct in_addr *, - struct in_addr *)); -#endif - -extern int fr_addipftune __P((ipftuneable_t *)); -extern int fr_delipftune __P((ipftuneable_t *)); - -extern int frflush __P((minor_t, int, int)); -extern void frsync __P((void *)); -extern frgroup_t *fr_addgroup __P((char *, void *, u_32_t, minor_t, int)); -extern int fr_derefrule __P((frentry_t **)); -extern void fr_delgroup __P((char *, minor_t, int)); -extern frgroup_t *fr_findgroup __P((char *, minor_t, int, frgroup_t ***)); - -extern int fr_loginit __P((void)); -extern int ipflog_clear __P((minor_t)); -extern int ipflog_read __P((minor_t, uio_t *)); -extern int ipflog __P((fr_info_t *, u_int)); -extern int ipllog __P((int, fr_info_t *, void **, size_t *, int *, int)); -extern void fr_logunload __P((void)); - -extern frentry_t *fr_acctpkt __P((fr_info_t *, u_32_t *)); -extern int fr_copytolog __P((int, char *, int)); -extern u_short fr_cksum __P((mb_t *, ip_t *, int, void *)); -extern void fr_deinitialise __P((void)); -extern frentry_t *fr_dolog __P((fr_info_t *, u_32_t *)); -extern frentry_t *fr_dstgrpmap __P((fr_info_t *, u_32_t *)); -extern void fr_fixskip __P((frentry_t **, frentry_t *, int)); -extern void fr_forgetifp __P((void *)); -extern frentry_t *fr_getrulen __P((int, char *, u_32_t)); -extern void fr_getstat __P((struct friostat *)); -extern int fr_icmp4errortype __P((int)); -extern int fr_ifpaddr __P((int, int, void *, - struct in_addr *, struct in_addr *)); -extern int fr_initialise __P((void)); -extern void fr_lock __P((caddr_t, int *)); -extern int fr_makefrip __P((int, ip_t *, fr_info_t *)); -extern int fr_matchtag __P((ipftag_t *, ipftag_t *)); -extern int fr_matchicmpqueryreply __P((int, icmpinfo_t *, - struct icmp *, int)); -extern u_32_t fr_newisn __P((fr_info_t *)); -extern u_short fr_nextipid __P((fr_info_t *)); -extern int fr_rulen __P((int, frentry_t *)); -extern int fr_scanlist __P((fr_info_t *, u_32_t)); -extern frentry_t *fr_srcgrpmap __P((fr_info_t *, u_32_t *)); -extern int fr_tcpudpchk __P((fr_info_t *, frtuc_t *)); -extern int fr_verifysrc __P((fr_info_t *fin)); -extern int fr_zerostats __P((char *)); - -extern int fr_running; -extern u_long fr_frouteok[2]; -extern int fr_pass; -extern int fr_flags; -extern int fr_active; -extern int fr_chksrc; -extern int fr_minttl; -extern int fr_refcnt; -extern int fr_control_forwarding; -extern int fr_update_ipid; -extern int nat_logging; -extern int ipstate_logging; -extern int ipl_suppress; -extern int ipl_buffer_sz; -extern int ipl_logmax; -extern int ipl_logall; -extern int ipl_logsize; -extern u_long fr_ticks; -extern fr_info_t frcache[2][8]; -extern char ipfilter_version[]; -extern iplog_t **iplh[IPL_LOGMAX+1], *iplt[IPL_LOGMAX+1]; -extern int iplused[IPL_LOGMAX + 1]; -extern struct frentry *ipfilter[2][2], *ipacct[2][2]; -#ifdef USE_INET6 -extern struct frentry *ipfilter6[2][2], *ipacct6[2][2]; -extern int icmptoicmp6types[ICMP_MAXTYPE+1]; -extern int icmptoicmp6unreach[ICMP_MAX_UNREACH]; -extern int icmpreplytype6[ICMP6_MAXTYPE + 1]; -#endif -extern int icmpreplytype4[ICMP_MAXTYPE + 1]; -extern struct frgroup *ipfgroups[IPL_LOGSIZE][2]; -extern struct filterstats frstats[]; -extern frentry_t *ipfrule_match __P((fr_info_t *)); -extern u_char ipf_iss_secret[32]; -extern ipftuneable_t ipf_tuneables[]; - -#endif /* __IP_FIL_H__ */ diff --git a/contrib/ipfilter/ip_fil_freebsd.c b/contrib/ipfilter/ip_fil_freebsd.c deleted file mode 100644 index 3b36b93117a8..000000000000 --- a/contrib/ipfilter/ip_fil_freebsd.c +++ /dev/null @@ -1,1692 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if !defined(lint) -static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_fil_freebsd.c,v 2.53.2.25 2005/02/01 03:15:56 darrenr Exp"; -#endif - -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \ - !defined(KLD_MODULE) && !defined(IPFILTER_LKM) -# include "opt_inet6.h" -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 440000) && \ - !defined(KLD_MODULE) && !defined(IPFILTER_LKM) -# include "opt_random_ip_id.h" -#endif -#include -#if defined(__FreeBSD__) && !defined(__FreeBSD_version) -# if defined(IPFILTER_LKM) -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -# endif -#endif -#include -#include -#include -#if __FreeBSD_version >= 220000 -# include -# include -#else -# include -#endif -#include -#include -#if (__FreeBSD_version >= 300000) -# include -#else -# include -#endif -#if !defined(__hpux) -# include -#endif -#include -#include - -#include -#if __FreeBSD_version >= 300000 -# include -# if !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#if defined(__osf__) -# include -#endif -#include -#include -#include -#ifndef _KERNEL -# include "netinet/ipf.h" -#endif -#include "netinet/ip_compat.h" -#ifdef USE_INET6 -# include -#endif -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "netinet/ip_auth.h" -#ifdef IPFILTER_SYNC -#include "netinet/ip_sync.h" -#endif -#ifdef IPFILTER_SCAN -#include "netinet/ip_scan.h" -#endif -#include "netinet/ip_pool.h" -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include -#endif -#include -#ifdef CSUM_DATA_VALID -#include -#endif -extern int ip_optcopy __P((struct ip *, struct ip *)); - -#if (__FreeBSD_version > 460000) -extern int path_mtu_discovery; -#endif - -# ifdef IPFILTER_M_IPFILTER -MALLOC_DEFINE(M_IPFILTER, "IP Filter", "IP Filter packet filter data structures"); -# endif - - -#if !defined(__osf__) -extern struct protosw inetsw[]; -#endif - -static int (*fr_savep) __P((ip_t *, int, void *, int, struct mbuf **)); -static int fr_send_ip __P((fr_info_t *, mb_t *, mb_t **)); -# ifdef USE_MUTEXES -ipfmutex_t ipl_mutex, ipf_authmx, ipf_rw, ipf_stinsert; -ipfmutex_t ipf_nat_new, ipf_natio, ipf_timeoutlock; -ipfrwlock_t ipf_mutex, ipf_global, ipf_ipidfrag; -ipfrwlock_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; -# endif -int ipf_locks_done = 0; - -#if (__FreeBSD_version >= 300000) -struct callout_handle fr_slowtimer_ch; -#endif - -#if (__FreeBSD_version >= 500011) -# include -# if defined(NETBSD_PF) -# include -# include -/* - * We provide the fr_checkp name just to minimize changes later. - */ -int (*fr_checkp) __P((ip_t *ip, int hlen, void *ifp, int out, mb_t **mp)); -# endif /* NETBSD_PF */ -#endif /* __FreeBSD_version >= 500011 */ - - -#if (__FreeBSD_version >= 501108) && defined(_KERNEL) - -static int -fr_check_wrapper(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) -{ - struct ip *ip = mtod(*mp, struct ip *); - return fr_check(ip, ip->ip_hl << 2, ifp, (dir == PFIL_OUT), mp); -} - -# ifdef USE_INET6 -# include - -static int -fr_check_wrapper6(void *arg, struct mbuf **mp, struct ifnet *ifp, int dir) -{ - return (fr_check(mtod(*mp, struct ip *), sizeof(struct ip6_hdr), - ifp, (dir == PFIL_OUT), mp)); -} -# endif -#endif /* __FreeBSD_version >= 501108 */ -#if defined(IPFILTER_LKM) -int iplidentify(s) -char *s; -{ - if (strcmp(s, "ipl") == 0) - return 1; - return 0; -} -#endif /* IPFILTER_LKM */ - - -int iplattach() -{ -#ifdef USE_SPL - int s; -#endif -#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) - int error = 0; -# if __FreeBSD_version >= 501108 - struct pfil_head *ph_inet; -# ifdef USE_INET6 - struct pfil_head *ph_inet6; -# endif -# endif -#endif - - SPL_NET(s); - if (fr_running > 0) { - SPL_X(s); - return EBUSY; - } - - MUTEX_INIT(&ipf_rw, "ipf rw mutex"); - RWLOCK_INIT(&ipf_global, "ipf filter load/unload mutex"); - MUTEX_INIT(&ipf_timeoutlock, "ipf timeout queue mutex"); - RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock"); - RWLOCK_INIT(&ipf_ipidfrag, "ipf IP NAT-Frag rwlock"); - ipf_locks_done = 1; - - if (fr_initialise() < 0) { - SPL_X(s); - return EIO; - } - - -# ifdef NETBSD_PF -# if __FreeBSD_version >= 500011 -# if __FreeBSD_version >= 501108 - ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); -# ifdef USE_INET6 - ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); -# endif - if (ph_inet == NULL -# ifdef USE_INET6 - && ph_inet6 == NULL -# endif - ) - return ENODEV; - - if (ph_inet != NULL) - error = pfil_add_hook((void *)fr_check_wrapper, NULL, - PFIL_IN|PFIL_OUT, ph_inet); - else - error = 0; -# else - error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif - if (error) { -# ifdef USE_INET6 - goto pfil_error; -# else - fr_deinitialise(); - SPL_X(s); - return error; -# endif - } -# else - pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif -# ifdef USE_INET6 -# if __FreeBSD_version >= 501108 - if (ph_inet6 != NULL) - error = pfil_add_hook((void *)fr_check_wrapper6, NULL, - PFIL_IN|PFIL_OUT, ph_inet6); - else - error = 0; - if (error) { - pfil_remove_hook((void *)fr_check_wrapper6, NULL, - PFIL_IN|PFIL_OUT, ph_inet6); -# else - error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); - if (error) { - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif -pfil_error: - fr_deinitialise(); - SPL_X(s); - return error; - } -# endif -# endif - if (fr_checkp != fr_check) { - fr_savep = fr_checkp; - fr_checkp = fr_check; - } - - bzero((char *)frcache, sizeof(frcache)); - fr_running = 1; - - if (fr_control_forwarding & 1) - ipforwarding = 1; - - SPL_X(s); -#if (__FreeBSD_version >= 300000) - fr_slowtimer_ch = timeout(fr_slowtimer, NULL, - (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); -#else - timeout(fr_slowtimer, NULL, (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT); -#endif - return 0; -} - - -/* - * Disable the filter by removing the hooks from the IP input/output - * stream. - */ -int ipldetach() -{ -#ifdef USE_SPL - int s; -#endif -#if defined(NETBSD_PF) && (__FreeBSD_version >= 500011) - int error = 0; -# if __FreeBSD_version >= 501108 - struct pfil_head *ph_inet; -# ifdef USE_INET6 - struct pfil_head *ph_inet6; -# endif -# endif -#endif - - if (fr_control_forwarding & 2) - ipforwarding = 0; - - SPL_NET(s); - -#if (__FreeBSD_version >= 300000) - if (fr_slowtimer_ch.callout != NULL) - untimeout(fr_slowtimer, NULL, fr_slowtimer_ch); - bzero(&fr_slowtimer_ch, sizeof(fr_slowtimer_ch)); -#else - untimeout(fr_slowtimer, NULL); -#endif /* FreeBSD */ - -#ifndef NETBSD_PF - if (fr_checkp != NULL) - fr_checkp = fr_savep; - fr_savep = NULL; -#endif - -#ifdef NETBSD_PF -# if (__FreeBSD_version >= 500011) -# if (__FreeBSD_version >= 501108) - ph_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); - if (ph_inet != NULL) - error = pfil_remove_hook((void *)fr_check_wrapper, NULL, - PFIL_IN|PFIL_OUT, ph_inet); - else - error = 0; -# else - error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); -# endif - if (error) { - SPL_X(s); - return error; - } -# else - pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT); -# endif -# ifdef USE_INET6 -# if (__FreeBSD_version >= 501108) - ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6); - if (ph_inet6 != NULL) - error = pfil_remove_hook((void *)fr_check_wrapper6, NULL, - PFIL_IN|PFIL_OUT, ph_inet6); - else - error = 0; -# else - error = pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT, - &inet6sw[ip6_protox[IPPROTO_IPV6]].pr_pfh); -# endif - if (error) { - SPL_X(s); - return error; - } -# endif -#endif - fr_deinitialise(); - - fr_running = -2; - - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - (void) frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE); - - if (ipf_locks_done == 1) { - MUTEX_DESTROY(&ipf_timeoutlock); - MUTEX_DESTROY(&ipf_rw); - RW_DESTROY(&ipf_mutex); - RW_DESTROY(&ipf_ipidfrag); - RW_DESTROY(&ipf_global); - ipf_locks_done = 0; - } - - SPL_X(s); - - return 0; -} - - -/* - * Filter ioctl interface. - */ -int iplioctl(dev, cmd, data, mode -# if defined(_KERNEL) && ((BSD >= 199506) || (__FreeBSD_version >= 220000)) -, p) -# if (__FreeBSD_version >= 500024) -struct thread *p; -# else -struct proc *p; -# endif /* __FreeBSD_version >= 500024 */ -# else -) -# endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -ioctlcmd_t cmd; -caddr_t data; -int mode; -{ -#ifdef USE_SPL - int s; -#endif - int error = 0, unit = 0, tmp; - friostat_t fio; - -#if (BSD >= 199306) && defined(_KERNEL) - if ((securelevel >= 2) && (mode & FWRITE)) - return EPERM; -#endif - - unit = GET_MINOR(dev); - if ((IPL_LOGMAX < unit) || (unit < 0)) - return ENXIO; - - if (fr_running <= 0) { - if (unit != IPL_LOGIPF) - return EIO; - if (cmd != SIOCIPFGETNEXT && cmd != SIOCIPFGET && - cmd != SIOCIPFSET && cmd != SIOCFRENB && - cmd != SIOCGETFS && cmd != SIOCGETFF) - return EIO; - } - - SPL_NET(s); - - error = fr_ioctlswitch(unit, data, cmd, mode); - if (error != -1) { - SPL_X(s); - return error; - } - error = 0; - - switch (cmd) - { - case FIONREAD : -#ifdef IPFILTER_LOG - BCOPYOUT(&iplused[IPL_LOGIPF], (caddr_t)data, - sizeof(iplused[IPL_LOGIPF])); -#endif - break; - case SIOCFRENB : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - if (tmp) { - if (fr_running > 0) - error = 0; - else - error = iplattach(); - if (error == 0) - fr_running = 1; - else - (void) ipldetach(); - } else { - error = ipldetach(); - if (error == 0) - fr_running = -1; - } - } - break; - case SIOCIPFSET : - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - case SIOCIPFGETNEXT : - case SIOCIPFGET : - error = fr_ipftune(cmd, data); - break; - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else - BCOPYIN(data, &fr_flags, sizeof(fr_flags)); - break; - case SIOCGETFF : - BCOPYOUT(&fr_flags, data, sizeof(fr_flags)); - break; - case SIOCFUNCL : - error = fr_resolvefunc(data); - break; - case SIOCINAFR : - case SIOCRMAFR : - case SIOCADAFR : - case SIOCZRLST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, fr_active, 1); - break; - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, 1 - fr_active, 1); - break; - case SIOCSWAPA : - if (!(mode & FWRITE)) - error = EPERM; - else { - bzero((char *)frcache, sizeof(frcache[0]) * 2); - *(u_int *)data = fr_active; - fr_active = 1 - fr_active; - } - break; - case SIOCGETFS : - fr_getstat(&fio); - error = fr_outobj(data, &fio, IPFOBJ_IPFSTAT); - break; - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = fr_zerostats(data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - tmp = frflush(unit, 4, tmp); - BCOPYOUT(&tmp, data, sizeof(tmp)); - } - break; -#ifdef USE_INET6 - case SIOCIPFL6 : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN(data, &tmp, sizeof(tmp)); - tmp = frflush(unit, 6, tmp); - BCOPYOUT(&tmp, data, sizeof(tmp)); - } - break; -#endif - case SIOCSTLCK : - BCOPYIN(data, &tmp, sizeof(tmp)); - fr_state_lock = tmp; - fr_nat_lock = tmp; - fr_frag_lock = tmp; - fr_auth_lock = tmp; - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else - *(int *)data = ipflog_clear(unit); - break; -#endif /* IPFILTER_LOG */ - case SIOCGFRST : - error = fr_outobj(data, fr_fragstats(), IPFOBJ_FRAGSTAT); - break; - case SIOCFRSYN : - if (!(mode & FWRITE)) - error = EPERM; - else { - frsync(NULL); - } - break; - default : - error = EINVAL; - break; - } - SPL_X(s); - return error; -} - - -#if 0 -void fr_forgetifp(ifp) -void *ifp; -{ - register frentry_t *f; - - WRITE_ENTER(&ipf_mutex); - for (f = ipacct[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipacct[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; -#ifdef USE_INET6 - for (f = ipacct6[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipacct6[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter6[0][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; - for (f = ipfilter6[1][fr_active]; (f != NULL); f = f->fr_next) - if (f->fr_ifa == ifp) - f->fr_ifa = (void *)-1; -#endif - RWLOCK_EXIT(&ipf_mutex); - fr_natsync(ifp); -} -#endif - - -/* - * routines below for saving IP headers to buffer - */ -int iplopen(dev, flags -#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) && defined(_KERNEL) -, devtype, p) -int devtype; -# if (__FreeBSD_version >= 500024) -struct thread *p; -# else -struct proc *p; -# endif /* __FreeBSD_version >= 500024 */ -#else -) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -int flags; -{ - u_int min = GET_MINOR(dev); - - if (IPL_LOGMAX < min) - min = ENXIO; - else - min = 0; - return min; -} - - -int iplclose(dev, flags -#if ((BSD >= 199506) || (__FreeBSD_version >= 220000)) && defined(_KERNEL) -, devtype, p) -int devtype; -# if (__FreeBSD_version >= 500024) -struct thread *p; -# else -struct proc *p; -# endif /* __FreeBSD_version >= 500024 */ -#else -) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -int flags; -{ - u_int min = GET_MINOR(dev); - - if (IPL_LOGMAX < min) - min = ENXIO; - else - min = 0; - return min; -} - -/* - * iplread/ipllog - * both of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -#if (BSD >= 199306) -int iplread(dev, uio, ioflag) -int ioflag; -#else -int iplread(dev, uio) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -register struct uio *uio; -{ - -# ifdef IPFILTER_SYNC - if (GET_MINOR(dev) == IPL_LOGSYNC) - return ipfsync_read(uio); -# endif - -#ifdef IPFILTER_LOG - return ipflog_read(GET_MINOR(dev), uio); -#else - return ENXIO; -#endif -} - - -/* - * iplwrite - * both of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -#if (BSD >= 199306) -int iplwrite(dev, uio, ioflag) -int ioflag; -#else -int iplwrite(dev, uio) -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 502116) -struct cdev *dev; -#else -dev_t dev; -#endif -register struct uio *uio; -{ - -#ifdef IPFILTER_SYNC - if (GET_MINOR(dev) == IPL_LOGSYNC) - return ipfsync_write(uio); -#endif - return ENXIO; -} - - -/* - * fr_send_reset - this could conceivably be a call to tcp_respond(), but that - * requires a large amount of setting up and isn't any more efficient. - */ -int fr_send_reset(fin) -fr_info_t *fin; -{ - struct tcphdr *tcp, *tcp2; - int tlen = 0, hlen; - struct mbuf *m; -#ifdef USE_INET6 - ip6_t *ip6; -#endif - ip_t *ip; - - tcp = fin->fin_dp; - if (tcp->th_flags & TH_RST) - return -1; /* feedback loop */ - -#ifndef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - return -1; -#endif - - tlen = fin->fin_dlen - (TCP_OFF(tcp) << 2) + - ((tcp->th_flags & TH_SYN) ? 1 : 0) + - ((tcp->th_flags & TH_FIN) ? 1 : 0); - -#ifdef USE_INET6 - hlen = (fin->fin_v == 6) ? sizeof(ip6_t) : sizeof(ip_t); -#else - hlen = sizeof(ip_t); -#endif -#ifdef MGETHDR - MGETHDR(m, M_DONTWAIT, MT_HEADER); -#else - MGET(m, M_DONTWAIT, MT_HEADER); -#endif - if (m == NULL) - return -1; - if (sizeof(*tcp2) + hlen > MLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - FREE_MB_T(m); - return -1; - } - } - - m->m_len = sizeof(*tcp2) + hlen; -#if (BSD >= 199103) - m->m_data += max_linkhdr; - m->m_pkthdr.len = m->m_len; - m->m_pkthdr.rcvif = (struct ifnet *)0; -#endif - ip = mtod(m, struct ip *); - bzero((char *)ip, hlen); -#ifdef USE_INET6 - ip6 = (ip6_t *)ip; -#endif - tcp2 = (struct tcphdr *)((char *)ip + hlen); - tcp2->th_sport = tcp->th_dport; - tcp2->th_dport = tcp->th_sport; - - if (tcp->th_flags & TH_ACK) { - tcp2->th_seq = tcp->th_ack; - tcp2->th_flags = TH_RST; - tcp2->th_ack = 0; - } else { - tcp2->th_seq = 0; - tcp2->th_ack = ntohl(tcp->th_seq); - tcp2->th_ack += tlen; - tcp2->th_ack = htonl(tcp2->th_ack); - tcp2->th_flags = TH_RST|TH_ACK; - } - TCP_X2_A(tcp2, 0); - TCP_OFF_A(tcp2, sizeof(*tcp2) >> 2); - tcp2->th_win = tcp->th_win; - tcp2->th_sum = 0; - tcp2->th_urp = 0; - -#ifdef USE_INET6 - if (fin->fin_v == 6) { - ip6->ip6_flow = ((ip6_t *)fin->fin_ip)->ip6_flow; - ip6->ip6_plen = htons(sizeof(struct tcphdr)); - ip6->ip6_nxt = IPPROTO_TCP; - ip6->ip6_hlim = 0; - ip6->ip6_src = fin->fin_dst6; - ip6->ip6_dst = fin->fin_src6; - tcp2->th_sum = in6_cksum(m, IPPROTO_TCP, - sizeof(*ip6), sizeof(*tcp2)); - return fr_send_ip(fin, m, &m); - } -#endif - ip->ip_p = IPPROTO_TCP; - ip->ip_len = htons(sizeof(struct tcphdr)); - ip->ip_src.s_addr = fin->fin_daddr; - ip->ip_dst.s_addr = fin->fin_saddr; - tcp2->th_sum = in_cksum(m, hlen + sizeof(*tcp2)); - ip->ip_len = hlen + sizeof(*tcp2); - return fr_send_ip(fin, m, &m); -} - - -static int fr_send_ip(fin, m, mpp) -fr_info_t *fin; -mb_t *m, **mpp; -{ - fr_info_t fnew; - ip_t *ip, *oip; - int hlen; - - ip = mtod(m, ip_t *); - bzero((char *)&fnew, sizeof(fnew)); - - IP_V_A(ip, fin->fin_v); - switch (fin->fin_v) - { - case 4 : - fnew.fin_v = 4; - oip = fin->fin_ip; - IP_HL_A(ip, sizeof(*oip) >> 2); - ip->ip_tos = oip->ip_tos; - ip->ip_id = fin->fin_ip->ip_id; -#if (__FreeBSD_version > 460000) - ip->ip_off = path_mtu_discovery ? IP_DF : 0; -#else - ip->ip_off = 0; -#endif - ip->ip_ttl = ip_defttl; - ip->ip_sum = 0; - hlen = sizeof(*oip); - break; -#ifdef USE_INET6 - case 6 : - { - ip6_t *ip6 = (ip6_t *)ip; - - ip6->ip6_vfc = 0x60; - ip6->ip6_hlim = IPDEFTTL; - - fnew.fin_v = 6; - hlen = sizeof(*ip6); - break; - } -#endif - default : - return EINVAL; - } -#ifdef IPSEC - m->m_pkthdr.rcvif = NULL; -#endif - - fnew.fin_ifp = fin->fin_ifp; - fnew.fin_flx = FI_NOCKSUM; - fnew.fin_m = m; - fnew.fin_ip = ip; - fnew.fin_mp = mpp; - fnew.fin_hlen = hlen; - fnew.fin_dp = (char *)ip + hlen; - (void) fr_makefrip(hlen, ip, &fnew); - - return fr_fastroute(m, mpp, &fnew, NULL); -} - - -int fr_send_icmp_err(type, fin, dst) -int type; -fr_info_t *fin; -int dst; -{ - int err, hlen, xtra, iclen, ohlen, avail, code; - struct in_addr dst4; - struct icmp *icmp; - struct mbuf *m; - void *ifp; -#ifdef USE_INET6 - ip6_t *ip6; - struct in6_addr dst6; -#endif - ip_t *ip, *ip2; - - if ((type < 0) || (type > ICMP_MAXTYPE)) - return -1; - - code = fin->fin_icode; -#ifdef USE_INET6 - if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int))) - return -1; -#endif - -#ifndef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - return -1; -#endif -#ifdef MGETHDR - MGETHDR(m, M_DONTWAIT, MT_HEADER); -#else - MGET(m, M_DONTWAIT, MT_HEADER); -#endif - if (m == NULL) - return -1; - avail = MHLEN; - - xtra = 0; - hlen = 0; - ohlen = 0; - ifp = fin->fin_ifp; - if (fin->fin_v == 4) { - if ((fin->fin_p == IPPROTO_ICMP) && - !(fin->fin_flx & FI_SHORT)) - switch (ntohs(fin->fin_data[0]) >> 8) - { - case ICMP_ECHO : - case ICMP_TSTAMP : - case ICMP_IREQ : - case ICMP_MASKREQ : - break; - default : - FREE_MB_T(m); - return 0; - } - - if (dst == 0) { - if (fr_ifpaddr(4, FRI_NORMAL, ifp, - &dst4, NULL) == -1) { - FREE_MB_T(m); - return -1; - } - } else - dst4.s_addr = fin->fin_daddr; - - hlen = sizeof(ip_t); - ohlen = fin->fin_hlen; - if (fin->fin_hlen < fin->fin_plen) - xtra = MIN(fin->fin_dlen, 8); - else - xtra = 0; - } - -#ifdef USE_INET6 - else if (fin->fin_v == 6) { - hlen = sizeof(ip6_t); - ohlen = sizeof(ip6_t); - type = icmptoicmp6types[type]; - if (type == ICMP6_DST_UNREACH) - code = icmptoicmp6unreach[code]; - - if (hlen + sizeof(*icmp) + max_linkhdr + - fin->fin_plen > avail) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - FREE_MB_T(m); - return -1; - } - avail = MCLBYTES; - } - xtra = MIN(fin->fin_plen, - avail - hlen - sizeof(*icmp) - max_linkhdr); - if (dst == 0) { - if (fr_ifpaddr(6, FRI_NORMAL, ifp, - (struct in_addr *)&dst6, NULL) == -1) { - FREE_MB_T(m); - return -1; - } - } else - dst6 = fin->fin_dst6; - } -#endif - else { - FREE_MB_T(m); - return -1; - } - - iclen = hlen + sizeof(*icmp); - avail -= (max_linkhdr + iclen); - if (avail < 0) { - FREE_MB_T(m); - return -1; - } - if (xtra > avail) - xtra = avail; - iclen += xtra; - m->m_data += max_linkhdr; - m->m_pkthdr.rcvif = (struct ifnet *)0; - m->m_pkthdr.len = iclen; - m->m_len = iclen; - ip = mtod(m, ip_t *); - icmp = (struct icmp *)((char *)ip + hlen); - ip2 = (ip_t *)&icmp->icmp_ip; - - icmp->icmp_type = type; - icmp->icmp_code = fin->fin_icode; - icmp->icmp_cksum = 0; -#ifdef icmp_nextmtu - if (type == ICMP_UNREACH && - fin->fin_icode == ICMP_UNREACH_NEEDFRAG && ifp) - icmp->icmp_nextmtu = htons(((struct ifnet *)ifp)->if_mtu); -#endif - - bcopy((char *)fin->fin_ip, (char *)ip2, ohlen); - -#ifdef USE_INET6 - ip6 = (ip6_t *)ip; - if (fin->fin_v == 6) { - ip6->ip6_flow = ((ip6_t *)fin->fin_ip)->ip6_flow; - ip6->ip6_plen = htons(iclen - hlen); - ip6->ip6_nxt = IPPROTO_ICMPV6; - ip6->ip6_hlim = 0; - ip6->ip6_src = dst6; - ip6->ip6_dst = fin->fin_src6; - if (xtra > 0) - bcopy((char *)fin->fin_ip + ohlen, - (char *)&icmp->icmp_ip + ohlen, xtra); - icmp->icmp_cksum = in6_cksum(m, IPPROTO_ICMPV6, - sizeof(*ip6), iclen - hlen); - } else -#endif - { - ip2->ip_len = htons(ip2->ip_len); - ip2->ip_off = htons(ip2->ip_off); - ip->ip_p = IPPROTO_ICMP; - ip->ip_src.s_addr = dst4.s_addr; - ip->ip_dst.s_addr = fin->fin_saddr; - - if (xtra > 0) - bcopy((char *)fin->fin_ip + ohlen, - (char *)&icmp->icmp_ip + ohlen, xtra); - icmp->icmp_cksum = ipf_cksum((u_short *)icmp, - sizeof(*icmp) + 8); - ip->ip_len = iclen; - ip->ip_p = IPPROTO_ICMP; - } - err = fr_send_ip(fin, m, &m); - return err; -} - - -#if !defined(IPFILTER_LKM) && (__FreeBSD_version < 300000) -# if (BSD < 199306) -int iplinit __P((void)); - -int -# else -void iplinit __P((void)); - -void -# endif -iplinit() -{ - if (iplattach() != 0) - printf("IP Filter failed to attach\n"); - ip_init(); -} -#endif /* __FreeBSD_version < 300000 */ - - -int fr_fastroute(m0, mpp, fin, fdp) -mb_t *m0, **mpp; -fr_info_t *fin; -frdest_t *fdp; -{ - register struct ip *ip, *mhip; - register struct mbuf *m = m0; - register struct route *ro; - int len, off, error = 0, hlen, code; - struct ifnet *ifp, *sifp; - struct sockaddr_in *dst; - struct route iproute; - u_short ip_off; - frentry_t *fr; - -#ifdef M_WRITABLE - /* - * HOT FIX/KLUDGE: - * - * If the mbuf we're about to send is not writable (because of - * a cluster reference, for example) we'll need to make a copy - * of it since this routine modifies the contents. - * - * If you have non-crappy network hardware that can transmit data - * from the mbuf, rather than making a copy, this is gonna be a - * problem. - */ - if (M_WRITABLE(m) == 0) { - if ((m0 = m_dup(m, M_DONTWAIT)) != 0) { - FREE_MB_T(m); - m = m0; - *mpp = m; - } else { - error = ENOBUFS; - FREE_MB_T(m); - *mpp = NULL; - fr_frouteok[1]++; - } - } -#endif - -#ifdef USE_INET6 - if (fin->fin_v == 6) { - /* - * currently "to " and "to :ip#" are not supported - * for IPv6 - */ -#if (__FreeBSD_version >= 490000) - return ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); -#else - return ip6_output(m0, NULL, NULL, 0, NULL, NULL); -#endif - } -#endif - - hlen = fin->fin_hlen; - ip = mtod(m0, struct ip *); - - /* - * Route packet. - */ - ro = &iproute; - bzero((caddr_t)ro, sizeof (*ro)); - dst = (struct sockaddr_in *)&ro->ro_dst; - dst->sin_family = AF_INET; - dst->sin_addr = ip->ip_dst; - - fr = fin->fin_fr; - if (fdp != NULL) - ifp = fdp->fd_ifp; - else - ifp = fin->fin_ifp; - - if ((ifp == NULL) && (!fr || !(fr->fr_flags & FR_FASTROUTE))) { - error = -2; - goto bad; - } - - /* - * In case we're here due to "to " being used with "keep state", - * check that we're going in the correct direction. - */ - if ((fr != NULL) && (fin->fin_rev != 0)) { - if ((ifp != NULL) && (fdp == &fr->fr_tif)) - return -1; - } - if (fdp != NULL) { - if (fdp->fd_ip.s_addr != 0) - dst->sin_addr = fdp->fd_ip; - } - - dst->sin_len = sizeof(*dst); - rtalloc(ro); - - if ((ifp == NULL) && (ro->ro_rt != NULL)) - ifp = ro->ro_rt->rt_ifp; - - if ((ro->ro_rt == NULL) || (ifp == NULL)) { - if (in_localaddr(ip->ip_dst)) - error = EHOSTUNREACH; - else - error = ENETUNREACH; - goto bad; - } - if (ro->ro_rt->rt_flags & RTF_GATEWAY) - dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; - if (ro->ro_rt) - ro->ro_rt->rt_use++; - - /* - * For input packets which are being "fastrouted", they won't - * go back through output filtering and miss their chance to get - * NAT'd and counted. - */ - if (fin->fin_out == 0) { - sifp = fin->fin_ifp; - fin->fin_ifp = ifp; - fin->fin_out = 1; - (void) fr_acctpkt(fin, NULL); - fin->fin_fr = NULL; - if (!fr || !(fr->fr_flags & FR_RETMASK)) { - u_32_t pass; - - (void) fr_checkstate(fin, &pass); - } - - switch (fr_checknatout(fin, NULL)) - { - case 0 : - break; - case 1 : - ip->ip_sum = 0; - break; - case -1 : - error = -1; - goto done; - break; - } - - fin->fin_ifp = sifp; - fin->fin_out = 0; - } else - ip->ip_sum = 0; - /* - * If small enough for interface, can just send directly. - */ - if (ip->ip_len <= ifp->if_mtu) { - ip->ip_len = htons(ip->ip_len); - ip->ip_off = htons(ip->ip_off); - - if (!ip->ip_sum) - ip->ip_sum = in_cksum(m, hlen); - error = (*ifp->if_output)(ifp, m, (struct sockaddr *)dst, - ro->ro_rt); - goto done; - } - /* - * Too large for interface; fragment if possible. - * Must be able to put at least 8 bytes per fragment. - */ - ip_off = ntohs(ip->ip_off); - if (ip_off & IP_DF) { - error = EMSGSIZE; - goto bad; - } - len = (ifp->if_mtu - hlen) &~ 7; - if (len < 8) { - error = EMSGSIZE; - goto bad; - } - - { - int mhlen, firstlen = len; - struct mbuf **mnext = &m->m_act; - - /* - * Loop through length of segment after first fragment, - * make new header and copy data of each part and link onto chain. - */ - m0 = m; - mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { -#ifdef MGETHDR - MGETHDR(m, M_DONTWAIT, MT_HEADER); -#else - MGET(m, M_DONTWAIT, MT_HEADER); -#endif - if (m == 0) { - m = m0; - error = ENOBUFS; - goto bad; - } - m->m_data += max_linkhdr; - mhip = mtod(m, struct ip *); - bcopy((char *)ip, (char *)mhip, sizeof(*ip)); - if (hlen > sizeof (struct ip)) { - mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); - IP_HL_A(mhip, mhlen >> 2); - } - m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + ip_off; - if (off + len >= ip->ip_len) - len = ip->ip_len - off; - else - mhip->ip_off |= IP_MF; - mhip->ip_len = htons((u_short)(len + mhlen)); - m->m_next = m_copy(m0, off, len); - if (m->m_next == 0) { - error = ENOBUFS; /* ??? */ - goto sendorfree; - } - m->m_pkthdr.len = mhlen + len; - m->m_pkthdr.rcvif = NULL; - mhip->ip_off = htons((u_short)mhip->ip_off); - mhip->ip_sum = 0; - mhip->ip_sum = in_cksum(m, mhlen); - *mnext = m; - mnext = &m->m_act; - } - /* - * Update first fragment by trimming what's been copied out - * and updating header, then send each fragment (in order). - */ - m_adj(m0, hlen + firstlen - ip->ip_len); - ip->ip_len = htons((u_short)(hlen + firstlen)); - ip->ip_off = htons((u_short)IP_MF); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m0, hlen); -sendorfree: - for (m = m0; m; m = m0) { - m0 = m->m_act; - m->m_act = 0; - if (error == 0) - error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst, ro->ro_rt); - else - FREE_MB_T(m); - } - } -done: - if (!error) - fr_frouteok[0]++; - else - fr_frouteok[1]++; - - if (ro->ro_rt) { - RTFREE(ro->ro_rt); - } - *mpp = NULL; - return 0; -bad: - if (error == EMSGSIZE) { - sifp = fin->fin_ifp; - code = fin->fin_icode; - fin->fin_icode = ICMP_UNREACH_NEEDFRAG; - fin->fin_ifp = ifp; - (void) fr_send_icmp_err(ICMP_UNREACH, fin, 1); - fin->fin_ifp = sifp; - fin->fin_icode = code; - } - FREE_MB_T(m); - goto done; -} - - -int fr_verifysrc(fin) -fr_info_t *fin; -{ - struct sockaddr_in *dst; - struct route iproute; - - bzero((char *)&iproute, sizeof(iproute)); - dst = (struct sockaddr_in *)&iproute.ro_dst; - dst->sin_len = sizeof(*dst); - dst->sin_family = AF_INET; - dst->sin_addr = fin->fin_src; - rtalloc(&iproute); - if (iproute.ro_rt == NULL) - return 0; - return (fin->fin_ifp == iproute.ro_rt->rt_ifp); -} - - -/* - * return the first IP Address associated with an interface - */ -int fr_ifpaddr(v, atype, ifptr, inp, inpmask) -int v, atype; -void *ifptr; -struct in_addr *inp, *inpmask; -{ -#ifdef USE_INET6 - struct in6_addr *inp6 = NULL; -#endif - struct sockaddr *sock, *mask; - struct sockaddr_in *sin; - struct ifaddr *ifa; - struct ifnet *ifp; - - if ((ifptr == NULL) || (ifptr == (void *)-1)) - return -1; - - sin = NULL; - ifp = ifptr; - - if (v == 4) - inp->s_addr = 0; -#ifdef USE_INET6 - else if (v == 6) - bzero((char *)inp, sizeof(struct in6_addr)); -#endif -#if (__FreeBSD_version >= 300000) - ifa = TAILQ_FIRST(&ifp->if_addrhead); -#else - ifa = ifp->if_addrlist; -#endif /* __FreeBSD_version >= 300000 */ - - sock = ifa->ifa_addr; - while (sock != NULL && ifa != NULL) { - sin = (struct sockaddr_in *)sock; - if ((v == 4) && (sin->sin_family == AF_INET)) - break; -#ifdef USE_INET6 - if ((v == 6) && (sin->sin_family == AF_INET6)) { - inp6 = &((struct sockaddr_in6 *)sin)->sin6_addr; - if (!IN6_IS_ADDR_LINKLOCAL(inp6) && - !IN6_IS_ADDR_LOOPBACK(inp6)) - break; - } -#endif -#if (__FreeBSD_version >= 300000) - ifa = TAILQ_NEXT(ifa, ifa_link); -#else - ifa = ifa->ifa_next; -#endif /* __FreeBSD_version >= 300000 */ - if (ifa != NULL) - sock = ifa->ifa_addr; - } - - if (ifa == NULL || sin == NULL) - return -1; - - mask = ifa->ifa_netmask; - if (atype == FRI_BROADCAST) - sock = ifa->ifa_broadaddr; - else if (atype == FRI_PEERADDR) - sock = ifa->ifa_dstaddr; - -#ifdef USE_INET6 - if (v == 6) { - return fr_ifpfillv6addr(atype, (struct sockaddr_in6 *)sock, - (struct sockaddr_in6 *)mask, - inp, inpmask); - } -#endif - return fr_ifpfillv4addr(atype, (struct sockaddr_in *)sock, - (struct sockaddr_in *)mask, inp, inpmask); -} - - -u_32_t fr_newisn(fin) -fr_info_t *fin; -{ - u_32_t newiss; -#if (__FreeBSD_version >= 400000) - newiss = arc4random(); -#else - static iss_seq_off = 0; - u_char hash[16]; - MD5_CTX ctx; - - /* - * Compute the base value of the ISS. It is a hash - * of (saddr, sport, daddr, dport, secret). - */ - MD5Init(&ctx); - - MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_src, - sizeof(fin->fin_fi.fi_src)); - MD5Update(&ctx, (u_char *) &fin->fin_fi.fi_dst, - sizeof(fin->fin_fi.fi_dst)); - MD5Update(&ctx, (u_char *) &fin->fin_dat, sizeof(fin->fin_dat)); - - MD5Update(&ctx, ipf_iss_secret, sizeof(ipf_iss_secret)); - - MD5Final(hash, &ctx); - - memcpy(&newiss, hash, sizeof(newiss)); - - /* - * Now increment our "timer", and add it in to - * the computed value. - * - * XXX Use `addin'? - * XXX TCP_ISSINCR too large to use? - */ - iss_seq_off += 0x00010000; - newiss += iss_seq_off; -#endif - return newiss; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_nextipid */ -/* Returns: int - 0 == success, -1 == error (packet should be droppped) */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Returns the next IPv4 ID to use for this packet. */ -/* ------------------------------------------------------------------------ */ -u_short fr_nextipid(fin) -fr_info_t *fin; -{ -#ifndef RANDOM_IP_ID - static u_short ipid = 0; - u_short id; - - MUTEX_ENTER(&ipf_rw); - id = ipid++; - MUTEX_EXIT(&ipf_rw); -#else - u_short id; - - id = ip_randomid(); -#endif - - return id; -} - - -INLINE void fr_checkv4sum(fin) -fr_info_t *fin; -{ -#ifdef CSUM_DATA_VALID - int manual = 0; - u_short sum; - ip_t *ip; - mb_t *m; - - if ((fin->fin_flx & FI_NOCKSUM) != 0) - return; - - m = fin->fin_m; - if (m == NULL) { - manual = 1; - goto skipauto; - } - ip = fin->fin_ip; - - 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 - sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, - htonl(m->m_pkthdr.csum_data + - fin->fin_ip->ip_len + fin->fin_p)); - sum ^= 0xffff; - if (sum != 0) - fin->fin_flx |= FI_BAD; - } else - manual = 1; -skipauto: -# ifdef IPFILTER_CKSUM - if (manual != 0) - if (fr_checkl4sum(fin) == -1) - fin->fin_flx |= FI_BAD; -# else - ; -# endif -#else -# ifdef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - fin->fin_flx |= FI_BAD; -# endif -#endif -} - - -#ifdef USE_INET6 -INLINE void fr_checkv6sum(fin) -fr_info_t *fin; -{ -# ifdef IPFILTER_CKSUM - if (fr_checkl4sum(fin) == -1) - fin->fin_flx |= FI_BAD; -# endif -} -#endif /* USE_INET6 */ - - -size_t mbufchainlen(m0) -struct mbuf *m0; -{ - size_t len; - - if ((m0->m_flags & M_PKTHDR) != 0) { - len = m0->m_pkthdr.len; - } else { - struct mbuf *m; - - for (m = m0, len = 0; m != NULL; m = m->m_next) - len += m->m_len; - } - return len; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_pullup */ -/* Returns: NULL == pullup failed, else pointer to protocol header */ -/* Parameters: m(I) - pointer to buffer where data packet starts */ -/* fin(I) - pointer to packet information */ -/* len(I) - number of bytes to pullup */ -/* */ -/* Attempt to move at least len bytes (from the start of the buffer) into a */ -/* single buffer for ease of access. Operating system native functions are */ -/* used to manage buffers - if necessary. If the entire packet ends up in */ -/* a single buffer, set the FI_COALESCE flag even though fr_coalesce() has */ -/* not been called. Both fin_ip and fin_dp are updated before exiting _IF_ */ -/* and ONLY if the pullup succeeds. */ -/* */ -/* We assume that 'min' is a pointer to a buffer that is part of the chain */ -/* of buffers that starts at *fin->fin_mp. */ -/* ------------------------------------------------------------------------ */ -void *fr_pullup(min, fin, len) -mb_t *min; -fr_info_t *fin; -int len; -{ - int out = fin->fin_out, dpoff, ipoff; - mb_t *m = min; - char *ip; - - if (m == NULL) - return NULL; - - ip = (char *)fin->fin_ip; - if ((fin->fin_flx & FI_COALESCE) != 0) - return ip; - - ipoff = fin->fin_ipoff; - if (fin->fin_dp != NULL) - dpoff = (char *)fin->fin_dp - (char *)ip; - else - dpoff = 0; - - if (M_LEN(m) < len) { -#ifdef MHLEN - /* - * Assume that M_PKTHDR is set and just work with what is left - * rather than check.. - * Should not make any real difference, anyway. - */ - if (len > MHLEN) -#else - if (len > MLEN) -#endif - { -#ifdef HAVE_M_PULLDOWN - if (m_pulldown(m, 0, len, NULL) == NULL) - m = NULL; -#else - FREE_MB_T(*fin->fin_mp); - m = NULL; -#endif - } else - { - m = m_pullup(m, len); - } - *fin->fin_mp = m; - fin->fin_m = m; - if (m == NULL) { - ATOMIC_INCL(frstats[out].fr_pull[1]); - return NULL; - } - ip = MTOD(m, char *) + ipoff; - } - - ATOMIC_INCL(frstats[out].fr_pull[0]); - fin->fin_ip = (ip_t *)ip; - if (fin->fin_dp != NULL) - fin->fin_dp = (char *)fin->fin_ip + dpoff; - - if (len == fin->fin_plen) - fin->fin_flx |= FI_COALESCE; - return ip; -} diff --git a/contrib/ipfilter/ip_frag.c b/contrib/ipfilter/ip_frag.c deleted file mode 100644 index 087ca19e72c3..000000000000 --- a/contrib/ipfilter/ip_frag.c +++ /dev/null @@ -1,858 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#include -#ifdef __hpux -# include -#endif -#if !defined(_KERNEL) -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include -# include -#else -# include -#endif -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) -# include -# if !defined(__SVR4) && !defined(__svr4__) -# include -# endif -#endif -#if !defined(__SVR4) && !defined(__svr4__) -# if defined(_KERNEL) && !defined(__sgi) -# include -# endif -#else -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif -#include -#ifdef sun -# include -#endif -#include -#include -#include -#include -#if !defined(linux) -# include -#endif -#include -#include -#include -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_auth.h" -#include "netinet/ip_proxy.h" -#if (__FreeBSD_version >= 300000) -# include -# if defined(_KERNEL) -# ifndef IPFILTER_LKM -# include -# include -# endif -extern struct callout_handle fr_slowtimer_ch; -# endif -#endif -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104230000) -# include -extern struct callout fr_slowtimer_ch; -#endif -#if defined(__OpenBSD__) -# include -extern struct timeout fr_slowtimer_ch; -#endif -/* END OF INCLUDES */ - -#if !defined(lint) -static const char sccsid[] = "@(#)ip_frag.c 1.11 3/24/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_frag.c,v 2.77 2004/01/27 00:24:54 darrenr Exp"; -#endif - - -static ipfr_t *ipfr_list = NULL; -static ipfr_t **ipfr_tail = &ipfr_list; -static ipfr_t **ipfr_heads; - -static ipfr_t *ipfr_natlist = NULL; -static ipfr_t **ipfr_nattail = &ipfr_natlist; -static ipfr_t **ipfr_nattab; - -static ipfr_t *ipfr_ipidlist = NULL; -static ipfr_t **ipfr_ipidtail = &ipfr_ipidlist; -static ipfr_t **ipfr_ipidtab; - -static ipfrstat_t ipfr_stats; -static int ipfr_inuse = 0; -int ipfr_size = IPFT_SIZE; - -int fr_ipfrttl = 120; /* 60 seconds */ -int fr_frag_lock = 0; -int fr_frag_init = 0; -u_long fr_ticks = 0; - - -static ipfr_t *ipfr_newfrag __P((fr_info_t *, u_32_t, ipfr_t **)); -static ipfr_t *fr_fraglookup __P((fr_info_t *, ipfr_t **)); -static void fr_fragdelete __P((ipfr_t *, ipfr_t ***)); - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fraginit */ -/* Returns: int - 0 == success, -1 == error */ -/* Parameters: Nil */ -/* */ -/* Initialise the hash tables for the fragment cache lookups. */ -/* ------------------------------------------------------------------------ */ -int fr_fraginit() -{ - KMALLOCS(ipfr_heads, ipfr_t **, ipfr_size * sizeof(ipfr_t *)); - if (ipfr_heads == NULL) - return -1; - bzero((char *)ipfr_heads, ipfr_size * sizeof(ipfr_t *)); - - KMALLOCS(ipfr_nattab, ipfr_t **, ipfr_size * sizeof(ipfr_t *)); - if (ipfr_nattab == NULL) - return -1; - bzero((char *)ipfr_nattab, ipfr_size * sizeof(ipfr_t *)); - - KMALLOCS(ipfr_ipidtab, ipfr_t **, ipfr_size * sizeof(ipfr_t *)); - if (ipfr_ipidtab == NULL) - return -1; - bzero((char *)ipfr_ipidtab, ipfr_size * sizeof(ipfr_t *)); - - RWLOCK_INIT(&ipf_frag, "ipf fragment rwlock"); - fr_frag_init = 1; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fragunload */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Free all memory allocated whilst running and from initialisation. */ -/* ------------------------------------------------------------------------ */ -void fr_fragunload() -{ - if (fr_frag_init == 1) { - fr_fragclear(); - - RW_DESTROY(&ipf_frag); - fr_frag_init = 0; - } - - if (ipfr_heads != NULL) - KFREES(ipfr_heads, ipfr_size * sizeof(ipfr_t *)); - ipfr_heads = NULL; - - if (ipfr_nattab != NULL) - KFREES(ipfr_nattab, ipfr_size * sizeof(ipfr_t *)); - ipfr_nattab = NULL; - - if (ipfr_ipidtab != NULL) - KFREES(ipfr_ipidtab, ipfr_size * sizeof(ipfr_t *)); - ipfr_ipidtab = NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fragstats */ -/* Returns: ipfrstat_t* - pointer to struct with current frag stats */ -/* Parameters: Nil */ -/* */ -/* Updates ipfr_stats with current information and returns a pointer to it */ -/* ------------------------------------------------------------------------ */ -ipfrstat_t *fr_fragstats() -{ - ipfr_stats.ifs_table = ipfr_heads; - ipfr_stats.ifs_nattab = ipfr_nattab; - ipfr_stats.ifs_inuse = ipfr_inuse; - return &ipfr_stats; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfr_newfrag */ -/* Returns: ipfr_t * - pointer to fragment cache state info or NULL */ -/* Parameters: fin(I) - pointer to packet information */ -/* table(I) - pointer to frag table to add to */ -/* */ -/* Add a new entry to the fragment cache, registering it as having come */ -/* through this box, with the result of the filter operation. */ -/* ------------------------------------------------------------------------ */ -static ipfr_t *ipfr_newfrag(fin, pass, table) -fr_info_t *fin; -u_32_t pass; -ipfr_t *table[]; -{ - ipfr_t *fra, frag; - u_int idx, off; - ip_t *ip; - - if (ipfr_inuse >= IPFT_SIZE) - return NULL; - - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) != FI_FRAG) - return NULL; - - ip = fin->fin_ip; - - if (pass & FR_FRSTRICT) - if ((ip->ip_off & IP_OFFMASK) != 0) - return NULL; - - frag.ipfr_p = ip->ip_p; - idx = ip->ip_p; - frag.ipfr_id = ip->ip_id; - idx += ip->ip_id; - frag.ipfr_tos = ip->ip_tos; - frag.ipfr_src.s_addr = ip->ip_src.s_addr; - idx += ip->ip_src.s_addr; - frag.ipfr_dst.s_addr = ip->ip_dst.s_addr; - idx += ip->ip_dst.s_addr; - frag.ipfr_ifp = fin->fin_ifp; - idx *= 127; - idx %= IPFT_SIZE; - - frag.ipfr_optmsk = fin->fin_fi.fi_optmsk & IPF_OPTCOPY; - frag.ipfr_secmsk = fin->fin_fi.fi_secmsk; - frag.ipfr_auth = fin->fin_fi.fi_auth; - - /* - * first, make sure it isn't already there... - */ - for (fra = table[idx]; (fra != NULL); fra = fra->ipfr_hnext) - if (!bcmp((char *)&frag.ipfr_ifp, (char *)&fra->ipfr_ifp, - IPFR_CMPSZ)) { - ipfr_stats.ifs_exists++; - return NULL; - } - - /* - * allocate some memory, if possible, if not, just record that we - * failed to do so. - */ - KMALLOC(fra, ipfr_t *); - if (fra == NULL) { - ipfr_stats.ifs_nomem++; - return NULL; - } - - if ((fra->ipfr_rule = fin->fin_fr) != NULL) - fin->fin_fr->fr_ref++; - - /* - * Insert the fragment into the fragment table, copy the struct used - * in the search using bcopy rather than reassign each field. - * Set the ttl to the default. - */ - if ((fra->ipfr_hnext = table[idx]) != NULL) - table[idx]->ipfr_hprev = &fra->ipfr_hnext; - fra->ipfr_hprev = table + idx; - fra->ipfr_data = NULL; - table[idx] = fra; - bcopy((char *)&frag.ipfr_ifp, (char *)&fra->ipfr_ifp, IPFR_CMPSZ); - fra->ipfr_ttl = fr_ticks + fr_ipfrttl; - - /* - * Compute the offset of the expected start of the next packet. - */ - off = ip->ip_off & IP_OFFMASK; - if (off == 0) - fra->ipfr_seen0 = 1; - fra->ipfr_off = off + (fin->fin_dlen >> 3); - fra->ipfr_pass = pass; - ipfr_stats.ifs_new++; - ipfr_inuse++; - return fra; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_newfrag */ -/* Returns: int - 0 == success, -1 == error */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Add a new entry to the fragment cache table based on the current packet */ -/* ------------------------------------------------------------------------ */ -int fr_newfrag(fin, pass) -u_32_t pass; -fr_info_t *fin; -{ - ipfr_t *fra; - - if ((fin->fin_v != 4) || (fr_frag_lock != 0)) - return -1; - - WRITE_ENTER(&ipf_frag); - fra = ipfr_newfrag(fin, pass, ipfr_heads); - if (fra != NULL) { - *ipfr_tail = fra; - fra->ipfr_prev = ipfr_tail; - ipfr_tail = &fra->ipfr_next; - if (ipfr_list == NULL) - ipfr_list = fra; - fra->ipfr_next = NULL; - } - RWLOCK_EXIT(&ipf_frag); - return fra ? 0 : -1; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_nat_newfrag */ -/* Returns: int - 0 == success, -1 == error */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT structure */ -/* */ -/* Create a new NAT fragment cache entry based on the current packet and */ -/* the NAT structure for this "session". */ -/* ------------------------------------------------------------------------ */ -int fr_nat_newfrag(fin, pass, nat) -fr_info_t *fin; -u_32_t pass; -nat_t *nat; -{ - ipfr_t *fra; - - if ((fin->fin_v != 4) || (fr_frag_lock != 0)) - return 0; - - WRITE_ENTER(&ipf_natfrag); - fra = ipfr_newfrag(fin, pass, ipfr_nattab); - if (fra != NULL) { - fra->ipfr_data = nat; - nat->nat_data = fra; - *ipfr_nattail = fra; - fra->ipfr_prev = ipfr_nattail; - ipfr_nattail = &fra->ipfr_next; - fra->ipfr_next = NULL; - } - RWLOCK_EXIT(&ipf_natfrag); - return fra ? 0 : -1; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ipid_newfrag */ -/* Returns: int - 0 == success, -1 == error */ -/* Parameters: fin(I) - pointer to packet information */ -/* ipid(I) - new IP ID for this fragmented packet */ -/* */ -/* Create a new fragment cache entry for this packet and store, as a data */ -/* pointer, the new IP ID value. */ -/* ------------------------------------------------------------------------ */ -int fr_ipid_newfrag(fin, ipid) -fr_info_t *fin; -u_32_t ipid; -{ - ipfr_t *fra; - - if ((fin->fin_v != 4) || (fr_frag_lock)) - return 0; - - WRITE_ENTER(&ipf_ipidfrag); - fra = ipfr_newfrag(fin, 0, ipfr_ipidtab); - if (fra != NULL) { - fra->ipfr_data = (void *)ipid; - *ipfr_ipidtail = fra; - fra->ipfr_prev = ipfr_ipidtail; - ipfr_ipidtail = &fra->ipfr_next; - fra->ipfr_next = NULL; - } - RWLOCK_EXIT(&ipf_ipidfrag); - return fra ? 0 : -1; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fraglookup */ -/* Returns: ipfr_t * - pointer to ipfr_t structure if there's a */ -/* matching entry in the frag table, else NULL */ -/* Parameters: fin(I) - pointer to packet information */ -/* table(I) - pointer to fragment cache table to search */ -/* */ -/* Check the fragment cache to see if there is already a record of this */ -/* packet with its filter result known. */ -/* ------------------------------------------------------------------------ */ -static ipfr_t *fr_fraglookup(fin, table) -fr_info_t *fin; -ipfr_t *table[]; -{ - ipfr_t *f, frag; - u_int idx; - ip_t *ip; - - if ((fin->fin_flx & (FI_FRAG|FI_BAD)) != FI_FRAG) - return NULL; - - /* - * For fragments, we record protocol, packet id, TOS and both IP#'s - * (these should all be the same for all fragments of a packet). - * - * build up a hash value to index the table with. - */ - ip = fin->fin_ip; - frag.ipfr_p = ip->ip_p; - idx = ip->ip_p; - frag.ipfr_id = ip->ip_id; - idx += ip->ip_id; - frag.ipfr_tos = ip->ip_tos; - frag.ipfr_src.s_addr = ip->ip_src.s_addr; - idx += ip->ip_src.s_addr; - frag.ipfr_dst.s_addr = ip->ip_dst.s_addr; - idx += ip->ip_dst.s_addr; - frag.ipfr_ifp = fin->fin_ifp; - idx *= 127; - idx %= IPFT_SIZE; - - frag.ipfr_optmsk = fin->fin_fi.fi_optmsk & IPF_OPTCOPY; - frag.ipfr_secmsk = fin->fin_fi.fi_secmsk; - frag.ipfr_auth = fin->fin_fi.fi_auth; - - /* - * check the table, careful to only compare the right amount of data - */ - for (f = table[idx]; f; f = f->ipfr_hnext) - if (!bcmp((char *)&frag.ipfr_ifp, (char *)&f->ipfr_ifp, - IPFR_CMPSZ)) { - u_short off; - - /* - * We don't want to let short packets match because - * they could be compromising the security of other - * rules that want to match on layer 4 fields (and - * can't because they have been fragmented off.) - * Why do this check here? The counter acts as an - * indicator of this kind of attack, whereas if it was - * elsewhere, it wouldn't know if other matching - * packets had been seen. - */ - if (fin->fin_flx & FI_SHORT) { - ATOMIC_INCL(ipfr_stats.ifs_short); - continue; - } - - /* - * XXX - We really need to be guarding against the - * retransmission of (src,dst,id,offset-range) here - * because a fragmented packet is never resent with - * the same IP ID# (or shouldn't). - */ - off = ip->ip_off & IP_OFFMASK; - if (f->ipfr_seen0) { - if (off == 0) { - ATOMIC_INCL(ipfr_stats.ifs_retrans0); - continue; - } - } else if (off == 0) - f->ipfr_seen0 = 1; - - if (f != table[idx]) { - ipfr_t **fp; - - /* - * Move fragment info. to the top of the list - * to speed up searches. First, delink... - */ - fp = f->ipfr_hprev; - (*fp) = f->ipfr_hnext; - if (f->ipfr_hnext != NULL) - f->ipfr_hnext->ipfr_hprev = fp; - /* - * Then put back at the top of the chain. - */ - f->ipfr_hnext = table[idx]; - table[idx]->ipfr_hprev = &f->ipfr_hnext; - f->ipfr_hprev = table + idx; - table[idx] = f; - } - - /* - * If we've follwed the fragments, and this is the - * last (in order), shrink expiration time. - */ - if (off == f->ipfr_off) { - if (!(ip->ip_off & IP_MF)) - f->ipfr_ttl = fr_ticks + 1; - f->ipfr_off = (fin->fin_dlen >> 3) + off; - } else if (f->ipfr_pass & FR_FRSTRICT) - continue; - ATOMIC_INCL(ipfr_stats.ifs_hits); - return f; - } - return NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_nat_knownfrag */ -/* Returns: nat_t* - pointer to 'parent' NAT structure if frag table */ -/* match found, else NULL */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Functional interface for NAT lookups of the NAT fragment cache */ -/* ------------------------------------------------------------------------ */ -nat_t *fr_nat_knownfrag(fin) -fr_info_t *fin; -{ - nat_t *nat; - ipfr_t *ipf; - - if ((fin->fin_v != 4) || (fr_frag_lock) || !ipfr_natlist) - return NULL; - READ_ENTER(&ipf_natfrag); - ipf = fr_fraglookup(fin, ipfr_nattab); - if (ipf != NULL) { - nat = ipf->ipfr_data; - /* - * This is the last fragment for this packet. - */ - if ((ipf->ipfr_ttl == fr_ticks + 1) && (nat != NULL)) { - nat->nat_data = NULL; - ipf->ipfr_data = NULL; - } - } else - nat = NULL; - RWLOCK_EXIT(&ipf_natfrag); - return nat; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ipid_knownfrag */ -/* Returns: u_32_t - IPv4 ID for this packet if match found, else */ -/* return 0xfffffff to indicate no match. */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* Functional interface for IP ID lookups of the IP ID fragment cache */ -/* ------------------------------------------------------------------------ */ -u_32_t fr_ipid_knownfrag(fin) -fr_info_t *fin; -{ - ipfr_t *ipf; - u_32_t id; - - if ((fin->fin_v != 4) || (fr_frag_lock) || !ipfr_ipidlist) - return 0xffffffff; - - READ_ENTER(&ipf_ipidfrag); - ipf = fr_fraglookup(fin, ipfr_ipidtab); - if (ipf != NULL) - id = (u_32_t)ipf->ipfr_data; - else - id = 0xffffffff; - RWLOCK_EXIT(&ipf_ipidfrag); - return id; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_knownfrag */ -/* Returns: frentry_t* - pointer to filter rule if a match is found in */ -/* the frag cache table, else NULL. */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(O) - pointer to where to store rule flags resturned */ -/* */ -/* Functional interface for normal lookups of the fragment cache. If a */ -/* match is found, return the rule pointer and flags from the rule, except */ -/* that if FR_LOGFIRST is set, reset FR_LOG. */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_knownfrag(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - frentry_t *fr = NULL; - ipfr_t *fra; - u_32_t pass; - - if ((fin->fin_v != 4) || (fr_frag_lock) || (ipfr_list == NULL)) - return NULL; - - READ_ENTER(&ipf_frag); - fra = fr_fraglookup(fin, ipfr_heads); - if (fra != NULL) { - fr = fra->ipfr_rule; - fin->fin_fr = fr; - if (fr != NULL) { - pass = fr->fr_flags; - if ((pass & FR_LOGFIRST) != 0) - pass &= ~(FR_LOGFIRST|FR_LOG); - *passp = pass; - } - } - RWLOCK_EXIT(&ipf_frag); - return fr; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_forget */ -/* Returns: Nil */ -/* Parameters: ptr(I) - pointer to data structure */ -/* */ -/* Search through all of the fragment cache entries and wherever a pointer */ -/* is found to match ptr, reset it to NULL. */ -/* ------------------------------------------------------------------------ */ -void fr_forget(ptr) -void *ptr; -{ - ipfr_t *fr; - - WRITE_ENTER(&ipf_frag); - for (fr = ipfr_list; fr; fr = fr->ipfr_next) - if (fr->ipfr_data == ptr) - fr->ipfr_data = NULL; - RWLOCK_EXIT(&ipf_frag); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_forgetnat */ -/* Returns: Nil */ -/* Parameters: ptr(I) - pointer to data structure */ -/* */ -/* Search through all of the fragment cache entries for NAT and wherever a */ -/* pointer is found to match ptr, reset it to NULL. */ -/* ------------------------------------------------------------------------ */ -void fr_forgetnat(ptr) -void *ptr; -{ - ipfr_t *fr; - - WRITE_ENTER(&ipf_natfrag); - for (fr = ipfr_natlist; fr; fr = fr->ipfr_next) - if (fr->ipfr_data == ptr) - fr->ipfr_data = NULL; - RWLOCK_EXIT(&ipf_natfrag); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fragdelete */ -/* Returns: Nil */ -/* Parameters: fra(I) - pointer to fragment structure to delete */ -/* tail(IO) - pointer to the pointer to the tail of the frag */ -/* list */ -/* */ -/* Remove a fragment cache table entry from the table & list. Also free */ -/* the filter rule it is associated with it if it is no longer used as a */ -/* result of decreasing the reference count. */ -/* ------------------------------------------------------------------------ */ -static void fr_fragdelete(fra, tail) -ipfr_t *fra, ***tail; -{ - frentry_t *fr; - - fr = fra->ipfr_rule; - if (fr != NULL) - (void)fr_derefrule(&fr); - - if (fra->ipfr_next) - fra->ipfr_next->ipfr_prev = fra->ipfr_prev; - *fra->ipfr_prev = fra->ipfr_next; - if (*tail == &fra->ipfr_next) - *tail = fra->ipfr_prev; - - if (fra->ipfr_hnext) - fra->ipfr_hnext->ipfr_hprev = fra->ipfr_hprev; - *fra->ipfr_hprev = fra->ipfr_hnext; - KFREE(fra); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fragclear */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Free memory in use by fragment state information kept. Do the normal */ -/* fragment state stuff first and then the NAT-fragment table. */ -/* ------------------------------------------------------------------------ */ -void fr_fragclear() -{ - ipfr_t *fra; - nat_t *nat; - - WRITE_ENTER(&ipf_frag); - while ((fra = ipfr_list) != NULL) - fr_fragdelete(fra, &ipfr_tail); - ipfr_tail = &ipfr_list; - RWLOCK_EXIT(&ipf_frag); - - WRITE_ENTER(&ipf_nat); - WRITE_ENTER(&ipf_natfrag); - while ((fra = ipfr_natlist) != NULL) { - nat = fra->ipfr_data; - if (nat != NULL) { - if (nat->nat_data == fra) - nat->nat_data = NULL; - } - fr_fragdelete(fra, &ipfr_nattail); - } - ipfr_nattail = &ipfr_natlist; - RWLOCK_EXIT(&ipf_natfrag); - RWLOCK_EXIT(&ipf_nat); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fragexpire */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Expire entries in the fragment cache table that have been there too long */ -/* ------------------------------------------------------------------------ */ -void fr_fragexpire() -{ - ipfr_t **fp, *fra; - nat_t *nat; -#if defined(USE_SPL) && defined(_KERNEL) - int s; -#endif - - if (fr_frag_lock) - return; - - SPL_NET(s); - WRITE_ENTER(&ipf_frag); - /* - * Go through the entire table, looking for entries to expire, - * which is indicated by the ttl being less than or equal to fr_ticks. - */ - for (fp = &ipfr_list; ((fra = *fp) != NULL); ) { - if (fra->ipfr_ttl > fr_ticks) - break; - fr_fragdelete(fra, &ipfr_tail); - ipfr_stats.ifs_expire++; - ipfr_inuse--; - } - RWLOCK_EXIT(&ipf_frag); - - WRITE_ENTER(&ipf_ipidfrag); - for (fp = &ipfr_ipidlist; ((fra = *fp) != NULL); ) { - if (fra->ipfr_ttl > fr_ticks) - break; - fr_fragdelete(fra, &ipfr_ipidtail); - ipfr_stats.ifs_expire++; - ipfr_inuse--; - } - RWLOCK_EXIT(&ipf_ipidfrag); - - /* - * Same again for the NAT table, except that if the structure also - * still points to a NAT structure, and the NAT structure points back - * at the one to be free'd, NULL the reference from the NAT struct. - * NOTE: We need to grab both mutex's early, and in this order so as - * to prevent a deadlock if both try to expire at the same time. - */ - WRITE_ENTER(&ipf_nat); - WRITE_ENTER(&ipf_natfrag); - for (fp = &ipfr_natlist; ((fra = *fp) != NULL); ) { - if (fra->ipfr_ttl > fr_ticks) - break; - nat = fra->ipfr_data; - if (nat != NULL) { - if (nat->nat_data == fra) - nat->nat_data = NULL; - } - fr_fragdelete(fra, &ipfr_nattail); - ipfr_stats.ifs_expire++; - ipfr_inuse--; - } - RWLOCK_EXIT(&ipf_natfrag); - RWLOCK_EXIT(&ipf_nat); - SPL_X(s); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_slowtimer */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Slowly expire held state for fragments. Timeouts are set * in */ -/* expectation of this being called twice per second. */ -/* ------------------------------------------------------------------------ */ -#if !defined(_KERNEL) || (!SOLARIS && !defined(__hpux) && !defined(__sgi) && \ - !defined(__osf__)) -# if defined(_KERNEL) && ((BSD >= 199103) || defined(__sgi)) -void fr_slowtimer __P((void *ptr)) -# else -int fr_slowtimer() -# endif -{ - READ_ENTER(&ipf_global); - - fr_fragexpire(); - fr_timeoutstate(); - fr_natexpire(); - fr_authexpire(); - fr_ticks++; - if (fr_running <= 0) - goto done; -# ifdef _KERNEL -# if defined(__NetBSD__) && (__NetBSD_Version__ >= 104240000) - callout_reset(&fr_slowtimer_ch, hz / 2, fr_slowtimer, NULL); -# else -# if defined(__OpenBSD__) - timeout_add(&fr_slowtimer_ch, hz/2); -# else -# if (__FreeBSD_version >= 300000) - fr_slowtimer_ch = timeout(fr_slowtimer, NULL, hz/2); -# else -# ifdef linux - ; -# else - timeout(fr_slowtimer, NULL, hz/2); -# endif -# endif /* FreeBSD */ -# endif /* OpenBSD */ -# endif /* NetBSD */ -# endif -done: - RWLOCK_EXIT(&ipf_global); -# if (BSD < 199103) || !defined(_KERNEL) - return 0; -# endif -} -#endif /* !SOLARIS && !defined(__hpux) && !defined(__sgi) */ diff --git a/contrib/ipfilter/ip_frag.h b/contrib/ipfilter/ip_frag.h deleted file mode 100644 index 786a08821086..000000000000 --- a/contrib/ipfilter/ip_frag.h +++ /dev/null @@ -1,86 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_frag.h 1.5 3/24/96 - * Id: ip_frag.h,v 2.23.2.1 2004/03/29 16:21:56 darrenr Exp - */ - -#ifndef __IP_FRAG_H__ -#define __IP_FRAG_H__ - -#define IPFT_SIZE 257 - -typedef struct ipfr { - struct ipfr *ipfr_hnext, **ipfr_hprev; - struct ipfr *ipfr_next, **ipfr_prev; - void *ipfr_data; - void *ipfr_ifp; - struct in_addr ipfr_src; - struct in_addr ipfr_dst; - u_32_t ipfr_optmsk; - u_short ipfr_secmsk; - u_short ipfr_auth; - u_short ipfr_id; - u_char ipfr_p; - u_char ipfr_tos; - u_32_t ipfr_pass; - u_short ipfr_off; - u_char ipfr_ttl; - u_char ipfr_seen0; - frentry_t *ipfr_rule; -} ipfr_t; - - -typedef struct ipfrstat { - u_long ifs_exists; /* add & already exists */ - u_long ifs_nomem; - u_long ifs_new; - u_long ifs_hits; - u_long ifs_expire; - u_long ifs_inuse; - u_long ifs_retrans0; - u_long ifs_short; - struct ipfr **ifs_table; - struct ipfr **ifs_nattab; -} ipfrstat_t; - -#define IPFR_CMPSZ (offsetof(ipfr_t, ipfr_pass) - \ - offsetof(ipfr_t, ipfr_ifp)) - -extern int ipfr_size; -extern int fr_ipfrttl; -extern int fr_frag_lock; -extern int fr_fraginit __P((void)); -extern void fr_fragunload __P((void)); -extern ipfrstat_t *fr_fragstats __P((void)); - -extern int fr_newfrag __P((fr_info_t *, u_32_t)); -extern frentry_t *fr_knownfrag __P((fr_info_t *, u_32_t *)); - -extern int fr_nat_newfrag __P((fr_info_t *, u_32_t, struct nat *)); -extern nat_t *fr_nat_knownfrag __P((fr_info_t *)); - -extern int fr_ipid_newfrag __P((fr_info_t *, u_32_t)); -extern u_32_t fr_ipid_knownfrag __P((fr_info_t *)); - -extern void fr_forget __P((void *)); -extern void fr_forgetnat __P((void *)); -extern void fr_fragclear __P((void)); -extern void fr_fragexpire __P((void)); - -#if defined(_KERNEL) && ((BSD >= 199306) || SOLARIS || defined(__sgi) \ - || defined(__osf__) || (defined(__sgi) && (IRIX >= 60500))) -# if defined(SOLARIS2) && (SOLARIS2 < 7) -extern void fr_slowtimer __P((void)); -# else -extern void fr_slowtimer __P((void *)); -# endif -#else -extern int fr_slowtimer __P((void)); -#endif - -#endif /* __IP_FRAG_H__ */ diff --git a/contrib/ipfilter/ip_ftp_pxy.c b/contrib/ipfilter/ip_ftp_pxy.c deleted file mode 100644 index 5bdc18a7c1ed..000000000000 --- a/contrib/ipfilter/ip_ftp_pxy.c +++ /dev/null @@ -1,1454 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1997-2003 by Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Simple FTP transparent proxy for in-kernel use. For use with the NAT - * code. - * - * Id: ip_ftp_pxy.c,v 2.88.2.15 2005/03/19 19:38:10 darrenr Exp - */ - -#define IPF_FTP_PROXY - -#define IPF_MINPORTLEN 18 -#define IPF_MAXPORTLEN 30 -#define IPF_MIN227LEN 39 -#define IPF_MAX227LEN 51 -#define IPF_MIN229LEN 47 -#define IPF_MAX229LEN 51 - -#define FTPXY_GO 0 -#define FTPXY_INIT 1 -#define FTPXY_USER_1 2 -#define FTPXY_USOK_1 3 -#define FTPXY_PASS_1 4 -#define FTPXY_PAOK_1 5 -#define FTPXY_AUTH_1 6 -#define FTPXY_AUOK_1 7 -#define FTPXY_ADAT_1 8 -#define FTPXY_ADOK_1 9 -#define FTPXY_ACCT_1 10 -#define FTPXY_ACOK_1 11 -#define FTPXY_USER_2 12 -#define FTPXY_USOK_2 13 -#define FTPXY_PASS_2 14 -#define FTPXY_PAOK_2 15 - -/* - * Values for FTP commands. Numerics cover 0-999 - */ -#define FTPXY_C_PASV 1000 - -int ippr_ftp_client __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_complete __P((char *, size_t)); -int ippr_ftp_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ftp_init __P((void)); -void ippr_ftp_fini __P((void)); -int ippr_ftp_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ftp_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ftp_pasv __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_epsv __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int)); -int ippr_ftp_port __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, int)); -int ippr_ftp_process __P((fr_info_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_server __P((fr_info_t *, ip_t *, nat_t *, ftpinfo_t *, int)); -int ippr_ftp_valid __P((ftpinfo_t *, int, char *, size_t)); -int ippr_ftp_server_valid __P((ftpside_t *, char *, size_t)); -int ippr_ftp_client_valid __P((ftpside_t *, char *, size_t)); -u_short ippr_ftp_atoi __P((char **)); -int ippr_ftp_pasvreply __P((fr_info_t *, ip_t *, nat_t *, ftpside_t *, - u_int, char *, char *, u_int)); - - -int ftp_proxy_init = 0; -int ippr_ftp_pasvonly = 0; -int ippr_ftp_insecure = 0; /* Do not require logins before transfers */ -int ippr_ftp_pasvrdr = 0; -int ippr_ftp_forcepasv = 0; /* PASV must be last command prior to 227 */ -#if defined(_KERNEL) -int ippr_ftp_debug = 0; -#else -int ippr_ftp_debug = 2; -#endif -/* - * 1 - security - * 2 - errors - * 3 - error debugging - * 4 - parsing errors - * 5 - parsing info - * 6 - parsing debug - */ - -static frentry_t ftppxyfr; -static ipftuneable_t ftptune = { - { &ippr_ftp_debug }, - "ippr_ftp_debug", - 0, - 10, - sizeof(ippr_ftp_debug), - 0, - NULL -}; - - -/* - * Initialize local structures. - */ -int ippr_ftp_init() -{ - bzero((char *)&ftppxyfr, sizeof(ftppxyfr)); - ftppxyfr.fr_ref = 1; - ftppxyfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&ftppxyfr.fr_lock, "FTP Proxy Mutex"); - ftp_proxy_init = 1; - (void) fr_addipftune(&ftptune); - - return 0; -} - - -void ippr_ftp_fini() -{ - (void) fr_delipftune(&ftptune); - - if (ftp_proxy_init == 1) { - MUTEX_DESTROY(&ftppxyfr.fr_lock); - ftp_proxy_init = 0; - } -} - - -int ippr_ftp_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ftpinfo_t *ftp; - ftpside_t *f; - - KMALLOC(ftp, ftpinfo_t *); - if (ftp == NULL) - return -1; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - aps->aps_data = ftp; - aps->aps_psiz = sizeof(ftpinfo_t); - - bzero((char *)ftp, sizeof(*ftp)); - f = &ftp->ftp_side[0]; - f->ftps_rptr = f->ftps_buf; - f->ftps_wptr = f->ftps_buf; - f = &ftp->ftp_side[1]; - f->ftps_rptr = f->ftps_buf; - f->ftps_wptr = f->ftps_buf; - ftp->ftp_passok = FTPXY_INIT; - ftp->ftp_incok = 0; - return 0; -} - - -int ippr_ftp_port(fin, ip, nat, f, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpside_t *f; -int dlen; -{ - tcphdr_t *tcp, tcph, *tcp2 = &tcph; - char newbuf[IPF_FTPBUFSZ], *s; - struct in_addr swip, swip2; - u_int a1, a2, a3, a4; - int inc, off, flags; - u_short a5, a6, sp; - size_t nlen, olen; - fr_info_t fi; - nat_t *nat2; - mb_t *m; - - m = fin->fin_m; - tcp = (tcphdr_t *)fin->fin_dp; - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - - /* - * Check for client sending out PORT message. - */ - if (dlen < IPF_MINPORTLEN) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:dlen(%d) < IPF_MINPORTLEN\n", - dlen); - return 0; - } - /* - * Skip the PORT command + space - */ - s = f->ftps_rptr + 5; - /* - * Pick out the address components, two at a time. - */ - a1 = ippr_ftp_atoi(&s); - if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 1); - return 0; - } - a2 = ippr_ftp_atoi(&s); - if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 2); - return 0; - } - - /* - * Check that IP address in the PORT/PASV reply is the same as the - * sender of the command - prevents using PORT for port scanning. - */ - a1 <<= 16; - a1 |= a2; - if (((nat->nat_dir == NAT_OUTBOUND) && - (a1 != ntohl(nat->nat_inip.s_addr))) || - ((nat->nat_dir == NAT_INBOUND) && - (a1 != ntohl(nat->nat_oip.s_addr)))) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_port:%s != nat->nat_inip\n", "a1"); - return APR_ERR(1); - } - - a5 = ippr_ftp_atoi(&s); - if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:ippr_ftp_atoi(%d) failed\n", 3); - return 0; - } - if (*s == ')') - s++; - - /* - * check for CR-LF at the end. - */ - if (*s == '\n') - s--; - if ((*s == '\r') && (*(s + 1) == '\n')) { - s += 2; - a6 = a5 & 0xff; - } else { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_port:missing %s\n", "cr-lf"); - return 0; - } - - a5 >>= 8; - a5 &= 0xff; - sp = a5 << 8 | a6; - /* - * Don't allow the PORT command to specify a port < 1024 due to - * security crap. - */ - if (sp < 1024) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_port:sp(%d) < 1024\n", sp); - return 0; - } - /* - * Calculate new address parts for PORT command - */ - if (nat->nat_dir == NAT_INBOUND) - a1 = ntohl(nat->nat_oip.s_addr); - else - a1 = ntohl(ip->ip_src.s_addr); - a2 = (a1 >> 16) & 0xff; - a3 = (a1 >> 8) & 0xff; - a4 = a1 & 0xff; - a1 >>= 24; - olen = s - f->ftps_rptr; - /* DO NOT change this to snprintf! */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(newbuf, sizeof(newbuf), "%s %u,%u,%u,%u,%u,%u\r\n", - "PORT", a1, a2, a3, a4, a5, a6); -#else - (void) sprintf(newbuf, "%s %u,%u,%u,%u,%u,%u\r\n", - "PORT", a1, a2, a3, a4, a5, a6); -#endif - - nlen = strlen(newbuf); - inc = nlen - olen; - if ((inc + ip->ip_len) > 65535) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_port:inc(%d) + ip->ip_len > 65535\n", - inc); - return 0; - } - -#if !defined(_KERNEL) - bcopy(newbuf, MTOD(m, char *) + off, nlen); -#else -# if defined(MENTAT) - if (inc < 0) - (void)adjmsg(m, inc); -# else /* defined(MENTAT) */ - /* - * m_adj takes care of pkthdr.len, if required and treats inc<0 to - * mean remove -len bytes from the end of the packet. - * The mbuf chain will be extended if necessary by m_copyback(). - */ - if (inc < 0) - m_adj(m, inc); -# endif /* defined(MENTAT) */ -#endif /* !defined(_KERNEL) */ - COPYBACK(m, off, nlen, newbuf); - - if (inc != 0) { - ip->ip_len += inc; - fin->fin_dlen += inc; - fin->fin_plen += inc; - } - - /* - * The server may not make the connection back from port 20, but - * it is the most likely so use it here to check for a conflicting - * mapping. - */ - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_flx |= FI_IGNORE; - fi.fin_data[0] = sp; - fi.fin_data[1] = fin->fin_data[1] - 1; - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - if (nat->nat_dir == NAT_OUTBOUND) - nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - else - nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - if (nat2 == NULL) { - int slen; - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp2); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = htons(sp); - TCP_OFF_A(tcp2, 5); - tcp2->th_flags = TH_SYN; - tcp2->th_dport = 0; /* XXX - don't specify remote port */ - fi.fin_data[1] = 0; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - fi.fin_dp = (char *)tcp2; - fi.fin_fr = &ftppxyfr; - fi.fin_out = nat->nat_dir; - fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; - swip = ip->ip_src; - swip2 = ip->ip_dst; - if (nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - ip->ip_src = nat->nat_inip; - } else if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_saddr = nat->nat_oip.s_addr; - ip->ip_src = nat->nat_oip; - } - - flags = NAT_SLAVE|IPN_TCP|SI_W_DPORT; - if (nat->nat_dir == NAT_INBOUND) - flags |= NAT_NOTRULEPORT; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, flags, nat->nat_dir); - - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_TCP); - nat_update(&fi, nat2, nat->nat_ptr); - fi.fin_ifp = NULL; - if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; - ip->ip_dst = nat->nat_inip; - } - (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_len = slen; - ip->ip_src = swip; - ip->ip_dst = swip2; - } else { - ipstate_t *is; - - nat_update(&fi, nat2, nat->nat_ptr); - READ_ENTER(&ipf_state); - is = nat2->nat_state; - if (is != NULL) { - MUTEX_ENTER(&is->is_lock); - (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb, - is->is_flags); - MUTEX_EXIT(&is->is_lock); - } - RWLOCK_EXIT(&ipf_state); - } - return APR_INC(inc); -} - - -int ippr_ftp_client(fin, ip, nat, ftp, dlen) -fr_info_t *fin; -nat_t *nat; -ftpinfo_t *ftp; -ip_t *ip; -int dlen; -{ - char *rptr, *wptr, cmd[6], c; - ftpside_t *f; - int inc, i; - - inc = 0; - f = &ftp->ftp_side[0]; - rptr = f->ftps_rptr; - wptr = f->ftps_wptr; - - for (i = 0; (i < 5) && (i < dlen); i++) { - c = rptr[i]; - if (ISALPHA(c)) { - cmd[i] = TOUPPER(c); - } else { - cmd[i] = c; - } - } - cmd[i] = '\0'; - - ftp->ftp_incok = 0; - if (!strncmp(cmd, "USER ", 5) || !strncmp(cmd, "XAUT ", 5)) { - if (ftp->ftp_passok == FTPXY_ADOK_1 || - ftp->ftp_passok == FTPXY_AUOK_1) { - ftp->ftp_passok = FTPXY_USER_2; - ftp->ftp_incok = 1; - } else { - ftp->ftp_passok = FTPXY_USER_1; - ftp->ftp_incok = 1; - } - } else if (!strncmp(cmd, "AUTH ", 5)) { - ftp->ftp_passok = FTPXY_AUTH_1; - ftp->ftp_incok = 1; - } else if (!strncmp(cmd, "PASS ", 5)) { - if (ftp->ftp_passok == FTPXY_USOK_1) { - ftp->ftp_passok = FTPXY_PASS_1; - ftp->ftp_incok = 1; - } else if (ftp->ftp_passok == FTPXY_USOK_2) { - ftp->ftp_passok = FTPXY_PASS_2; - ftp->ftp_incok = 1; - } - } else if ((ftp->ftp_passok == FTPXY_AUOK_1) && - !strncmp(cmd, "ADAT ", 5)) { - ftp->ftp_passok = FTPXY_ADAT_1; - ftp->ftp_incok = 1; - } else if ((ftp->ftp_passok == FTPXY_PAOK_1 || - ftp->ftp_passok == FTPXY_PAOK_2) && - !strncmp(cmd, "ACCT ", 5)) { - ftp->ftp_passok = FTPXY_ACCT_1; - ftp->ftp_incok = 1; - } else if ((ftp->ftp_passok == FTPXY_GO) && !ippr_ftp_pasvonly && - !strncmp(cmd, "PORT ", 5)) { - inc = ippr_ftp_port(fin, ip, nat, f, dlen); - } else if (ippr_ftp_insecure && !ippr_ftp_pasvonly && - !strncmp(cmd, "PORT ", 5)) { - inc = ippr_ftp_port(fin, ip, nat, f, dlen); - } - - while ((*rptr++ != '\n') && (rptr < wptr)) - ; - f->ftps_rptr = rptr; - return inc; -} - - -int ippr_ftp_pasv(fin, ip, nat, ftp, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpinfo_t *ftp; -int dlen; -{ - u_int a1, a2, a3, a4, data_ip; - char newbuf[IPF_FTPBUFSZ]; - char *s, *brackets[2]; - u_short a5, a6; - ftpside_t *f; - - if (ippr_ftp_forcepasv != 0 && - ftp->ftp_side[0].ftps_cmds != FTPXY_C_PASV) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:ftps_cmds(%d) != FTPXY_C_PASV\n", - ftp->ftp_side[0].ftps_cmds); - return 0; - } - - f = &ftp->ftp_side[1]; - -#define PASV_REPLEN 24 - /* - * Check for PASV reply message. - */ - if (dlen < IPF_MIN227LEN) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:dlen(%d) < IPF_MIN227LEN\n", - dlen); - return 0; - } else if (strncmp(f->ftps_rptr, - "227 Entering Passive Mod", PASV_REPLEN)) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:%d reply wrong\n", 227); - return 0; - } - - brackets[0] = ""; - brackets[1] = ""; - /* - * Skip the PASV reply + space - */ - s = f->ftps_rptr + PASV_REPLEN; - while (*s && !ISDIGIT(*s)) { - if (*s == '(') { - brackets[0] = "("; - brackets[1] = ")"; - } - s++; - } - - /* - * Pick out the address components, two at a time. - */ - a1 = ippr_ftp_atoi(&s); - if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 1); - return 0; - } - a2 = ippr_ftp_atoi(&s); - if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 2); - return 0; - } - - /* - * check that IP address in the PASV reply is the same as the - * sender of the command - prevents using PASV for port scanning. - */ - a1 <<= 16; - a1 |= a2; - - if (((nat->nat_dir == NAT_INBOUND) && - (a1 != ntohl(nat->nat_inip.s_addr))) || - ((nat->nat_dir == NAT_OUTBOUND) && - (a1 != ntohl(nat->nat_oip.s_addr)))) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:%s != nat->nat_oip\n", "a1"); - return 0; - } - - a5 = ippr_ftp_atoi(&s); - if (s == NULL) { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:ippr_ftp_atoi(%d) failed\n", 3); - return 0; - } - - if (*s == ')') - s++; - if (*s == '.') - s++; - if (*s == '\n') - s--; - /* - * check for CR-LF at the end. - */ - if ((*s == '\r') && (*(s + 1) == '\n')) { - s += 2; - } else { - if (ippr_ftp_debug > 1) - printf("ippr_ftp_pasv:missing %s", "cr-lf\n"); - return 0; - } - - a6 = a5 & 0xff; - a5 >>= 8; - /* - * Calculate new address parts for 227 reply - */ - if (nat->nat_dir == NAT_INBOUND) { - data_ip = nat->nat_outip.s_addr; - a1 = ntohl(data_ip); - } else - data_ip = htonl(a1); - - a2 = (a1 >> 16) & 0xff; - a3 = (a1 >> 8) & 0xff; - a4 = a1 & 0xff; - a1 >>= 24; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(newbuf, sizeof(newbuf), "%s %s%u,%u,%u,%u,%u,%u%s\r\n", - "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4, - a5, a6, brackets[1]); -#else - (void) sprintf(newbuf, "%s %s%u,%u,%u,%u,%u,%u%s\r\n", - "227 Entering Passive Mode", brackets[0], a1, a2, a3, a4, - a5, a6, brackets[1]); -#endif - return ippr_ftp_pasvreply(fin, ip, nat, f, (a5 << 8 | a6), - newbuf, s, data_ip); -} - -int ippr_ftp_pasvreply(fin, ip, nat, f, port, newmsg, s, data_ip) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpside_t *f; -u_int port; -char *newmsg; -char *s; -u_int data_ip; -{ - int inc, off, nflags, sflags; - tcphdr_t *tcp, tcph, *tcp2; - struct in_addr swip, swip2; - struct in_addr data_addr; - size_t nlen, olen; - fr_info_t fi; - nat_t *nat2; - mb_t *m; - - m = fin->fin_m; - tcp = (tcphdr_t *)fin->fin_dp; - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - - data_addr.s_addr = data_ip; - tcp2 = &tcph; - inc = 0; - - - olen = s - f->ftps_rptr; - nlen = strlen(newmsg); - inc = nlen - olen; - if ((inc + ip->ip_len) > 65535) { - if (ippr_ftp_debug > 0) - printf("ippr_ftp_pasv:inc(%d) + ip->ip_len > 65535\n", - inc); - return 0; - } - -#if !defined(_KERNEL) - bcopy(newmsg, MTOD(m, char *) + off, nlen); -#else -# if defined(MENTAT) - if (inc < 0) - (void)adjmsg(m, inc); -# else /* defined(MENTAT) */ - /* - * m_adj takes care of pkthdr.len, if required and treats inc<0 to - * mean remove -len bytes from the end of the packet. - * The mbuf chain will be extended if necessary by m_copyback(). - */ - if (inc < 0) - m_adj(m, inc); -# endif /* defined(MENTAT) */ -#endif /* !defined(_KERNEL) */ - COPYBACK(m, off, nlen, newmsg); - - if (inc != 0) { - ip->ip_len += inc; - fin->fin_dlen += inc; - fin->fin_plen += inc; - } - - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_flx |= FI_IGNORE; - fi.fin_data[0] = 0; - fi.fin_data[1] = port; - nflags = IPN_TCP|SI_W_SPORT; - if (ippr_ftp_pasvrdr && f->ftps_ifp) - nflags |= SI_W_DPORT; - if (nat->nat_dir == NAT_OUTBOUND) - nat2 = nat_outlookup(&fi, nflags|NAT_SEARCH, - nat->nat_p, nat->nat_inip, nat->nat_oip); - else - nat2 = nat_inlookup(&fi, nflags|NAT_SEARCH, - nat->nat_p, nat->nat_inip, nat->nat_oip); - if (nat2 == NULL) { - int slen; - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp2); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = 0; /* XXX - fake it for nat_new */ - TCP_OFF_A(tcp2, 5); - tcp2->th_flags = TH_SYN; - fi.fin_data[1] = port; - fi.fin_dlen = sizeof(*tcp2); - tcp2->th_dport = htons(port); - fi.fin_data[0] = 0; - fi.fin_dp = (char *)tcp2; - fi.fin_plen = fi.fin_hlen + sizeof(*tcp); - fi.fin_fr = &ftppxyfr; - fi.fin_out = nat->nat_dir; - fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; - swip = ip->ip_src; - swip2 = ip->ip_dst; - if (nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_daddr = data_addr.s_addr; - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - ip->ip_dst = data_addr; - ip->ip_src = nat->nat_inip; - } else if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_saddr = nat->nat_oip.s_addr; - fi.fin_fi.fi_daddr = nat->nat_outip.s_addr; - ip->ip_src = nat->nat_oip; - ip->ip_dst = nat->nat_outip; - } - - sflags = nflags; - nflags |= NAT_SLAVE; - if (nat->nat_dir == NAT_INBOUND) - nflags |= NAT_NOTRULEPORT; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_TCP); - nat_update(&fi, nat2, nat->nat_ptr); - fi.fin_ifp = NULL; - if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; - ip->ip_dst = nat->nat_inip; - } - (void) fr_addstate(&fi, &nat2->nat_state, sflags); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - - ip->ip_len = slen; - ip->ip_src = swip; - ip->ip_dst = swip2; - } else { - ipstate_t *is; - - nat_update(&fi, nat2, nat->nat_ptr); - READ_ENTER(&ipf_state); - is = nat2->nat_state; - if (is != NULL) { - MUTEX_ENTER(&is->is_lock); - (void)fr_tcp_age(&is->is_sti, &fi, ips_tqtqb, - is->is_flags); - MUTEX_EXIT(&is->is_lock); - } - RWLOCK_EXIT(&ipf_state); - } - return inc; -} - - -int ippr_ftp_server(fin, ip, nat, ftp, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpinfo_t *ftp; -int dlen; -{ - char *rptr, *wptr; - ftpside_t *f; - int inc; - - inc = 0; - f = &ftp->ftp_side[1]; - rptr = f->ftps_rptr; - wptr = f->ftps_wptr; - - if (*rptr == ' ') - goto server_cmd_ok; - if (!ISDIGIT(*rptr) || !ISDIGIT(*(rptr + 1)) || !ISDIGIT(*(rptr + 2))) - return 0; - if (ftp->ftp_passok == FTPXY_GO) { - if (!strncmp(rptr, "227 ", 4)) - inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen); - else if (!strncmp(rptr, "229 ", 4)) - inc = ippr_ftp_epsv(fin, ip, nat, f, dlen); - } else if (ippr_ftp_insecure && !strncmp(rptr, "227 ", 4)) { - inc = ippr_ftp_pasv(fin, ip, nat, ftp, dlen); - } else if (ippr_ftp_insecure && !strncmp(rptr, "229 ", 4)) { - inc = ippr_ftp_epsv(fin, ip, nat, f, dlen); - } else if (*rptr == '5' || *rptr == '4') - ftp->ftp_passok = FTPXY_INIT; - else if (ftp->ftp_incok) { - if (*rptr == '3') { - if (ftp->ftp_passok == FTPXY_ACCT_1) - ftp->ftp_passok = FTPXY_GO; - else - ftp->ftp_passok++; - } else if (*rptr == '2') { - switch (ftp->ftp_passok) - { - case FTPXY_USER_1 : - case FTPXY_USER_2 : - case FTPXY_PASS_1 : - case FTPXY_PASS_2 : - case FTPXY_ACCT_1 : - ftp->ftp_passok = FTPXY_GO; - break; - default : - ftp->ftp_passok += 3; - break; - } - } - } -server_cmd_ok: - ftp->ftp_incok = 0; - - while ((*rptr++ != '\n') && (rptr < wptr)) - ; - f->ftps_rptr = rptr; - return inc; -} - - -/* - * Look to see if the buffer starts with something which we recognise as - * being the correct syntax for the FTP protocol. - */ -int ippr_ftp_client_valid(ftps, buf, len) -ftpside_t *ftps; -char *buf; -size_t len; -{ - register char *s, c, pc; - register size_t i = len; - char cmd[5]; - - s = buf; - - if (ftps->ftps_junk == 1) - return 1; - - if (i < 5) { - if (ippr_ftp_debug > 3) - printf("ippr_ftp_client_valid:i(%d) < 5\n", (int)i); - return 2; - } - - i--; - c = *s++; - - if (ISALPHA(c)) { - cmd[0] = TOUPPER(c); - c = *s++; - i--; - if (ISALPHA(c)) { - cmd[1] = TOUPPER(c); - c = *s++; - i--; - if (ISALPHA(c)) { - cmd[2] = TOUPPER(c); - c = *s++; - i--; - if (ISALPHA(c)) { - cmd[3] = TOUPPER(c); - c = *s++; - i--; - if ((c != ' ') && (c != '\r')) - goto bad_client_command; - } else if ((c != ' ') && (c != '\r')) - goto bad_client_command; - } else - goto bad_client_command; - } else - goto bad_client_command; - } else { -bad_client_command: - if (ippr_ftp_debug > 3) - printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*.*s]\n", - "ippr_ftp_client_valid", - ftps->ftps_junk, (int)len, (int)i, c, - (int)len, (int)len, buf); - return 1; - } - - for (; i; i--) { - pc = c; - c = *s++; - if ((pc == '\r') && (c == '\n')) { - cmd[4] = '\0'; - if (!strcmp(cmd, "PASV")) - ftps->ftps_cmds = FTPXY_C_PASV; - else - ftps->ftps_cmds = 0; - return 0; - } - } -#if !defined(_KERNEL) - printf("ippr_ftp_client_valid:junk after cmd[%*.*s]\n", - (int)len, (int)len, buf); -#endif - return 2; -} - - -int ippr_ftp_server_valid(ftps, buf, len) -ftpside_t *ftps; -char *buf; -size_t len; -{ - register char *s, c, pc; - register size_t i = len; - int cmd; - - s = buf; - cmd = 0; - - if (ftps->ftps_junk == 1) - return 1; - - if (i < 5) { - if (ippr_ftp_debug > 3) - printf("ippr_ftp_servert_valid:i(%d) < 5\n", (int)i); - return 2; - } - - c = *s++; - i--; - if (c == ' ') - goto search_eol; - - if (ISDIGIT(c)) { - cmd = (c - '0') * 100; - c = *s++; - i--; - if (ISDIGIT(c)) { - cmd += (c - '0') * 10; - c = *s++; - i--; - if (ISDIGIT(c)) { - cmd += (c - '0'); - c = *s++; - i--; - if ((c != '-') && (c != ' ')) - goto bad_server_command; - } else - goto bad_server_command; - } else - goto bad_server_command; - } else { -bad_server_command: - if (ippr_ftp_debug > 3) - printf("%s:bad:junk %d len %d/%d c 0x%x buf [%*.*s]\n", - "ippr_ftp_server_valid", - ftps->ftps_junk, (int)len, (int)i, - c, (int)len, (int)len, buf); - return 1; - } -search_eol: - for (; i; i--) { - pc = c; - c = *s++; - if ((pc == '\r') && (c == '\n')) { - ftps->ftps_cmds = cmd; - return 0; - } - } - if (ippr_ftp_debug > 3) - printf("ippr_ftp_server_valid:junk after cmd[%*.*s]\n", - (int)len, (int)len, buf); - return 2; -} - - -int ippr_ftp_valid(ftp, side, buf, len) -ftpinfo_t *ftp; -int side; -char *buf; -size_t len; -{ - ftpside_t *ftps; - int ret; - - ftps = &ftp->ftp_side[side]; - - if (side == 0) - ret = ippr_ftp_client_valid(ftps, buf, len); - else - ret = ippr_ftp_server_valid(ftps, buf, len); - return ret; -} - - -/* - * For map rules, the following applies: - * rv == 0 for outbound processing, - * rv == 1 for inbound processing. - * For rdr rules, the following applies: - * rv == 0 for inbound processing, - * rv == 1 for outbound processing. - */ -int ippr_ftp_process(fin, nat, ftp, rv) -fr_info_t *fin; -nat_t *nat; -ftpinfo_t *ftp; -int rv; -{ - int mlen, len, off, inc, i, sel, sel2, ok, ackoff, seqoff; - char *rptr, *wptr, *s; - u_32_t thseq, thack; - ap_session_t *aps; - ftpside_t *f, *t; - tcphdr_t *tcp; - ip_t *ip; - mb_t *m; - - m = fin->fin_m; - ip = fin->fin_ip; - tcp = (tcphdr_t *)fin->fin_dp; - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - - f = &ftp->ftp_side[rv]; - t = &ftp->ftp_side[1 - rv]; - thseq = ntohl(tcp->th_seq); - thack = ntohl(tcp->th_ack); - -#ifdef __sgi - mlen = fin->fin_plen - off; -#else - mlen = MSGDSIZE(m) - off; -#endif - if (ippr_ftp_debug > 4) - printf("ippr_ftp_process: mlen %d\n", mlen); - - if (mlen <= 0) { - if ((tcp->th_flags & TH_OPENING) == TH_OPENING) { - f->ftps_seq[0] = thseq + 1; - t->ftps_seq[0] = thack; - } - return 0; - } - aps = nat->nat_aps; - - sel = aps->aps_sel[1 - rv]; - sel2 = aps->aps_sel[rv]; - if (rv == 0) { - seqoff = aps->aps_seqoff[sel]; - if (aps->aps_seqmin[sel] > seqoff + thseq) - seqoff = aps->aps_seqoff[!sel]; - ackoff = aps->aps_ackoff[sel2]; - if (aps->aps_ackmin[sel2] > ackoff + thack) - ackoff = aps->aps_ackoff[!sel2]; - } else { - seqoff = aps->aps_ackoff[sel]; - if (ippr_ftp_debug > 2) - printf("seqoff %d thseq %x ackmin %x\n", seqoff, thseq, - aps->aps_ackmin[sel]); - if (aps->aps_ackmin[sel] > seqoff + thseq) - seqoff = aps->aps_ackoff[!sel]; - - ackoff = aps->aps_seqoff[sel2]; - if (ippr_ftp_debug > 2) - printf("ackoff %d thack %x seqmin %x\n", ackoff, thack, - aps->aps_seqmin[sel2]); - if (ackoff > 0) { - if (aps->aps_seqmin[sel2] > ackoff + thack) - ackoff = aps->aps_seqoff[!sel2]; - } else { - if (aps->aps_seqmin[sel2] > thack) - ackoff = aps->aps_seqoff[!sel2]; - } - } - if (ippr_ftp_debug > 2) { - printf("%s: %x seq %x/%d ack %x/%d len %d/%d off %d\n", - rv ? "IN" : "OUT", tcp->th_flags, thseq, seqoff, - thack, ackoff, mlen, fin->fin_plen, off); - printf("sel %d seqmin %x/%x offset %d/%d\n", sel, - aps->aps_seqmin[sel], aps->aps_seqmin[sel2], - aps->aps_seqoff[sel], aps->aps_seqoff[sel2]); - printf("sel %d ackmin %x/%x offset %d/%d\n", sel2, - aps->aps_ackmin[sel], aps->aps_ackmin[sel2], - aps->aps_ackoff[sel], aps->aps_ackoff[sel2]); - } - - /* - * XXX - Ideally, this packet should get dropped because we now know - * that it is out of order (and there is no real danger in doing so - * apart from causing packets to go through here ordered). - */ - if (ippr_ftp_debug > 2) { - printf("rv %d t:seq[0] %x seq[1] %x %d/%d\n", - rv, t->ftps_seq[0], t->ftps_seq[1], seqoff, ackoff); - } - - ok = 0; - if (t->ftps_seq[0] == 0) { - t->ftps_seq[0] = thack; - ok = 1; - } else { - if (ackoff == 0) { - if (t->ftps_seq[0] == thack) - ok = 1; - else if (t->ftps_seq[1] == thack) { - t->ftps_seq[0] = thack; - ok = 1; - } - } else { - if (t->ftps_seq[0] + ackoff == thack) - ok = 1; - else if (t->ftps_seq[0] == thack + ackoff) - ok = 1; - else if (t->ftps_seq[1] + ackoff == thack) { - t->ftps_seq[0] = thack - ackoff; - ok = 1; - } else if (t->ftps_seq[1] == thack + ackoff) { - t->ftps_seq[0] = thack - ackoff; - ok = 1; - } - } - } - - if (ippr_ftp_debug > 2) { - if (!ok) - printf("%s ok\n", "not"); - } - - if (!mlen) { - if (t->ftps_seq[0] + ackoff != thack) { - if (ippr_ftp_debug > 1) { - printf("%s:seq[0](%x) + (%x) != (%x)\n", - "ippr_ftp_process", t->ftps_seq[0], - ackoff, thack); - } - return APR_ERR(1); - } - - if (ippr_ftp_debug > 2) { - printf("ippr_ftp_process:f:seq[0] %x seq[1] %x\n", - f->ftps_seq[0], f->ftps_seq[1]); - } - - if (tcp->th_flags & TH_FIN) { - if (thseq == f->ftps_seq[1]) { - f->ftps_seq[0] = f->ftps_seq[1] - seqoff; - f->ftps_seq[1] = thseq + 1 - seqoff; - } else { - if (ippr_ftp_debug > 1) { - printf("FIN: thseq %x seqoff %d ftps_seq %x\n", - thseq, seqoff, f->ftps_seq[0]); - } - return APR_ERR(1); - } - } - f->ftps_len = 0; - return 0; - } - - ok = 0; - if ((thseq == f->ftps_seq[0]) || (thseq == f->ftps_seq[1])) { - ok = 1; - /* - * Retransmitted data packet. - */ - } else if ((thseq + mlen == f->ftps_seq[0]) || - (thseq + mlen == f->ftps_seq[1])) { - ok = 1; - } - - if (ok == 0) { - inc = thseq - f->ftps_seq[0]; - if (ippr_ftp_debug > 1) { - printf("inc %d sel %d rv %d\n", inc, sel, rv); - printf("th_seq %x ftps_seq %x/%x\n", - thseq, f->ftps_seq[0], f->ftps_seq[1]); - printf("ackmin %x ackoff %d\n", aps->aps_ackmin[sel], - aps->aps_ackoff[sel]); - printf("seqmin %x seqoff %d\n", aps->aps_seqmin[sel], - aps->aps_seqoff[sel]); - } - - return APR_ERR(1); - } - - inc = 0; - rptr = f->ftps_rptr; - wptr = f->ftps_wptr; - f->ftps_seq[0] = thseq; - f->ftps_seq[1] = f->ftps_seq[0] + mlen; - f->ftps_len = mlen; - - while (mlen > 0) { - len = MIN(mlen, sizeof(f->ftps_buf) - (wptr - rptr)); - COPYDATA(m, off, len, wptr); - mlen -= len; - off += len; - wptr += len; - - if (ippr_ftp_debug > 3) - printf("%s:len %d/%d off %d wptr %lx junk %d [%*.*s]\n", - "ippr_ftp_process", - len, mlen, off, (u_long)wptr, f->ftps_junk, - len, len, rptr); - - f->ftps_wptr = wptr; - if (f->ftps_junk != 0) { - i = f->ftps_junk; - f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, - wptr - rptr); - - if (ippr_ftp_debug > 5) - printf("%s:junk %d -> %d\n", - "ippr_ftp_process", i, f->ftps_junk); - - if (f->ftps_junk != 0) { - if (wptr - rptr == sizeof(f->ftps_buf)) { - if (ippr_ftp_debug > 4) - printf("%s:full buffer\n", - "ippr_ftp_process"); - f->ftps_rptr = f->ftps_buf; - f->ftps_wptr = f->ftps_buf; - rptr = f->ftps_rptr; - wptr = f->ftps_wptr; - /* - * Because we throw away data here that - * we would otherwise parse, set the - * junk flag to indicate just ignore - * any data upto the next CRLF. - */ - f->ftps_junk = 1; - continue; - } - } - } - - while ((f->ftps_junk == 0) && (wptr > rptr)) { - len = wptr - rptr; - f->ftps_junk = ippr_ftp_valid(ftp, rv, rptr, len); - - if (ippr_ftp_debug > 3) { - printf("%s=%d len %d rv %d ptr %lx/%lx ", - "ippr_ftp_valid", - f->ftps_junk, len, rv, (u_long)rptr, - (u_long)wptr); - printf("buf [%*.*s]\n", len, len, rptr); - } - - if (f->ftps_junk == 0) { - f->ftps_rptr = rptr; - if (rv) - inc += ippr_ftp_server(fin, ip, nat, - ftp, len); - else - inc += ippr_ftp_client(fin, ip, nat, - ftp, len); - rptr = f->ftps_rptr; - wptr = f->ftps_wptr; - } - } - - /* - * Off to a bad start so lets just forget about using the - * ftp proxy for this connection. - */ - if ((f->ftps_cmds == 0) && (f->ftps_junk == 1)) { - /* f->ftps_seq[1] += inc; */ - - if (ippr_ftp_debug > 1) - printf("%s:cmds == 0 junk == 1\n", - "ippr_ftp_process"); - return APR_ERR(2); - } - - if ((f->ftps_junk != 0) && (rptr < wptr)) { - for (s = rptr; s < wptr; s++) { - if ((*s == '\r') && (s + 1 < wptr) && - (*(s + 1) == '\n')) { - rptr = s + 2; - f->ftps_junk = 0; - break; - } - } - } - - if (rptr == wptr) { - rptr = wptr = f->ftps_buf; - } else { - /* - * Compact the buffer back to the start. The junk - * flag should already be set and because we're not - * throwing away any data, it is preserved from its - * current state. - */ - if (rptr > f->ftps_buf) { - bcopy(rptr, f->ftps_buf, len); - wptr -= rptr - f->ftps_buf; - rptr = f->ftps_buf; - } - } - f->ftps_rptr = rptr; - f->ftps_wptr = wptr; - } - - /* f->ftps_seq[1] += inc; */ - if (tcp->th_flags & TH_FIN) - f->ftps_seq[1]++; - if (ippr_ftp_debug > 3) { -#ifdef __sgi - mlen = fin->fin_plen; -#else - mlen = MSGDSIZE(m); -#endif - mlen -= off; - printf("ftps_seq[1] = %x inc %d len %d\n", - f->ftps_seq[1], inc, mlen); - } - - f->ftps_rptr = rptr; - f->ftps_wptr = wptr; - return APR_INC(inc); -} - - -int ippr_ftp_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ftpinfo_t *ftp; - int rev; - - ftp = aps->aps_data; - if (ftp == NULL) - return 0; - - rev = (nat->nat_dir == NAT_OUTBOUND) ? 0 : 1; - if (ftp->ftp_side[1 - rev].ftps_ifp == NULL) - ftp->ftp_side[1 - rev].ftps_ifp = fin->fin_ifp; - - return ippr_ftp_process(fin, nat, ftp, rev); -} - - -int ippr_ftp_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ftpinfo_t *ftp; - int rev; - - ftp = aps->aps_data; - if (ftp == NULL) - return 0; - - rev = (nat->nat_dir == NAT_OUTBOUND) ? 0 : 1; - if (ftp->ftp_side[rev].ftps_ifp == NULL) - ftp->ftp_side[rev].ftps_ifp = fin->fin_ifp; - - return ippr_ftp_process(fin, nat, ftp, 1 - rev); -} - - -/* - * ippr_ftp_atoi - implement a version of atoi which processes numbers in - * pairs separated by commas (which are expected to be in the range 0 - 255), - * returning a 16 bit number combining either side of the , as the MSB and - * LSB. - */ -u_short ippr_ftp_atoi(ptr) -char **ptr; -{ - register char *s = *ptr, c; - register u_char i = 0, j = 0; - - while (((c = *s++) != '\0') && ISDIGIT(c)) { - i *= 10; - i += c - '0'; - } - if (c != ',') { - *ptr = NULL; - return 0; - } - while (((c = *s++) != '\0') && ISDIGIT(c)) { - j *= 10; - j += c - '0'; - } - *ptr = s; - i &= 0xff; - j &= 0xff; - return (i << 8) | j; -} - - -int ippr_ftp_epsv(fin, ip, nat, f, dlen) -fr_info_t *fin; -ip_t *ip; -nat_t *nat; -ftpside_t *f; -int dlen; -{ - char newbuf[IPF_FTPBUFSZ]; - char *s; - u_short ap = 0; - -#define EPSV_REPLEN 33 - /* - * Check for EPSV reply message. - */ - if (dlen < IPF_MIN229LEN) - return (0); - else if (strncmp(f->ftps_rptr, - "229 Entering Extended Passive Mode", EPSV_REPLEN)) - return (0); - - /* - * Skip the EPSV command + space - */ - s = f->ftps_rptr + 33; - while (*s && !ISDIGIT(*s)) - s++; - - /* - * As per RFC 2428, there are no addres components in the EPSV - * response. So we'll go straight to getting the port. - */ - while (*s && ISDIGIT(*s)) { - ap *= 10; - ap += *s++ - '0'; - } - - if (!s) - return 0; - - if (*s == '|') - s++; - if (*s == ')') - s++; - if (*s == '\n') - s--; - /* - * check for CR-LF at the end. - */ - if ((*s == '\r') && (*(s + 1) == '\n')) { - s += 2; - } else - return 0; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(newbuf, sizeof(newbuf), "%s (|||%u|)\r\n", - "229 Entering Extended Passive Mode", ap); -#else - (void) sprintf(newbuf, "%s (|||%u|)\r\n", - "229 Entering Extended Passive Mode", ap); -#endif - - return ippr_ftp_pasvreply(fin, ip, nat, f, (u_int)ap, newbuf, s, - ip->ip_src.s_addr); -} diff --git a/contrib/ipfilter/ip_h323_pxy.c b/contrib/ipfilter/ip_h323_pxy.c deleted file mode 100644 index b6e7c7bf34e8..000000000000 --- a/contrib/ipfilter/ip_h323_pxy.c +++ /dev/null @@ -1,296 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright 2001, QNX Software Systems Ltd. All Rights Reserved - * - * This source code has been published by QNX Software Systems Ltd. (QSSL). - * However, any use, reproduction, modification, distribution or transfer of - * this software, or any software which includes or is based upon any of this - * code, is only permitted under the terms of the QNX Open Community License - * version 1.0 (see licensing.qnx.com for details) or as otherwise expressly - * authorized by a written license agreement from QSSL. For more information, - * please email licensing@qnx.com. - * - * For more details, see QNX_OCL.txt provided with this distribution. - */ - -/* - * Simple H.323 proxy - * - * by xtang@canada.com - * ported to ipfilter 3.4.20 by Michael Grant mg-ipf@grant.org - */ - -#if __FreeBSD_version >= 220000 && defined(_KERNEL) -# include -# include -#else -# ifndef linux -# include -# endif -#endif - -#define IPF_H323_PROXY - -int ippr_h323_init __P((void)); -void ippr_h323_fini __P((void)); -int ippr_h323_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_h323_del __P((ap_session_t *)); -int ippr_h323_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_h323_in __P((fr_info_t *, ap_session_t *, nat_t *)); - -int ippr_h245_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_h245_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_h245_in __P((fr_info_t *, ap_session_t *, nat_t *)); - -static frentry_t h323_fr; - -int h323_proxy_init = 0; - -static int find_port __P((int, caddr_t, int datlen, int *, u_short *)); - - -static int find_port(ipaddr, data, datlen, off, port) -int ipaddr; -caddr_t data; -int datlen, *off; -unsigned short *port; -{ - u_32_t addr, netaddr; - u_char *dp; - int offset; - - if (datlen < 6) - return -1; - - *port = 0; - offset = *off; - dp = (u_char *)data; - netaddr = ntohl(ipaddr); - - for (offset = 0; offset <= datlen - 6; offset++, dp++) { - addr = (dp[0] << 24) | (dp[1] << 16) | (dp[2] << 8) | dp[3]; - if (netaddr == addr) - { - *port = (*(dp + 4) << 8) | *(dp + 5); - break; - } - } - *off = offset; - return (offset > datlen - 6) ? -1 : 0; -} - -/* - * Initialize local structures. - */ -int ippr_h323_init() -{ - bzero((char *)&h323_fr, sizeof(h323_fr)); - h323_fr.fr_ref = 1; - h323_fr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&h323_fr.fr_lock, "H323 proxy rule lock"); - h323_proxy_init = 1; - - return 0; -} - - -void ippr_h323_fini() -{ - if (h323_proxy_init == 1) { - MUTEX_DESTROY(&h323_fr.fr_lock); - h323_proxy_init = 0; - } -} - - -int ippr_h323_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - aps->aps_data = NULL; - aps->aps_psiz = 0; - - return 0; -} - - -void ippr_h323_del(aps) -ap_session_t *aps; -{ - int i; - ipnat_t *ipn; - - if (aps->aps_data) { - for (i = 0, ipn = aps->aps_data; - i < (aps->aps_psiz / sizeof(ipnat_t)); - i++, ipn = (ipnat_t *)((char *)ipn + sizeof(*ipn))) - { - /* - * Check the comment in ippr_h323_in() function, - * just above fr_nat_ioctl() call. - * We are lucky here because this function is not - * called with ipf_nat locked. - */ - if (fr_nat_ioctl((caddr_t)ipn, SIOCRMNAT, NAT_SYSSPACE| - NAT_LOCKHELD|FWRITE) == -1) { - /*EMPTY*/; - /* log the error */ - } - } - KFREES(aps->aps_data, aps->aps_psiz); - /* avoid double free */ - aps->aps_data = NULL; - aps->aps_psiz = 0; - } - return; -} - - -int ippr_h323_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - int ipaddr, off, datlen; - unsigned short port; - caddr_t data; - tcphdr_t *tcp; - ip_t *ip; - - ip = fin->fin_ip; - tcp = (tcphdr_t *)fin->fin_dp; - ipaddr = ip->ip_src.s_addr; - - data = (caddr_t)tcp + (TCP_OFF(tcp) << 2); - datlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); - if (find_port(ipaddr, data, datlen, &off, &port) == 0) { - ipnat_t *ipn; - char *newarray; - - /* setup a nat rule to set a h245 proxy on tcp-port "port" - * it's like: - * map / -> / proxy port /tcp - */ - KMALLOCS(newarray, char *, aps->aps_psiz + sizeof(*ipn)); - if (newarray == NULL) { - return -1; - } - ipn = (ipnat_t *)&newarray[aps->aps_psiz]; - bcopy((caddr_t)nat->nat_ptr, (caddr_t)ipn, sizeof(ipnat_t)); - (void) strncpy(ipn->in_plabel, "h245", APR_LABELLEN); - - ipn->in_inip = nat->nat_inip.s_addr; - ipn->in_inmsk = 0xffffffff; - ipn->in_dport = htons(port); - /* - * we got a problem here. we need to call fr_nat_ioctl() to add - * the h245 proxy rule, but since we already hold (READ locked) - * the nat table rwlock (ipf_nat), if we go into fr_nat_ioctl(), - * it will try to WRITE lock it. This will causing dead lock - * on RTP. - * - * The quick & dirty solution here is release the read lock, - * call fr_nat_ioctl() and re-lock it. - * A (maybe better) solution is do a UPGRADE(), and instead - * of calling fr_nat_ioctl(), we add the nat rule ourself. - */ - RWLOCK_EXIT(&ipf_nat); - if (fr_nat_ioctl((caddr_t)ipn, SIOCADNAT, - NAT_SYSSPACE|FWRITE) == -1) { - READ_ENTER(&ipf_nat); - return -1; - } - READ_ENTER(&ipf_nat); - if (aps->aps_data != NULL && aps->aps_psiz > 0) { - bcopy(aps->aps_data, newarray, aps->aps_psiz); - KFREES(aps->aps_data, aps->aps_psiz); - } - aps->aps_data = newarray; - aps->aps_psiz += sizeof(*ipn); - } - return 0; -} - - -int ippr_h245_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - aps->aps_data = NULL; - aps->aps_psiz = 0; - return 0; -} - - -int ippr_h245_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - int ipaddr, off, datlen; - tcphdr_t *tcp; - caddr_t data; - u_short port; - ip_t *ip; - - aps = aps; /* LINT */ - - ip = fin->fin_ip; - tcp = (tcphdr_t *)fin->fin_dp; - ipaddr = nat->nat_inip.s_addr; - data = (caddr_t)tcp + (TCP_OFF(tcp) << 2); - datlen = ip->ip_len - fin->fin_hlen - (TCP_OFF(tcp) << 2); - if (find_port(ipaddr, data, datlen, &off, &port) == 0) { - fr_info_t fi; - nat_t *nat2; - -/* port = htons(port); */ - nat2 = nat_outlookup(fin->fin_ifp, IPN_UDP, IPPROTO_UDP, - ip->ip_src, ip->ip_dst); - if (nat2 == NULL) { - struct ip newip; - struct udphdr udp; - - bcopy((caddr_t)ip, (caddr_t)&newip, sizeof(newip)); - newip.ip_len = fin->fin_hlen + sizeof(udp); - newip.ip_p = IPPROTO_UDP; - newip.ip_src = nat->nat_inip; - - bzero((char *)&udp, sizeof(udp)); - udp.uh_sport = port; - - bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); - fi.fin_fi.fi_p = IPPROTO_UDP; - fi.fin_data[0] = port; - fi.fin_data[1] = 0; - fi.fin_dp = (char *)&udp; - - nat2 = nat_new(&fi, nat->nat_ptr, NULL, - NAT_SLAVE|IPN_UDP|SI_W_DPORT, - NAT_OUTBOUND); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_UDP); - nat_update(&fi, nat2, nat2->nat_ptr); - - nat2->nat_ptr->in_hits++; -#ifdef IPFILTER_LOG - nat_log(nat2, (u_int)(nat->nat_ptr->in_redir)); -#endif - bcopy((caddr_t)&ip->ip_src.s_addr, - data + off, 4); - bcopy((caddr_t)&nat2->nat_outport, - data + off + 4, 2); - } - } - } - return 0; -} diff --git a/contrib/ipfilter/ip_htable.c b/contrib/ipfilter/ip_htable.c deleted file mode 100644 index 50aa92627b29..000000000000 --- a/contrib/ipfilter/ip_htable.c +++ /dev/null @@ -1,455 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#include -#if !defined(_KERNEL) -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#include -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include -#endif -#if defined(__FreeBSD__) -# include -# include -#endif -#if !defined(__svr4__) && !defined(__SVR4) && !defined(__hpux) && \ - !defined(linux) -# include -#endif -#if defined(_KERNEL) -# include -#else -# include -#endif -#include -#include - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_lookup.h" -#include "netinet/ip_htable.h" -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_htable.c,v 2.34.2.2 2004/10/17 15:49:15 darrenr Exp"; -#endif - -#ifdef IPFILTER_LOOKUP -static iphtent_t *fr_iphmfind __P((iphtable_t *, struct in_addr *)); -static u_long ipht_nomem[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static u_long ipf_nhtables[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; -static u_long ipf_nhtnodes[IPL_LOGSIZE] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -iphtable_t *ipf_htables[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL }; - - -void fr_htable_unload() -{ - iplookupflush_t fop; - - fop.iplf_unit = IPL_LOGALL; - (void)fr_flushhtable(&fop); -} - - -int fr_gethtablestat(op) -iplookupop_t *op; -{ - iphtstat_t stats; - - if (op->iplo_size != sizeof(stats)) - return EINVAL; - - stats.iphs_tables = ipf_htables[op->iplo_unit]; - stats.iphs_numtables = ipf_nhtables[op->iplo_unit]; - stats.iphs_numnodes = ipf_nhtnodes[op->iplo_unit]; - stats.iphs_nomem = ipht_nomem[op->iplo_unit]; - - return COPYOUT(&stats, op->iplo_struct, sizeof(stats)); - -} - - -/* - * Create a new hash table using the template passed. - */ -int fr_newhtable(op) -iplookupop_t *op; -{ - iphtable_t *iph, *oiph; - char name[FR_GROUPLEN]; - int err, i, unit; - - KMALLOC(iph, iphtable_t *); - if (iph == NULL) - return ENOMEM; - - err = COPYIN(op->iplo_struct, iph, sizeof(*iph)); - if (err != 0) { - KFREE(iph); - return EFAULT; - } - - unit = op->iplo_unit; - if (iph->iph_unit != unit) { - KFREE(iph); - return EINVAL; - } - - if ((op->iplo_arg & IPHASH_ANON) == 0) { - if (fr_findhtable(op->iplo_unit, op->iplo_name) != NULL) { - KFREE(iph); - return EEXIST; - } - } else { - i = IPHASH_ANON; - do { - i++; -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%u", i); -#else - (void)sprintf(name, "%u", i); -#endif - for (oiph = ipf_htables[unit]; oiph != NULL; - oiph = oiph->iph_next) - if (strncmp(oiph->iph_name, name, - sizeof(oiph->iph_name)) == 0) - break; - } while (oiph != NULL); - (void)strncpy(iph->iph_name, name, sizeof(iph->iph_name)); - err = COPYOUT(iph, op->iplo_struct, sizeof(*iph)); - if (err != 0) { - KFREE(iph); - return EFAULT; - } - iph->iph_type |= IPHASH_ANON; - } - - KMALLOCS(iph->iph_table, iphtent_t **, - iph->iph_size * sizeof(*iph->iph_table)); - if (iph->iph_table == NULL) { - KFREE(iph); - ipht_nomem[unit]++; - return ENOMEM; - } - - bzero((char *)iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); - iph->iph_masks = 0; - - iph->iph_next = ipf_htables[unit]; - iph->iph_pnext = &ipf_htables[unit]; - if (ipf_htables[unit] != NULL) - ipf_htables[unit]->iph_pnext = &iph->iph_next; - ipf_htables[unit] = iph; - - ipf_nhtables[unit]++; - - return 0; -} - - -/* - */ -int fr_removehtable(op) -iplookupop_t *op; -{ - iphtable_t *iph; - - - iph = fr_findhtable(op->iplo_unit, op->iplo_name); - if (iph == NULL) - return ESRCH; - - if (iph->iph_unit != op->iplo_unit) { - return EINVAL; - } - - if (iph->iph_ref != 0) { - return EBUSY; - } - - fr_delhtable(iph); - - return 0; -} - - -void fr_delhtable(iph) -iphtable_t *iph; -{ - iphtent_t *ipe; - int i; - - for (i = 0; i < iph->iph_size; i++) - while ((ipe = iph->iph_table[i]) != NULL) - if (fr_delhtent(iph, ipe) != 0) - return; - - *iph->iph_pnext = iph->iph_next; - if (iph->iph_next != NULL) - iph->iph_next->iph_pnext = iph->iph_pnext; - - ipf_nhtables[iph->iph_unit]--; - - if (iph->iph_ref == 0) { - KFREES(iph->iph_table, iph->iph_size * sizeof(*iph->iph_table)); - KFREE(iph); - } -} - - -void fr_derefhtable(iph) -iphtable_t *iph; -{ - iph->iph_ref--; - if (iph->iph_ref == 0) - fr_delhtable(iph); -} - - -iphtable_t *fr_findhtable(unit, name) -int unit; -char *name; -{ - iphtable_t *iph; - - for (iph = ipf_htables[unit]; iph != NULL; iph = iph->iph_next) - if (strncmp(iph->iph_name, name, sizeof(iph->iph_name)) == 0) - break; - return iph; -} - - -size_t fr_flushhtable(op) -iplookupflush_t *op; -{ - iphtable_t *iph; - size_t freed; - int i; - - freed = 0; - - for (i = 0; i <= IPL_LOGMAX; i++) { - if (op->iplf_unit == i || op->iplf_unit == IPL_LOGALL) { - while ((iph = ipf_htables[i]) != NULL) { - fr_delhtable(iph); - freed++; - } - } - } - - return freed; -} - - -/* - * Add an entry to a hash table. - */ -int fr_addhtent(iph, ipeo) -iphtable_t *iph; -iphtent_t *ipeo; -{ - iphtent_t *ipe; - u_int hv; - int bits; - - KMALLOC(ipe, iphtent_t *); - if (ipe == NULL) - return -1; - - bcopy((char *)ipeo, (char *)ipe, sizeof(*ipe)); - ipe->ipe_addr.in4_addr &= ipe->ipe_mask.in4_addr; - ipe->ipe_addr.in4_addr = ntohl(ipe->ipe_addr.in4_addr); - bits = count4bits(ipe->ipe_mask.in4_addr); - ipe->ipe_mask.in4_addr = ntohl(ipe->ipe_mask.in4_addr); - - hv = IPE_HASH_FN(ipe->ipe_addr.in4_addr, ipe->ipe_mask.in4_addr, - iph->iph_size); - ipe->ipe_ref = 0; - ipe->ipe_next = iph->iph_table[hv]; - ipe->ipe_pnext = iph->iph_table + hv; - - if (iph->iph_table[hv] != NULL) - iph->iph_table[hv]->ipe_pnext = &ipe->ipe_next; - iph->iph_table[hv] = ipe; - if ((bits >= 0) && (bits != 32)) - iph->iph_masks |= 1 << bits; - - switch (iph->iph_type & ~IPHASH_ANON) - { - case IPHASH_GROUPMAP : - ipe->ipe_ptr = fr_addgroup(ipe->ipe_group, NULL, - iph->iph_flags, IPL_LOGIPF, - fr_active); - break; - - default : - ipe->ipe_ptr = NULL; - ipe->ipe_value = 0; - break; - } - - ipf_nhtnodes[iph->iph_unit]++; - - return 0; -} - - -/* - * Delete an entry from a hash table. - */ -int fr_delhtent(iph, ipe) -iphtable_t *iph; -iphtent_t *ipe; -{ - - if (ipe->ipe_ref != 0) - return EBUSY; - - - *ipe->ipe_pnext = ipe->ipe_next; - if (ipe->ipe_next != NULL) - ipe->ipe_next->ipe_pnext = ipe->ipe_pnext; - - switch (iph->iph_type & ~IPHASH_ANON) - { - case IPHASH_GROUPMAP : - if (ipe->ipe_group != NULL) - fr_delgroup(ipe->ipe_group, IPL_LOGIPF, fr_active); - break; - - default : - ipe->ipe_ptr = NULL; - ipe->ipe_value = 0; - break; - } - - KFREE(ipe); - - ipf_nhtnodes[iph->iph_unit]--; - - return 0; -} - - -void *fr_iphmfindgroup(tptr, aptr) -void *tptr, *aptr; -{ - struct in_addr *addr; - iphtable_t *iph; - iphtent_t *ipe; - void *rval; - - READ_ENTER(&ip_poolrw); - iph = tptr; - addr = aptr; - - ipe = fr_iphmfind(iph, addr); - if (ipe != NULL) - rval = ipe->ipe_ptr; - else - rval = NULL; - RWLOCK_EXIT(&ip_poolrw); - return rval; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_iphmfindip */ -/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ -/* version(I) - IP protocol version (4 or 6) */ -/* aptr(I) - pointer to address information */ -/* */ -/* Search the hash table for a given address and return a search result. */ -/* ------------------------------------------------------------------------ */ -int fr_iphmfindip(tptr, version, aptr) -void *tptr, *aptr; -int version; -{ - struct in_addr *addr; - iphtable_t *iph; - iphtent_t *ipe; - int rval; - - if (version != 4) - return -1; - - if (tptr == NULL || aptr == NULL) - return -1; - - iph = tptr; - addr = aptr; - - READ_ENTER(&ip_poolrw); - ipe = fr_iphmfind(iph, addr); - if (ipe != NULL) - rval = 0; - else - rval = 1; - RWLOCK_EXIT(&ip_poolrw); - return rval; -} - - -/* Locks: ip_poolrw */ -static iphtent_t *fr_iphmfind(iph, addr) -iphtable_t *iph; -struct in_addr *addr; -{ - u_32_t hmsk, msk, ips; - iphtent_t *ipe; - u_int hv; - - hmsk = iph->iph_masks; - msk = 0xffffffff; -maskloop: - ips = ntohl(addr->s_addr) & msk; - hv = IPE_HASH_FN(ips, msk, iph->iph_size); - for (ipe = iph->iph_table[hv]; (ipe != NULL); ipe = ipe->ipe_next) { - if (ipe->ipe_mask.in4_addr != msk || - ipe->ipe_addr.in4_addr != ips) { - continue; - } - break; - } - - if ((ipe == NULL) && (hmsk != 0)) { - while (hmsk != 0) { - msk <<= 1; - if (hmsk & 0x80000000) - break; - hmsk <<= 1; - } - if (hmsk != 0) { - hmsk <<= 1; - goto maskloop; - } - } - return ipe; -} - -#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_htable.h b/contrib/ipfilter/ip_htable.h deleted file mode 100644 index e13845977d09..000000000000 --- a/contrib/ipfilter/ip_htable.h +++ /dev/null @@ -1,71 +0,0 @@ -/* $NetBSD$ */ - -#ifndef __IP_HTABLE_H__ -#define __IP_HTABLE_H__ - -#include "netinet/ip_lookup.h" - -typedef struct iphtent_s { - struct iphtent_s *ipe_next, **ipe_pnext; - void *ipe_ptr; - i6addr_t ipe_addr; - i6addr_t ipe_mask; - int ipe_ref; - union { - char ipeu_char[16]; - u_long ipeu_long; - u_int ipeu_int; - }ipe_un; -} iphtent_t; - -#define ipe_value ipe_un.ipeu_int -#define ipe_group ipe_un.ipeu_char - -#define IPE_HASH_FN(a, m, s) (((a) * (m)) % (s)) - - -typedef struct iphtable_s { - ipfrwlock_t iph_rwlock; - struct iphtable_s *iph_next, **iph_pnext; - struct iphtent_s **iph_table; - size_t iph_size; /* size of hash table */ - u_long iph_seed; /* hashing seed */ - u_32_t iph_flags; - u_int iph_unit; /* IPL_LOG* */ - u_int iph_ref; - u_int iph_type; /* lookup or group map - IPHASH_* */ - u_int iph_masks; /* IPv4 netmasks in use */ - char iph_name[FR_GROUPLEN]; /* hash table number */ -} iphtable_t; - -/* iph_type */ -#define IPHASH_LOOKUP 0 -#define IPHASH_GROUPMAP 1 -#define IPHASH_ANON 0x80000000 - - -typedef struct iphtstat_s { - iphtable_t *iphs_tables; - u_long iphs_numtables; - u_long iphs_numnodes; - u_long iphs_nomem; - u_long iphs_pad[16]; -} iphtstat_t; - - -extern iphtable_t *ipf_htables[IPL_LOGSIZE]; - -extern void fr_htable_unload __P((void)); -extern int fr_newhtable __P((iplookupop_t *)); -extern iphtable_t *fr_findhtable __P((int, char *)); -extern int fr_removehtable __P((iplookupop_t *)); -extern size_t fr_flushhtable __P((iplookupflush_t *)); -extern int fr_addhtent __P((iphtable_t *, iphtent_t *)); -extern int fr_delhtent __P((iphtable_t *, iphtent_t *)); -extern void fr_derefhtable __P((iphtable_t *)); -extern void fr_delhtable __P((iphtable_t *)); -extern void *fr_iphmfindgroup __P((void *, void *)); -extern int fr_iphmfindip __P((void *, int, void *)); -extern int fr_gethtablestat __P((iplookupop_t *)); - -#endif /* __IP_HTABLE_H__ */ diff --git a/contrib/ipfilter/ip_ipsec_pxy.c b/contrib/ipfilter/ip_ipsec_pxy.c deleted file mode 100644 index 2159ecb08078..000000000000 --- a/contrib/ipfilter/ip_ipsec_pxy.c +++ /dev/null @@ -1,343 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2001-2003 by Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Simple ISAKMP transparent proxy for in-kernel use. For use with the NAT - * code. - * - * Id: ip_ipsec_pxy.c,v 2.20.2.6 2005/03/28 10:47:53 darrenr Exp - * - */ -#define IPF_IPSEC_PROXY - - -int ippr_ipsec_init __P((void)); -void ippr_ipsec_fini __P((void)); -int ippr_ipsec_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_ipsec_del __P((ap_session_t *)); -int ippr_ipsec_inout __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_ipsec_match __P((fr_info_t *, ap_session_t *, nat_t *)); - -static frentry_t ipsecfr; -static ipftq_t *ipsecnattqe; -static ipftq_t *ipsecstatetqe; -static char ipsec_buffer[1500]; - -int ipsec_proxy_init = 0; -int ipsec_proxy_ttl = 60; - -/* - * IPSec application proxy initialization. - */ -int ippr_ipsec_init() -{ - bzero((char *)&ipsecfr, sizeof(ipsecfr)); - ipsecfr.fr_ref = 1; - ipsecfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&ipsecfr.fr_lock, "IPsec proxy rule lock"); - ipsec_proxy_init = 1; - - ipsecnattqe = fr_addtimeoutqueue(&nat_utqe, ipsec_proxy_ttl); - if (ipsecnattqe == NULL) - return -1; - ipsecstatetqe = fr_addtimeoutqueue(&ips_utqe, ipsec_proxy_ttl); - if (ipsecstatetqe == NULL) { - if (fr_deletetimeoutqueue(ipsecnattqe) == 0) - fr_freetimeoutqueue(ipsecnattqe); - ipsecnattqe = NULL; - return -1; - } - - ipsecnattqe->ifq_flags |= IFQF_PROXY; - ipsecstatetqe->ifq_flags |= IFQF_PROXY; - - ipsecfr.fr_age[0] = ipsec_proxy_ttl; - ipsecfr.fr_age[1] = ipsec_proxy_ttl; - return 0; -} - - -void ippr_ipsec_fini() -{ - if (ipsecnattqe != NULL) { - if (fr_deletetimeoutqueue(ipsecnattqe) == 0) - fr_freetimeoutqueue(ipsecnattqe); - } - ipsecnattqe = NULL; - if (ipsecstatetqe != NULL) { - if (fr_deletetimeoutqueue(ipsecstatetqe) == 0) - fr_freetimeoutqueue(ipsecstatetqe); - } - ipsecstatetqe = NULL; - - if (ipsec_proxy_init == 1) { - MUTEX_DESTROY(&ipsecfr.fr_lock); - ipsec_proxy_init = 0; - } -} - - -/* - * Setup for a new IPSEC proxy. - */ -int ippr_ipsec_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ipsec_pxy_t *ipsec; - fr_info_t fi; - ipnat_t *ipn; - char *ptr; - int p, off, dlen, ttl; - mb_t *m; - ip_t *ip; - - bzero(ipsec_buffer, sizeof(ipsec_buffer)); - off = fin->fin_hlen + sizeof(udphdr_t); - ip = fin->fin_ip; - m = fin->fin_m; - - dlen = M_LEN(m) - off; - if (dlen < 16) - return -1; - COPYDATA(m, off, MIN(sizeof(ipsec_buffer), dlen), ipsec_buffer); - - if (nat_outlookup(fin, 0, IPPROTO_ESP, nat->nat_inip, - ip->ip_dst) != NULL) - return -1; - - aps->aps_psiz = sizeof(*ipsec); - KMALLOCS(aps->aps_data, ipsec_pxy_t *, sizeof(*ipsec)); - if (aps->aps_data == NULL) - return -1; - - ipsec = aps->aps_data; - bzero((char *)ipsec, sizeof(*ipsec)); - - /* - * Create NAT rule against which the tunnel/transport mapping is - * created. This is required because the current NAT rule does not - * describe ESP but UDP instead. - */ - ipn = &ipsec->ipsc_rule; - ttl = IPF_TTLVAL(ipsecnattqe->ifq_ttl); - ipn->in_tqehead[0] = fr_addtimeoutqueue(&nat_utqe, ttl); - ipn->in_tqehead[1] = fr_addtimeoutqueue(&nat_utqe, ttl); - ipn->in_ifps[0] = fin->fin_ifp; - ipn->in_apr = NULL; - ipn->in_use = 1; - ipn->in_hits = 1; - ipn->in_nip = ntohl(nat->nat_outip.s_addr); - ipn->in_ippip = 1; - ipn->in_inip = nat->nat_inip.s_addr; - ipn->in_inmsk = 0xffffffff; - ipn->in_outip = fin->fin_saddr; - ipn->in_outmsk = nat->nat_outip.s_addr; - ipn->in_srcip = fin->fin_saddr; - ipn->in_srcmsk = 0xffffffff; - ipn->in_redir = NAT_MAP; - bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0], - sizeof(ipn->in_ifnames[0])); - ipn->in_p = IPPROTO_ESP; - - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_fi.fi_p = IPPROTO_ESP; - fi.fin_fr = &ipsecfr; - fi.fin_data[0] = 0; - fi.fin_data[1] = 0; - p = ip->ip_p; - ip->ip_p = IPPROTO_ESP; - fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG); - fi.fin_flx |= FI_IGNORE; - - ptr = ipsec_buffer; - bcopy(ptr, (char *)ipsec->ipsc_icookie, sizeof(ipsec_cookie_t)); - ptr += sizeof(ipsec_cookie_t); - bcopy(ptr, (char *)ipsec->ipsc_rcookie, sizeof(ipsec_cookie_t)); - /* - * The responder cookie should only be non-zero if the initiator - * cookie is non-zero. Therefore, it is safe to assume(!) that the - * cookies are both set after copying if the responder is non-zero. - */ - if ((ipsec->ipsc_rcookie[0]|ipsec->ipsc_rcookie[1]) != 0) - ipsec->ipsc_rckset = 1; - - ipsec->ipsc_nat = nat_new(&fi, ipn, &ipsec->ipsc_nat, - NAT_SLAVE|SI_WILDP, NAT_OUTBOUND); - if (ipsec->ipsc_nat != NULL) { - (void) nat_proto(&fi, ipsec->ipsc_nat, 0); - nat_update(&fi, ipsec->ipsc_nat, ipn); - - fi.fin_data[0] = 0; - fi.fin_data[1] = 0; - ipsec->ipsc_state = fr_addstate(&fi, &ipsec->ipsc_state, - SI_WILDP); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_p = p & 0xff; - return 0; -} - - -/* - * For outgoing IKE packets. refresh timeouts for NAT & state entries, if - * we can. If they have disappeared, recreate them. - */ -int ippr_ipsec_inout(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ipsec_pxy_t *ipsec; - fr_info_t fi; - ip_t *ip; - int p; - - if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND)) - return 0; - - if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND)) - return 0; - - ipsec = aps->aps_data; - - if (ipsec != NULL) { - ip = fin->fin_ip; - p = ip->ip_p; - - if ((ipsec->ipsc_nat == NULL) || (ipsec->ipsc_state == NULL)) { - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_fi.fi_p = IPPROTO_ESP; - fi.fin_fr = &ipsecfr; - fi.fin_data[0] = 0; - fi.fin_data[1] = 0; - ip->ip_p = IPPROTO_ESP; - fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG); - fi.fin_flx |= FI_IGNORE; - } - - /* - * Update NAT timeout/create NAT if missing. - */ - if (ipsec->ipsc_nat != NULL) - fr_queueback(&ipsec->ipsc_nat->nat_tqe); - else { - ipsec->ipsc_nat = nat_new(&fi, &ipsec->ipsc_rule, - &ipsec->ipsc_nat, - NAT_SLAVE|SI_WILDP, - nat->nat_dir); - if (ipsec->ipsc_nat != NULL) { - (void) nat_proto(&fi, ipsec->ipsc_nat, 0); - nat_update(&fi, ipsec->ipsc_nat, - &ipsec->ipsc_rule); - } - } - - /* - * Update state timeout/create state if missing. - */ - READ_ENTER(&ipf_state); - if (ipsec->ipsc_state != NULL) { - fr_queueback(&ipsec->ipsc_state->is_sti); - ipsec->ipsc_state->is_die = nat->nat_age; - RWLOCK_EXIT(&ipf_state); - } else { - RWLOCK_EXIT(&ipf_state); - fi.fin_data[0] = 0; - fi.fin_data[1] = 0; - ipsec->ipsc_state = fr_addstate(&fi, - &ipsec->ipsc_state, - SI_WILDP); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_p = p; - } - return 0; -} - - -/* - * This extends the NAT matching to be based on the cookies associated with - * a session and found at the front of IKE packets. The cookies are always - * in the same order (not reversed depending on packet flow direction as with - * UDP/TCP port numbers). - */ -int ippr_ipsec_match(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ipsec_pxy_t *ipsec; - u_32_t cookies[4]; - mb_t *m; - int off; - - nat = nat; /* LINT */ - - if ((fin->fin_dlen < sizeof(cookies)) || (fin->fin_flx & FI_FRAG)) - return -1; - - ipsec = aps->aps_data; - off = fin->fin_hlen + sizeof(udphdr_t); - m = fin->fin_m; - COPYDATA(m, off, sizeof(cookies), (char *)cookies); - - if ((cookies[0] != ipsec->ipsc_icookie[0]) || - (cookies[1] != ipsec->ipsc_icookie[1])) - return -1; - - if (ipsec->ipsc_rckset == 0) { - if ((cookies[2]|cookies[3]) == 0) { - return 0; - } - ipsec->ipsc_rckset = 1; - ipsec->ipsc_rcookie[0] = cookies[2]; - ipsec->ipsc_rcookie[1] = cookies[3]; - return 0; - } - - if ((cookies[2] != ipsec->ipsc_rcookie[0]) || - (cookies[3] != ipsec->ipsc_rcookie[1])) - return -1; - return 0; -} - - -/* - * clean up after ourselves. - */ -void ippr_ipsec_del(aps) -ap_session_t *aps; -{ - ipsec_pxy_t *ipsec; - - ipsec = aps->aps_data; - - if (ipsec != NULL) { - /* - * Don't bother changing any of the NAT structure details, - * *_del() is on a callback from aps_free(), from nat_delete() - */ - - READ_ENTER(&ipf_state); - if (ipsec->ipsc_state != NULL) { - ipsec->ipsc_state->is_die = fr_ticks + 1; - ipsec->ipsc_state->is_me = NULL; - fr_queuefront(&ipsec->ipsc_state->is_sti); - } - RWLOCK_EXIT(&ipf_state); - - ipsec->ipsc_state = NULL; - ipsec->ipsc_nat = NULL; - } -} diff --git a/contrib/ipfilter/ip_irc_pxy.c b/contrib/ipfilter/ip_irc_pxy.c deleted file mode 100644 index 45a120f519b6..000000000000 --- a/contrib/ipfilter/ip_irc_pxy.c +++ /dev/null @@ -1,435 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2000-2003 Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_irc_pxy.c,v 2.39.2.4 2005/02/04 10:22:55 darrenr Exp - */ - -#define IPF_IRC_PROXY - -#define IPF_IRCBUFSZ 96 /* This *MUST* be >= 64! */ - - -int ippr_irc_init __P((void)); -void ippr_irc_fini __P((void)); -int ippr_irc_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_irc_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_irc_send __P((fr_info_t *, nat_t *)); -int ippr_irc_complete __P((ircinfo_t *, char *, size_t)); -u_short ipf_irc_atoi __P((char **)); - -static frentry_t ircnatfr; - -int irc_proxy_init = 0; - - -/* - * Initialize local structures. - */ -int ippr_irc_init() -{ - bzero((char *)&ircnatfr, sizeof(ircnatfr)); - ircnatfr.fr_ref = 1; - ircnatfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&ircnatfr.fr_lock, "IRC proxy rule lock"); - irc_proxy_init = 1; - - return 0; -} - - -void ippr_irc_fini() -{ - if (irc_proxy_init == 1) { - MUTEX_DESTROY(&ircnatfr.fr_lock); - irc_proxy_init = 0; - } -} - - -char *ippr_irc_dcctypes[] = { - "CHAT ", /* CHAT chat ipnumber portnumber */ - "SEND ", /* SEND filename ipnumber portnumber */ - "MOVE ", - "TSEND ", - "SCHAT ", - NULL, -}; - - -/* - * :A PRIVMSG B :^ADCC CHAT chat 0 0^A\r\n - * PRIVMSG B ^ADCC CHAT chat 0 0^A\r\n - */ - - -int ippr_irc_complete(ircp, buf, len) -ircinfo_t *ircp; -char *buf; -size_t len; -{ - register char *s, c; - register size_t i; - u_32_t l; - int j, k; - - ircp->irc_ipnum = 0; - ircp->irc_port = 0; - - if (len < 31) - return 0; - s = buf; - c = *s++; - i = len - 1; - - if ((c != ':') && (c != 'P')) - return 0; - - if (c == ':') { - /* - * Loosely check that the source is a nickname of some sort - */ - s++; - c = *s; - ircp->irc_snick = s; - if (!ISALPHA(c)) - return 0; - i--; - for (c = *s; !ISSPACE(c) && (i > 0); i--) - c = *s++; - if (i < 31) - return 0; - if (c != 'P') - return 0; - } else - ircp->irc_snick = NULL; - - /* - * Check command string - */ - if (strncmp(s, "PRIVMSG ", 8)) - return 0; - i -= 8; - s += 8; - c = *s; - ircp->irc_dnick = s; - - /* - * Loosely check that the destination is a nickname of some sort - */ - if (!ISALPHA(c)) - return 0; - for (; !ISSPACE(c) && (i > 0); i--) - c = *s++; - if (i < 20) - return 0; - s++, - i--; - - /* - * Look for a ^A to start the DCC - */ - c = *s; - if (c == ':') { - s++; - c = *s; - } - - if (strncmp(s, "\001DCC ", 4)) - return 0; - - i -= 4; - s += 4; - - /* - * Check for a recognised DCC command - */ - for (j = 0, k = 0; ippr_irc_dcctypes[j]; j++) { - k = MIN(strlen(ippr_irc_dcctypes[j]), i); - if (!strncmp(ippr_irc_dcctypes[j], s, k)) - break; - } - if (!ippr_irc_dcctypes[j]) - return 0; - - ircp->irc_type = s; - i -= k; - s += k; - - if (i < 11) - return 0; - - /* - * Check for the arg - */ - c = *s; - if (ISSPACE(c)) - return 0; - ircp->irc_arg = s; - for (; (c != ' ') && (c != '\001') && (i > 0); i--) - c = *s++; - - if (c == '\001') /* In reality a ^A can quote another ^A...*/ - return 0; - - if (i < 5) - return 0; - - s++; - i--; - c = *s; - if (!ISDIGIT(c)) - return 0; - ircp->irc_addr = s; - /* - * Get the IP# - */ - for (l = 0; ISDIGIT(c) && (i > 0); i--) { - l *= 10; - l += c - '0'; - c = *s++; - } - - if (i < 4) - return 0; - - if (c != ' ') - return 0; - - ircp->irc_ipnum = l; - s++; - i--; - c = *s; - if (!ISDIGIT(c)) - return 0; - /* - * Get the port# - */ - for (l = 0; ISDIGIT(c) && (i > 0); i--) { - l *= 10; - l += c - '0'; - c = *s++; - } - if (i < 3) - return 0; - if (strncmp(s, "\001\r\n", 3)) - return 0; - s += 3; - ircp->irc_len = s - buf; - ircp->irc_port = l; - return 1; -} - - -int ippr_irc_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - ircinfo_t *irc; - - KMALLOC(irc, ircinfo_t *); - if (irc == NULL) - return -1; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - aps->aps_data = irc; - aps->aps_psiz = sizeof(ircinfo_t); - - bzero((char *)irc, sizeof(*irc)); - return 0; -} - - -int ippr_irc_send(fin, nat) -fr_info_t *fin; -nat_t *nat; -{ - char ctcpbuf[IPF_IRCBUFSZ], newbuf[IPF_IRCBUFSZ]; - tcphdr_t *tcp, tcph, *tcp2 = &tcph; - int off, inc = 0, i, dlen; - size_t nlen = 0, olen; - struct in_addr swip; - u_short a5, sp; - ircinfo_t *irc; - fr_info_t fi; - nat_t *nat2; - u_int a1; - ip_t *ip; - mb_t *m; -#ifdef MENTAT - mb_t *m1; -#endif - - m = fin->fin_m; - ip = fin->fin_ip; - tcp = (tcphdr_t *)fin->fin_dp; - bzero(ctcpbuf, sizeof(ctcpbuf)); - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - -#ifdef __sgi - dlen = fin->fin_plen - off; -#else - dlen = MSGDSIZE(m) - off; -#endif - if (dlen <= 0) - return 0; - COPYDATA(m, off, MIN(sizeof(ctcpbuf), dlen), ctcpbuf); - - if (dlen <= 0) - return 0; - ctcpbuf[sizeof(ctcpbuf) - 1] = '\0'; - *newbuf = '\0'; - - irc = nat->nat_aps->aps_data; - if (ippr_irc_complete(irc, ctcpbuf, dlen) == 0) - return 0; - - /* - * check that IP address in the PORT/PASV reply is the same as the - * sender of the command - prevents using PORT for port scanning. - */ - if (irc->irc_ipnum != ntohl(nat->nat_inip.s_addr)) - return 0; - - a5 = irc->irc_port; - - /* - * Calculate new address parts for the DCC command - */ - a1 = ntohl(ip->ip_src.s_addr); - olen = irc->irc_len; - i = irc->irc_addr - ctcpbuf; - i++; - (void) strncpy(newbuf, ctcpbuf, i); - /* DO NOT change these! */ -#if defined(SNPRINTF) && defined(KERNEL) - SNPRINTF(newbuf, sizeof(newbuf) - i, "%u %u\001\r\n", a1, a5); -#else - (void) sprintf(newbuf, "%u %u\001\r\n", a1, a5); -#endif - - nlen = strlen(newbuf); - inc = nlen - olen; - - if ((inc + ip->ip_len) > 65535) - return 0; - -#ifdef MENTAT - for (m1 = m; m1->b_cont; m1 = m1->b_cont) - ; - if ((inc > 0) && (m1->b_datap->db_lim - m1->b_wptr < inc)) { - mblk_t *nm; - - /* alloc enough to keep same trailer space for lower driver */ - nm = allocb(nlen, BPRI_MED); - PANIC((!nm),("ippr_irc_out: allocb failed")); - - nm->b_band = m1->b_band; - nm->b_wptr += nlen; - - m1->b_wptr -= olen; - PANIC((m1->b_wptr < m1->b_rptr), - ("ippr_irc_out: cannot handle fragmented data block")); - - linkb(m1, nm); - } else { -# if SOLARIS && defined(ICK_VALID) - if (m1->b_datap->db_struiolim == m1->b_wptr) - m1->b_datap->db_struiolim += inc; - m1->b_datap->db_struioflag &= ~STRUIO_IP; -# endif - m1->b_wptr += inc; - } -#else - if (inc < 0) - m_adj(m, inc); - /* the mbuf chain will be extended if necessary by m_copyback() */ -#endif - COPYBACK(m, off, nlen, newbuf); - - if (inc != 0) { -#if defined(MENTAT) || defined(__sgi) - register u_32_t sum1, sum2; - - sum1 = ip->ip_len; - sum2 = ip->ip_len + inc; - - /* Because ~1 == -2, We really need ~1 == -1 */ - if (sum1 > sum2) - sum2--; - sum2 -= sum1; - sum2 = (sum2 & 0xffff) + (sum2 >> 16); - - fix_outcksum(fin, &ip->ip_sum, sum2); -#endif - ip->ip_len += inc; - } - - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - sp = htons(a5); - /* - * Don't allow the PORT command to specify a port < 1024 due to - * security crap. - */ - if (ntohs(sp) < 1024) - return 0; - - /* - * The server may not make the connection back from port 20, but - * it is the most likely so use it here to check for a conflicting - * mapping. - */ - bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); - fi.fin_data[0] = sp; - fi.fin_data[1] = fin->fin_data[1]; - nat2 = nat_outlookup(fin, IPN_TCP, nat->nat_p, nat->nat_inip, - ip->ip_dst); - if (nat2 == NULL) { - bcopy((caddr_t)fin, (caddr_t)&fi, sizeof(fi)); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = sp; - tcp2->th_dport = 0; /* XXX - don't specify remote port */ - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_data[0] = ntohs(sp); - fi.fin_data[1] = 0; - fi.fin_dp = (char *)tcp2; - fi.fin_fr = &ircnatfr; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - swip = ip->ip_src; - ip->ip_src = nat->nat_inip; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, - NAT_SLAVE|IPN_TCP|SI_W_DPORT, NAT_OUTBOUND); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, 0); - nat_update(&fi, nat2, nat2->nat_ptr); - - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_src = swip; - } - return inc; -} - - -int ippr_irc_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - aps = aps; /* LINT */ - return ippr_irc_send(fin, nat); -} diff --git a/contrib/ipfilter/ip_lfil.c b/contrib/ipfilter/ip_lfil.c deleted file mode 100644 index 196d64e0fedf..000000000000 --- a/contrib/ipfilter/ip_lfil.c +++ /dev/null @@ -1,975 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_lfil.c,v 2.6.2.5 2002/10/03 13:47:19 darrenr Exp $"; -#endif - -#if defined(KERNEL) && !defined(_KERNEL) -# define _KERNEL -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _KERNEL -# include -# include -# include -# include -#else -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _KERNEL -# include -#endif -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_proxy.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_auth.h" -#ifdef _KERNEL -#include -#endif -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - - -#ifndef _KERNEL -# include "ipt.h" -static struct ifnet **ifneta = NULL; -static int nifs = 0; -#endif - -int fr_running = 0; -int ipl_unreach = ICMP_UNREACH_FILTER; -u_long ipl_frouteok[2] = {0, 0}; - -static int frzerostats __P((caddr_t)); -static void frsync __P((void)); -#if defined(__NetBSD__) || defined(__OpenBSD__) -static int frrequest __P((int, u_long, caddr_t, int)); -#else -static int frrequest __P((int, u_long, caddr_t, int)); -#endif -#ifdef _KERNEL -static int (*fr_savep) __P((ip_t *, int, void *, int, mb_t **)); -#else -int ipllog __P((void)); -void init_ifp __P((void)); -static int no_output __P((mb_t *, struct ifnet *)); -static int write_output __P((mb_t *, struct ifnet *)); -#endif - -#ifdef _KERNEL - -int fr_precheck(struct iphdr *ip, struct device *dev, int out, struct device **ifp) -{ - int hlen = ip->ihl << 2; - - return fr_check((ip_t *)ip, hlen, dev, out, (mb_t **)ifp); -} - - -int iplattach() -{ - char *defpass; - int s; - - if (fr_running || (fr_checkp == fr_precheck)) { - printk("IP Filter: already initialized\n"); - return EBUSY; - } - - fr_running = 1; - bzero((char *)frcache, sizeof(frcache)); - bzero((char *)nat_table, sizeof(nat_table)); - fr_savep = fr_checkp; - fr_checkp = fr_precheck; - -# ifdef IPFILTER_LOG - ipflog_init(); -# endif - if (fr_pass & FR_PASS) - defpass = "pass"; - else if (fr_pass & FR_BLOCK) - defpass = "block"; - else - defpass = "no-match -> block"; - - printk("IP Filter: initialized. Default = %s all, Logging = %s\n", - defpass, -# ifdef IPFILTER_LOG - "enabled"); -# else - "disabled"); -# endif - return 0; -} - - -/* - * Disable the filter by removing the hooks from the IP input/output - * stream. - */ -int ipldetach() -{ - int s, i = FR_INQUE|FR_OUTQUE; - - if (!fr_running) - { - printk("IP Filter: not initialized\n"); - return 0; - } - - fr_checkp = fr_savep; - i = frflush(IPL_LOGIPF, i); - fr_running = 0; - - ipfr_unload(); - ip_natunload(); - fr_stateunload(); - fr_authunload(); - - printk("IP Filter: unloaded\n"); - - return 0; -} -#endif /* _KERNEL */ - - -static int frzerostats(data) -caddr_t data; -{ - struct friostat fio; - int error; - - bcopy((char *)frstats, (char *)fio.f_st, - sizeof(struct filterstats) * 2); - fio.f_fin[0] = ipfilter[0][0]; - fio.f_fin[1] = ipfilter[0][1]; - fio.f_fout[0] = ipfilter[1][0]; - fio.f_fout[1] = ipfilter[1][1]; - fio.f_acctin[0] = ipacct[0][0]; - fio.f_acctin[1] = ipacct[0][1]; - fio.f_acctout[0] = ipacct[1][0]; - fio.f_acctout[1] = ipacct[1][1]; - fio.f_active = fr_active; - fio.f_froute[0] = ipl_frouteok[0]; - fio.f_froute[1] = ipl_frouteok[1]; - error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio)); - if (!error) - bzero((char *)frstats, sizeof(*frstats) * 2); - return error; -} - - -/* - * Filter ioctl interface. - */ -#if defined(_KERNEL) -int iplioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) -{ - int s; - caddr_t data = (caddr_t)arg; - - int mode = file->f_mode; -#else -int iplioctl(dev_t dev, int cmd, caddr_t data, int mode) -{ -#endif - int error = 0, unit = 0, tmp; - -#ifdef _KERNEL - unit = GET_MINOR(inode->i_rdev); - if ((IPL_LOGMAX < unit) || (unit < 0)) - return ENXIO; -#endif - - if (unit == IPL_LOGNAT) { - error = nat_ioctl(data, cmd, mode); - return error; - } - if (unit == IPL_LOGSTATE) { - error = fr_state_ioctl(data, cmd, mode); - return error; - } - - switch (cmd) { - case FIONREAD : -#ifdef IPFILTER_LOG - error = IWCOPY((caddr_t)&iplused[IPL_LOGIPF], data, - sizeof(iplused[IPL_LOGIPF])); -#endif - break; -#if !defined(IPFILTER_LKM) && defined(_KERNEL) - case SIOCFRENB : - { - u_int enable; - - if (!(mode & FWRITE)) - error = EPERM; - else { - error = IRCOPY(data, (caddr_t)&enable, sizeof(enable)); - if (error) - break; - if (enable) - error = iplattach(); - else - error = ipldetach(); - } - break; - } -#endif - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else - error = IRCOPY(data, (caddr_t)&fr_flags, - sizeof(fr_flags)); - break; - case SIOCGETFF : - error = IWCOPY((caddr_t)&fr_flags, data, sizeof(fr_flags)); - break; - case SIOCINAFR : - case SIOCRMAFR : - case SIOCADAFR : - case SIOCZRLST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, fr_active); - break; - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, data, 1 - fr_active); - break; - case SIOCSWAPA : - if (!(mode & FWRITE)) - error = EPERM; - else { - bzero((char *)frcache, sizeof(frcache[0]) * 2); - *(u_int *)data = fr_active; - fr_active = 1 - fr_active; - } - break; - case SIOCGETFS : - { - struct friostat fio; - - bcopy((char *)frstats, (char *)fio.f_st, - sizeof(struct filterstats) * 2); - fio.f_fin[0] = ipfilter[0][0]; - fio.f_fin[1] = ipfilter[0][1]; - fio.f_fout[0] = ipfilter[1][0]; - fio.f_fout[1] = ipfilter[1][1]; - fio.f_acctin[0] = ipacct[0][0]; - fio.f_acctin[1] = ipacct[0][1]; - fio.f_acctout[0] = ipacct[1][0]; - fio.f_acctout[1] = ipacct[1][1]; - fio.f_auth = ipauth; - fio.f_active = fr_active; - fio.f_froute[0] = ipl_frouteok[0]; - fio.f_froute[1] = ipl_frouteok[1]; - error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio)); - break; - } - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frzerostats(data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - error = IRCOPY(data, (caddr_t)&tmp, sizeof(tmp)); - if (!error) { - tmp = frflush(unit, tmp); - error = IWCOPY((caddr_t)&tmp, data, - sizeof(tmp)); - } - } - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else - *(int *)data = ipflog_clear(unit); - break; -#endif /* IPFILTER_LOG */ - case SIOCGFRST : - error = IWCOPYPTR((caddr_t)ipfr_fragstats(), data, - sizeof(ipfrstat_t)); - break; - case SIOCFRSYN : - if (!(mode & FWRITE)) - error = EPERM; - else { -#if defined(_KERNEL) && defined(__sgi) - ipfsync(); -#endif - frsync(); - } - break; - default : - error = EINVAL; - break; - } - return error; -} - - -static void frsync() -{ -#ifdef _KERNEL - struct device *dev; - - for (dev = dev_base; dev; dev = dev->next) - ip_natsync(dev); -#endif -} - - -static int frrequest(unit, req, data, set) -int unit; -u_long req; -int set; -caddr_t data; -{ - register frentry_t *fp, *f, **fprev; - register frentry_t **ftail; - frentry_t frd; - frdest_t *fdp; - frgroup_t *fg = NULL; - int error = 0, in; - u_int group; - - fp = &frd; - error = IRCOPYPTR(data, (caddr_t)fp, sizeof(*fp)); - if (error) - return error; - - /* - * Check that the group number does exist and that if a head group - * has been specified, doesn't exist. - */ - if (fp->fr_grhead && - fr_findgroup((u_int)fp->fr_grhead, fp->fr_flags, unit, set, NULL)) - return EEXIST; - if (fp->fr_group && - !fr_findgroup((u_int)fp->fr_group, fp->fr_flags, unit, set, NULL)) - return ESRCH; - - in = (fp->fr_flags & FR_INQUE) ? 0 : 1; - - if (unit == IPL_LOGAUTH) - ftail = fprev = &ipauth; - else if (fp->fr_flags & FR_ACCOUNT) - ftail = fprev = &ipacct[in][set]; - else if (fp->fr_flags & (FR_OUTQUE|FR_INQUE)) - ftail = fprev = &ipfilter[in][set]; - else - return ESRCH; - - if ((group = fp->fr_group)) { - if (!(fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL))) - return ESRCH; - ftail = fprev = fg->fg_start; - } - - bzero((char *)frcache, sizeof(frcache[0]) * 2); - - if (*fp->fr_ifname) { - fp->fr_ifa = GETUNIT(fp->fr_ifname, fp->fr_ip.fi_v); - if (!fp->fr_ifa) - fp->fr_ifa = (void *)-1; - } - - fdp = &fp->fr_dif; - fp->fr_flags &= ~FR_DUP; - if (*fdp->fd_ifname) { - fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_ip.fi_v); - if (!fdp->fd_ifp) - fdp->fd_ifp = (struct ifnet *)-1; - else - fp->fr_flags |= FR_DUP; - } - - fdp = &fp->fr_tif; - if (*fdp->fd_ifname) { - fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fp->fr_ip.fi_v); - if (!fdp->fd_ifp) - fdp->fd_ifp = (struct ifnet *)-1; - } - - /* - * Look for a matching filter rule, but don't include the next or - * interface pointer in the comparison (fr_next, fr_ifa). - */ - for (; (f = *ftail); ftail = &f->fr_next) - if (bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip, - FR_CMPSIZ) == 0) - break; - - /* - * If zero'ing statistics, copy current to caller and zero. - */ - if (req == SIOCZRLST) { - if (!f) - return ESRCH; - error = IWCOPYPTR((caddr_t)f, data, sizeof(*f)); - if (error) - return error; - f->fr_hits = 0; - f->fr_bytes = 0; - return 0; - } - - if (!f) { - if (req == SIOCINAFR || req == SIOCINIFR) { - ftail = fprev; - if (fp->fr_hits) { - while (--fp->fr_hits && (f = *ftail)) { - ftail = &f->fr_next; - } - } - } - f = NULL; - } - - if (req == SIOCRMAFR || req == SIOCRMIFR) { - if (!f) - error = ESRCH; - else { - if (f->fr_ref > 1) - return EBUSY; - if (fg && fg->fg_head) - fg->fg_head->fr_ref--; - if (unit == IPL_LOGAUTH) - return fr_auth_ioctl(data, mode, req, f, ftail); - if (f->fr_grhead) - fr_delgroup((u_int)f->fr_grhead, fp->fr_flags, - unit, set); - fixskip(fprev, f, -1); - *ftail = f->fr_next; - KFREE(f); - } - } else { - if (f) - error = EEXIST; - else { - if (unit == IPL_LOGAUTH) - return fr_auth_ioctl(data, mode, req, f, ftail); - KMALLOC(f, frentry_t *); - if (f != NULL) { - if (fg && fg->fg_head) - fg->fg_head->fr_ref++; - bcopy((char *)fp, (char *)f, sizeof(*f)); - f->fr_ref = 1; - f->fr_hits = 0; - f->fr_next = *ftail; - *ftail = f; - if (req == SIOCINIFR || req == SIOCINAFR) - fixskip(fprev, f, 1); - f->fr_grp = NULL; - if ((group = f->fr_grhead)) - fg = fr_addgroup(group, f, unit, set); - } else - error = ENOMEM; - } - } - return (error); -} - - -#ifdef _KERNEL -/* - * routines below for saving IP headers to buffer - */ -int iplopen(struct inode *inode, struct file *file) -{ - u_int min = GET_MINOR(inode->i_rdev); - - if (IPL_LOGMAX < min) - min = ENXIO; - else { - MOD_INC_USE_COUNT; - min = 0; - } - return min; -} - - -void iplclose(struct inode *inode, struct file *file) -{ - u_int min = GET_MINOR(inode->i_rdev); - - if (IPL_LOGMAX >= min) { - MOD_DEC_USE_COUNT; - } -} - -/* - * iplread/ipllog - * both of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -int iplread(struct inode *inode, struct file *file, char *buf, int nbytes) -{ - struct uio uiob, *uio = &uiob; - - uio->uio_buf = buf; - uio->uio_resid = nbytes; -# ifdef IPFILTER_LOG - return ipflog_read(GET_MINOR(inode->i_rdev), uio); -# else - return ENXIO; -# endif -} - - -/* - * send_reset - this could conceivably be a call to tcp_respond(), but that - * requires a large amount of setting up and isn't any more efficient. - */ -int send_reset(ti, ifp) -struct tcpiphdr *ti; -struct ifnet *ifp; -{ - tcphdr_t *tcp; - int tlen = 0; - ip_t *ip; - mb_t *m; - - if (ti->ti_flags & TH_RST) - return -1; /* feedback loop */ - - m = alloc_skb(sizeof(tcpiphdr_t), GFP_ATOMIC); - if (m == NULL) - return -1; - - if (ti->ti_flags & TH_SYN) - tlen = 1; - - m->dev = ifp; - m->csum = 0; - ip = mtod(m, ip_t *); - m->h.iph = ip; - m->ip_hdr = NULL; - m->m_len = sizeof(tcpiphdr_t); - tcp = (tcphdr_t *)((char *)ip + sizeof(ip_t)); - bzero((char *)ip, sizeof(tcpiphdr_t)); - - ip->ip_v = IPVERSION; - ip->ip_hl = sizeof(ip_t) >> 2; - ip->ip_tos = ((ip_t *)ti)->ip_tos; - ip->ip_p = ((ip_t *)ti)->ip_p; - ip->ip_id = ((ip_t *)ti)->ip_id; - ip->ip_len = htons(sizeof(tcpiphdr_t)); - ip->ip_ttl = 127; - ip->ip_src.s_addr = ti->ti_dst.s_addr; - ip->ip_dst.s_addr = ti->ti_src.s_addr; - tcp->th_dport = ti->ti_sport; - tcp->th_sport = ti->ti_dport; - tcp->th_ack = htonl(ntohl(ti->ti_seq) + tlen); - tcp->th_off = sizeof(tcphdr_t) >> 2; - tcp->th_flags = TH_RST|TH_ACK; - - ip->ip_sum = 0; - ip->ip_sum = ipf_cksum((u_short *)ip, sizeof(ip_t)); - tcp->th_sum = fr_tcpsum(m, ip, tcp); - return ip_forward(m, NULL, IPFWD_NOTTLDEC, ip->ip_dst.s_addr); -} - - -size_t mbufchainlen(m0) -register mb_t *m0; -{ - register size_t len = 0; - - for (; m0; m0 = m0->m_next) - len += m0->m_len; - return len; -} - - -void ipfr_fastroute(m0, fin, fdp) -mb_t *m0; -fr_info_t *fin; -frdest_t *fdp; -{ -#if notyet - register ip_t *ip, *mhip; - register mb_t *m = m0; - register struct route *ro; - struct ifnet *ifp = fdp->fd_ifp; - int len, off, error = 0; - int hlen = fin->fin_hlen; - struct route iproute; - struct sockaddr_in *dst; - - ip = mtod(m0, ip_t *); - /* - * Route packet. - */ - ro = &iproute; - bzero((caddr_t)ro, sizeof (*ro)); - dst = (struct sockaddr_in *)&ro->ro_dst; - dst->sin_family = AF_INET; - dst->sin_addr = fdp->fd_ip.s_addr ? fdp->fd_ip : ip->ip_dst; - /* - * XXX -allocate route here - */ - if (!ifp) { - if (!(fin->fin_fr->fr_flags & FR_FASTROUTE)) { - error = -2; - goto bad; - } - if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) { - if (in_localaddr(ip->ip_dst)) - error = EHOSTUNREACH; - else - error = ENETUNREACH; - goto bad; - } - if (ro->ro_rt->rt_flags & RTF_GATEWAY) - dst = (struct sockaddr_in *)&ro->ro_rt->rt_gateway; - } - ro->ro_rt->rt_use++; - - /* - * For input packets which are being "fastrouted", they won't - * go back through output filtering and miss their chance to get - * NAT'd. - */ - (void) ip_natout(ip, hlen, fin); - if (fin->fin_out) - ip->ip_sum = 0; - /* - * If small enough for interface, can just send directly. - */ - if (ip->ip_len <= ifp->if_mtu) { -# ifndef sparc - ip->ip_id = htons(ip->ip_id); - ip->ip_len = htons(ip->ip_len); - ip->ip_off = htons(ip->ip_off); -# endif - if (!ip->ip_sum) - ip->ip_sum = in_cksum(m, hlen); - error = (*ifp->hard_start_xmit)(m, ifp, m); - goto done; - } - /* - * Too large for interface; fragment if possible. - * Must be able to put at least 8 bytes per fragment. - */ - if (ip->ip_off & IP_DF) { - error = EMSGSIZE; - goto bad; - } - len = (ifp->if_mtu - hlen) &~ 7; - if (len < 8) { - error = EMSGSIZE; - goto bad; - } - - { - int mhlen, firstlen = len; - mb_t **mnext = &m->m_act; - - /* - * Loop through length of segment after first fragment, - * make new header and copy data of each part and link onto chain. - */ - m0 = m; - mhlen = sizeof (struct ip); - for (off = hlen + len; off < ip->ip_len; off += len) { - MGET(m, M_DONTWAIT, MT_HEADER); - if (m == 0) { - error = ENOBUFS; - goto bad; - } - m->m_data += max_linkhdr; - mhip = mtod(m, struct ip *); - bcopy((char *)ip, (char *)mhip, sizeof(*ip)); - if (hlen > sizeof (struct ip)) { - mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); - mhip->ip_hl = mhlen >> 2; - } - m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); - if (ip->ip_off & IP_MF) - mhip->ip_off |= IP_MF; - if (off + len >= ip->ip_len) - len = ip->ip_len - off; - else - mhip->ip_off |= IP_MF; - mhip->ip_len = htons((u_short)(len + mhlen)); - m->m_next = m_copy(m0, off, len); - if (m->m_next == 0) { - error = ENOBUFS; /* ??? */ - goto sendorfree; - } -# ifndef sparc - mhip->ip_off = htons((u_short)mhip->ip_off); -# endif - mhip->ip_sum = 0; - mhip->ip_sum = in_cksum(m, mhlen); - *mnext = m; - mnext = &m->m_act; - } - /* - * Update first fragment by trimming what's been copied out - * and updating header, then send each fragment (in order). - */ - m_adj(m0, hlen + firstlen - ip->ip_len); - ip->ip_len = htons((u_short)(hlen + firstlen)); - ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); - ip->ip_sum = 0; - ip->ip_sum = in_cksum(m0, hlen); -sendorfree: - for (m = m0; m; m = m0) { - m0 = m->m_act; - m->m_act = 0; - if (error == 0) - error = (*ifp->if_output)(ifp, m, - (struct sockaddr *)dst); - else - m_freem(m); - } - } -done: - if (!error) - ipl_frouteok[0]++; - else - ipl_frouteok[1]++; - - if (ro->ro_rt) { - RTFREE(ro->ro_rt); - } - return; -bad: - m_freem(m); - goto done; -# endif -} - - -/* - * Fake BSD uiomove() call. - */ -int uiomove(caddr_t src, size_t ssize, int rw, struct uio *uio) -{ - int error; - size_t mv = MIN(ssize, uio->uio_resid); - - if (rw == UIO_READ) { - error = IWCOPY(src, (caddr_t)uio->uio_buf, mv); - } else if (rw == UIO_WRITE) { - error = IRCOPY((caddr_t)uio->uio_buf, src, mv); - } else - error = EINVAL; - if (!error) { - uio->uio_resid -= mv; - uio->uio_buf += mv; - } - return error; -} - -# ifdef IPFILTER_LKM -# ifndef IPL_MAJOR -# define IPL_MAJOR 95 -# endif - -# ifndef IPL_NAME -# define IPL_NAME "/dev/ipl" -# endif - -static struct file_operations ipl_fops = { - NULL, /* lseek */ - iplread, /* read */ - NULL, /* write */ - NULL, /* readdir */ - NULL, /* select */ - iplioctl, /* ioctl */ - NULL, /* mmap */ - iplopen, /* open */ - iplclose, /* release */ - NULL, /* fsync */ - NULL, /* fasync */ - NULL, /* check_media_change */ - NULL, /* revalidate */ -}; - - -int init_module(void) -{ - int error = 0, major; - - if (register_chrdev(IPL_MAJOR, "ipf", &ipl_fops)) { - printk("ipf: unable to get major number: %d\n", IPL_MAJOR); - return -EIO; - } - - error = iplattach(); - if (!error) - register_symtab(0); - return -error; -} - -void cleanup_module(void) -{ - unregister_chrdev(IPL_MAJOR, "ipf"); - (void) ipldetach(); -} -# endif /* IPFILTER_LKM */ -#else /* #ifdef _KERNEL */ - - -static int no_output __P((mb_t *m, struct ifnet *ifp)) -{ - return 0; -} - - -static int write_output __P((mb_t *m, struct ifnet *ifp)) -{ - FILE *fp; - char fname[32]; - ip_t *ip; - - ip = mtod(m, ip_t *); - sprintf(fname, "/tmp/%s", ifp->name); - if ((fp = fopen(fname, "a"))) { - fwrite((char *)ip, ntohs(ip->ip_len), 1, fp); - fclose(fp); - } - return 0; -} - - -struct ifnet *get_unit(name, v) -char *name; -int v; -{ - struct ifnet *ifp, **ifa; - char ifname[32], *s; - - for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { - (void) sprintf(ifname, "%s", ifp->name); - if (!strcmp(name, ifname)) - return ifp; - } - - if (!ifneta) { - ifneta = (struct ifnet **)malloc(sizeof(ifp) * 2); - ifneta[1] = NULL; - ifneta[0] = (struct ifnet *)calloc(1, sizeof(*ifp)); - nifs = 1; - } else { - nifs++; - ifneta = (struct ifnet **)realloc(ifneta, - (nifs + 1) * sizeof(*ifa)); - ifneta[nifs] = NULL; - ifneta[nifs - 1] = (struct ifnet *)malloc(sizeof(*ifp)); - } - ifp = ifneta[nifs - 1]; - - for (s = name; *s && !isdigit(*s); s++) - ; - if (*s && isdigit(*s)) { - ifp->name = (char *)malloc(s - name + 1); - strncpy(ifp->name, name, s - name); - ifp->name[s - name] = '\0'; - } else { - ifp->name = strdup(name); - } - ifp->hard_start_xmit = no_output; - return ifp; -} - - - -void init_ifp() -{ - FILE *fp; - struct ifnet *ifp, **ifa; - char fname[32]; - - for (ifa = ifneta; ifa && (ifp = *ifa); ifa++) { - ifp->hard_start_xmit = write_output; - sprintf(fname, "/tmp/%s", ifp->name); - if ((fp = fopen(fname, "w"))) - fclose(fp); - } -} - - -void ipfr_fastroute(ip, fin, fdp) -ip_t *ip; -fr_info_t *fin; -frdest_t *fdp; -{ - struct ifnet *ifp = fdp->fd_ifp; - - if (!ifp) - return; /* no routing table out here */ - - ip->ip_len = htons((u_short)ip->ip_len); - ip->ip_off = htons((u_short)(ip->ip_off | IP_MF)); - ip->ip_sum = 0; - (*ifp->hard_start_xmit)((mb_t *)ip, ifp); -} - - -int ipllog __P((void)) -{ - verbose("l"); - return 0; -} - - -int send_reset(ip, ifp) -ip_t *ip; -struct ifnet *ifp; -{ - verbose("- TCP RST sent\n"); - return 0; -} - - -int icmp_error(ip, ifp) -ip_t *ip; -struct ifnet *ifp; -{ - verbose("- TCP RST sent\n"); - return 0; -} -#endif /* _KERNEL */ diff --git a/contrib/ipfilter/ip_log.c b/contrib/ipfilter/ip_log.c deleted file mode 100644 index 124308197949..000000000000 --- a/contrib/ipfilter/ip_log.c +++ /dev/null @@ -1,674 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1997-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_log.c,v 2.75.2.6 2004/10/16 07:59:27 darrenr Exp - */ -#include -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ - defined(_KERNEL) -# include "opt_ipfilter_log.h" -#endif -#if defined(__FreeBSD__) && !defined(IPFILTER_LKM) -# if defined(_KERNEL) -# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include "opt_ipfilter.h" -# endif -# else -# include -# endif -#endif -#ifndef SOLARIS -# define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif -#include -#include -#include -#ifndef _KERNEL -# include -# include -# include -# include -# define _KERNEL -# define KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -# undef KERNEL -#endif -#if __FreeBSD_version >= 220000 && defined(_KERNEL) -# include -# include -#else -# include -#endif -#include -#if defined(_KERNEL) -# include -# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) -# include -# endif -#endif /* _KERNEL */ -#if !SOLARIS && !defined(__hpux) && !defined(linux) -# if (NetBSD > 199609) || (OpenBSD > 199603) || (__FreeBSD_version >= 300000) -# include -# else -# include -# endif -# include -#else -# if !defined(__hpux) && defined(_KERNEL) -# include -# include -# include -# include -# include -# include -# include -# include -# include -# endif /* !__hpux */ -#endif /* !SOLARIS && !__hpux */ -#if !defined(linux) -# include -#endif -#include - -#include -#ifdef sun -# include -#endif -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#ifdef __sgi -# include -# ifdef IFF_DRVRLOCK /* IRIX6 */ -# include -# endif -#endif -#if !defined(__hpux) && !defined(linux) && \ - !(defined(__sgi) && !defined(IFF_DRVRLOCK)) /*IRIX<6*/ -# include -#endif -#include -#include -#include -#include -#include -#ifdef USE_INET6 -# include -#endif -#if !defined(linux) -# include -#endif -#ifndef _KERNEL -# include -#endif -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_auth.h" -#if (__FreeBSD_version >= 300000) || defined(__NetBSD__) -# include -#endif -/* END OF INCLUDES */ - -#ifdef IPFILTER_LOG - -# if defined(IPL_SELECT) -# include -# include -# define READ_COLLISION 0x001 - -iplog_select_t iplog_ss[IPL_LOGMAX+1]; - -extern int selwait; -# endif /* IPL_SELECT */ - -# if defined(linux) && defined(_KERNEL) -wait_queue_head_t iplh_linux[IPL_LOGSIZE]; -# endif -# if SOLARIS -extern kcondvar_t iplwait; -# endif - -iplog_t **iplh[IPL_LOGSIZE], *iplt[IPL_LOGSIZE], *ipll[IPL_LOGSIZE]; -int iplused[IPL_LOGSIZE]; -static fr_info_t iplcrc[IPL_LOGSIZE]; -int ipl_suppress = 1; -int ipl_buffer_sz; -int ipl_logmax = IPL_LOGMAX; -int ipl_logall = 0; -int ipl_log_init = 0; -int ipl_logsize = IPFILTER_LOGSIZE; -int ipl_magic[IPL_LOGSIZE] = { IPL_MAGIC, IPL_MAGIC_NAT, IPL_MAGIC_STATE, - IPL_MAGIC, IPL_MAGIC, IPL_MAGIC, - IPL_MAGIC, IPL_MAGIC }; - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_loginit */ -/* Returns: int - 0 == success (always returned) */ -/* Parameters: Nil */ -/* */ -/* Initialise log buffers & pointers. Also iniialised the CRC to a local */ -/* secret for use in calculating the "last log checksum". */ -/* ------------------------------------------------------------------------ */ -int fr_loginit() -{ - int i; - - for (i = IPL_LOGMAX; i >= 0; i--) { - iplt[i] = NULL; - ipll[i] = NULL; - iplh[i] = &iplt[i]; - iplused[i] = 0; - bzero((char *)&iplcrc[i], sizeof(iplcrc[i])); -# ifdef IPL_SELECT - iplog_ss[i].read_waiter = 0; - iplog_ss[i].state = 0; -# endif -# if defined(linux) && defined(_KERNEL) - init_waitqueue_head(iplh_linux + i); -# endif - } - -# if SOLARIS && defined(_KERNEL) - cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL); -# endif - MUTEX_INIT(&ipl_mutex, "ipf log mutex"); - - ipl_log_init = 1; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_logunload */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Clean up any log data that has accumulated without being read. */ -/* ------------------------------------------------------------------------ */ -void fr_logunload() -{ - int i; - - if (ipl_log_init == 0) - return; - - for (i = IPL_LOGMAX; i >= 0; i--) - (void) ipflog_clear(i); - -# if SOLARIS && defined(_KERNEL) - cv_destroy(&iplwait); -# endif - MUTEX_DESTROY(&ipl_mutex); - - ipl_log_init = 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipflog */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: fin(I) - pointer to packet information */ -/* flags(I) - flags from filter rules */ -/* */ -/* Create a log record for a packet given that it has been triggered by a */ -/* rule (or the default setting). Calculate the transport protocol header */ -/* size using predetermined size of a couple of popular protocols and thus */ -/* how much data to copy into the log, including part of the data body if */ -/* requested. */ -/* ------------------------------------------------------------------------ */ -int ipflog(fin, flags) -fr_info_t *fin; -u_int flags; -{ - register size_t hlen; - int types[2], mlen; - size_t sizes[2]; - void *ptrs[2]; - ipflog_t ipfl; - u_char p; - mb_t *m; -# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) - qif_t *ifp; -# else - struct ifnet *ifp; -# endif /* SOLARIS || __hpux */ - - ipfl.fl_nattag.ipt_num[0] = 0; - m = fin->fin_m; - ifp = fin->fin_ifp; - hlen = fin->fin_hlen; - /* - * calculate header size. - */ - if (fin->fin_off == 0) { - p = fin->fin_fi.fi_p; - if (p == IPPROTO_TCP) - hlen += MIN(sizeof(tcphdr_t), fin->fin_dlen); - else if (p == IPPROTO_UDP) - hlen += MIN(sizeof(udphdr_t), fin->fin_dlen); - else if (p == IPPROTO_ICMP) { - struct icmp *icmp; - - icmp = (struct icmp *)fin->fin_dp; - - /* - * For ICMP, if the packet is an error packet, also - * include the information about the packet which - * caused the error. - */ - switch (icmp->icmp_type) - { - case ICMP_UNREACH : - case ICMP_SOURCEQUENCH : - case ICMP_REDIRECT : - case ICMP_TIMXCEED : - case ICMP_PARAMPROB : - hlen += MIN(sizeof(struct icmp) + 8, - fin->fin_dlen); - break; - default : - hlen += MIN(sizeof(struct icmp), - fin->fin_dlen); - break; - } - } -# ifdef USE_INET6 - else if (p == IPPROTO_ICMPV6) { - struct icmp6_hdr *icmp; - - icmp = (struct icmp6_hdr *)fin->fin_dp; - - /* - * For ICMPV6, if the packet is an error packet, also - * include the information about the packet which - * caused the error. - */ - if (icmp->icmp6_type < 128) { - hlen += MIN(sizeof(struct icmp6_hdr) + 8, - fin->fin_dlen); - } else { - hlen += MIN(sizeof(struct icmp6_hdr), - fin->fin_dlen); - } - } -# endif - } - /* - * Get the interface number and name to which this packet is - * currently associated. - */ -# if (SOLARIS || defined(__hpux)) && defined(_KERNEL) - ipfl.fl_unit = (u_int)ifp->qf_ppa; - COPYIFNAME(ifp, ipfl.fl_ifname); -# else -# if (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603)) || defined(linux) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) - COPYIFNAME(ifp, ipfl.fl_ifname); -# else - ipfl.fl_unit = (u_int)ifp->if_unit; -# if defined(_KERNEL) - if ((ipfl.fl_ifname[0] = ifp->if_name[0])) - if ((ipfl.fl_ifname[1] = ifp->if_name[1])) - if ((ipfl.fl_ifname[2] = ifp->if_name[2])) - ipfl.fl_ifname[3] = ifp->if_name[3]; -# else - (void) strncpy(ipfl.fl_ifname, IFNAME(ifp), sizeof(ipfl.fl_ifname)); - ipfl.fl_ifname[sizeof(ipfl.fl_ifname) - 1] = '\0'; -# endif -# endif -# endif /* __hpux || SOLARIS */ - mlen = fin->fin_plen - hlen; - if (!ipl_logall) { - mlen = (flags & FR_LOGBODY) ? MIN(mlen, 128) : 0; - } else if ((flags & FR_LOGBODY) == 0) { - mlen = 0; - } - if (mlen < 0) - mlen = 0; - ipfl.fl_plen = (u_char)mlen; - ipfl.fl_hlen = (u_char)hlen; - ipfl.fl_rule = fin->fin_rule; - (void) strncpy(ipfl.fl_group, fin->fin_group, FR_GROUPLEN); - if (fin->fin_fr != NULL) { - ipfl.fl_loglevel = fin->fin_fr->fr_loglevel; - ipfl.fl_logtag = fin->fin_fr->fr_logtag; - } else { - ipfl.fl_loglevel = 0xffff; - ipfl.fl_logtag = FR_NOLOGTAG; - } - if (fin->fin_nattag != NULL) - bcopy(fin->fin_nattag, (void *)&ipfl.fl_nattag, - sizeof(ipfl.fl_nattag)); - ipfl.fl_flags = flags; - ipfl.fl_dir = fin->fin_out; - ipfl.fl_lflags = fin->fin_flx; - ptrs[0] = (void *)&ipfl; - sizes[0] = sizeof(ipfl); - types[0] = 0; -# if defined(MENTAT) && defined(_KERNEL) - /* - * Are we copied from the mblk or an aligned array ? - */ - if (fin->fin_ip == (ip_t *)m->b_rptr) { - ptrs[1] = m; - sizes[1] = hlen + mlen; - types[1] = 1; - } else { - ptrs[1] = fin->fin_ip; - sizes[1] = hlen + mlen; - types[1] = 0; - } -# else - ptrs[1] = m; - sizes[1] = hlen + mlen; - types[1] = 1; -# endif /* MENTAT */ - return ipllog(IPL_LOGIPF, fin, ptrs, sizes, types, 2); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipllog */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: dev(I) - device that owns this log record */ -/* fin(I) - pointer to packet information */ -/* items(I) - array of pointers to log data */ -/* itemsz(I) - array of size of valid memory pointed to */ -/* types(I) - type of data pointed to by items pointers */ -/* cnt(I) - number of elements in arrays items/itemsz/types */ -/* */ -/* Takes an array of parameters and constructs one record to include the */ -/* miscellaneous packet information, as well as packet data, for reading */ -/* from the log device. */ -/* ------------------------------------------------------------------------ */ -int ipllog(dev, fin, items, itemsz, types, cnt) -int dev; -fr_info_t *fin; -void **items; -size_t *itemsz; -int *types, cnt; -{ - caddr_t buf, ptr; - iplog_t *ipl; - size_t len; - int i; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif - - /* - * Check to see if this log record has a CRC which matches the last - * record logged. If it does, just up the count on the previous one - * rather than create a new one. - */ - if (ipl_suppress) { - MUTEX_ENTER(&ipl_mutex); - if ((fin != NULL) && (fin->fin_off == 0)) { - if ((ipll[dev] != NULL) && - bcmp((char *)fin, (char *)&iplcrc[dev], - FI_LCSIZE) == 0) { - ipll[dev]->ipl_count++; - MUTEX_EXIT(&ipl_mutex); - return 0; - } - bcopy((char *)fin, (char *)&iplcrc[dev], FI_LCSIZE); - } else - bzero((char *)&iplcrc[dev], FI_CSIZE); - MUTEX_EXIT(&ipl_mutex); - } - - /* - * Get the total amount of data to be logged. - */ - for (i = 0, len = sizeof(iplog_t); i < cnt; i++) - len += itemsz[i]; - - /* - * check that we have space to record this information and can - * allocate that much. - */ - KMALLOCS(buf, caddr_t, len); - if (buf == NULL) - return -1; - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - if ((iplused[dev] + len) > ipl_logsize) { - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - KFREES(buf, len); - return -1; - } - iplused[dev] += len; - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - - /* - * advance the log pointer to the next empty record and deduct the - * amount of space we're going to use. - */ - ipl = (iplog_t *)buf; - ipl->ipl_magic = ipl_magic[dev]; - ipl->ipl_count = 1; - ipl->ipl_next = NULL; - ipl->ipl_dsize = len; -#ifdef _KERNEL - GETKTIME(&ipl->ipl_sec); -#else - ipl->ipl_sec = 0; - ipl->ipl_usec = 0; -#endif - - /* - * Loop through all the items to be logged, copying each one to the - * buffer. Use bcopy for normal data or the mb_t copyout routine. - */ - for (i = 0, ptr = buf + sizeof(*ipl); i < cnt; i++) { - if (types[i] == 0) { - bcopy(items[i], ptr, itemsz[i]); - } else if (types[i] == 1) { - COPYDATA(items[i], 0, itemsz[i], ptr); - } - ptr += itemsz[i]; - } - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - ipll[dev] = ipl; - *iplh[dev] = ipl; - iplh[dev] = &ipl->ipl_next; - - /* - * Now that the log record has been completed and added to the queue, - * wake up any listeners who may want to read it. - */ -# if SOLARIS && defined(_KERNEL) - cv_signal(&iplwait); - MUTEX_EXIT(&ipl_mutex); -# else - MUTEX_EXIT(&ipl_mutex); - WAKEUP(iplh,dev); -# endif - SPL_X(s); -# ifdef IPL_SELECT - iplog_input_ready(dev); -# endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipflog_read */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: unit(I) - device we are reading from */ -/* uio(O) - pointer to information about where to store data */ -/* */ -/* Called to handle a read on an IPFilter device. Returns only complete */ -/* log messages - will not partially copy a log record out to userland. */ -/* */ -/* NOTE: This function will block and wait for a signal to return data if */ -/* there is none present. Asynchronous I/O is not implemented. */ -/* ------------------------------------------------------------------------ */ -int ipflog_read(unit, uio) -minor_t unit; -struct uio *uio; -{ - size_t dlen, copied; - int error = 0; - iplog_t *ipl; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif - - /* - * Sanity checks. Make sure the minor # is valid and we're copying - * a valid chunk of data. - */ - if (IPL_LOGMAX < unit) - return ENXIO; - if (uio->uio_resid == 0) - return 0; - if ((uio->uio_resid < sizeof(iplog_t)) || - (uio->uio_resid > ipl_logsize)) - return EINVAL; - - /* - * Lock the log so we can snapshot the variables. Wait for a signal - * if the log is empty. - */ - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - - while (iplt[unit] == NULL) { -# if SOLARIS && defined(_KERNEL) - if (!cv_wait_sig(&iplwait, &ipl_mutex.ipf_lk)) { - MUTEX_EXIT(&ipl_mutex); - return EINTR; - } -# else -# if defined(__hpux) && defined(_KERNEL) - lock_t *l; - -# ifdef IPL_SELECT - if (uio->uio_fpflags & (FNBLOCK|FNDELAY)) { - /* this is no blocking system call */ - MUTEX_EXIT(&ipl_mutex); - return 0; - } -# endif - - MUTEX_EXIT(&ipl_mutex); - l = get_sleep_lock(&iplh[unit]); - error = sleep(&iplh[unit], PZERO+1); - spinunlock(l); -# else -# if defined(__osf__) && defined(_KERNEL) - error = mpsleep(&iplh[unit], PSUSP|PCATCH, "iplread", 0, - &ipl_mutex, MS_LOCK_SIMPLE); -# else - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - error = SLEEP(unit + iplh, "ipl sleep"); -# endif /* __osf__ */ -# endif /* __hpux */ - if (error) - return error; - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); -# endif /* SOLARIS */ - } - -# if (BSD >= 199101) || defined(__FreeBSD__) || defined(__osf__) - uio->uio_rw = UIO_READ; -# endif - - for (copied = 0; (ipl = iplt[unit]) != NULL; copied += dlen) { - dlen = ipl->ipl_dsize; - if (dlen > uio->uio_resid) - break; - /* - * Don't hold the mutex over the uiomove call. - */ - iplt[unit] = ipl->ipl_next; - iplused[unit] -= dlen; - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - error = UIOMOVE((caddr_t)ipl, dlen, UIO_READ, uio); - if (error) { - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - ipl->ipl_next = iplt[unit]; - iplt[unit] = ipl; - iplused[unit] += dlen; - break; - } - MUTEX_ENTER(&ipl_mutex); - KFREES((caddr_t)ipl, dlen); - SPL_NET(s); - } - if (!iplt[unit]) { - iplused[unit] = 0; - iplh[unit] = &iplt[unit]; - ipll[unit] = NULL; - } - - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipflog_clear */ -/* Returns: int - number of log bytes cleared. */ -/* Parameters: unit(I) - device we are reading from */ -/* */ -/* Deletes all queued up log records for a given output device. */ -/* ------------------------------------------------------------------------ */ -int ipflog_clear(unit) -minor_t unit; -{ - iplog_t *ipl; - int used; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif - - SPL_NET(s); - MUTEX_ENTER(&ipl_mutex); - while ((ipl = iplt[unit]) != NULL) { - iplt[unit] = ipl->ipl_next; - KFREES((caddr_t)ipl, ipl->ipl_dsize); - } - iplh[unit] = &iplt[unit]; - ipll[unit] = NULL; - used = iplused[unit]; - iplused[unit] = 0; - bzero((char *)&iplcrc[unit], FI_CSIZE); - MUTEX_EXIT(&ipl_mutex); - SPL_X(s); - return used; -} -#endif /* IPFILTER_LOG */ diff --git a/contrib/ipfilter/ip_lookup.c b/contrib/ipfilter/ip_lookup.c deleted file mode 100644 index b8323739e6dd..000000000000 --- a/contrib/ipfilter/ip_lookup.c +++ /dev/null @@ -1,530 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2002-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#if defined(__osf__) -# define _PROTO_NET_H_ -#endif -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 220000 && defined(_KERNEL) -# include -# include -#else -# include -#endif -#if !defined(_KERNEL) -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#include -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# ifdef __osf__ -# include -# endif -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif -#include -#if defined(__FreeBSD__) -# include -# include -#endif -#if defined(_KERNEL) -# include -# if !defined(__SVR4) && !defined(__svr4__) -# include -# endif -#endif -#include - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_pool.h" -#include "netinet/ip_htable.h" -#include "netinet/ip_lookup.h" -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_lookup.c,v 2.35.2.5 2004/07/06 11:16:25 darrenr Exp"; -#endif - -#ifdef IPFILTER_LOOKUP -int ip_lookup_inited = 0; - -static int iplookup_addnode __P((caddr_t)); -static int iplookup_delnode __P((caddr_t data)); -static int iplookup_addtable __P((caddr_t)); -static int iplookup_deltable __P((caddr_t)); -static int iplookup_stats __P((caddr_t)); -static int iplookup_flush __P((caddr_t)); - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_init */ -/* Returns: int - 0 = success, else error */ -/* Parameters: Nil */ -/* */ -/* Initialise all of the subcomponents of the lookup infrstructure. */ -/* ------------------------------------------------------------------------ */ -int ip_lookup_init() -{ - - if (ip_pool_init() == -1) - return -1; - - RWLOCK_INIT(&ip_poolrw, "ip pool rwlock"); - - ip_lookup_inited = 1; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_unload */ -/* Returns: int - 0 = success, else error */ -/* Parameters: Nil */ -/* */ -/* Free up all pool related memory that has been allocated whilst IPFilter */ -/* has been running. Also, do any other deinitialisation required such */ -/* ip_lookup_init() can be called again, safely. */ -/* ------------------------------------------------------------------------ */ -void ip_lookup_unload() -{ - ip_pool_fini(); - fr_htable_unload(); - - if (ip_lookup_inited == 1) { - RW_DESTROY(&ip_poolrw); - ip_lookup_inited = 0; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_ioctl */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(IO) - pointer to ioctl data to be copied to/from user */ -/* space. */ -/* cmd(I) - ioctl command number */ -/* mode(I) - file mode bits used with open */ -/* */ -/* Handle ioctl commands sent to the ioctl device. For the most part, this */ -/* involves just calling another function to handle the specifics of each */ -/* command. */ -/* ------------------------------------------------------------------------ */ -int ip_lookup_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - int err; -# if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -# endif - - mode = mode; /* LINT */ - - SPL_NET(s); - - switch (cmd) - { - case SIOCLOOKUPADDNODE : - case SIOCLOOKUPADDNODEW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_addnode(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPDELNODE : - case SIOCLOOKUPDELNODEW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_delnode(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPADDTABLE : - WRITE_ENTER(&ip_poolrw); - err = iplookup_addtable(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPDELTABLE : - WRITE_ENTER(&ip_poolrw); - err = iplookup_deltable(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPSTAT : - case SIOCLOOKUPSTATW : - WRITE_ENTER(&ip_poolrw); - err = iplookup_stats(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - case SIOCLOOKUPFLUSH : - WRITE_ENTER(&ip_poolrw); - err = iplookup_flush(data); - RWLOCK_EXIT(&ip_poolrw); - break; - - default : - err = EINVAL; - break; - } - SPL_X(s); - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_addnode */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ -/* */ -/* Add a new data node to a lookup structure. First, check to see if the */ -/* parent structure refered to by name exists and if it does, then go on to */ -/* add a node to it. */ -/* ------------------------------------------------------------------------ */ -static int iplookup_addnode(data) -caddr_t data; -{ - ip_pool_node_t node, *m; - iplookupop_t op; - iphtable_t *iph; - iphtent_t hte; - ip_pool_t *p; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - - switch (op.iplo_type) - { - case IPLT_POOL : - if (op.iplo_size != sizeof(node)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &node, sizeof(node)); - if (err != 0) - return EFAULT; - - p = ip_pool_find(op.iplo_unit, op.iplo_name); - if (p == NULL) - return ESRCH; - - /* - * add an entry to a pool - return an error if it already - * exists remove an entry from a pool - if it exists - * - in both cases, the pool *must* exist! - */ - m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); - if (m) - return EEXIST; - err = ip_pool_insert(p, &node.ipn_addr.adf_addr, - &node.ipn_mask.adf_addr, node.ipn_info); - break; - - case IPLT_HASH : - if (op.iplo_size != sizeof(hte)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); - if (err != 0) - return EFAULT; - - iph = fr_findhtable(op.iplo_unit, op.iplo_name); - if (iph == NULL) - return ESRCH; - err = fr_addhtent(iph, &hte); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_delnode */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ -/* */ -/* Delete a node from a lookup table by first looking for the table it is */ -/* in and then deleting the entry that gets found. */ -/* ------------------------------------------------------------------------ */ -static int iplookup_delnode(data) -caddr_t data; -{ - ip_pool_node_t node, *m; - iplookupop_t op; - iphtable_t *iph; - iphtent_t hte; - ip_pool_t *p; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - - op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - - switch (op.iplo_type) - { - case IPLT_POOL : - if (op.iplo_size != sizeof(node)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &node, sizeof(node)); - if (err != 0) - return EFAULT; - - p = ip_pool_find(op.iplo_unit, op.iplo_name); - if (!p) - return ESRCH; - - m = ip_pool_findeq(p, &node.ipn_addr, &node.ipn_mask); - if (m == NULL) - return ENOENT; - err = ip_pool_remove(p, m); - break; - - case IPLT_HASH : - if (op.iplo_size != sizeof(hte)) - return EINVAL; - - err = COPYIN(op.iplo_struct, &hte, sizeof(hte)); - if (err != 0) - return EFAULT; - - iph = fr_findhtable(op.iplo_unit, op.iplo_name); - if (iph == NULL) - return ESRCH; - err = fr_delhtent(iph, &hte); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_addtable */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ -/* */ -/* Create a new lookup table, if one doesn't already exist using the name */ -/* for this one. */ -/* ------------------------------------------------------------------------ */ -static int iplookup_addtable(data) -caddr_t data; -{ - iplookupop_t op; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - - op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - - switch (op.iplo_type) - { - case IPLT_POOL : - if (ip_pool_find(op.iplo_unit, op.iplo_name) != NULL) - err = EEXIST; - else - err = ip_pool_create(&op); - break; - - case IPLT_HASH : - if (fr_findhtable(op.iplo_unit, op.iplo_name) != NULL) - err = EEXIST; - else - err = fr_newhtable(&op); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_deltable */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ -/* */ -/* Decodes ioctl request to remove a particular hash table or pool and */ -/* calls the relevant function to do the cleanup. */ -/* ------------------------------------------------------------------------ */ -static int iplookup_deltable(data) -caddr_t data; -{ - iplookupop_t op; - int err; - - BCOPYIN(data, &op, sizeof(op)); - op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; - - if (op.iplo_arg & IPLT_ANON) - op.iplo_arg &= IPLT_ANON; - - /* - * create a new pool - fail if one already exists with - * the same # - */ - switch (op.iplo_type) - { - case IPLT_POOL : - err = ip_pool_destroy(&op); - break; - - case IPLT_HASH : - err = fr_removehtable(&op); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_stats */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ -/* */ -/* Copy statistical information from inside the kernel back to user space. */ -/* ------------------------------------------------------------------------ */ -static int iplookup_stats(data) -caddr_t data; -{ - iplookupop_t op; - int err; - - err = 0; - BCOPYIN(data, &op, sizeof(op)); - - switch (op.iplo_type) - { - case IPLT_POOL : - err = ip_pool_statistics(&op); - break; - - case IPLT_HASH : - err = fr_gethtablestat(&op); - break; - - default : - err = EINVAL; - break; - } - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: iplookup_flush */ -/* Returns: int - 0 = success, else error */ -/* Parameters: data(I) - pointer to data from ioctl call */ -/* */ -/* A flush is called when we want to flush all the nodes from a particular */ -/* entry in the hash table/pool or want to remove all groups from those. */ -/* ------------------------------------------------------------------------ */ -static int iplookup_flush(data) -caddr_t data; -{ - int err, unit, num, type; - iplookupflush_t flush; - - err = 0; - BCOPYIN(data, &flush, sizeof(flush)); - - flush.iplf_name[sizeof(flush.iplf_name) - 1] = '\0'; - - unit = flush.iplf_unit; - if ((unit < 0 || unit > IPL_LOGMAX) && (unit != IPLT_ALL)) - return EINVAL; - - type = flush.iplf_type; - err = EINVAL; - num = 0; - - if (type == IPLT_POOL || type == IPLT_ALL) { - err = 0; - num = ip_pool_flush(&flush); - } - - if (type == IPLT_HASH || type == IPLT_ALL) { - err = 0; - num += fr_flushhtable(&flush); - } - - if (err == 0) { - flush.iplf_count = num; - err = COPYOUT(&flush, data, sizeof(flush)); - } - return err; -} - - -void ip_lookup_deref(type, ptr) -int type; -void *ptr; -{ - if (ptr == NULL) - return; - - WRITE_ENTER(&ip_poolrw); - switch (type) - { - case IPLT_POOL : - ip_pool_deref(ptr); - break; - - case IPLT_HASH : - fr_derefhtable(ptr); - break; - } - RWLOCK_EXIT(&ip_poolrw); -} - - -#else /* IPFILTER_LOOKUP */ - -/*ARGSUSED*/ -int ip_lookup_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - return EIO; -} -#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_lookup.h b/contrib/ipfilter/ip_lookup.h deleted file mode 100644 index e9f8cb8afe4d..000000000000 --- a/contrib/ipfilter/ip_lookup.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $NetBSD$ */ - - -#ifndef __IP_LOOKUP_H__ -#define __IP_LOOKUP_H__ - -#if defined(__STDC__) || defined(__GNUC__) -# define SIOCLOOKUPADDTABLE _IOWR('r', 60, struct iplookupop) -# define SIOCLOOKUPDELTABLE _IOWR('r', 61, struct iplookupop) -# define SIOCLOOKUPSTAT _IOWR('r', 64, struct iplookupop) -# define SIOCLOOKUPSTATW _IOW('r', 64, struct iplookupop) -# define SIOCLOOKUPFLUSH _IOWR('r', 65, struct iplookupflush) -# define SIOCLOOKUPADDNODE _IOWR('r', 67, struct iplookupop) -# define SIOCLOOKUPADDNODEW _IOW('r', 67, struct iplookupop) -# define SIOCLOOKUPDELNODE _IOWR('r', 68, struct iplookupop) -# define SIOCLOOKUPDELNODEW _IOW('r', 68, struct iplookupop) -#else -# define SIOCLOOKUPADDTABLE _IOWR(r, 60, struct iplookupop) -# define SIOCLOOKUPDELTABLE _IOWR(r, 61, struct iplookupop) -# define SIOCLOOKUPSTAT _IOWR(r, 64, struct iplookupop) -# define SIOCLOOKUPSTATW _IOW(r, 64, struct iplookupop) -# define SIOCLOOKUPFLUSH _IOWR(r, 65, struct iplookupflush) -# define SIOCLOOKUPADDNODE _IOWR(r, 67, struct iplookupop) -# define SIOCLOOKUPADDNODEW _IOW(r, 67, struct iplookupop) -# define SIOCLOOKUPDELNODE _IOWR(r, 68, struct iplookupop) -# define SIOCLOOKUPDELNODEW _IOW(r, 68, struct iplookupop) -#endif - -typedef struct iplookupop { - int iplo_type; /* IPLT_* */ - int iplo_unit; /* IPL_LOG* */ - u_int iplo_arg; - char iplo_name[FR_GROUPLEN]; - size_t iplo_size; /* sizeof struct at iplo_struct */ - void *iplo_struct; -} iplookupop_t; - -typedef struct iplookupflush { - int iplf_type; /* IPLT_* */ - int iplf_unit; /* IPL_LOG* */ - u_int iplf_arg; - size_t iplf_count; - char iplf_name[FR_GROUPLEN]; -} iplookupflush_t; - -typedef struct iplookuplink { - int ipll_type; /* IPLT_* */ - int ipll_unit; /* IPL_LOG* */ - u_int ipll_num; - char ipll_group[FR_GROUPLEN]; -} iplookuplink_t; - -#define IPLT_ALL -1 -#define IPLT_NONE 0 -#define IPLT_POOL 1 -#define IPLT_HASH 2 - -#define IPLT_ANON 0x80000000 - -extern int ip_lookup_init __P((void)); -extern int ip_lookup_ioctl __P((caddr_t, ioctlcmd_t, int)); -extern void ip_lookup_unload __P((void)); -extern void ip_lookup_deref __P((int, void *)); - -#endif /* __IP_LOOKUP_H__ */ diff --git a/contrib/ipfilter/ip_msnrpc_pxy.c b/contrib/ipfilter/ip_msnrpc_pxy.c deleted file mode 100644 index 187a9645a527..000000000000 --- a/contrib/ipfilter/ip_msnrpc_pxy.c +++ /dev/null @@ -1,328 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2000-2003 by Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Simple DCE transparent proxy for MSN RPC. - * - * ******* NOTE: THIS PROXY DOES NOT DO ADDRESS TRANSLATION ******** - * - * Id: ip_msnrpc_pxy.c,v 2.17.2.1 2005/02/04 10:22:55 darrenr Exp - */ - -#define IPF_MSNRPC_PROXY - -#define IPF_MINMSNRPCLEN 24 -#define IPF_MSNRPCSKIP (2 + 19 + 2 + 2 + 2 + 19 + 2 + 2) - - -typedef struct msnrpchdr { - u_char mrh_major; /* major # == 5 */ - u_char mrh_minor; /* minor # == 0 */ - u_char mrh_type; - u_char mrh_flags; - u_32_t mrh_endian; - u_short mrh_dlen; /* data size */ - u_short mrh_alen; /* authentication length */ - u_32_t mrh_cid; /* call identifier */ - u_32_t mrh_hint; /* allocation hint */ - u_short mrh_ctxt; /* presentation context hint */ - u_char mrh_ccnt; /* cancel count */ - u_char mrh_ans; -} msnrpchdr_t; - -int ippr_msnrpc_init __P((void)); -void ippr_msnrpc_fini __P((void)); -int ippr_msnrpc_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_msnrpc_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_msnrpc_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_msnrpc_check __P((ip_t *, msnrpchdr_t *)); - -static frentry_t msnfr; - -int msn_proxy_init = 0; - -/* - * Initialize local structures. - */ -int ippr_msnrpc_init() -{ - bzero((char *)&msnfr, sizeof(msnfr)); - msnfr.fr_ref = 1; - msnfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&msnfr.fr_lock, "MSN RPC proxy rule lock"); - msn_proxy_init = 1; - - return 0; -} - - -void ippr_msnrpc_fini() -{ - if (msn_proxy_init == 1) { - MUTEX_DESTROY(&msnfr.fr_lock); - msn_proxy_init = 0; - } -} - - -int ippr_msnrpc_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - msnrpcinfo_t *mri; - - KMALLOC(mri, msnrpcinfo_t *); - if (mri == NULL) - return -1; - aps->aps_data = mri; - aps->aps_psiz = sizeof(msnrpcinfo_t); - - bzero((char *)mri, sizeof(*mri)); - mri->mri_cmd[0] = 0xff; - mri->mri_cmd[1] = 0xff; - return 0; -} - - -int ippr_msnrpc_check(ip, mrh) -ip_t *ip; -msnrpchdr_t *mrh; -{ - if (mrh->mrh_major != 5) - return -1; - if (mrh->mrh_minor != 0) - return -1; - if (mrh->mrh_alen != 0) - return -1; - if (mrh->mrh_endian == 0x10) { - /* Both gateway and packet match endian */ - if (mrh->mrh_dlen > ip->ip_len) - return -1; - if (mrh->mrh_type == 0 || mrh->mrh_type == 2) - if (mrh->mrh_hint > ip->ip_len) - return -1; - } else if (mrh->mrh_endian == 0x10000000) { - /* XXX - Endian mismatch - should be swapping! */ - return -1; - } else { - return -1; - } - return 0; -} - - -int ippr_msnrpc_out(fin, ip, aps, nat) -fr_info_t *fin; -ip_t *ip; -ap_session_t *aps; -nat_t *nat; -{ - msnrpcinfo_t *mri; - msnrpchdr_t *mrh; - tcphdr_t *tcp; - int dlen; - - mri = aps->aps_data; - if (mri == NULL) - return 0; - - tcp = (tcphdr_t *)fin->fin_dp; - dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); - if (dlen < IPF_MINMSNRPCLEN) - return 0; - - mrh = (msnrpchdr_t *)((char *)tcp + (TCP_OFF(tcp) << 2)); - if (ippr_msnrpc_check(ip, mrh)) - return 0; - - mri->mri_valid++; - - switch (mrh->mrh_type) - { - case 0x0b : /* BIND */ - case 0x00 : /* REQUEST */ - break; - case 0x0c : /* BIND ACK */ - case 0x02 : /* RESPONSE */ - default: - return 0; - } - mri->mri_cmd[1] = mrh->mrh_type; - return 0; -} - - -int ippr_msnrpc_in(fin, ip, aps, nat) -fr_info_t *fin; -ip_t *ip; -ap_session_t *aps; -nat_t *nat; -{ - tcphdr_t *tcp, tcph, *tcp2 = &tcph; - int dlen, sz, sz2, i; - msnrpcinfo_t *mri; - msnrpchdr_t *mrh; - fr_info_t fi; - u_short len; - char *s; - - mri = aps->aps_data; - if (mri == NULL) - return 0; - tcp = (tcphdr_t *)fin->fin_dp; - dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); - if (dlen < IPF_MINMSNRPCLEN) - return 0; - - mrh = (msnrpchdr_t *)((char *)tcp + (TCP_OFF(tcp) << 2)); - if (ippr_msnrpc_check(ip, mrh)) - return 0; - - mri->mri_valid++; - - switch (mrh->mrh_type) - { - case 0x0c : /* BIND ACK */ - if (mri->mri_cmd[1] != 0x0b) - return 0; - break; - case 0x02 : /* RESPONSE */ - if (mri->mri_cmd[1] != 0x00) - return 0; - break; - case 0x0b : /* BIND */ - case 0x00 : /* REQUEST */ - default: - return 0; - } - mri->mri_cmd[0] = mrh->mrh_type; - dlen -= sizeof(*mrh); - - /* - * Only processes RESPONSE's - */ - if (mrh->mrh_type != 0x02) - return 0; - - /* - * Skip over some bytes...what are these really ? - */ - if (dlen <= 44) - return 0; - s = (char *)(mrh + 1) + 20; - dlen -= 20; - bcopy(s, (char *)&len, sizeof(len)); - if (len == 1) { - s += 20; - dlen -= 20; - } else if (len == 2) { - s += 24; - dlen -= 24; - } else - return 0; - - if (dlen <= 10) - return 0; - dlen -= 10; - bcopy(s, (char *)&sz, sizeof(sz)); - s += sizeof(sz); - bcopy(s, (char *)&sz2, sizeof(sz2)); - s += sizeof(sz2); - if (sz2 != sz) - return 0; - if (sz > dlen) - return 0; - if (*s++ != 5) - return 0; - if (*s++ != 0) - return 0; - sz -= IPF_MSNRPCSKIP; - s += IPF_MSNRPCSKIP; - dlen -= IPF_MSNRPCSKIP; - - do { - if (sz < 7 || dlen < 7) - break; - bcopy(s, (char *)&len, sizeof(len)); - if (dlen < len) - break; - if (sz < len) - break; - - if (len != 1) - break; - sz -= 3; - i = *(s + 2); - s += 3; - dlen -= 3; - - bcopy(s, (char *)&len, sizeof(len)); - if (dlen < len) - break; - if (sz < len) - break; - s += sizeof(len); - - switch (i) - { - case 7 : - if (len == 2) { - bcopy(s, (char *)&mri->mri_rport, 2); - mri->mri_flags |= 1; - } - break; - case 9 : - if (len == 4) { - bcopy(s, (char *)&mri->mri_raddr, 4); - mri->mri_flags |= 2; - } - break; - default : - break; - } - sz -= len; - s += len; - dlen -= len; - } while (sz > 0); - - if (mri->mri_flags == 3) { - int slen; - - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - bzero((char *)tcp2, sizeof(*tcp2)); - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp2); - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - TCP_OFF_A(tcp2, 5); - fi.fin_data[0] = htons(mri->mri_rport); - tcp2->th_sport = mri->mri_rport; - fi.fin_data[1] = 0; - tcp2->th_dport = 0; - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - fi.fin_dp = (char *)tcp2; - fi.fin_fi.fi_daddr = ip->ip_dst.s_addr; - fi.fin_fi.fi_saddr = mri->mri_raddr.s_addr; - if (!fi.fin_fr) - fi.fin_fr = &msnfr; - if (fr_stlookup(&fi, NULL, NULL)) { - RWLOCK_EXIT(&ipf_state); - } else { - (void) fr_addstate(&fi, NULL, SI_W_DPORT|SI_CLONE); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_len = slen; - } - mri->mri_flags = 0; - return 0; -} diff --git a/contrib/ipfilter/ip_nat.c b/contrib/ipfilter/ip_nat.c deleted file mode 100644 index 55295028463a..000000000000 --- a/contrib/ipfilter/ip_nat.c +++ /dev/null @@ -1,4834 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1995-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#include -#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ - defined(_KERNEL) -# include "opt_ipfilter_log.h" -#endif -#if !defined(_KERNEL) -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include -# include -#else -# include -#endif -#include -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) -# include -# if !defined(__SVR4) && !defined(__svr4__) -# include -# endif -#endif -#if defined(__SVR4) || defined(__svr4__) -# include -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#if __FreeBSD_version >= 300000 -# include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#endif -#ifdef sun -# include -#endif -#include -#include -#include -#include - -#ifdef RFC1825 -# include -# include -extern struct ifnet vpnif; -#endif - -#if !defined(linux) -# include -#endif -#include -#include -#include -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#ifdef IPFILTER_SYNC -#include "netinet/ip_sync.h" -#endif -#if (__FreeBSD_version >= 300000) -# include -#endif -/* END OF INCLUDES */ - -#undef SOCKADDR_IN -#define SOCKADDR_IN struct sockaddr_in - -#if !defined(lint) -static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_nat.c,v 2.195.2.38 2005/03/28 11:09:54 darrenr Exp"; -#endif - - -/* ======================================================================== */ -/* How the NAT is organised and works. */ -/* */ -/* Inside (interface y) NAT Outside (interface x) */ -/* -------------------- -+- ------------------------------------- */ -/* Packet going | out, processsed by fr_checknatout() for x */ -/* ------------> | ------------> */ -/* src=10.1.1.1 | src=192.1.1.1 */ -/* | */ -/* | in, processed by fr_checknatin() for x */ -/* <------------ | <------------ */ -/* dst=10.1.1.1 | dst=192.1.1.1 */ -/* -------------------- -+- ------------------------------------- */ -/* fr_checknatout() - changes ip_src and if required, sport */ -/* - creates a new mapping, if required. */ -/* fr_checknatin() - changes ip_dst and if required, dport */ -/* */ -/* In the NAT table, internal source is recorded as "in" and externally */ -/* seen as "out". */ -/* ======================================================================== */ - - -nat_t **nat_table[2] = { NULL, NULL }, - *nat_instances = NULL; -ipnat_t *nat_list = NULL; -u_int ipf_nattable_max = NAT_TABLE_MAX; -u_int ipf_nattable_sz = NAT_TABLE_SZ; -u_int ipf_natrules_sz = NAT_SIZE; -u_int ipf_rdrrules_sz = RDR_SIZE; -u_int ipf_hostmap_sz = HOSTMAP_SIZE; -u_int fr_nat_maxbucket = 0, - fr_nat_maxbucket_reset = 1; -u_32_t nat_masks = 0; -u_32_t rdr_masks = 0; -ipnat_t **nat_rules = NULL; -ipnat_t **rdr_rules = NULL; -hostmap_t **maptable = NULL; -ipftq_t nat_tqb[IPF_TCP_NSTATES]; -ipftq_t nat_udptq; -ipftq_t nat_icmptq; -ipftq_t nat_iptq; -ipftq_t *nat_utqe = NULL; -#ifdef IPFILTER_LOG -int nat_logging = 1; -#else -int nat_logging = 0; -#endif - -u_long fr_defnatage = DEF_NAT_AGE, - fr_defnatipage = 120, /* 60 seconds */ - fr_defnaticmpage = 6; /* 3 seconds */ -natstat_t nat_stats; -int fr_nat_lock = 0; -int fr_nat_init = 0; -#if SOLARIS -extern int pfil_delayed_copy; -#endif - -static int nat_flushtable __P((void)); -static int nat_clearlist __P((void)); -static void nat_addnat __P((struct ipnat *)); -static void nat_addrdr __P((struct ipnat *)); -static void nat_delete __P((struct nat *, int)); -static void nat_delrdr __P((struct ipnat *)); -static void nat_delnat __P((struct ipnat *)); -static int fr_natgetent __P((caddr_t)); -static int fr_natgetsz __P((caddr_t)); -static int fr_natputent __P((caddr_t, int)); -static void nat_tabmove __P((nat_t *)); -static int nat_match __P((fr_info_t *, ipnat_t *)); -static INLINE int nat_newmap __P((fr_info_t *, nat_t *, natinfo_t *)); -static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); -static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr, - struct in_addr, struct in_addr, u_32_t)); -static void nat_hostmapdel __P((struct hostmap *)); -static INLINE int nat_icmpquerytype4 __P((int)); -static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int)); -static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int)); -static INLINE int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, - tcphdr_t *, nat_t **, int)); -static void nat_resolverule __P((ipnat_t *)); -static nat_t *fr_natclone __P((fr_info_t *, nat_t *)); -static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *)); -static INLINE int nat_wildok __P((nat_t *, int, int, int, int)); - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natinit */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: Nil */ -/* */ -/* Initialise all of the NAT locks, tables and other structures. */ -/* ------------------------------------------------------------------------ */ -int fr_natinit() -{ - int i; - - KMALLOCS(nat_table[0], nat_t **, sizeof(nat_t *) * ipf_nattable_sz); - if (nat_table[0] != NULL) - bzero((char *)nat_table[0], ipf_nattable_sz * sizeof(nat_t *)); - else - return -1; - - KMALLOCS(nat_table[1], nat_t **, sizeof(nat_t *) * ipf_nattable_sz); - if (nat_table[1] != NULL) - bzero((char *)nat_table[1], ipf_nattable_sz * sizeof(nat_t *)); - else - return -2; - - KMALLOCS(nat_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_natrules_sz); - if (nat_rules != NULL) - bzero((char *)nat_rules, ipf_natrules_sz * sizeof(ipnat_t *)); - else - return -3; - - KMALLOCS(rdr_rules, ipnat_t **, sizeof(ipnat_t *) * ipf_rdrrules_sz); - if (rdr_rules != NULL) - bzero((char *)rdr_rules, ipf_rdrrules_sz * sizeof(ipnat_t *)); - else - return -4; - - KMALLOCS(maptable, hostmap_t **, sizeof(hostmap_t *) * ipf_hostmap_sz); - if (maptable != NULL) - bzero((char *)maptable, sizeof(hostmap_t *) * ipf_hostmap_sz); - else - return -5; - - KMALLOCS(nat_stats.ns_bucketlen[0], u_long *, - ipf_nattable_sz * sizeof(u_long)); - if (nat_stats.ns_bucketlen[0] == NULL) - return -6; - bzero((char *)nat_stats.ns_bucketlen[0], - ipf_nattable_sz * sizeof(u_long)); - - KMALLOCS(nat_stats.ns_bucketlen[1], u_long *, - ipf_nattable_sz * sizeof(u_long)); - if (nat_stats.ns_bucketlen[1] == NULL) - return -7; - - bzero((char *)nat_stats.ns_bucketlen[1], - ipf_nattable_sz * sizeof(u_long)); - - if (fr_nat_maxbucket == 0) { - for (i = ipf_nattable_sz; i > 0; i >>= 1) - fr_nat_maxbucket++; - fr_nat_maxbucket *= 2; - } - - fr_sttab_init(nat_tqb); - /* - * Increase this because we may have "keep state" following this too - * and packet storms can occur if this is removed too quickly. - */ - nat_tqb[IPF_TCPS_CLOSED].ifq_ttl = fr_tcplastack; - nat_tqb[IPF_TCP_NSTATES - 1].ifq_next = &nat_udptq; - nat_udptq.ifq_ttl = fr_defnatage; - nat_udptq.ifq_ref = 1; - nat_udptq.ifq_head = NULL; - nat_udptq.ifq_tail = &nat_udptq.ifq_head; - MUTEX_INIT(&nat_udptq.ifq_lock, "nat ipftq udp tab"); - nat_udptq.ifq_next = &nat_icmptq; - nat_icmptq.ifq_ttl = fr_defnaticmpage; - nat_icmptq.ifq_ref = 1; - nat_icmptq.ifq_head = NULL; - nat_icmptq.ifq_tail = &nat_icmptq.ifq_head; - MUTEX_INIT(&nat_icmptq.ifq_lock, "nat icmp ipftq tab"); - nat_icmptq.ifq_next = &nat_iptq; - nat_iptq.ifq_ttl = fr_defnatipage; - nat_iptq.ifq_ref = 1; - nat_iptq.ifq_head = NULL; - nat_iptq.ifq_tail = &nat_iptq.ifq_head; - MUTEX_INIT(&nat_iptq.ifq_lock, "nat ip ipftq tab"); - nat_iptq.ifq_next = NULL; - - for (i = 0; i < IPF_TCP_NSTATES; i++) { - if (nat_tqb[i].ifq_ttl < fr_defnaticmpage) - nat_tqb[i].ifq_ttl = fr_defnaticmpage; -#ifdef LARGE_NAT - else if (nat_tqb[i].ifq_ttl > fr_defnatage) - nat_tqb[i].ifq_ttl = fr_defnatage; -#endif - } - - /* - * Increase this because we may have "keep state" following - * this too and packet storms can occur if this is removed - * too quickly. - */ - nat_tqb[IPF_TCPS_CLOSED].ifq_ttl = nat_tqb[IPF_TCPS_LAST_ACK].ifq_ttl; - - RWLOCK_INIT(&ipf_nat, "ipf IP NAT rwlock"); - RWLOCK_INIT(&ipf_natfrag, "ipf IP NAT-Frag rwlock"); - MUTEX_INIT(&ipf_nat_new, "ipf nat new mutex"); - MUTEX_INIT(&ipf_natio, "ipf nat io mutex"); - - fr_nat_init = 1; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_addrdr */ -/* Returns: Nil */ -/* Parameters: n(I) - pointer to NAT rule to add */ -/* */ -/* Adds a redirect rule to the hash table of redirect rules and the list of */ -/* loaded NAT rules. Updates the bitmask indicating which netmasks are in */ -/* use by redirect rules. */ -/* ------------------------------------------------------------------------ */ -static void nat_addrdr(n) -ipnat_t *n; -{ - ipnat_t **np; - u_32_t j; - u_int hv; - int k; - - k = count4bits(n->in_outmsk); - if ((k >= 0) && (k != 32)) - rdr_masks |= 1 << k; - j = (n->in_outip & n->in_outmsk); - hv = NAT_HASH_FN(j, 0, ipf_rdrrules_sz); - np = rdr_rules + hv; - while (*np != NULL) - np = &(*np)->in_rnext; - n->in_rnext = NULL; - n->in_prnext = np; - n->in_hv = hv; - *np = n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_addnat */ -/* Returns: Nil */ -/* Parameters: n(I) - pointer to NAT rule to add */ -/* */ -/* Adds a NAT map rule to the hash table of rules and the list of loaded */ -/* NAT rules. Updates the bitmask indicating which netmasks are in use by */ -/* redirect rules. */ -/* ------------------------------------------------------------------------ */ -static void nat_addnat(n) -ipnat_t *n; -{ - ipnat_t **np; - u_32_t j; - u_int hv; - int k; - - k = count4bits(n->in_inmsk); - if ((k >= 0) && (k != 32)) - nat_masks |= 1 << k; - j = (n->in_inip & n->in_inmsk); - hv = NAT_HASH_FN(j, 0, ipf_natrules_sz); - np = nat_rules + hv; - while (*np != NULL) - np = &(*np)->in_mnext; - n->in_mnext = NULL; - n->in_pmnext = np; - n->in_hv = hv; - *np = n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_delrdr */ -/* Returns: Nil */ -/* Parameters: n(I) - pointer to NAT rule to delete */ -/* */ -/* Removes a redirect rule from the hash table of redirect rules. */ -/* ------------------------------------------------------------------------ */ -static void nat_delrdr(n) -ipnat_t *n; -{ - if (n->in_rnext) - n->in_rnext->in_prnext = n->in_prnext; - *n->in_prnext = n->in_rnext; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_delnat */ -/* Returns: Nil */ -/* Parameters: n(I) - pointer to NAT rule to delete */ -/* */ -/* Removes a NAT map rule from the hash table of NAT map rules. */ -/* ------------------------------------------------------------------------ */ -static void nat_delnat(n) -ipnat_t *n; -{ - if (n->in_mnext != NULL) - n->in_mnext->in_pmnext = n->in_pmnext; - *n->in_pmnext = n->in_mnext; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_hostmap */ -/* Returns: struct hostmap* - NULL if no hostmap could be created, */ -/* else a pointer to the hostmapping to use */ -/* Parameters: np(I) - pointer to NAT rule */ -/* real(I) - real IP address */ -/* map(I) - mapped IP address */ -/* port(I) - destination port number */ -/* Write Locks: ipf_nat */ -/* */ -/* Check if an ip address has already been allocated for a given mapping */ -/* that is not doing port based translation. If is not yet allocated, then */ -/* create a new entry if a non-NULL NAT rule pointer has been supplied. */ -/* ------------------------------------------------------------------------ */ -static struct hostmap *nat_hostmap(np, src, dst, map, port) -ipnat_t *np; -struct in_addr src; -struct in_addr dst; -struct in_addr map; -u_32_t port; -{ - hostmap_t *hm; - u_int hv; - - hv = (src.s_addr ^ dst.s_addr); - hv += src.s_addr; - hv += dst.s_addr; - hv %= HOSTMAP_SIZE; - for (hm = maptable[hv]; hm; hm = hm->hm_next) - if ((hm->hm_srcip.s_addr == src.s_addr) && - (hm->hm_dstip.s_addr == dst.s_addr) && - ((np == NULL) || (np == hm->hm_ipnat)) && - ((port == 0) || (port == hm->hm_port))) { - hm->hm_ref++; - return hm; - } - - if (np == NULL) - return NULL; - - KMALLOC(hm, hostmap_t *); - if (hm) { - hm->hm_next = maptable[hv]; - hm->hm_pnext = maptable + hv; - if (maptable[hv] != NULL) - maptable[hv]->hm_pnext = &hm->hm_next; - maptable[hv] = hm; - hm->hm_ipnat = np; - hm->hm_srcip = src; - hm->hm_dstip = dst; - hm->hm_mapip = map; - hm->hm_ref = 1; - hm->hm_port = port; - } - return hm; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_hostmapdel */ -/* Returns: Nil */ -/* Parameters: hm(I) - pointer to hostmap structure */ -/* Write Locks: ipf_nat */ -/* */ -/* Decrement the references to this hostmap structure by one. If this */ -/* reaches zero then remove it and free it. */ -/* ------------------------------------------------------------------------ */ -static void nat_hostmapdel(hm) -struct hostmap *hm; -{ - hm->hm_ref--; - if (hm->hm_ref == 0) { - if (hm->hm_next) - hm->hm_next->hm_pnext = hm->hm_pnext; - *hm->hm_pnext = hm->hm_next; - KFREE(hm); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fix_outcksum */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* sp(I) - location of 16bit checksum to update */ -/* n((I) - amount to adjust checksum by */ -/* */ -/* Adjusts the 16bit checksum by "n" for packets going out. */ -/* ------------------------------------------------------------------------ */ -void fix_outcksum(fin, sp, n) -fr_info_t *fin; -u_short *sp; -u_32_t n; -{ - u_short sumshort; - u_32_t sum1; - - if (n == 0) - return; - - if (n & NAT_HW_CKSUM) { - n &= 0xffff; - n += fin->fin_dlen; - n = (n & 0xffff) + (n >> 16); - *sp = n & 0xffff; - return; - } - sum1 = (~ntohs(*sp)) & 0xffff; - sum1 += (n); - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - /* Again */ - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - sumshort = ~(u_short)sum1; - *(sp) = htons(sumshort); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fix_incksum */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* sp(I) - location of 16bit checksum to update */ -/* n((I) - amount to adjust checksum by */ -/* */ -/* Adjusts the 16bit checksum by "n" for packets going in. */ -/* ------------------------------------------------------------------------ */ -void fix_incksum(fin, sp, n) -fr_info_t *fin; -u_short *sp; -u_32_t n; -{ - u_short sumshort; - u_32_t sum1; - - if (n == 0) - return; - - if (n & NAT_HW_CKSUM) { - n &= 0xffff; - n += fin->fin_dlen; - n = (n & 0xffff) + (n >> 16); - *sp = n & 0xffff; - return; - } - sum1 = (~ntohs(*sp)) & 0xffff; - sum1 += ~(n) & 0xffff; - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - /* Again */ - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - sumshort = ~(u_short)sum1; - *(sp) = htons(sumshort); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fix_datacksum */ -/* Returns: Nil */ -/* Parameters: sp(I) - location of 16bit checksum to update */ -/* n((I) - amount to adjust checksum by */ -/* */ -/* Fix_datacksum is used *only* for the adjustments of checksums in the */ -/* data section of an IP packet. */ -/* */ -/* The only situation in which you need to do this is when NAT'ing an */ -/* ICMP error message. Such a message, contains in its body the IP header */ -/* of the original IP packet, that causes the error. */ -/* */ -/* You can't use fix_incksum or fix_outcksum in that case, because for the */ -/* kernel the data section of the ICMP error is just data, and no special */ -/* processing like hardware cksum or ntohs processing have been done by the */ -/* kernel on the data section. */ -/* ------------------------------------------------------------------------ */ -void fix_datacksum(sp, n) -u_short *sp; -u_32_t n; -{ - u_short sumshort; - u_32_t sum1; - - if (n == 0) - return; - - sum1 = (~ntohs(*sp)) & 0xffff; - sum1 += (n); - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - /* Again */ - sum1 = (sum1 >> 16) + (sum1 & 0xffff); - sumshort = ~(u_short)sum1; - *(sp) = htons(sumshort); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_nat_ioctl */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* cmd(I) - ioctl command integer */ -/* mode(I) - file mode bits used with open */ -/* */ -/* Processes an ioctl call made to operate on the IP Filter NAT device. */ -/* ------------------------------------------------------------------------ */ -int fr_nat_ioctl(data, cmd, mode) -ioctlcmd_t cmd; -caddr_t data; -int mode; -{ - ipnat_t *nat, *nt, *n = NULL, **np = NULL; - int error = 0, ret, arg, getlock; - ipnat_t natd; - -#if (BSD >= 199306) && defined(_KERNEL) - if ((securelevel >= 2) && (mode & FWRITE)) - return EPERM; -#endif - -#if defined(__osf__) && defined(_KERNEL) - getlock = 0; -#else - getlock = (mode & NAT_LOCKHELD) ? 0 : 1; -#endif - - nat = NULL; /* XXX gcc -Wuninitialized */ - if (cmd == (ioctlcmd_t)SIOCADNAT) { - KMALLOC(nt, ipnat_t *); - } else { - nt = NULL; - } - - if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT)) { - if (mode & NAT_SYSSPACE) { - bcopy(data, (char *)&natd, sizeof(natd)); - error = 0; - } else { - error = fr_inobj(data, &natd, IPFOBJ_IPNAT); - } - - } else if (cmd == (ioctlcmd_t)SIOCIPFFL) { /* SIOCFLNAT & SIOCCNATL */ - BCOPYIN(data, &arg, sizeof(arg)); - } - - if (error != 0) - goto done; - - /* - * For add/delete, look to see if the NAT entry is already present - */ - if ((cmd == (ioctlcmd_t)SIOCADNAT) || (cmd == (ioctlcmd_t)SIOCRMNAT)) { - nat = &natd; - if (nat->in_v == 0) /* For backward compat. */ - nat->in_v = 4; - nat->in_flags &= IPN_USERFLAGS; - if ((nat->in_redir & NAT_MAPBLK) == 0) { - if ((nat->in_flags & IPN_SPLIT) == 0) - nat->in_inip &= nat->in_inmsk; - if ((nat->in_flags & IPN_IPRANGE) == 0) - nat->in_outip &= nat->in_outmsk; - } - MUTEX_ENTER(&ipf_natio); - for (np = &nat_list; ((n = *np) != NULL); np = &n->in_next) - if (!bcmp((char *)&nat->in_flags, (char *)&n->in_flags, - IPN_CMPSIZ)) - break; - } - - switch (cmd) - { -#ifdef IPFILTER_LOG - case SIOCIPFFB : - { - int tmp; - - if (!(mode & FWRITE)) - error = EPERM; - else { - tmp = ipflog_clear(IPL_LOGNAT); - BCOPYOUT((char *)&tmp, (char *)data, sizeof(tmp)); - } - break; - } - case SIOCSETLG : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN((char *)data, (char *)&nat_logging, - sizeof(nat_logging)); - } - break; - case SIOCGETLG : - BCOPYOUT((char *)&nat_logging, (char *)data, - sizeof(nat_logging)); - break; - case FIONREAD : - arg = iplused[IPL_LOGNAT]; - BCOPYOUT(&arg, data, sizeof(arg)); - break; -#endif - case SIOCADNAT : - if (!(mode & FWRITE)) { - error = EPERM; - } else if (n != NULL) { - error = EEXIST; - } else if (nt == NULL) { - error = ENOMEM; - } - if (error != 0) { - MUTEX_EXIT(&ipf_natio); - break; - } - bcopy((char *)nat, (char *)nt, sizeof(*n)); - error = nat_siocaddnat(nt, np, getlock); - MUTEX_EXIT(&ipf_natio); - if (error == 0) - nt = NULL; - break; - case SIOCRMNAT : - if (!(mode & FWRITE)) { - error = EPERM; - n = NULL; - } else if (n == NULL) { - error = ESRCH; - } - - if (error != 0) { - MUTEX_EXIT(&ipf_natio); - break; - } - nat_siocdelnat(n, np, getlock); - - MUTEX_EXIT(&ipf_natio); - n = NULL; - break; - case SIOCGNATS : - nat_stats.ns_table[0] = nat_table[0]; - nat_stats.ns_table[1] = nat_table[1]; - nat_stats.ns_list = nat_list; - nat_stats.ns_maptable = maptable; - nat_stats.ns_nattab_sz = ipf_nattable_sz; - nat_stats.ns_nattab_max = ipf_nattable_max; - nat_stats.ns_rultab_sz = ipf_natrules_sz; - nat_stats.ns_rdrtab_sz = ipf_rdrrules_sz; - nat_stats.ns_hostmap_sz = ipf_hostmap_sz; - nat_stats.ns_instances = nat_instances; - nat_stats.ns_apslist = ap_sess_list; - error = fr_outobj(data, &nat_stats, IPFOBJ_NATSTAT); - break; - case SIOCGNATL : - { - natlookup_t nl; - - if (getlock) { - READ_ENTER(&ipf_nat); - } - error = fr_inobj(data, &nl, IPFOBJ_NATLOOKUP); - if (error == 0) { - if (nat_lookupredir(&nl) != NULL) { - error = fr_outobj(data, &nl, IPFOBJ_NATLOOKUP); - } else { - error = ESRCH; - } - } - if (getlock) { - RWLOCK_EXIT(&ipf_nat); - } - break; - } - case SIOCIPFFL : /* old SIOCFLNAT & SIOCCNATL */ - if (!(mode & FWRITE)) { - error = EPERM; - break; - } - if (getlock) { - WRITE_ENTER(&ipf_nat); - } - error = 0; - if (arg == 0) - ret = nat_flushtable(); - else if (arg == 1) - ret = nat_clearlist(); - else - error = EINVAL; - if (getlock) { - RWLOCK_EXIT(&ipf_nat); - } - if (error == 0) { - BCOPYOUT(&ret, data, sizeof(ret)); - } - break; - case SIOCPROXY : - error = appr_ioctl(data, cmd, mode); - break; - case SIOCSTLCK : - fr_lock(data, &fr_nat_lock); - break; - case SIOCSTPUT : - if (fr_nat_lock) { - error = fr_natputent(data, getlock); - } else { - error = EACCES; - } - break; - case SIOCSTGSZ : - if (fr_nat_lock) { - if (getlock) { - READ_ENTER(&ipf_nat); - } - error = fr_natgetsz(data); - if (getlock) { - RWLOCK_EXIT(&ipf_nat); - } - } else - error = EACCES; - break; - case SIOCSTGET : - if (fr_nat_lock) { - if (getlock) { - READ_ENTER(&ipf_nat); - } - error = fr_natgetent(data); - if (getlock) { - RWLOCK_EXIT(&ipf_nat); - } - } else - error = EACCES; - break; - default : - error = EINVAL; - break; - } -done: - if (nt) - KFREE(nt); - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_siocaddnat */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: n(I) - pointer to new NAT rule */ -/* np(I) - pointer to where to insert new NAT rule */ -/* getlock(I) - flag indicating if lock on ipf_nat is held */ -/* Mutex Locks: ipf_natio */ -/* */ -/* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ -/* from information passed to the kernel, then add it to the appropriate */ -/* NAT rule table(s). */ -/* ------------------------------------------------------------------------ */ -static int nat_siocaddnat(n, np, getlock) -ipnat_t *n, **np; -int getlock; -{ - int error = 0, i, j; - - nat_resolverule(n); - if (n->in_plabel[0] != '\0') { - if (n->in_apr == NULL) - return ENOENT; - } - - if ((n->in_age[0] == 0) && (n->in_age[1] != 0)) - return EINVAL; - - n->in_use = 0; - if (n->in_redir & NAT_MAPBLK) - n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); - else if (n->in_flags & IPN_AUTOPORTMAP) - n->in_space = USABLE_PORTS * ~ntohl(n->in_inmsk); - else if (n->in_flags & IPN_IPRANGE) - n->in_space = ntohl(n->in_outmsk) - ntohl(n->in_outip); - else if (n->in_flags & IPN_SPLIT) - n->in_space = 2; - else if (n->in_outmsk != 0) - n->in_space = ~ntohl(n->in_outmsk); - else - n->in_space = 1; - - /* - * Calculate the number of valid IP addresses in the output - * mapping range. In all cases, the range is inclusive of - * the start and ending IP addresses. - * If to a CIDR address, lose 2: broadcast + network address - * (so subtract 1) - * If to a range, add one. - * If to a single IP address, set to 1. - */ - if (n->in_space) { - if ((n->in_flags & IPN_IPRANGE) != 0) - n->in_space += 1; - else - n->in_space -= 1; - } else - n->in_space = 1; - - if ((n->in_outmsk != 0xffffffff) && (n->in_outmsk != 0) && - ((n->in_flags & (IPN_IPRANGE|IPN_SPLIT)) == 0)) - n->in_nip = ntohl(n->in_outip) + 1; - else if ((n->in_flags & IPN_SPLIT) && - (n->in_redir & NAT_REDIRECT)) - n->in_nip = ntohl(n->in_inip); - else - n->in_nip = ntohl(n->in_outip); - if (n->in_redir & NAT_MAP) { - n->in_pnext = ntohs(n->in_pmin); - /* - * Multiply by the number of ports made available. - */ - if (ntohs(n->in_pmax) >= ntohs(n->in_pmin)) { - n->in_space *= (ntohs(n->in_pmax) - - ntohs(n->in_pmin) + 1); - /* - * Because two different sources can map to - * different destinations but use the same - * local IP#/port #. - * If the result is smaller than in_space, then - * we may have wrapped around 32bits. - */ - i = n->in_inmsk; - if ((i != 0) && (i != 0xffffffff)) { - j = n->in_space * (~ntohl(i) + 1); - if (j >= n->in_space) - n->in_space = j; - else - n->in_space = 0xffffffff; - } - } - /* - * If no protocol is specified, multiple by 256 to allow for - * at least one IP:IP mapping per protocol. - */ - if ((n->in_flags & IPN_TCPUDPICMP) == 0) { - j = n->in_space * 256; - if (j >= n->in_space) - n->in_space = j; - else - n->in_space = 0xffffffff; - } - } - - /* Otherwise, these fields are preset */ - - if (getlock) { - WRITE_ENTER(&ipf_nat); - } - n->in_next = NULL; - *np = n; - - if (n->in_age[0] != 0) - n->in_tqehead[0] = fr_addtimeoutqueue(&nat_utqe, n->in_age[0]); - - if (n->in_age[1] != 0) - n->in_tqehead[1] = fr_addtimeoutqueue(&nat_utqe, n->in_age[1]); - - if (n->in_redir & NAT_REDIRECT) { - n->in_flags &= ~IPN_NOTDST; - nat_addrdr(n); - } - if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) { - n->in_flags &= ~IPN_NOTSRC; - nat_addnat(n); - } - n = NULL; - nat_stats.ns_rules++; -#if SOLARIS - pfil_delayed_copy = 0; -#endif - if (getlock) { - RWLOCK_EXIT(&ipf_nat); /* WRITE */ - } - - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_resolvrule */ -/* Returns: Nil */ -/* Parameters: n(I) - pointer to NAT rule */ -/* */ -/* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ -/* from information passed to the kernel, then add it to the appropriate */ -/* NAT rule table(s). */ -/* ------------------------------------------------------------------------ */ -static void nat_resolverule(n) -ipnat_t *n; -{ - n->in_ifnames[0][LIFNAMSIZ - 1] = '\0'; - n->in_ifps[0] = fr_resolvenic(n->in_ifnames[0], 4); - - n->in_ifnames[1][LIFNAMSIZ - 1] = '\0'; - if (n->in_ifnames[1][0] == '\0') { - (void) strncpy(n->in_ifnames[1], n->in_ifnames[0], LIFNAMSIZ); - n->in_ifps[1] = n->in_ifps[0]; - } else { - n->in_ifps[1] = fr_resolvenic(n->in_ifnames[0], 4); - } - - if (n->in_plabel[0] != '\0') { - n->in_apr = appr_lookup(n->in_p, n->in_plabel); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_siocdelnat */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: n(I) - pointer to new NAT rule */ -/* np(I) - pointer to where to insert new NAT rule */ -/* getlock(I) - flag indicating if lock on ipf_nat is held */ -/* Mutex Locks: ipf_natio */ -/* */ -/* Handle SIOCADNAT. Resolve and calculate details inside the NAT rule */ -/* from information passed to the kernel, then add it to the appropriate */ -/* NAT rule table(s). */ -/* ------------------------------------------------------------------------ */ -static void nat_siocdelnat(n, np, getlock) -ipnat_t *n, **np; -int getlock; -{ - if (getlock) { - WRITE_ENTER(&ipf_nat); - } - if (n->in_redir & NAT_REDIRECT) - nat_delrdr(n); - if (n->in_redir & (NAT_MAPBLK|NAT_MAP)) - nat_delnat(n); - if (nat_list == NULL) { - nat_masks = 0; - rdr_masks = 0; - } - - if (n->in_tqehead[0] != NULL) { - if (fr_deletetimeoutqueue(n->in_tqehead[0]) == 0) { - fr_freetimeoutqueue(n->in_tqehead[1]); - } - } - - if (n->in_tqehead[1] != NULL) { - if (fr_deletetimeoutqueue(n->in_tqehead[1]) == 0) { - fr_freetimeoutqueue(n->in_tqehead[1]); - } - } - - *np = n->in_next; - - if (n->in_use == 0) { - if (n->in_apr) - appr_free(n->in_apr); - KFREE(n); - nat_stats.ns_rules--; -#if SOLARIS - if (nat_stats.ns_rules == 0) - pfil_delayed_copy = 1; -#endif - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } - if (getlock) { - RWLOCK_EXIT(&ipf_nat); /* READ/WRITE */ - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natgetsz */ -/* Returns: int - 0 == success, != 0 is the error value. */ -/* Parameters: data(I) - pointer to natget structure with kernel pointer */ -/* get the size of. */ -/* */ -/* Handle SIOCSTGSZ. */ -/* Return the size of the nat list entry to be copied back to user space. */ -/* The size of the entry is stored in the ng_sz field and the enture natget */ -/* structure is copied back to the user. */ -/* ------------------------------------------------------------------------ */ -static int fr_natgetsz(data) -caddr_t data; -{ - ap_session_t *aps; - nat_t *nat, *n; - natget_t ng; - - BCOPYIN(data, &ng, sizeof(ng)); - - nat = ng.ng_ptr; - if (!nat) { - nat = nat_instances; - ng.ng_sz = 0; - /* - * Empty list so the size returned is 0. Simple. - */ - if (nat == NULL) { - BCOPYOUT(&ng, data, sizeof(ng)); - return 0; - } - } else { - /* - * Make sure the pointer we're copying from exists in the - * current list of entries. Security precaution to prevent - * copying of random kernel data. - */ - for (n = nat_instances; n; n = n->nat_next) - if (n == nat) - break; - if (!n) - return ESRCH; - } - - /* - * Incluse any space required for proxy data structures. - */ - ng.ng_sz = sizeof(nat_save_t); - aps = nat->nat_aps; - if (aps != NULL) { - ng.ng_sz += sizeof(ap_session_t) - 4; - if (aps->aps_data != 0) - ng.ng_sz += aps->aps_psiz; - } - - BCOPYOUT(&ng, data, sizeof(ng)); - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natgetent */ -/* Returns: int - 0 == success, != 0 is the error value. */ -/* Parameters: data(I) - pointer to natget structure with kernel pointer */ -/* to NAT structure to copy out. */ -/* */ -/* Handle SIOCSTGET. */ -/* Copies out NAT entry to user space. Any additional data held for a */ -/* proxy is also copied, as to is the NAT rule which was responsible for it */ -/* ------------------------------------------------------------------------ */ -static int fr_natgetent(data) -caddr_t data; -{ - int error, outsize; - ap_session_t *aps; - nat_save_t *ipn, ipns; - nat_t *n, *nat; - - error = fr_inobj(data, &ipns, IPFOBJ_NATSAVE); - if (error != 0) - return error; - - if ((ipns.ipn_dsize < sizeof(ipns)) || (ipns.ipn_dsize > 81920)) - return EINVAL; - - KMALLOCS(ipn, nat_save_t *, ipns.ipn_dsize); - if (ipn == NULL) - return ENOMEM; - - ipn->ipn_dsize = ipns.ipn_dsize; - nat = ipns.ipn_next; - if (nat == NULL) { - nat = nat_instances; - if (nat == NULL) { - if (nat_instances == NULL) - error = ENOENT; - goto finished; - } - } else { - /* - * Make sure the pointer we're copying from exists in the - * current list of entries. Security precaution to prevent - * copying of random kernel data. - */ - for (n = nat_instances; n; n = n->nat_next) - if (n == nat) - break; - if (n == NULL) { - error = ESRCH; - goto finished; - } - } - ipn->ipn_next = nat->nat_next; - - /* - * Copy the NAT structure. - */ - bcopy((char *)nat, &ipn->ipn_nat, sizeof(*nat)); - - /* - * If we have a pointer to the NAT rule it belongs to, save that too. - */ - if (nat->nat_ptr != NULL) - bcopy((char *)nat->nat_ptr, (char *)&ipn->ipn_ipnat, - sizeof(ipn->ipn_ipnat)); - - /* - * If we also know the NAT entry has an associated filter rule, - * save that too. - */ - if (nat->nat_fr != NULL) - bcopy((char *)nat->nat_fr, (char *)&ipn->ipn_fr, - sizeof(ipn->ipn_fr)); - - /* - * Last but not least, if there is an application proxy session set - * up for this NAT entry, then copy that out too, including any - * private data saved along side it by the proxy. - */ - aps = nat->nat_aps; - outsize = ipn->ipn_dsize - sizeof(*ipn) + sizeof(ipn->ipn_data); - if (aps != NULL) { - char *s; - - if (outsize < sizeof(*aps)) { - error = ENOBUFS; - goto finished; - } - - s = ipn->ipn_data; - bcopy((char *)aps, s, sizeof(*aps)); - s += sizeof(*aps); - outsize -= sizeof(*aps); - if ((aps->aps_data != NULL) && (outsize >= aps->aps_psiz)) - bcopy(aps->aps_data, s, aps->aps_psiz); - else - error = ENOBUFS; - } - if (error == 0) { - error = fr_outobjsz(data, ipn, IPFOBJ_NATSAVE, ipns.ipn_dsize); - } - -finished: - if (ipn != NULL) { - KFREES(ipn, ipns.ipn_dsize); - } - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natputent */ -/* Returns: int - 0 == success, != 0 is the error value. */ -/* Parameters: data(I) - pointer to natget structure with NAT */ -/* structure information to load into the kernel */ -/* getlock(I) - flag indicating whether or not a write lock */ -/* on ipf_nat is already held. */ -/* */ -/* Handle SIOCSTPUT. */ -/* Loads a NAT table entry from user space, including a NAT rule, proxy and */ -/* firewall rule data structures, if pointers to them indicate so. */ -/* ------------------------------------------------------------------------ */ -static int fr_natputent(data, getlock) -caddr_t data; -int getlock; -{ - nat_save_t ipn, *ipnn; - ap_session_t *aps; - nat_t *n, *nat; - frentry_t *fr; - fr_info_t fin; - ipnat_t *in; - int error; - - error = fr_inobj(data, &ipn, IPFOBJ_NATSAVE); - if (error != 0) - return error; - - /* - * Initialise early because of code at junkput label. - */ - in = NULL; - aps = NULL; - nat = NULL; - ipnn = NULL; - - /* - * New entry, copy in the rest of the NAT entry if it's size is more - * than just the nat_t structure. - */ - fr = NULL; - if (ipn.ipn_dsize > sizeof(ipn)) { - if (ipn.ipn_dsize > 81920) { - error = ENOMEM; - goto junkput; - } - - KMALLOCS(ipnn, nat_save_t *, ipn.ipn_dsize); - if (ipnn == NULL) - return ENOMEM; - - error = fr_inobjsz(data, ipnn, IPFOBJ_NATSAVE, ipn.ipn_dsize); - if (error != 0) { - error = EFAULT; - goto junkput; - } - } else - ipnn = &ipn; - - KMALLOC(nat, nat_t *); - if (nat == NULL) { - error = ENOMEM; - goto junkput; - } - - bcopy((char *)&ipnn->ipn_nat, (char *)nat, sizeof(*nat)); - /* - * Initialize all these so that nat_delete() doesn't cause a crash. - */ - bzero((char *)nat, offsetof(struct nat, nat_tqe)); - nat->nat_tqe.tqe_pnext = NULL; - nat->nat_tqe.tqe_next = NULL; - nat->nat_tqe.tqe_ifq = NULL; - nat->nat_tqe.tqe_parent = nat; - - /* - * Restore the rule associated with this nat session - */ - in = ipnn->ipn_nat.nat_ptr; - if (in != NULL) { - KMALLOC(in, ipnat_t *); - nat->nat_ptr = in; - if (in == NULL) { - error = ENOMEM; - goto junkput; - } - bzero((char *)in, offsetof(struct ipnat, in_next6)); - bcopy((char *)&ipnn->ipn_ipnat, (char *)in, sizeof(*in)); - in->in_use = 1; - in->in_flags |= IPN_DELETE; - - ATOMIC_INC(nat_stats.ns_rules); - - nat_resolverule(in); - } - - /* - * Check that the NAT entry doesn't already exist in the kernel. - */ - bzero((char *)&fin, sizeof(fin)); - fin.fin_p = nat->nat_p; - if (nat->nat_dir == NAT_OUTBOUND) { - fin.fin_data[0] = ntohs(nat->nat_oport); - fin.fin_data[1] = ntohs(nat->nat_outport); - fin.fin_ifp = nat->nat_ifps[1]; - if (nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip, - nat->nat_inip) != NULL) { - error = EEXIST; - goto junkput; - } - } else if (nat->nat_dir == NAT_INBOUND) { - fin.fin_data[0] = ntohs(nat->nat_outport); - fin.fin_data[1] = ntohs(nat->nat_oport); - fin.fin_ifp = nat->nat_ifps[0]; - if (nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip, - nat->nat_oip) != NULL) { - error = EEXIST; - goto junkput; - } - } else { - error = EINVAL; - goto junkput; - } - - /* - * Restore ap_session_t structure. Include the private data allocated - * if it was there. - */ - aps = nat->nat_aps; - if (aps != NULL) { - KMALLOC(aps, ap_session_t *); - nat->nat_aps = aps; - if (aps == NULL) { - error = ENOMEM; - goto junkput; - } - bcopy(ipnn->ipn_data, (char *)aps, sizeof(*aps)); - if (in != NULL) - aps->aps_apr = in->in_apr; - else - aps->aps_apr = NULL; - if (aps->aps_psiz != 0) { - if (aps->aps_psiz > 81920) { - error = ENOMEM; - goto junkput; - } - KMALLOCS(aps->aps_data, void *, aps->aps_psiz); - if (aps->aps_data == NULL) { - error = ENOMEM; - goto junkput; - } - bcopy(ipnn->ipn_data + sizeof(*aps), aps->aps_data, - aps->aps_psiz); - } else { - aps->aps_psiz = 0; - aps->aps_data = NULL; - } - } - - /* - * If there was a filtering rule associated with this entry then - * build up a new one. - */ - fr = nat->nat_fr; - if (fr != NULL) { - if ((nat->nat_flags & SI_NEWFR) != 0) { - KMALLOC(fr, frentry_t *); - nat->nat_fr = fr; - if (fr == NULL) { - error = ENOMEM; - goto junkput; - } - ipnn->ipn_nat.nat_fr = fr; - fr->fr_ref = 1; - (void) fr_outobj(data, ipnn, IPFOBJ_NATSAVE); - bcopy((char *)&ipnn->ipn_fr, (char *)fr, sizeof(*fr)); - MUTEX_NUKE(&fr->fr_lock); - MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock"); - } else { - READ_ENTER(&ipf_nat); - for (n = nat_instances; n; n = n->nat_next) - if (n->nat_fr == fr) - break; - - if (n != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - MUTEX_EXIT(&fr->fr_lock); - } - RWLOCK_EXIT(&ipf_nat); - - if (!n) { - error = ESRCH; - goto junkput; - } - } - } - - if (ipnn != &ipn) { - KFREES(ipnn, ipn.ipn_dsize); - ipnn = NULL; - } - - if (getlock) { - WRITE_ENTER(&ipf_nat); - } - error = nat_insert(nat, nat->nat_rev); - if ((error == 0) && (aps != NULL)) { - aps->aps_next = ap_sess_list; - ap_sess_list = aps; - } - if (getlock) { - RWLOCK_EXIT(&ipf_nat); - } - - if (error == 0) - return 0; - - error = ENOMEM; - -junkput: - if (fr != NULL) - fr_derefrule(&fr); - - if ((ipnn != NULL) && (ipnn != &ipn)) { - KFREES(ipnn, ipn.ipn_dsize); - } - if (nat != NULL) { - if (aps != NULL) { - if (aps->aps_data != NULL) { - KFREES(aps->aps_data, aps->aps_psiz); - } - KFREE(aps); - } - if (in != NULL) { - if (in->in_apr) - appr_free(in->in_apr); - KFREE(in); - } - KFREE(nat); - } - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_delete */ -/* Returns: Nil */ -/* Parameters: natd(I) - pointer to NAT structure to delete */ -/* logtype(I) - type of LOG record to create before deleting */ -/* Write Lock: ipf_nat */ -/* */ -/* Delete a nat entry from the various lists and table. If NAT logging is */ -/* enabled then generate a NAT log record for this event. */ -/* ------------------------------------------------------------------------ */ -static void nat_delete(nat, logtype) -struct nat *nat; -int logtype; -{ - struct ipnat *ipn; - - if (logtype != 0 && nat_logging != 0) - nat_log(nat, logtype); - - MUTEX_ENTER(&ipf_nat_new); - - /* - * Take it as a general indication that all the pointers are set if - * nat_pnext is set. - */ - if (nat->nat_pnext != NULL) { - nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--; - nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--; - - *nat->nat_pnext = nat->nat_next; - if (nat->nat_next != NULL) { - nat->nat_next->nat_pnext = nat->nat_pnext; - nat->nat_next = NULL; - } - nat->nat_pnext = NULL; - - *nat->nat_phnext[0] = nat->nat_hnext[0]; - if (nat->nat_hnext[0] != NULL) { - nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0]; - nat->nat_hnext[0] = NULL; - } - nat->nat_phnext[0] = NULL; - - *nat->nat_phnext[1] = nat->nat_hnext[1]; - if (nat->nat_hnext[1] != NULL) { - nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1]; - nat->nat_hnext[1] = NULL; - } - nat->nat_phnext[1] = NULL; - - if ((nat->nat_flags & SI_WILDP) != 0) - nat_stats.ns_wilds--; - } - - if (nat->nat_me != NULL) { - *nat->nat_me = NULL; - nat->nat_me = NULL; - } - - fr_deletequeueentry(&nat->nat_tqe); - - nat->nat_ref--; - if (nat->nat_ref > 0) { - MUTEX_EXIT(&ipf_nat_new); - return; - } - -#ifdef IPFILTER_SYNC - if (nat->nat_sync) - ipfsync_del(nat->nat_sync); -#endif - - if (nat->nat_fr != NULL) - (void)fr_derefrule(&nat->nat_fr); - - if (nat->nat_hm != NULL) - nat_hostmapdel(nat->nat_hm); - - /* - * If there is an active reference from the nat entry to its parent - * rule, decrement the rule's reference count and free it too if no - * longer being used. - */ - ipn = nat->nat_ptr; - if (ipn != NULL) { - ipn->in_space++; - ipn->in_use--; - if (ipn->in_use == 0 && (ipn->in_flags & IPN_DELETE)) { - if (ipn->in_apr) - appr_free(ipn->in_apr); - KFREE(ipn); - nat_stats.ns_rules--; -#if SOLARIS - if (nat_stats.ns_rules == 0) - pfil_delayed_copy = 1; -#endif - } - } - - MUTEX_DESTROY(&nat->nat_lock); - - aps_free(nat->nat_aps); - nat_stats.ns_inuse--; - MUTEX_EXIT(&ipf_nat_new); - - /* - * If there's a fragment table entry too for this nat entry, then - * dereference that as well. This is after nat_lock is released - * because of Tru64. - */ - fr_forgetnat((void *)nat); - - KFREE(nat); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_flushtable */ -/* Returns: int - number of NAT rules deleted */ -/* Parameters: Nil */ -/* */ -/* Deletes all currently active NAT sessions. In deleting each NAT entry a */ -/* log record should be emitted in nat_delete() if NAT logging is enabled. */ -/* ------------------------------------------------------------------------ */ -/* - * nat_flushtable - clear the NAT table of all mapping entries. - */ -static int nat_flushtable() -{ - nat_t *nat; - int j = 0; - - /* - * ALL NAT mappings deleted, so lets just make the deletions - * quicker. - */ - if (nat_table[0] != NULL) - bzero((char *)nat_table[0], - sizeof(nat_table[0]) * ipf_nattable_sz); - if (nat_table[1] != NULL) - bzero((char *)nat_table[1], - sizeof(nat_table[1]) * ipf_nattable_sz); - - while ((nat = nat_instances) != NULL) { - nat_delete(nat, NL_FLUSH); - j++; - } - - nat_stats.ns_inuse = 0; - return j; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_clearlist */ -/* Returns: int - number of NAT/RDR rules deleted */ -/* Parameters: Nil */ -/* */ -/* Delete all rules in the current list of rules. There is nothing elegant */ -/* about this cleanup: simply free all entries on the list of rules and */ -/* clear out the tables used for hashed NAT rule lookups. */ -/* ------------------------------------------------------------------------ */ -static int nat_clearlist() -{ - ipnat_t *n, **np = &nat_list; - int i = 0; - - if (nat_rules != NULL) - bzero((char *)nat_rules, sizeof(*nat_rules) * ipf_natrules_sz); - if (rdr_rules != NULL) - bzero((char *)rdr_rules, sizeof(*rdr_rules) * ipf_rdrrules_sz); - - while ((n = *np) != NULL) { - *np = n->in_next; - if (n->in_use == 0) { - if (n->in_apr != NULL) - appr_free(n->in_apr); - KFREE(n); - nat_stats.ns_rules--; - } else { - n->in_flags |= IPN_DELETE; - n->in_next = NULL; - } - i++; - } -#if SOLARIS - pfil_delayed_copy = 1; -#endif - nat_masks = 0; - rdr_masks = 0; - return i; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_newmap */ -/* Returns: int - -1 == error, 0 == success */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT entry */ -/* ni(I) - pointer to structure with misc. information needed */ -/* to create new NAT entry. */ -/* */ -/* Given an empty NAT structure, populate it with new information about a */ -/* new NAT session, as defined by the matching NAT rule. */ -/* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/ -/* to the new IP address for the translation. */ -/* ------------------------------------------------------------------------ */ -static INLINE int nat_newmap(fin, nat, ni) -fr_info_t *fin; -nat_t *nat; -natinfo_t *ni; -{ - u_short st_port, dport, sport, port, sp, dp; - struct in_addr in, inb; - hostmap_t *hm; - u_32_t flags; - u_32_t st_ip; - ipnat_t *np; - nat_t *natl; - int l; - - /* - * If it's an outbound packet which doesn't match any existing - * record, then create a new port - */ - l = 0; - hm = NULL; - np = ni->nai_np; - st_ip = np->in_nip; - st_port = np->in_pnext; - flags = ni->nai_flags; - sport = ni->nai_sport; - dport = ni->nai_dport; - - /* - * Do a loop until we either run out of entries to try or we find - * a NAT mapping that isn't currently being used. This is done - * because the change to the source is not (usually) being fixed. - */ - do { - port = 0; - in.s_addr = htonl(np->in_nip); - if (l == 0) { - /* - * Check to see if there is an existing NAT - * setup for this IP address pair. - */ - hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, - in, 0); - if (hm != NULL) - in.s_addr = hm->hm_mapip.s_addr; - } else if ((l == 1) && (hm != NULL)) { - nat_hostmapdel(hm); - hm = NULL; - } - in.s_addr = ntohl(in.s_addr); - - nat->nat_hm = hm; - - if ((np->in_outmsk == 0xffffffff) && (np->in_pnext == 0)) { - if (l > 0) - return -1; - } - - if (np->in_redir == NAT_BIMAP && - np->in_inmsk == np->in_outmsk) { - /* - * map the address block in a 1:1 fashion - */ - in.s_addr = np->in_outip; - in.s_addr |= fin->fin_saddr & ~np->in_inmsk; - in.s_addr = ntohl(in.s_addr); - - } else if (np->in_redir & NAT_MAPBLK) { - if ((l >= np->in_ppip) || ((l > 0) && - !(flags & IPN_TCPUDP))) - return -1; - /* - * map-block - Calculate destination address. - */ - in.s_addr = ntohl(fin->fin_saddr); - in.s_addr &= ntohl(~np->in_inmsk); - inb.s_addr = in.s_addr; - in.s_addr /= np->in_ippip; - in.s_addr &= ntohl(~np->in_outmsk); - in.s_addr += ntohl(np->in_outip); - /* - * Calculate destination port. - */ - if ((flags & IPN_TCPUDP) && - (np->in_ppip != 0)) { - port = ntohs(sport) + l; - port %= np->in_ppip; - port += np->in_ppip * - (inb.s_addr % np->in_ippip); - port += MAPBLK_MINPORT; - port = htons(port); - } - - } else if ((np->in_outip == 0) && - (np->in_outmsk == 0xffffffff)) { - /* - * 0/32 - use the interface's IP address. - */ - if ((l > 0) || - fr_ifpaddr(4, FRI_NORMAL, fin->fin_ifp, - &in, NULL) == -1) - return -1; - in.s_addr = ntohl(in.s_addr); - - } else if ((np->in_outip == 0) && (np->in_outmsk == 0)) { - /* - * 0/0 - use the original source address/port. - */ - if (l > 0) - return -1; - in.s_addr = ntohl(fin->fin_saddr); - - } else if ((np->in_outmsk != 0xffffffff) && - (np->in_pnext == 0) && ((l > 0) || (hm == NULL))) - np->in_nip++; - - natl = NULL; - - if ((flags & IPN_TCPUDP) && - ((np->in_redir & NAT_MAPBLK) == 0) && - (np->in_flags & IPN_AUTOPORTMAP)) { - /* - * "ports auto" (without map-block) - */ - if ((l > 0) && (l % np->in_ppip == 0)) { - if (l > np->in_space) { - return -1; - } else if ((l > np->in_ppip) && - np->in_outmsk != 0xffffffff) - np->in_nip++; - } - if (np->in_ppip != 0) { - port = ntohs(sport); - port += (l % np->in_ppip); - port %= np->in_ppip; - port += np->in_ppip * - (ntohl(fin->fin_saddr) % - np->in_ippip); - port += MAPBLK_MINPORT; - port = htons(port); - } - - } else if (((np->in_redir & NAT_MAPBLK) == 0) && - (flags & IPN_TCPUDPICMP) && (np->in_pnext != 0)) { - /* - * Standard port translation. Select next port. - */ - port = htons(np->in_pnext++); - - if (np->in_pnext > ntohs(np->in_pmax)) { - np->in_pnext = ntohs(np->in_pmin); - if (np->in_outmsk != 0xffffffff) - np->in_nip++; - } - } - - if (np->in_flags & IPN_IPRANGE) { - if (np->in_nip > ntohl(np->in_outmsk)) - np->in_nip = ntohl(np->in_outip); - } else { - if ((np->in_outmsk != 0xffffffff) && - ((np->in_nip + 1) & ntohl(np->in_outmsk)) > - ntohl(np->in_outip)) - np->in_nip = ntohl(np->in_outip) + 1; - } - - if ((port == 0) && (flags & (IPN_TCPUDPICMP|IPN_ICMPQUERY))) - port = sport; - - /* - * Here we do a lookup of the connection as seen from - * the outside. If an IP# pair already exists, try - * again. So if you have A->B becomes C->B, you can - * also have D->E become C->E but not D->B causing - * another C->B. Also take protocol and ports into - * account when determining whether a pre-existing - * NAT setup will cause an external conflict where - * this is appropriate. - */ - inb.s_addr = htonl(in.s_addr); - sp = fin->fin_data[0]; - dp = fin->fin_data[1]; - fin->fin_data[0] = fin->fin_data[1]; - fin->fin_data[1] = htons(port); - natl = nat_inlookup(fin, flags & ~(SI_WILDP|NAT_SEARCH), - (u_int)fin->fin_p, fin->fin_dst, inb); - fin->fin_data[0] = sp; - fin->fin_data[1] = dp; - - /* - * Has the search wrapped around and come back to the - * start ? - */ - if ((natl != NULL) && - (np->in_pnext != 0) && (st_port == np->in_pnext) && - (np->in_nip != 0) && (st_ip == np->in_nip)) - return -1; - l++; - } while (natl != NULL); - - if (np->in_space > 0) - np->in_space--; - - /* Setup the NAT table */ - nat->nat_inip = fin->fin_src; - nat->nat_outip.s_addr = htonl(in.s_addr); - nat->nat_oip = fin->fin_dst; - if (nat->nat_hm == NULL) - nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, - nat->nat_outip, 0); - - /* - * The ICMP checksum does not have a pseudo header containing - * the IP addresses - */ - ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr)); - ni->nai_sum2 = LONG_SUM(in.s_addr); - if ((flags & IPN_TCPUDP)) { - ni->nai_sum1 += ntohs(sport); - ni->nai_sum2 += ntohs(port); - } - - if (flags & IPN_TCPUDP) { - nat->nat_inport = sport; - nat->nat_outport = port; /* sport */ - nat->nat_oport = dport; - ((tcphdr_t *)fin->fin_dp)->th_sport = port; - } else if (flags & IPN_ICMPQUERY) { - ((icmphdr_t *)fin->fin_dp)->icmp_id = port; - nat->nat_inport = port; - nat->nat_outport = port; - } else if (fin->fin_p == IPPROTO_GRE) { -#if 0 - nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags; - if (GRE_REV(nat->nat_gre.gs_flags) == 1) { - nat->nat_oport = 0;/*fin->fin_data[1];*/ - nat->nat_inport = 0;/*fin->fin_data[0];*/ - nat->nat_outport = 0;/*fin->fin_data[0];*/ - nat->nat_call[0] = fin->fin_data[0]; - nat->nat_call[1] = fin->fin_data[0]; - } -#endif - } - ni->nai_ip.s_addr = in.s_addr; - ni->nai_port = port; - ni->nai_nport = dport; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_newrdr */ -/* Returns: int - -1 == error, 0 == success (no move), 1 == success and */ -/* allow rule to be moved if IPN_ROUNDR is set. */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT entry */ -/* ni(I) - pointer to structure with misc. information needed */ -/* to create new NAT entry. */ -/* */ -/* ni.nai_ip is passed in uninitialised and must be set, in host byte order,*/ -/* to the new IP address for the translation. */ -/* ------------------------------------------------------------------------ */ -static INLINE int nat_newrdr(fin, nat, ni) -fr_info_t *fin; -nat_t *nat; -natinfo_t *ni; -{ - u_short nport, dport, sport; - struct in_addr in; - hostmap_t *hm; - u_32_t flags; - ipnat_t *np; - int move; - - move = 1; - hm = NULL; - in.s_addr = 0; - np = ni->nai_np; - flags = ni->nai_flags; - sport = ni->nai_sport; - dport = ni->nai_dport; - - /* - * If the matching rule has IPN_STICKY set, then we want to have the - * same rule kick in as before. Why would this happen? If you have - * a collection of rdr rules with "round-robin sticky", the current - * packet might match a different one to the previous connection but - * we want the same destination to be used. - */ - if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == - (IPN_ROUNDR|IPN_STICKY)) { - hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in, - (u_32_t)dport); - if (hm != NULL) { - in.s_addr = ntohl(hm->hm_mapip.s_addr); - np = hm->hm_ipnat; - ni->nai_np = np; - move = 0; - } - } - - /* - * Otherwise, it's an inbound packet. Most likely, we don't - * want to rewrite source ports and source addresses. Instead, - * we want to rewrite to a fixed internal address and fixed - * internal port. - */ - if (np->in_flags & IPN_SPLIT) { - in.s_addr = np->in_nip; - - if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == IPN_STICKY) { - hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, - in, (u_32_t)dport); - if (hm != NULL) { - in.s_addr = hm->hm_mapip.s_addr; - move = 0; - } - } - - if (hm == NULL || hm->hm_ref == 1) { - if (np->in_inip == htonl(in.s_addr)) { - np->in_nip = ntohl(np->in_inmsk); - move = 0; - } else { - np->in_nip = ntohl(np->in_inip); - } - } - - } else if ((np->in_inip == 0) && (np->in_inmsk == 0xffffffff)) { - /* - * 0/32 - use the interface's IP address. - */ - if (fr_ifpaddr(4, FRI_NORMAL, fin->fin_ifp, &in, NULL) == -1) - return -1; - in.s_addr = ntohl(in.s_addr); - - } else if ((np->in_inip == 0) && (np->in_inmsk== 0)) { - /* - * 0/0 - use the original destination address/port. - */ - in.s_addr = ntohl(fin->fin_daddr); - - } else if (np->in_redir == NAT_BIMAP && - np->in_inmsk == np->in_outmsk) { - /* - * map the address block in a 1:1 fashion - */ - in.s_addr = np->in_inip; - in.s_addr |= fin->fin_daddr & ~np->in_inmsk; - in.s_addr = ntohl(in.s_addr); - } else { - in.s_addr = ntohl(np->in_inip); - } - - if ((np->in_pnext == 0) || ((flags & NAT_NOTRULEPORT) != 0)) - nport = dport; - else { - /* - * Whilst not optimized for the case where - * pmin == pmax, the gain is not significant. - */ - if (((np->in_flags & IPN_FIXEDDPORT) == 0) && - (np->in_pmin != np->in_pmax)) { - nport = ntohs(dport) - ntohs(np->in_pmin) + - ntohs(np->in_pnext); - nport = htons(nport); - } else - nport = np->in_pnext; - } - - /* - * When the redirect-to address is set to 0.0.0.0, just - * assume a blank `forwarding' of the packet. We don't - * setup any translation for this either. - */ - if (in.s_addr == 0) { - if (nport == dport) - return -1; - in.s_addr = ntohl(fin->fin_daddr); - } - - nat->nat_inip.s_addr = htonl(in.s_addr); - nat->nat_outip = fin->fin_dst; - nat->nat_oip = fin->fin_src; - - ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport); - ni->nai_sum2 = LONG_SUM(in.s_addr) + ntohs(nport); - - ni->nai_ip.s_addr = in.s_addr; - ni->nai_nport = nport; - ni->nai_port = sport; - - if (flags & IPN_TCPUDP) { - nat->nat_inport = nport; - nat->nat_outport = dport; - nat->nat_oport = sport; - ((tcphdr_t *)fin->fin_dp)->th_dport = nport; - } else if (flags & IPN_ICMPQUERY) { - ((icmphdr_t *)fin->fin_dp)->icmp_id = nport; - nat->nat_inport = nport; - nat->nat_outport = nport; - } else if (fin->fin_p == IPPROTO_GRE) { -#if 0 - nat->nat_gre.gs_flags = ((grehdr_t *)fin->fin_dp)->gr_flags; - if (GRE_REV(nat->nat_gre.gs_flags) == 1) { - nat->nat_call[0] = fin->fin_data[0]; - nat->nat_call[1] = fin->fin_data[1]; - nat->nat_oport = 0; /*fin->fin_data[0];*/ - nat->nat_inport = 0; /*fin->fin_data[1];*/ - nat->nat_outport = 0; /*fin->fin_data[1];*/ - } -#endif - } - - return move; -} - -/* ------------------------------------------------------------------------ */ -/* Function: nat_new */ -/* Returns: nat_t* - NULL == failure to create new NAT structure, */ -/* else pointer to new NAT structure */ -/* Parameters: fin(I) - pointer to packet information */ -/* np(I) - pointer to NAT rule */ -/* natsave(I) - pointer to where to store NAT struct pointer */ -/* flags(I) - flags describing the current packet */ -/* direction(I) - direction of packet (in/out) */ -/* Write Lock: ipf_nat */ -/* */ -/* Attempts to create a new NAT entry. Does not actually change the packet */ -/* in any way. */ -/* */ -/* This fucntion is in three main parts: (1) deal with creating a new NAT */ -/* structure for a "MAP" rule (outgoing NAT translation); (2) deal with */ -/* creating a new NAT structure for a "RDR" rule (incoming NAT translation) */ -/* and (3) building that structure and putting it into the NAT table(s). */ -/* ------------------------------------------------------------------------ */ -nat_t *nat_new(fin, np, natsave, flags, direction) -fr_info_t *fin; -ipnat_t *np; -nat_t **natsave; -u_int flags; -int direction; -{ - u_short port = 0, sport = 0, dport = 0, nport = 0; - tcphdr_t *tcp = NULL; - hostmap_t *hm = NULL; - struct in_addr in; - nat_t *nat, *natl; - u_int nflags; - natinfo_t ni; - u_32_t sumd; - int move; -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC) - qpktinfo_t *qpi = fin->fin_qpi; -#endif - - if (nat_stats.ns_inuse >= ipf_nattable_max) { - nat_stats.ns_memfail++; - return NULL; - } - - move = 1; - nflags = np->in_flags & flags; - nflags &= NAT_FROMRULE; - - ni.nai_np = np; - ni.nai_nflags = nflags; - ni.nai_flags = flags; - - /* Give me a new nat */ - KMALLOC(nat, nat_t *); - if (nat == NULL) { - nat_stats.ns_memfail++; - /* - * Try to automatically tune the max # of entries in the - * table allowed to be less than what will cause kmem_alloc() - * to fail and try to eliminate panics due to out of memory - * conditions arising. - */ - if (ipf_nattable_max > ipf_nattable_sz) { - ipf_nattable_max = nat_stats.ns_inuse - 100; - printf("ipf_nattable_max reduced to %d\n", - ipf_nattable_max); - } - return NULL; - } - - if (flags & IPN_TCPUDP) { - tcp = fin->fin_dp; - ni.nai_sport = htons(fin->fin_sport); - ni.nai_dport = htons(fin->fin_dport); - } else if (flags & IPN_ICMPQUERY) { - /* - * In the ICMP query NAT code, we translate the ICMP id fields - * to make them unique. This is indepedent of the ICMP type - * (e.g. in the unlikely event that a host sends an echo and - * an tstamp request with the same id, both packets will have - * their ip address/id field changed in the same way). - */ - /* The icmp_id field is used by the sender to identify the - * process making the icmp request. (the receiver justs - * copies it back in its response). So, it closely matches - * the concept of source port. We overlay sport, so we can - * maximally reuse the existing code. - */ - ni.nai_sport = ((icmphdr_t *)fin->fin_dp)->icmp_id; - ni.nai_dport = ni.nai_sport; - } - - bzero((char *)nat, sizeof(*nat)); - nat->nat_flags = flags; - - if ((flags & NAT_SLAVE) == 0) { - MUTEX_ENTER(&ipf_nat_new); - } - - /* - * Search the current table for a match. - */ - if (direction == NAT_OUTBOUND) { - /* - * We can now arrange to call this for the same connection - * because ipf_nat_new doesn't protect the code path into - * this function. - */ - natl = nat_outlookup(fin, nflags, (u_int)fin->fin_p, - fin->fin_src, fin->fin_dst); - if (natl != NULL) { - nat = natl; - goto done; - } - - move = nat_newmap(fin, nat, &ni); - if (move == -1) - goto badnat; - - np = ni.nai_np; - in = ni.nai_ip; - } else { - /* - * NAT_INBOUND is used only for redirects rules - */ - natl = nat_inlookup(fin, nflags, (u_int)fin->fin_p, - fin->fin_src, fin->fin_dst); - if (natl != NULL) { - nat = natl; - goto done; - } - - move = nat_newrdr(fin, nat, &ni); - if (move == -1) - goto badnat; - - np = ni.nai_np; - in = ni.nai_ip; - } - port = ni.nai_port; - nport = ni.nai_nport; - - if ((move == 1) && (np->in_flags & IPN_ROUNDR)) { - if (np->in_redir == NAT_REDIRECT) { - nat_delrdr(np); - nat_addrdr(np); - } else if (np->in_redir == NAT_MAP) { - nat_delnat(np); - nat_addnat(np); - } - } - - if (flags & IPN_TCPUDP) { - sport = ni.nai_sport; - dport = ni.nai_dport; - } else if (flags & IPN_ICMPQUERY) { - sport = ni.nai_sport; - dport = 0; - } - - CALC_SUMD(ni.nai_sum1, ni.nai_sum2, sumd); - nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_M_CTL_MAGIC) - if ((flags & IPN_TCP) && dohwcksum && - (((ill_t *)qpi->qpi_ill)->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) { - if (direction == NAT_OUTBOUND) - ni.nai_sum1 = LONG_SUM(in.s_addr); - else - ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr)); - ni.nai_sum1 += LONG_SUM(ntohl(fin->fin_daddr)); - ni.nai_sum1 += 30; - ni.nai_sum1 = (ni.nai_sum1 & 0xffff) + (ni.nai_sum1 >> 16); - nat->nat_sumd[1] = NAT_HW_CKSUM|(ni.nai_sum1 & 0xffff); - } else -#endif - nat->nat_sumd[1] = nat->nat_sumd[0]; - - if ((flags & IPN_TCPUDPICMP) && ((sport != port) || (dport != nport))) { - if (direction == NAT_OUTBOUND) - ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_saddr)); - else - ni.nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)); - - ni.nai_sum2 = LONG_SUM(in.s_addr); - - CALC_SUMD(ni.nai_sum1, ni.nai_sum2, sumd); - nat->nat_ipsumd = (sumd & 0xffff) + (sumd >> 16); - } else { - nat->nat_ipsumd = nat->nat_sumd[0]; - if (!(flags & IPN_TCPUDPICMP)) { - nat->nat_sumd[0] = 0; - nat->nat_sumd[1] = 0; - } - } - - if (nat_finalise(fin, nat, &ni, tcp, natsave, direction) == -1) { - goto badnat; - } - if (flags & SI_WILDP) - nat_stats.ns_wilds++; - goto done; -badnat: - nat_stats.ns_badnat++; - if ((hm = nat->nat_hm) != NULL) - nat_hostmapdel(hm); - KFREE(nat); - nat = NULL; -done: - if ((flags & NAT_SLAVE) == 0) { - MUTEX_EXIT(&ipf_nat_new); - } - return nat; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_finalise */ -/* Returns: int - 0 == sucess, -1 == failure */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT entry */ -/* ni(I) - pointer to structure with misc. information needed */ -/* to create new NAT entry. */ -/* Write Lock: ipf_nat */ -/* */ -/* This is the tail end of constructing a new NAT entry and is the same */ -/* for both IPv4 and IPv6. */ -/* ------------------------------------------------------------------------ */ -/*ARGSUSED*/ -static INLINE int nat_finalise(fin, nat, ni, tcp, natsave, direction) -fr_info_t *fin; -nat_t *nat; -natinfo_t *ni; -tcphdr_t *tcp; -nat_t **natsave; -int direction; -{ - frentry_t *fr; - ipnat_t *np; - - np = ni->nai_np; - - COPYIFNAME(fin->fin_ifp, nat->nat_ifnames[0]); -#ifdef IPFILTER_SYNC - if ((nat->nat_flags & SI_CLONE) == 0) - nat->nat_sync = ipfsync_new(SMC_NAT, fin, nat); -#endif - - nat->nat_me = natsave; - nat->nat_dir = direction; - nat->nat_ifps[0] = fin->fin_ifp; - nat->nat_ptr = np; - nat->nat_p = fin->fin_p; - nat->nat_mssclamp = np->in_mssclamp; - fr = fin->fin_fr; - nat->nat_fr = fr; - - if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0)) - if (appr_new(fin, nat) == -1) - return -1; - - if (nat_insert(nat, fin->fin_rev) == 0) { - if (nat_logging) - nat_log(nat, (u_int)np->in_redir); - np->in_use++; - if (fr != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - MUTEX_EXIT(&fr->fr_lock); - } - return 0; - } - - /* - * nat_insert failed, so cleanup time... - */ - return -1; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_insert */ -/* Returns: int - 0 == sucess, -1 == failure */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* rev(I) - flag indicating forward/reverse direction of packet */ -/* Write Lock: ipf_nat */ -/* */ -/* Insert a NAT entry into the hash tables for searching and add it to the */ -/* list of active NAT entries. Adjust global counters when complete. */ -/* ------------------------------------------------------------------------ */ -int nat_insert(nat, rev) -nat_t *nat; -int rev; -{ - u_int hv1, hv2; - nat_t **natp; - - /* - * Try and return an error as early as possible, so calculate the hash - * entry numbers first and then proceed. - */ - if ((nat->nat_flags & (SI_W_SPORT|SI_W_DPORT)) == 0) { - hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport, - 0xffffffff); - hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1 + nat->nat_oport, - ipf_nattable_sz); - hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport, - 0xffffffff); - hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2 + nat->nat_oport, - ipf_nattable_sz); - } else { - hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, 0, 0xffffffff); - hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1, ipf_nattable_sz); - hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, 0, 0xffffffff); - hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2, ipf_nattable_sz); - } - - if (nat_stats.ns_bucketlen[0][hv1] >= fr_nat_maxbucket || - nat_stats.ns_bucketlen[1][hv2] >= fr_nat_maxbucket) { - return -1; - } - - nat->nat_hv[0] = hv1; - nat->nat_hv[1] = hv2; - - MUTEX_INIT(&nat->nat_lock, "nat entry lock"); - - nat->nat_rev = rev; - nat->nat_ref = 1; - nat->nat_bytes[0] = 0; - nat->nat_pkts[0] = 0; - nat->nat_bytes[1] = 0; - nat->nat_pkts[1] = 0; - - nat->nat_ifnames[0][LIFNAMSIZ - 1] = '\0'; - nat->nat_ifps[0] = fr_resolvenic(nat->nat_ifnames[0], 4); - - if (nat->nat_ifnames[1][0] !='\0') { - nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; - nat->nat_ifps[1] = fr_resolvenic(nat->nat_ifnames[1], 4); - } else { - (void) strncpy(nat->nat_ifnames[1], nat->nat_ifnames[0], - LIFNAMSIZ); - nat->nat_ifnames[1][LIFNAMSIZ - 1] = '\0'; - nat->nat_ifps[1] = nat->nat_ifps[0]; - } - - nat->nat_next = nat_instances; - nat->nat_pnext = &nat_instances; - if (nat_instances) - nat_instances->nat_pnext = &nat->nat_next; - nat_instances = nat; - - natp = &nat_table[0][hv1]; - if (*natp) - (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; - nat->nat_phnext[0] = natp; - nat->nat_hnext[0] = *natp; - *natp = nat; - nat_stats.ns_bucketlen[0][hv1]++; - - natp = &nat_table[1][hv2]; - if (*natp) - (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; - nat->nat_phnext[1] = natp; - nat->nat_hnext[1] = *natp; - *natp = nat; - nat_stats.ns_bucketlen[1][hv2]++; - - fr_setnatqueue(nat, rev); - - nat_stats.ns_added++; - nat_stats.ns_inuse++; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_icmperrorlookup */ -/* Returns: nat_t* - point to matching NAT structure */ -/* Parameters: fin(I) - pointer to packet information */ -/* dir(I) - direction of packet (in/out) */ -/* */ -/* Check if the ICMP error message is related to an existing TCP, UDP or */ -/* ICMP query nat entry. It is assumed that the packet is already of the */ -/* the required length. */ -/* ------------------------------------------------------------------------ */ -nat_t *nat_icmperrorlookup(fin, dir) -fr_info_t *fin; -int dir; -{ - int flags = 0, type, minlen; - icmphdr_t *icmp, *orgicmp; - tcphdr_t *tcp = NULL; - u_short data[2]; - nat_t *nat; - ip_t *oip; - u_int p; - - icmp = fin->fin_dp; - type = icmp->icmp_type; - /* - * Does it at least have the return (basic) IP header ? - * Only a basic IP header (no options) should be with an ICMP error - * header. Also, if it's not an error type, then return. - */ - if ((fin->fin_hlen != sizeof(ip_t)) || - !fr_icmp4errortype(type)) - return NULL; - - /* - * Check packet size - */ - oip = (ip_t *)((char *)fin->fin_dp + 8); - minlen = IP_HL(oip) << 2; - if ((minlen < sizeof(ip_t)) || - (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen)) - return NULL; - /* - * Is the buffer big enough for all of it ? It's the size of the IP - * header claimed in the encapsulated part which is of concern. It - * may be too big to be in this buffer but not so big that it's - * outside the ICMP packet, leading to TCP deref's causing problems. - * This is possible because we don't know how big oip_hl is when we - * do the pullup early in fr_check() and thus can't gaurantee it is - * all here now. - */ -#ifdef _KERNEL - { - mb_t *m; - - m = fin->fin_m; -# if defined(MENTAT) - if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > (char *)m->b_wptr) - return NULL; -# else - if ((char *)oip + fin->fin_dlen - ICMPERR_ICMPHLEN > - (char *)fin->fin_ip + M_LEN(m)) - return NULL; -# endif - } -#endif - - if (fin->fin_daddr != oip->ip_src.s_addr) - return NULL; - - p = oip->ip_p; - if (p == IPPROTO_TCP) - flags = IPN_TCP; - else if (p == IPPROTO_UDP) - flags = IPN_UDP; - else if (p == IPPROTO_ICMP) { - orgicmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - - /* see if this is related to an ICMP query */ - if (nat_icmpquerytype4(orgicmp->icmp_type)) { - data[0] = fin->fin_data[0]; - data[1] = fin->fin_data[1]; - fin->fin_data[0] = 0; - fin->fin_data[1] = orgicmp->icmp_id; - - flags = IPN_ICMPERR|IPN_ICMPQUERY; - /* - * NOTE : dir refers to the direction of the original - * ip packet. By definition the icmp error - * message flows in the opposite direction. - */ - if (dir == NAT_INBOUND) - nat = nat_inlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); - else - nat = nat_outlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); - fin->fin_data[0] = data[0]; - fin->fin_data[1] = data[1]; - return nat; - } - } - - if (flags & IPN_TCPUDP) { - minlen += 8; /* + 64bits of data to get ports */ - if (fin->fin_plen < ICMPERR_IPICMPHLEN + minlen) - return NULL; - - data[0] = fin->fin_data[0]; - data[1] = fin->fin_data[1]; - tcp = (tcphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - fin->fin_data[0] = ntohs(tcp->th_dport); - fin->fin_data[1] = ntohs(tcp->th_sport); - - if (dir == NAT_INBOUND) { - nat = nat_inlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); - } else { - nat = nat_outlookup(fin, flags, p, oip->ip_dst, - oip->ip_src); - } - fin->fin_data[0] = data[0]; - fin->fin_data[1] = data[1]; - return nat; - } - if (dir == NAT_INBOUND) - return nat_inlookup(fin, 0, p, oip->ip_dst, oip->ip_src); - else - return nat_outlookup(fin, 0, p, oip->ip_dst, oip->ip_src); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_icmperror */ -/* Returns: nat_t* - point to matching NAT structure */ -/* Parameters: fin(I) - pointer to packet information */ -/* nflags(I) - NAT flags for this packet */ -/* dir(I) - direction of packet (in/out) */ -/* */ -/* Fix up an ICMP packet which is an error message for an existing NAT */ -/* session. This will correct both packet header data and checksums. */ -/* */ -/* This should *ONLY* be used for incoming ICMP error packets to make sure */ -/* a NAT'd ICMP packet gets correctly recognised. */ -/* ------------------------------------------------------------------------ */ -nat_t *nat_icmperror(fin, nflags, dir) -fr_info_t *fin; -u_int *nflags; -int dir; -{ - u_32_t sum1, sum2, sumd, sumd2; - struct in_addr in; - icmphdr_t *icmp; - int flags, dlen; - u_short *csump; - tcphdr_t *tcp; - nat_t *nat; - ip_t *oip; - void *dp; - - if ((fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) - return NULL; - /* - * nat_icmperrorlookup() will return NULL for `defective' packets. - */ - if ((fin->fin_v != 4) || !(nat = nat_icmperrorlookup(fin, dir))) - return NULL; - - tcp = NULL; - csump = NULL; - flags = 0; - sumd2 = 0; - *nflags = IPN_ICMPERR; - icmp = fin->fin_dp; - oip = (ip_t *)&icmp->icmp_ip; - dp = (((char *)oip) + (IP_HL(oip) << 2)); - if (oip->ip_p == IPPROTO_TCP) { - tcp = (tcphdr_t *)dp; - csump = (u_short *)&tcp->th_sum; - flags = IPN_TCP; - } else if (oip->ip_p == IPPROTO_UDP) { - udphdr_t *udp; - - udp = (udphdr_t *)dp; - tcp = (tcphdr_t *)dp; - csump = (u_short *)&udp->uh_sum; - flags = IPN_UDP; - } else if (oip->ip_p == IPPROTO_ICMP) - flags = IPN_ICMPQUERY; - dlen = fin->fin_plen - ((char *)dp - (char *)fin->fin_ip); - - /* - * Need to adjust ICMP header to include the real IP#'s and - * port #'s. Only apply a checksum change relative to the - * IP address change as it will be modified again in fr_checknatout - * for both address and port. Two checksum changes are - * necessary for the two header address changes. Be careful - * to only modify the checksum once for the port # and twice - * for the IP#. - */ - - /* - * Step 1 - * Fix the IP addresses in the offending IP packet. You also need - * to adjust the IP header checksum of that offending IP packet - * and the ICMP checksum of the ICMP error message itself. - * - * Unfortunately, for UDP and TCP, the IP addresses are also contained - * in the pseudo header that is used to compute the UDP resp. TCP - * checksum. So, we must compensate that as well. Even worse, the - * change in the UDP and TCP checksums require yet another - * adjustment of the ICMP checksum of the ICMP error message. - */ - - if (oip->ip_dst.s_addr == nat->nat_oip.s_addr) { - sum1 = LONG_SUM(ntohl(oip->ip_src.s_addr)); - in = nat->nat_inip; - oip->ip_src = in; - } else { - sum1 = LONG_SUM(ntohl(oip->ip_dst.s_addr)); - in = nat->nat_outip; - oip->ip_dst = in; - } - - sum2 = LONG_SUM(ntohl(in.s_addr)); - - CALC_SUMD(sum1, sum2, sumd); - - /* - * Fix IP checksum of the offending IP packet to adjust for - * the change in the IP address. - * - * Normally, you would expect that the ICMP checksum of the - * ICMP error message needs to be adjusted as well for the - * IP address change in oip. - * However, this is a NOP, because the ICMP checksum is - * calculated over the complete ICMP packet, which includes the - * changed oip IP addresses and oip->ip_sum. However, these - * two changes cancel each other out (if the delta for - * the IP address is x, then the delta for ip_sum is minus x), - * so no change in the icmp_cksum is necessary. - * - * Be careful that nat_dir refers to the direction of the - * offending IP packet (oip), not to its ICMP response (icmp) - */ - fix_datacksum(&oip->ip_sum, sumd); - /* Fix icmp cksum : IP Addr + Cksum */ - sumd2 = (sumd >> 16); - - /* - * Fix UDP pseudo header checksum to compensate for the - * IP address change. - */ - if ((oip->ip_p == IPPROTO_UDP) && (dlen >= 8) && (*csump != 0)) { - /* - * The UDP checksum is optional, only adjust it - * if it has been set. - */ - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate the UDP - * checksum adjustment. - */ - sumd2 = sumd << 1; - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; - } - - /* - * Fix TCP pseudo header checksum to compensate for the - * IP address change. Before we can do the change, we - * must make sure that oip is sufficient large to hold - * the TCP checksum (normally it does not!). - * 18 = offsetof(tcphdr_t, th_sum) + 2 - */ - else if (oip->ip_p == IPPROTO_TCP && dlen >= 18) { - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate the TCP - * checksum adjustment. - */ - sumd2 = sumd << 1; - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; - } else { - if (nat->nat_dir == NAT_OUTBOUND) - sumd2 = ~sumd2; - else - sumd2 = ~sumd2 + 1; - } - - if (((flags & IPN_TCPUDP) != 0) && (dlen >= 4)) { - int mode = 0; - - /* - * Step 2 : - * For offending TCP/UDP IP packets, translate the ports as - * well, based on the NAT specification. Of course such - * a change must be reflected in the ICMP checksum as well. - * - * Advance notice : Now it becomes complicated :-) - * - * Since the port fields are part of the TCP/UDP checksum - * of the offending IP packet, you need to adjust that checksum - * as well... but, if you change, you must change the icmp - * checksum *again*, to reflect that change. - * - * To further complicate: the TCP checksum is not in the first - * 8 bytes of the offending ip packet, so it most likely is not - * available. Some OSses like Solaris return enough bytes to - * include the TCP checksum. So we have to check if the - * ip->ip_len actually holds the TCP checksum of the oip! - */ - - if (nat->nat_oport == tcp->th_dport) { - if (tcp->th_sport != nat->nat_inport) { - mode = 1; - sum1 = ntohs(nat->nat_inport); - sum2 = ntohs(tcp->th_sport); - } - } else if (tcp->th_sport == nat->nat_oport) { - mode = 2; - sum1 = ntohs(nat->nat_outport); - sum2 = ntohs(tcp->th_dport); - } - - if (mode == 1) { - /* - * Fix ICMP checksum to compensate port adjustment. - */ - tcp->th_sport = htons(sum1); - - /* - * Fix udp checksum to compensate port adjustment. - * NOTE : the offending IP packet flows the other - * direction compared to the ICMP message. - * - * The UDP checksum is optional, only adjust it if - * it has been set. - */ - if ((oip->ip_p == IPPROTO_UDP) && - (dlen >= 8) && (*csump != 0)) { - sumd = sum1 - sum2; - sumd2 += sumd; - - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compenstate - * UDP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; - } - - /* - * Fix TCP checksum (if present) to compensate port - * adjustment. NOTE : the offending IP packet flows - * the other direction compared to the ICMP message. - */ - if (oip->ip_p == IPPROTO_TCP) { - if (dlen >= 18) { - sumd = sum1 - sum2; - sumd2 += sumd; - - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate - * TCP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; - } else { - sumd = sum2 - sum1 + 1; - sumd2 += sumd; - } - } - } else if (mode == 2) { - /* - * Fix ICMP checksum to compensate port adjustment. - */ - tcp->th_dport = htons(sum1); - - /* - * Fix UDP checksum to compensate port adjustment. - * NOTE : the offending IP packet flows the other - * direction compared to the ICMP message. - * - * The UDP checksum is optional, only adjust - * it if it has been set. - */ - if ((oip->ip_p == IPPROTO_UDP) && - (dlen >= 8) && (*csump != 0)) { - sumd = sum1 - sum2; - sumd2 += sumd; - - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate - * UDP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; - } - - /* - * Fix TCP checksum (if present) to compensate port - * adjustment. NOTE : the offending IP packet flows - * the other direction compared to the ICMP message. - */ - if (oip->ip_p == IPPROTO_TCP) { - if (dlen >= 18) { - sumd = sum1 - sum2; - sumd2 += sumd; - - sum1 = ntohs(*csump); - fix_datacksum(csump, sumd); - sum2 = ntohs(*csump); - - /* - * Fix ICMP checksum to compensate - * TCP checksum adjustment. - */ - CALC_SUMD(sum1, sum2, sumd); - sumd2 += sumd; - } else { - if (nat->nat_dir == NAT_INBOUND) - sumd = sum2 - sum1; - else - sumd = sum2 - sum1 + 1; - sumd2 += sumd; - } - } - } - if (sumd2 != 0) { - sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); - sumd2 = (sumd2 & 0xffff) + (sumd2 >> 16); - fix_incksum(fin, &icmp->icmp_cksum, sumd2); - } - } else if (((flags & IPN_ICMPQUERY) != 0) && (dlen >= 8)) { - icmphdr_t *orgicmp; - - /* - * XXX - what if this is bogus hl and we go off the end ? - * In this case, nat_icmperrorlookup() will have returned NULL. - */ - orgicmp = (icmphdr_t *)dp; - - if (nat->nat_dir == NAT_OUTBOUND) { - if (orgicmp->icmp_id != nat->nat_inport) { - - /* - * Fix ICMP checksum (of the offening ICMP - * query packet) to compensate the change - * in the ICMP id of the offending ICMP - * packet. - * - * Since you modify orgicmp->icmp_id with - * a delta (say x) and you compensate that - * in origicmp->icmp_cksum with a delta - * minus x, you don't have to adjust the - * overall icmp->icmp_cksum - */ - sum1 = ntohs(orgicmp->icmp_id); - sum2 = ntohs(nat->nat_inport); - CALC_SUMD(sum1, sum2, sumd); - orgicmp->icmp_id = nat->nat_inport; - fix_datacksum(&orgicmp->icmp_cksum, sumd); - } - } /* nat_dir == NAT_INBOUND is impossible for icmp queries */ - } - return nat; -} - - -/* - * NB: these lookups don't lock access to the list, it assumed that it has - * already been done! - */ - -/* ------------------------------------------------------------------------ */ -/* Function: nat_inlookup */ -/* Returns: nat_t* - NULL == no match, */ -/* else pointer to matching NAT entry */ -/* Parameters: fin(I) - pointer to packet information */ -/* flags(I) - NAT flags for this packet */ -/* p(I) - protocol for this packet */ -/* src(I) - source IP address */ -/* mapdst(I) - destination IP address */ -/* */ -/* Lookup a nat entry based on the mapped destination ip address/port and */ -/* real source address/port. We use this lookup when receiving a packet, */ -/* we're looking for a table entry, based on the destination address. */ -/* */ -/* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. */ -/* */ -/* NOTE: IT IS ASSUMED THAT ipf_nat IS ONLY HELD WITH A READ LOCK WHEN */ -/* THIS FUNCTION IS CALLED WITH NAT_SEARCH SET IN nflags. */ -/* */ -/* flags -> relevant are IPN_UDP/IPN_TCP/IPN_ICMPQUERY that indicate if */ -/* the packet is of said protocol */ -/* ------------------------------------------------------------------------ */ -nat_t *nat_inlookup(fin, flags, p, src, mapdst) -fr_info_t *fin; -u_int flags, p; -struct in_addr src , mapdst; -{ - u_short sport, dport; - grehdr_t *gre; - ipnat_t *ipn; - u_int sflags; - nat_t *nat; - int nflags; - u_32_t dst; - void *ifp; - u_int hv; - - if (fin != NULL) - ifp = fin->fin_ifp; - else - ifp = NULL; - sport = 0; - dport = 0; - gre = NULL; - dst = mapdst.s_addr; - sflags = flags & NAT_TCPUDPICMP; - - switch (p) - { - case IPPROTO_TCP : - case IPPROTO_UDP : - sport = htons(fin->fin_data[0]); - dport = htons(fin->fin_data[1]); - break; - case IPPROTO_ICMP : - if (flags & IPN_ICMPERR) - sport = fin->fin_data[1]; - else - dport = fin->fin_data[1]; - break; - default : - break; - } - - - if ((flags & SI_WILDP) != 0) - goto find_in_wild_ports; - - hv = NAT_HASH_FN(dst, dport, 0xffffffff); - hv = NAT_HASH_FN(src.s_addr, hv + sport, ipf_nattable_sz); - nat = nat_table[1][hv]; - for (; nat; nat = nat->nat_hnext[1]) { - nflags = nat->nat_flags; - - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[0]) - continue; - } else { - if (ifp != nat->nat_ifps[1]) - continue; - } - } - - if (nat->nat_oip.s_addr == src.s_addr && - nat->nat_outip.s_addr == dst && - (((p == 0) && - (sflags == (nat->nat_flags & IPN_TCPUDPICMP))) - || (p == nat->nat_p))) { - switch (p) - { -#if 0 - case IPPROTO_GRE : - if (nat->nat_call[1] != fin->fin_data[0]) - continue; - break; -#endif - case IPPROTO_ICMP : - if ((flags & IPN_ICMPERR) != 0) { - if (nat->nat_outport != sport) - continue; - } else { - if (nat->nat_outport != dport) - continue; - } - break; - case IPPROTO_TCP : - case IPPROTO_UDP : - if (nat->nat_oport != sport) - continue; - if (nat->nat_outport != dport) - continue; - break; - default : - break; - } - - ipn = nat->nat_ptr; - if ((ipn != NULL) && (nat->nat_aps != NULL)) - if (appr_match(fin, nat) != 0) - continue; - return nat; - } - } - - /* - * So if we didn't find it but there are wildcard members in the hash - * table, go back and look for them. We do this search and update here - * because it is modifying the NAT table and we want to do this only - * for the first packet that matches. The exception, of course, is - * for "dummy" (FI_IGNORE) lookups. - */ -find_in_wild_ports: - if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) - return NULL; - if (nat_stats.ns_wilds == 0) - return NULL; - - RWLOCK_EXIT(&ipf_nat); - - hv = NAT_HASH_FN(dst, 0, 0xffffffff); - hv = NAT_HASH_FN(src.s_addr, hv, ipf_nattable_sz); - - WRITE_ENTER(&ipf_nat); - - nat = nat_table[1][hv]; - for (; nat; nat = nat->nat_hnext[1]) { - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[0]) - continue; - } else { - if (ifp != nat->nat_ifps[1]) - continue; - } - } - - if (nat->nat_p != fin->fin_p) - continue; - if (nat->nat_oip.s_addr != src.s_addr || - nat->nat_outip.s_addr != dst) - continue; - - nflags = nat->nat_flags; - if (!(nflags & (NAT_TCPUDP|SI_WILDP))) - continue; - - if (nat_wildok(nat, (int)sport, (int)dport, nflags, - NAT_INBOUND) == 1) { - if ((fin->fin_flx & FI_IGNORE) != 0) - break; - if ((nflags & SI_CLONE) != 0) { - nat = fr_natclone(fin, nat); - if (nat == NULL) - break; - } else { - MUTEX_ENTER(&ipf_nat_new); - nat_stats.ns_wilds--; - MUTEX_EXIT(&ipf_nat_new); - } - nat->nat_oport = sport; - nat->nat_outport = dport; - nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT); - nat_tabmove(nat); - break; - } - } - - MUTEX_DOWNGRADE(&ipf_nat); - - return nat; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_tabmove */ -/* Returns: Nil */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* Write Lock: ipf_nat */ -/* */ -/* This function is only called for TCP/UDP NAT table entries where the */ -/* original was placed in the table without hashing on the ports and we now */ -/* want to include hashing on port numbers. */ -/* ------------------------------------------------------------------------ */ -static void nat_tabmove(nat) -nat_t *nat; -{ - nat_t **natp; - u_int hv; - - if (nat->nat_flags & SI_CLONE) - return; - - /* - * Remove the NAT entry from the old location - */ - if (nat->nat_hnext[0]) - nat->nat_hnext[0]->nat_phnext[0] = nat->nat_phnext[0]; - *nat->nat_phnext[0] = nat->nat_hnext[0]; - nat_stats.ns_bucketlen[0][nat->nat_hv[0]]--; - - if (nat->nat_hnext[1]) - nat->nat_hnext[1]->nat_phnext[1] = nat->nat_phnext[1]; - *nat->nat_phnext[1] = nat->nat_hnext[1]; - nat_stats.ns_bucketlen[1][nat->nat_hv[1]]--; - - /* - * Add into the NAT table in the new position - */ - hv = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport, 0xffffffff); - hv = NAT_HASH_FN(nat->nat_oip.s_addr, hv + nat->nat_oport, - ipf_nattable_sz); - nat->nat_hv[0] = hv; - natp = &nat_table[0][hv]; - if (*natp) - (*natp)->nat_phnext[0] = &nat->nat_hnext[0]; - nat->nat_phnext[0] = natp; - nat->nat_hnext[0] = *natp; - *natp = nat; - nat_stats.ns_bucketlen[0][hv]++; - - hv = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport, 0xffffffff); - hv = NAT_HASH_FN(nat->nat_oip.s_addr, hv + nat->nat_oport, - ipf_nattable_sz); - nat->nat_hv[1] = hv; - natp = &nat_table[1][hv]; - if (*natp) - (*natp)->nat_phnext[1] = &nat->nat_hnext[1]; - nat->nat_phnext[1] = natp; - nat->nat_hnext[1] = *natp; - *natp = nat; - nat_stats.ns_bucketlen[1][hv]++; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_outlookup */ -/* Returns: nat_t* - NULL == no match, */ -/* else pointer to matching NAT entry */ -/* Parameters: fin(I) - pointer to packet information */ -/* flags(I) - NAT flags for this packet */ -/* p(I) - protocol for this packet */ -/* src(I) - source IP address */ -/* dst(I) - destination IP address */ -/* rw(I) - 1 == write lock on ipf_nat held, 0 == read lock. */ -/* */ -/* Lookup a nat entry based on the source 'real' ip address/port and */ -/* destination address/port. We use this lookup when sending a packet out, */ -/* we're looking for a table entry, based on the source address. */ -/* */ -/* NOTE: THE PACKET BEING CHECKED (IF FOUND) HAS A MAPPING ALREADY. */ -/* */ -/* NOTE: IT IS ASSUMED THAT ipf_nat IS ONLY HELD WITH A READ LOCK WHEN */ -/* THIS FUNCTION IS CALLED WITH NAT_SEARCH SET IN nflags. */ -/* */ -/* flags -> relevant are IPN_UDP/IPN_TCP/IPN_ICMPQUERY that indicate if */ -/* the packet is of said protocol */ -/* ------------------------------------------------------------------------ */ -nat_t *nat_outlookup(fin, flags, p, src, dst) -fr_info_t *fin; -u_int flags, p; -struct in_addr src , dst; -{ - u_short sport, dport; - u_int sflags; - ipnat_t *ipn; - u_32_t srcip; - nat_t *nat; - int nflags; - void *ifp; - u_int hv; - - ifp = fin->fin_ifp; - srcip = src.s_addr; - sflags = flags & IPN_TCPUDPICMP; - sport = 0; - dport = 0; - - switch (p) - { - case IPPROTO_TCP : - case IPPROTO_UDP : - sport = htons(fin->fin_data[0]); - dport = htons(fin->fin_data[1]); - break; - case IPPROTO_ICMP : - if (flags & IPN_ICMPERR) - sport = fin->fin_data[1]; - else - dport = fin->fin_data[1]; - break; - default : - break; - } - - if ((flags & SI_WILDP) != 0) - goto find_out_wild_ports; - - hv = NAT_HASH_FN(srcip, sport, 0xffffffff); - hv = NAT_HASH_FN(dst.s_addr, hv + dport, ipf_nattable_sz); - nat = nat_table[0][hv]; - for (; nat; nat = nat->nat_hnext[0]) { - nflags = nat->nat_flags; - - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[1]) - continue; - } else { - if (ifp != nat->nat_ifps[0]) - continue; - } - } - - if (nat->nat_inip.s_addr == srcip && - nat->nat_oip.s_addr == dst.s_addr && - (((p == 0) && (sflags == (nflags & NAT_TCPUDPICMP))) - || (p == nat->nat_p))) { - switch (p) - { -#if 0 - case IPPROTO_GRE : - if (nat->nat_call[1] != fin->fin_data[0]) - continue; - break; -#endif - case IPPROTO_TCP : - case IPPROTO_UDP : - if (nat->nat_oport != dport) - continue; - if (nat->nat_inport != sport) - continue; - break; - default : - break; - } - - ipn = nat->nat_ptr; - if ((ipn != NULL) && (nat->nat_aps != NULL)) - if (appr_match(fin, nat) != 0) - continue; - return nat; - } - } - - /* - * So if we didn't find it but there are wildcard members in the hash - * table, go back and look for them. We do this search and update here - * because it is modifying the NAT table and we want to do this only - * for the first packet that matches. The exception, of course, is - * for "dummy" (FI_IGNORE) lookups. - */ -find_out_wild_ports: - if (!(flags & NAT_TCPUDP) || !(flags & NAT_SEARCH)) - return NULL; - if (nat_stats.ns_wilds == 0) - return NULL; - - RWLOCK_EXIT(&ipf_nat); - - hv = NAT_HASH_FN(srcip, 0, 0xffffffff); - hv = NAT_HASH_FN(dst.s_addr, hv, ipf_nattable_sz); - - WRITE_ENTER(&ipf_nat); - - nat = nat_table[0][hv]; - for (; nat; nat = nat->nat_hnext[0]) { - if (ifp != NULL) { - if (nat->nat_dir == NAT_REDIRECT) { - if (ifp != nat->nat_ifps[1]) - continue; - } else { - if (ifp != nat->nat_ifps[0]) - continue; - } - } - - if (nat->nat_p != fin->fin_p) - continue; - if ((nat->nat_inip.s_addr != srcip) || - (nat->nat_oip.s_addr != dst.s_addr)) - continue; - - nflags = nat->nat_flags; - if (!(nflags & (NAT_TCPUDP|SI_WILDP))) - continue; - - if (nat_wildok(nat, (int)sport, (int)dport, nflags, - NAT_OUTBOUND) == 1) { - if ((fin->fin_flx & FI_IGNORE) != 0) - break; - if ((nflags & SI_CLONE) != 0) { - nat = fr_natclone(fin, nat); - if (nat == NULL) - break; - } else { - MUTEX_ENTER(&ipf_nat_new); - nat_stats.ns_wilds--; - MUTEX_EXIT(&ipf_nat_new); - } - nat->nat_inport = sport; - nat->nat_oport = dport; - if (nat->nat_outport == 0) - nat->nat_outport = sport; - nat->nat_flags &= ~(SI_W_DPORT|SI_W_SPORT); - nat_tabmove(nat); - break; - } - } - - MUTEX_DOWNGRADE(&ipf_nat); - - return nat; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_lookupredir */ -/* Returns: nat_t* - NULL == no match, */ -/* else pointer to matching NAT entry */ -/* Parameters: np(I) - pointer to description of packet to find NAT table */ -/* entry for. */ -/* */ -/* Lookup the NAT tables to search for a matching redirect */ -/* ------------------------------------------------------------------------ */ -nat_t *nat_lookupredir(np) -natlookup_t *np; -{ - fr_info_t fi; - nat_t *nat; - - bzero((char *)&fi, sizeof(fi)); - if (np->nl_flags & IPN_IN) { - fi.fin_data[0] = ntohs(np->nl_realport); - fi.fin_data[1] = ntohs(np->nl_outport); - } else { - fi.fin_data[0] = ntohs(np->nl_inport); - fi.fin_data[1] = ntohs(np->nl_outport); - } - if (np->nl_flags & IPN_TCP) - fi.fin_p = IPPROTO_TCP; - else if (np->nl_flags & IPN_UDP) - fi.fin_p = IPPROTO_UDP; - else if (np->nl_flags & (IPN_ICMPERR|IPN_ICMPQUERY)) - fi.fin_p = IPPROTO_ICMP; - - /* - * We can do two sorts of lookups: - * - IPN_IN: we have the `real' and `out' address, look for `in'. - * - default: we have the `in' and `out' address, look for `real'. - */ - if (np->nl_flags & IPN_IN) { - if ((nat = nat_inlookup(&fi, np->nl_flags, fi.fin_p, - np->nl_realip, np->nl_outip))) { - np->nl_inip = nat->nat_inip; - np->nl_inport = nat->nat_inport; - } - } else { - /* - * If nl_inip is non null, this is a lookup based on the real - * ip address. Else, we use the fake. - */ - if ((nat = nat_outlookup(&fi, np->nl_flags, fi.fin_p, - np->nl_inip, np->nl_outip))) { - - if ((np->nl_flags & IPN_FINDFORWARD) != 0) { - fr_info_t fin; - bzero((char *)&fin, sizeof(fin)); - fin.fin_p = nat->nat_p; - fin.fin_data[0] = ntohs(nat->nat_outport); - fin.fin_data[1] = ntohs(nat->nat_oport); - if (nat_inlookup(&fin, np->nl_flags, fin.fin_p, - nat->nat_outip, - nat->nat_oip) != NULL) { - np->nl_flags &= ~IPN_FINDFORWARD; - } - } - - np->nl_realip = nat->nat_outip; - np->nl_realport = nat->nat_outport; - } - } - - return nat; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_match */ -/* Returns: int - 0 == no match, 1 == match */ -/* Parameters: fin(I) - pointer to packet information */ -/* np(I) - pointer to NAT rule */ -/* */ -/* Pull the matching of a packet against a NAT rule out of that complex */ -/* loop inside fr_checknatin() and lay it out properly in its own function. */ -/* ------------------------------------------------------------------------ */ -static int nat_match(fin, np) -fr_info_t *fin; -ipnat_t *np; -{ - frtuc_t *ft; - - if (fin->fin_v != 4) - return 0; - - if (np->in_p && fin->fin_p != np->in_p) - return 0; - - if (fin->fin_out) { - if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK))) - return 0; - if (((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip) - ^ ((np->in_flags & IPN_NOTSRC) != 0)) - return 0; - if (((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip) - ^ ((np->in_flags & IPN_NOTDST) != 0)) - return 0; - } else { - if (!(np->in_redir & NAT_REDIRECT)) - return 0; - if (((fin->fin_fi.fi_saddr & np->in_srcmsk) != np->in_srcip) - ^ ((np->in_flags & IPN_NOTSRC) != 0)) - return 0; - if (((fin->fin_fi.fi_daddr & np->in_outmsk) != np->in_outip) - ^ ((np->in_flags & IPN_NOTDST) != 0)) - return 0; - } - - ft = &np->in_tuc; - if (!(fin->fin_flx & FI_TCPUDP) || - (fin->fin_flx & (FI_SHORT|FI_FRAGBODY))) { - if (ft->ftu_scmp || ft->ftu_dcmp) - return 0; - return 1; - } - - return fr_tcpudpchk(fin, ft); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_update */ -/* Returns: Nil */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* np(I) - pointer to NAT rule */ -/* */ -/* Updates the lifetime of a NAT table entry for non-TCP packets. Must be */ -/* called with fin_rev updated - i.e. after calling nat_proto(). */ -/* ------------------------------------------------------------------------ */ -void nat_update(fin, nat, np) -fr_info_t *fin; -nat_t *nat; -ipnat_t *np; -{ - ipftq_t *ifq, *ifq2; - ipftqent_t *tqe; - - MUTEX_ENTER(&nat->nat_lock); - tqe = &nat->nat_tqe; - ifq = tqe->tqe_ifq; - - /* - * We allow over-riding of NAT timeouts from NAT rules, even for - * TCP, however, if it is TCP and there is no rule timeout set, - * then do not update the timeout here. - */ - if (np != NULL) - ifq2 = np->in_tqehead[fin->fin_rev]; - else - ifq2 = NULL; - - if (nat->nat_p == IPPROTO_TCP && ifq2 == NULL) { - (void) fr_tcp_age(&nat->nat_tqe, fin, nat_tqb, 0); - } else { - if (ifq2 == NULL) { - if (nat->nat_p == IPPROTO_UDP) - ifq2 = &nat_udptq; - else if (nat->nat_p == IPPROTO_ICMP) - ifq2 = &nat_icmptq; - else - ifq2 = &nat_iptq; - } - - fr_movequeue(tqe, ifq, ifq2); - } - MUTEX_EXIT(&nat->nat_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checknatout */ -/* Returns: int - -1 == packet failed NAT checks so block it, */ -/* 0 == no packet translation occurred, */ -/* 1 == packet was successfully translated. */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(I) - pointer to filtering result flags */ -/* */ -/* Check to see if an outcoming packet should be changed. ICMP packets are */ -/* first checked to see if they match an existing entry (if an error), */ -/* otherwise a search of the current NAT table is made. If neither results */ -/* in a match then a search for a matching NAT rule is made. Create a new */ -/* NAT entry if a we matched a NAT rule. Lastly, actually change the */ -/* packet header(s) as required. */ -/* ------------------------------------------------------------------------ */ -int fr_checknatout(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - struct ifnet *ifp, *sifp; - icmphdr_t *icmp = NULL; - tcphdr_t *tcp = NULL; - int rval, natfailed; - ipnat_t *np = NULL; - u_int nflags = 0; - u_32_t ipa, iph; - int natadd = 1; - frentry_t *fr; - nat_t *nat; - - if (nat_stats.ns_rules == 0 || fr_nat_lock != 0) - return 0; - - natfailed = 0; - fr = fin->fin_fr; - sifp = fin->fin_ifp; - if ((fr != NULL) && !(fr->fr_flags & FR_DUP) && - fr->fr_tif.fd_ifp && fr->fr_tif.fd_ifp != (void *)-1) - fin->fin_ifp = fr->fr_tif.fd_ifp; - ifp = fin->fin_ifp; - - if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { - switch (fin->fin_p) - { - case IPPROTO_TCP : - nflags = IPN_TCP; - break; - case IPPROTO_UDP : - nflags = IPN_UDP; - break; - case IPPROTO_ICMP : - icmp = fin->fin_dp; - - /* - * This is an incoming packet, so the destination is - * the icmp_id and the source port equals 0 - */ - if (nat_icmpquerytype4(icmp->icmp_type)) - nflags = IPN_ICMPQUERY; - break; - default : - break; - } - - if ((nflags & IPN_TCPUDP)) - tcp = fin->fin_dp; - } - - ipa = fin->fin_saddr; - - READ_ENTER(&ipf_nat); - - if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) && - (nat = nat_icmperror(fin, &nflags, NAT_OUTBOUND))) - /*EMPTY*/; - else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin))) - natadd = 0; - else if ((nat = nat_outlookup(fin, nflags|NAT_SEARCH, (u_int)fin->fin_p, - fin->fin_src, fin->fin_dst))) { - nflags = nat->nat_flags; - } else { - u_32_t hv, msk, nmsk; - - /* - * If there is no current entry in the nat table for this IP#, - * create one for it (if there is a matching rule). - */ - RWLOCK_EXIT(&ipf_nat); - msk = 0xffffffff; - nmsk = nat_masks; - WRITE_ENTER(&ipf_nat); -maskloop: - iph = ipa & htonl(msk); - hv = NAT_HASH_FN(iph, 0, ipf_natrules_sz); - for (np = nat_rules[hv]; np; np = np->in_mnext) - { - if ((np->in_ifps[0] && (np->in_ifps[0] != ifp))) - continue; - if (np->in_v != fin->fin_v) - continue; - if (np->in_p && (np->in_p != fin->fin_p)) - continue; - if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags)) - continue; - if (np->in_flags & IPN_FILTER) { - if (!nat_match(fin, np)) - continue; - } else if ((ipa & np->in_inmsk) != np->in_inip) - continue; - - if ((fr != NULL) && - !fr_matchtag(&np->in_tag, &fr->fr_nattag)) - continue; - - if (*np->in_plabel != '\0') { - if (((np->in_flags & IPN_FILTER) == 0) && - (np->in_dport != tcp->th_dport)) - continue; - if (appr_ok(fin, tcp, np) == 0) - continue; - } - - if ((nat = nat_new(fin, np, NULL, nflags, - NAT_OUTBOUND))) { - np->in_hits++; - break; - } else - natfailed = -1; - } - if ((np == NULL) && (nmsk != 0)) { - while (nmsk) { - msk <<= 1; - if (nmsk & 0x80000000) - break; - nmsk <<= 1; - } - if (nmsk != 0) { - nmsk <<= 1; - goto maskloop; - } - } - MUTEX_DOWNGRADE(&ipf_nat); - } - - if (nat != NULL) { - rval = fr_natout(fin, nat, natadd, nflags); - if (rval == 1) { - MUTEX_ENTER(&nat->nat_lock); - nat->nat_ref++; - MUTEX_EXIT(&nat->nat_lock); - fin->fin_nat = nat; - } - } else - rval = natfailed; - RWLOCK_EXIT(&ipf_nat); - - if (rval == -1) { - if (passp != NULL) - *passp = FR_BLOCK; - fin->fin_flx |= FI_BADNAT; - } - fin->fin_ifp = sifp; - return rval; -} - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natout */ -/* Returns: int - -1 == packet failed NAT checks so block it, */ -/* 1 == packet was successfully translated. */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT structure */ -/* natadd(I) - flag indicating if it is safe to add frag cache */ -/* nflags(I) - NAT flags set for this packet */ -/* */ -/* Translate a packet coming "out" on an interface. */ -/* ------------------------------------------------------------------------ */ -int fr_natout(fin, nat, natadd, nflags) -fr_info_t *fin; -nat_t *nat; -int natadd; -u_32_t nflags; -{ - icmphdr_t *icmp; - u_short *csump; - tcphdr_t *tcp; - ipnat_t *np; - int i; - - tcp = NULL; - icmp = NULL; - csump = NULL; - np = nat->nat_ptr; - - if ((natadd != 0) && (fin->fin_flx & FI_FRAG) && (np != NULL)) - (void) fr_nat_newfrag(fin, 0, nat); - - MUTEX_ENTER(&nat->nat_lock); - nat->nat_bytes[1] += fin->fin_plen; - nat->nat_pkts[1]++; - MUTEX_EXIT(&nat->nat_lock); - - /* - * Fix up checksums, not by recalculating them, but - * simply computing adjustments. - * This is only done for STREAMS based IP implementations where the - * checksum has already been calculated by IP. In all other cases, - * IPFilter is called before the checksum needs calculating so there - * is no call to modify whatever is in the header now. - */ - if (fin->fin_v == 4) { - if (nflags == IPN_ICMPERR) { - u_32_t s1, s2, sumd; - - s1 = LONG_SUM(ntohl(fin->fin_saddr)); - s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)); - CALC_SUMD(s1, s2, sumd); - fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd); - } -#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || defined(linux) - else { - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(fin, &fin->fin_ip->ip_sum, - nat->nat_ipsumd); - else - fix_incksum(fin, &fin->fin_ip->ip_sum, - nat->nat_ipsumd); - } -#endif - } - - if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { - if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) { - tcp = fin->fin_dp; - - tcp->th_sport = nat->nat_outport; - fin->fin_data[0] = ntohs(nat->nat_outport); - } - - if ((nat->nat_outport != 0) && (nflags & IPN_ICMPQUERY)) { - icmp = fin->fin_dp; - icmp->icmp_id = nat->nat_outport; - } - - csump = nat_proto(fin, nat, nflags); - } - - fin->fin_ip->ip_src = nat->nat_outip; - - nat_update(fin, nat, np); - - /* - * The above comments do not hold for layer 4 (or higher) checksums... - */ - if (csump != NULL) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_outcksum(fin, csump, nat->nat_sumd[1]); - else - fix_incksum(fin, csump, nat->nat_sumd[1]); - } -#ifdef IPFILTER_SYNC - ipfsync_update(SMC_NAT, fin, nat->nat_sync); -#endif - /* ------------------------------------------------------------- */ - /* A few quick notes: */ - /* Following are test conditions prior to calling the */ - /* appr_check routine. */ - /* */ - /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ - /* with a redirect rule, we attempt to match the packet's */ - /* source port against in_dport, otherwise we'd compare the */ - /* packet's destination. */ - /* ------------------------------------------------------------- */ - if ((np != NULL) && (np->in_apr != NULL)) { - i = appr_check(fin, nat); - if (i == 0) - i = 1; - } else - i = 1; - ATOMIC_INCL(nat_stats.ns_mapped[1]); - fin->fin_flx |= FI_NATED; - return i; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checknatin */ -/* Returns: int - -1 == packet failed NAT checks so block it, */ -/* 0 == no packet translation occurred, */ -/* 1 == packet was successfully translated. */ -/* Parameters: fin(I) - pointer to packet information */ -/* passp(I) - pointer to filtering result flags */ -/* */ -/* Check to see if an incoming packet should be changed. ICMP packets are */ -/* first checked to see if they match an existing entry (if an error), */ -/* otherwise a search of the current NAT table is made. If neither results */ -/* in a match then a search for a matching NAT rule is made. Create a new */ -/* NAT entry if a we matched a NAT rule. Lastly, actually change the */ -/* packet header(s) as required. */ -/* ------------------------------------------------------------------------ */ -int fr_checknatin(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - u_int nflags, natadd; - int rval, natfailed; - struct ifnet *ifp; - struct in_addr in; - icmphdr_t *icmp; - tcphdr_t *tcp; - u_short dport; - ipnat_t *np; - nat_t *nat; - u_32_t iph; - - if (nat_stats.ns_rules == 0 || fr_nat_lock != 0) - return 0; - - tcp = NULL; - icmp = NULL; - dport = 0; - natadd = 1; - nflags = 0; - natfailed = 0; - ifp = fin->fin_ifp; - - if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { - switch (fin->fin_p) - { - case IPPROTO_TCP : - nflags = IPN_TCP; - break; - case IPPROTO_UDP : - nflags = IPN_UDP; - break; - case IPPROTO_ICMP : - icmp = fin->fin_dp; - - /* - * This is an incoming packet, so the destination is - * the icmp_id and the source port equals 0 - */ - if (nat_icmpquerytype4(icmp->icmp_type)) { - nflags = IPN_ICMPQUERY; - dport = icmp->icmp_id; - } break; - default : - break; - } - - if ((nflags & IPN_TCPUDP)) { - tcp = fin->fin_dp; - dport = tcp->th_dport; - } - } - - in = fin->fin_dst; - - READ_ENTER(&ipf_nat); - - if ((fin->fin_p == IPPROTO_ICMP) && !(nflags & IPN_ICMPQUERY) && - (nat = nat_icmperror(fin, &nflags, NAT_INBOUND))) - /*EMPTY*/; - else if ((fin->fin_flx & FI_FRAG) && (nat = fr_nat_knownfrag(fin))) - natadd = 0; - else if ((nat = nat_inlookup(fin, nflags|NAT_SEARCH, (u_int)fin->fin_p, - fin->fin_src, in))) { - nflags = nat->nat_flags; - } else { - u_32_t hv, msk, rmsk; - - RWLOCK_EXIT(&ipf_nat); - rmsk = rdr_masks; - msk = 0xffffffff; - WRITE_ENTER(&ipf_nat); - /* - * If there is no current entry in the nat table for this IP#, - * create one for it (if there is a matching rule). - */ -maskloop: - iph = in.s_addr & htonl(msk); - hv = NAT_HASH_FN(iph, 0, ipf_rdrrules_sz); - for (np = rdr_rules[hv]; np; np = np->in_rnext) { - if (np->in_ifps[0] && (np->in_ifps[0] != ifp)) - continue; - if (np->in_v != fin->fin_v) - continue; - if (np->in_p && (np->in_p != fin->fin_p)) - continue; - if ((np->in_flags & IPN_RF) && !(np->in_flags & nflags)) - continue; - if (np->in_flags & IPN_FILTER) { - if (!nat_match(fin, np)) - continue; - } else { - if ((in.s_addr & np->in_outmsk) != np->in_outip) - continue; - if (np->in_pmin && - ((ntohs(np->in_pmax) < ntohs(dport)) || - (ntohs(dport) < ntohs(np->in_pmin)))) - continue; - } - - if (*np->in_plabel != '\0') { - if (!appr_ok(fin, tcp, np)) { - continue; - } - } - - nat = nat_new(fin, np, NULL, nflags, NAT_INBOUND); - if (nat != NULL) { - np->in_hits++; - break; - } else - natfailed = -1; - } - - if ((np == NULL) && (rmsk != 0)) { - while (rmsk) { - msk <<= 1; - if (rmsk & 0x80000000) - break; - rmsk <<= 1; - } - if (rmsk != 0) { - rmsk <<= 1; - goto maskloop; - } - } - MUTEX_DOWNGRADE(&ipf_nat); - } - if (nat != NULL) { - rval = fr_natin(fin, nat, natadd, nflags); - if (rval == 1) { - MUTEX_ENTER(&nat->nat_lock); - nat->nat_ref++; - MUTEX_EXIT(&nat->nat_lock); - fin->fin_nat = nat; - fin->fin_state = nat->nat_state; - } - } else - rval = natfailed; - RWLOCK_EXIT(&ipf_nat); - - if (rval == -1) { - if (passp != NULL) - *passp = FR_BLOCK; - fin->fin_flx |= FI_BADNAT; - } - return rval; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natin */ -/* Returns: int - -1 == packet failed NAT checks so block it, */ -/* 1 == packet was successfully translated. */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT structure */ -/* natadd(I) - flag indicating if it is safe to add frag cache */ -/* nflags(I) - NAT flags set for this packet */ -/* Locks Held: ipf_nat (READ) */ -/* */ -/* Translate a packet coming "in" on an interface. */ -/* ------------------------------------------------------------------------ */ -int fr_natin(fin, nat, natadd, nflags) -fr_info_t *fin; -nat_t *nat; -int natadd; -u_32_t nflags; -{ - icmphdr_t *icmp; - u_short *csump; - tcphdr_t *tcp; - ipnat_t *np; - int i; - - tcp = NULL; - csump = NULL; - np = nat->nat_ptr; - fin->fin_fr = nat->nat_fr; - - if (np != NULL) { - if ((natadd != 0) && (fin->fin_flx & FI_FRAG)) - (void) fr_nat_newfrag(fin, 0, nat); - - /* ------------------------------------------------------------- */ - /* A few quick notes: */ - /* Following are test conditions prior to calling the */ - /* appr_check routine. */ - /* */ - /* A NULL tcp indicates a non TCP/UDP packet. When dealing */ - /* with a map rule, we attempt to match the packet's */ - /* source port against in_dport, otherwise we'd compare the */ - /* packet's destination. */ - /* ------------------------------------------------------------- */ - if (np->in_apr != NULL) { - i = appr_check(fin, nat); - if (i == -1) { - return -1; - } - } - } - -#ifdef IPFILTER_SYNC - ipfsync_update(SMC_NAT, fin, nat->nat_sync); -#endif - - MUTEX_ENTER(&nat->nat_lock); - nat->nat_bytes[0] += fin->fin_plen; - nat->nat_pkts[0]++; - MUTEX_EXIT(&nat->nat_lock); - - fin->fin_ip->ip_dst = nat->nat_inip; - fin->fin_fi.fi_daddr = nat->nat_inip.s_addr; - if (nflags & IPN_TCPUDP) - tcp = fin->fin_dp; - - /* - * Fix up checksums, not by recalculating them, but - * simply computing adjustments. - * Why only do this for some platforms on inbound packets ? - * Because for those that it is done, IP processing is yet to happen - * and so the IPv4 header checksum has not yet been evaluated. - * Perhaps it should always be done for the benefit of things like - * fast forwarding (so that it doesn't need to be recomputed) but with - * header checksum offloading, perhaps it is a moot point. - */ -#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ - defined(__osf__) || defined(linux) - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd); - else - fix_outcksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd); -#endif - - if (!(fin->fin_flx & FI_SHORT) && (fin->fin_off == 0)) { - if ((nat->nat_inport != 0) && (nflags & IPN_TCPUDP)) { - tcp->th_dport = nat->nat_inport; - fin->fin_data[1] = ntohs(nat->nat_inport); - } - - - if ((nat->nat_inport != 0) && (nflags & IPN_ICMPQUERY)) { - icmp = fin->fin_dp; - - icmp->icmp_id = nat->nat_inport; - } - - csump = nat_proto(fin, nat, nflags); - } - - nat_update(fin, nat, np); - - /* - * The above comments do not hold for layer 4 (or higher) checksums... - */ - if (csump != NULL) { - if (nat->nat_dir == NAT_OUTBOUND) - fix_incksum(fin, csump, nat->nat_sumd[0]); - else - fix_outcksum(fin, csump, nat->nat_sumd[0]); - } - ATOMIC_INCL(nat_stats.ns_mapped[0]); - fin->fin_flx |= FI_NATED; - if (np != NULL && np->in_tag.ipt_num[0] != 0) - fin->fin_nattag = &np->in_tag; - return 1; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_proto */ -/* Returns: u_short* - pointer to transport header checksum to update, */ -/* NULL if the transport protocol is not recognised */ -/* as needing a checksum update. */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT structure */ -/* nflags(I) - NAT flags set for this packet */ -/* */ -/* Return the pointer to the checksum field for each protocol so understood.*/ -/* If support for making other changes to a protocol header is required, */ -/* that is not strictly 'address' translation, such as clamping the MSS in */ -/* TCP down to a specific value, then do it from here. */ -/* ------------------------------------------------------------------------ */ -u_short *nat_proto(fin, nat, nflags) -fr_info_t *fin; -nat_t *nat; -u_int nflags; -{ - icmphdr_t *icmp; - u_short *csump; - tcphdr_t *tcp; - udphdr_t *udp; - - csump = NULL; - if (fin->fin_out == 0) { - fin->fin_rev = (nat->nat_dir == NAT_OUTBOUND); - } else { - fin->fin_rev = (nat->nat_dir == NAT_INBOUND); - } - - switch (fin->fin_p) - { - case IPPROTO_TCP : - tcp = fin->fin_dp; - - csump = &tcp->th_sum; - - /* - * Do a MSS CLAMPING on a SYN packet, - * only deal IPv4 for now. - */ - if ((nat->nat_mssclamp != 0) && (tcp->th_flags & TH_SYN) != 0) - nat_mssclamp(tcp, nat->nat_mssclamp, fin, csump); - - break; - - case IPPROTO_UDP : - udp = fin->fin_dp; - - if (udp->uh_sum) - csump = &udp->uh_sum; - break; - - case IPPROTO_ICMP : - icmp = fin->fin_dp; - - if ((nflags & IPN_ICMPQUERY) != 0) { - if (icmp->icmp_cksum != 0) - csump = &icmp->icmp_cksum; - } - break; - } - return csump; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natunload */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Free all memory used by NAT structures allocated at runtime. */ -/* ------------------------------------------------------------------------ */ -void fr_natunload() -{ - ipftq_t *ifq, *ifqnext; - - (void) nat_clearlist(); - (void) nat_flushtable(); - - /* - * Proxy timeout queues are not cleaned here because although they - * exist on the NAT list, appr_unload is called after fr_natunload - * and the proxies actually are responsible for them being created. - * Should the proxy timeouts have their own list? There's no real - * justification as this is the only complication. - */ - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - if (((ifq->ifq_flags & IFQF_PROXY) == 0) && - (fr_deletetimeoutqueue(ifq) == 0)) - fr_freetimeoutqueue(ifq); - } - - if (nat_table[0] != NULL) { - KFREES(nat_table[0], sizeof(nat_t *) * ipf_nattable_sz); - nat_table[0] = NULL; - } - if (nat_table[1] != NULL) { - KFREES(nat_table[1], sizeof(nat_t *) * ipf_nattable_sz); - nat_table[1] = NULL; - } - if (nat_rules != NULL) { - KFREES(nat_rules, sizeof(ipnat_t *) * ipf_natrules_sz); - nat_rules = NULL; - } - if (rdr_rules != NULL) { - KFREES(rdr_rules, sizeof(ipnat_t *) * ipf_rdrrules_sz); - rdr_rules = NULL; - } - if (maptable != NULL) { - KFREES(maptable, sizeof(hostmap_t *) * ipf_hostmap_sz); - maptable = NULL; - } - if (nat_stats.ns_bucketlen[0] != NULL) { - KFREES(nat_stats.ns_bucketlen[0], - sizeof(u_long *) * ipf_nattable_sz); - nat_stats.ns_bucketlen[0] = NULL; - } - if (nat_stats.ns_bucketlen[1] != NULL) { - KFREES(nat_stats.ns_bucketlen[1], - sizeof(u_long *) * ipf_nattable_sz); - nat_stats.ns_bucketlen[1] = NULL; - } - - if (fr_nat_maxbucket_reset == 1) - fr_nat_maxbucket = 0; - - if (fr_nat_init == 1) { - fr_nat_init = 0; - fr_sttab_destroy(nat_tqb); - - RW_DESTROY(&ipf_natfrag); - RW_DESTROY(&ipf_nat); - - MUTEX_DESTROY(&ipf_nat_new); - MUTEX_DESTROY(&ipf_natio); - - MUTEX_DESTROY(&nat_udptq.ifq_lock); - MUTEX_DESTROY(&nat_icmptq.ifq_lock); - MUTEX_DESTROY(&nat_iptq.ifq_lock); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natexpire */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Check all of the timeout queues for entries at the top which need to be */ -/* expired. */ -/* ------------------------------------------------------------------------ */ -void fr_natexpire() -{ - ipftq_t *ifq, *ifqnext; - ipftqent_t *tqe, *tqn; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif - int i; - - SPL_NET(s); - WRITE_ENTER(&ipf_nat); - for (ifq = nat_tqb, i = 0; ifq != NULL; ifq = ifq->ifq_next) { - for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); i++) { - if (tqe->tqe_die > fr_ticks) - break; - tqn = tqe->tqe_next; - nat_delete(tqe->tqe_parent, NL_EXPIRE); - } - } - - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - - for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); i++) { - if (tqe->tqe_die > fr_ticks) - break; - tqn = tqe->tqe_next; - nat_delete(tqe->tqe_parent, NL_EXPIRE); - } - } - - for (ifq = nat_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - - if (((ifq->ifq_flags & IFQF_DELETE) != 0) && - (ifq->ifq_ref == 0)) { - fr_freetimeoutqueue(ifq); - } - } - - RWLOCK_EXIT(&ipf_nat); - SPL_X(s); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natsync */ -/* Returns: Nil */ -/* Parameters: ifp(I) - pointer to network interface */ -/* */ -/* Walk through all of the currently active NAT sessions, looking for those */ -/* which need to have their translated address updated. */ -/* ------------------------------------------------------------------------ */ -void fr_natsync(ifp) -void *ifp; -{ - u_32_t sum1, sum2, sumd; - struct in_addr in; - ipnat_t *n; - nat_t *nat; - void *ifp2; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif - - if (fr_running <= 0) - return; - - /* - * Change IP addresses for NAT sessions for any protocol except TCP - * since it will break the TCP connection anyway. The only rules - * which will get changed are those which are "map ... -> 0/32", - * where the rule specifies the address is taken from the interface. - */ - SPL_NET(s); - WRITE_ENTER(&ipf_nat); - - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_nat); - return; - } - - for (nat = nat_instances; nat; nat = nat->nat_next) { - if ((nat->nat_flags & IPN_TCP) != 0) - continue; - n = nat->nat_ptr; - if ((n == NULL) || - (n->in_outip != 0) || (n->in_outmsk != 0xffffffff)) - continue; - if (((ifp == NULL) || (ifp == nat->nat_ifps[0]) || - (ifp == nat->nat_ifps[1]))) { - nat->nat_ifps[0] = GETIFP(nat->nat_ifnames[0], 4); - if (nat->nat_ifnames[1][0] != '\0') { - nat->nat_ifps[1] = GETIFP(nat->nat_ifnames[1], - 4); - } else - nat->nat_ifps[1] = nat->nat_ifps[0]; - ifp2 = nat->nat_ifps[0]; - if (ifp2 == NULL) - continue; - - /* - * Change the map-to address to be the same as the - * new one. - */ - sum1 = nat->nat_outip.s_addr; - if (fr_ifpaddr(4, FRI_NORMAL, ifp2, &in, NULL) != -1) - nat->nat_outip = in; - sum2 = nat->nat_outip.s_addr; - - if (sum1 == sum2) - continue; - /* - * Readjust the checksum adjustment to take into - * account the new IP#. - */ - CALC_SUMD(sum1, sum2, sumd); - /* XXX - dont change for TCP when solaris does - * hardware checksumming. - */ - sumd += nat->nat_sumd[0]; - nat->nat_sumd[0] = (sumd & 0xffff) + (sumd >> 16); - nat->nat_sumd[1] = nat->nat_sumd[0]; - } - } - - for (n = nat_list; (n != NULL); n = n->in_next) { - if ((ifp == NULL) || (n->in_ifps[0] == ifp)) - n->in_ifps[0] = fr_resolvenic(n->in_ifnames[0], 4); - if ((ifp == NULL) || (n->in_ifps[1] == ifp)) - n->in_ifps[1] = fr_resolvenic(n->in_ifnames[1], 4); - } - RWLOCK_EXIT(&ipf_nat); - SPL_X(s); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_icmpquerytype4 */ -/* Returns: int - 1 == success, 0 == failure */ -/* Parameters: icmptype(I) - ICMP type number */ -/* */ -/* Tests to see if the ICMP type number passed is a query/response type or */ -/* not. */ -/* ------------------------------------------------------------------------ */ -static INLINE int nat_icmpquerytype4(icmptype) -int icmptype; -{ - - /* - * For the ICMP query NAT code, it is essential that both the query - * and the reply match on the NAT rule. Because the NAT structure - * does not keep track of the icmptype, and a single NAT structure - * is used for all icmp types with the same src, dest and id, we - * simply define the replies as queries as well. The funny thing is, - * altough it seems silly to call a reply a query, this is exactly - * as it is defined in the IPv4 specification - */ - - switch (icmptype) - { - - case ICMP_ECHOREPLY: - case ICMP_ECHO: - /* route aedvertisement/solliciation is currently unsupported: */ - /* it would require rewriting the ICMP data section */ - case ICMP_TSTAMP: - case ICMP_TSTAMPREPLY: - case ICMP_IREQ: - case ICMP_IREQREPLY: - case ICMP_MASKREQ: - case ICMP_MASKREPLY: - return 1; - default: - return 0; - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_log */ -/* Returns: Nil */ -/* Parameters: nat(I) - pointer to NAT structure */ -/* type(I) - type of log entry to create */ -/* */ -/* Creates a NAT log entry. */ -/* ------------------------------------------------------------------------ */ -void nat_log(nat, type) -struct nat *nat; -u_int type; -{ -#ifdef IPFILTER_LOG -# ifndef LARGE_NAT - struct ipnat *np; - int rulen; -# endif - struct natlog natl; - void *items[1]; - size_t sizes[1]; - int types[1]; - - natl.nl_inip = nat->nat_inip; - natl.nl_outip = nat->nat_outip; - natl.nl_origip = nat->nat_oip; - natl.nl_bytes[0] = nat->nat_bytes[0]; - natl.nl_bytes[1] = nat->nat_bytes[1]; - natl.nl_pkts[0] = nat->nat_pkts[0]; - natl.nl_pkts[1] = nat->nat_pkts[1]; - natl.nl_origport = nat->nat_oport; - natl.nl_inport = nat->nat_inport; - natl.nl_outport = nat->nat_outport; - natl.nl_p = nat->nat_p; - natl.nl_type = type; - natl.nl_rule = -1; -# ifndef LARGE_NAT - if (nat->nat_ptr != NULL) { - for (rulen = 0, np = nat_list; np; np = np->in_next, rulen++) - if (np == nat->nat_ptr) { - natl.nl_rule = rulen; - break; - } - } -# endif - items[0] = &natl; - sizes[0] = sizeof(natl); - types[0] = 0; - - (void) ipllog(IPL_LOGNAT, NULL, items, sizes, types, 1); -#endif -} - - -#if defined(__OpenBSD__) -/* ------------------------------------------------------------------------ */ -/* Function: nat_ifdetach */ -/* Returns: Nil */ -/* Parameters: ifp(I) - pointer to network interface */ -/* */ -/* Compatibility interface for OpenBSD to trigger the correct updating of */ -/* interface references within IPFilter. */ -/* ------------------------------------------------------------------------ */ -void nat_ifdetach(ifp) -void *ifp; -{ - frsync(ifp); - return; -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natderef */ -/* Returns: Nil */ -/* Parameters: isp(I) - pointer to pointer to NAT table entry */ -/* */ -/* Decrement the reference counter for this NAT table entry and free it if */ -/* there are no more things using it. */ -/* ------------------------------------------------------------------------ */ -void fr_natderef(natp) -nat_t **natp; -{ - nat_t *nat; - - nat = *natp; - *natp = NULL; - WRITE_ENTER(&ipf_nat); - nat->nat_ref--; - if (nat->nat_ref == 0) - nat_delete(nat, NL_EXPIRE); - RWLOCK_EXIT(&ipf_nat); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_natclone */ -/* Returns: ipstate_t* - NULL == cloning failed, */ -/* else pointer to new state structure */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to master state structure */ -/* Write Lock: ipf_nat */ -/* */ -/* Create a "duplcate" state table entry from the master. */ -/* ------------------------------------------------------------------------ */ -static nat_t *fr_natclone(fin, nat) -fr_info_t *fin; -nat_t *nat; -{ - frentry_t *fr; - nat_t *clone; - ipnat_t *np; - - KMALLOC(clone, nat_t *); - if (clone == NULL) - return NULL; - bcopy((char *)nat, (char *)clone, sizeof(*clone)); - - MUTEX_NUKE(&clone->nat_lock); - - clone->nat_flags &= ~SI_CLONE; - clone->nat_flags |= SI_CLONED; - - - if (nat_insert(clone, fin->fin_rev) == -1) { - KFREE(clone); - return NULL; - } - np = clone->nat_ptr; - if (np != NULL) { - if (nat_logging) - nat_log(clone, (u_int)np->in_redir); - np->in_use++; - } - fr = clone->nat_fr; - if (fr != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - MUTEX_EXIT(&fr->fr_lock); - } - - - /* - * Because the clone is created outside the normal loop of things and - * TCP has special needs in terms of state, initialise the timeout - * state of the new NAT from here. - */ - if (clone->nat_p == IPPROTO_TCP) { - (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, \ - clone->nat_flags); - } -#ifdef IPFILTER_SYNC - clone->nat_sync = ipfsync_new(SMC_NAT, fin, clone); -#endif - if (nat_logging) - nat_log(clone, NL_CLONE); - return clone; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_wildok */ -/* Returns: int - 1 == packet's ports match wildcards */ -/* 0 == packet's ports don't match wildcards */ -/* Parameters: nat(I) - NAT entry */ -/* sport(I) - source port */ -/* dport(I) - destination port */ -/* flags(I) - wildcard flags */ -/* dir(I) - packet direction */ -/* */ -/* Use NAT entry and packet direction to determine which combination of */ -/* wildcard flags should be used. */ -/* ------------------------------------------------------------------------ */ -static INLINE int nat_wildok(nat, sport, dport, flags, dir) -nat_t *nat; -int sport; -int dport; -int flags; -int dir; -{ - /* - * When called by dir is set to - * nat_inlookup NAT_INBOUND (0) - * nat_outlookup NAT_OUTBOUND (1) - * - * We simply combine the packet's direction in dir with the original - * "intended" direction of that NAT entry in nat->nat_dir to decide - * which combination of wildcard flags to allow. - */ - - switch ((dir << 1) | nat->nat_dir) - { - case 3: /* outbound packet / outbound entry */ - if (((nat->nat_inport == sport) || - (flags & SI_W_SPORT)) && - ((nat->nat_oport == dport) || - (flags & SI_W_DPORT))) - return 1; - break; - case 2: /* outbound packet / inbound entry */ - if (((nat->nat_outport == sport) || - (flags & SI_W_DPORT)) && - ((nat->nat_oport == dport) || - (flags & SI_W_SPORT))) - return 1; - break; - case 1: /* inbound packet / outbound entry */ - if (((nat->nat_oport == sport) || - (flags & SI_W_DPORT)) && - ((nat->nat_outport == dport) || - (flags & SI_W_SPORT))) - return 1; - break; - case 0: /* inbound packet / inbound entry */ - if (((nat->nat_oport == sport) || - (flags & SI_W_SPORT)) && - ((nat->nat_outport == dport) || - (flags & SI_W_DPORT))) - return 1; - break; - default: - break; - } - - return(0); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: nat_mssclamp */ -/* Returns: Nil */ -/* Parameters: tcp(I) - pointer to TCP header */ -/* maxmss(I) - value to clamp the TCP MSS to */ -/* fin(I) - pointer to packet information */ -/* csump(I) - pointer to TCP checksum */ -/* */ -/* Check for MSS option and clamp it if necessary. If found and changed, */ -/* then the TCP header checksum will be updated to reflect the change in */ -/* the MSS. */ -/* ------------------------------------------------------------------------ */ -static void nat_mssclamp(tcp, maxmss, fin, csump) -tcphdr_t *tcp; -u_32_t maxmss; -fr_info_t *fin; -u_short *csump; -{ - u_char *cp, *ep, opt; - int hlen, advance; - u_32_t mss, sumd; - - hlen = TCP_OFF(tcp) << 2; - if (hlen > sizeof(*tcp)) { - cp = (u_char *)tcp + sizeof(*tcp); - ep = (u_char *)tcp + hlen; - - while (cp < ep) { - opt = cp[0]; - if (opt == TCPOPT_EOL) - break; - else if (opt == TCPOPT_NOP) { - cp++; - continue; - } - - if (cp + 1 >= ep) - break; - advance = cp[1]; - if ((cp + advance > ep) || (advance <= 0)) - break; - switch (opt) - { - case TCPOPT_MAXSEG: - if (advance != 4) - break; - mss = cp[2] * 256 + cp[3]; - if (mss > maxmss) { - cp[2] = maxmss / 256; - cp[3] = maxmss & 0xff; - CALC_SUMD(mss, maxmss, sumd); - fix_outcksum(fin, csump, sumd); - } - break; - default: - /* ignore unknown options */ - break; - } - - cp += advance; - } - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_setnatqueue */ -/* Returns: Nil */ -/* Parameters: nat(I)- pointer to NAT structure */ -/* rev(I) - forward(0) or reverse(1) direction */ -/* Locks: ipf_nat (read or write) */ -/* */ -/* Put the NAT entry on its default queue entry, using rev as a helped in */ -/* determining which queue it should be placed on. */ -/* ------------------------------------------------------------------------ */ -void fr_setnatqueue(nat, rev) -nat_t *nat; -int rev; -{ - ipftq_t *oifq, *nifq; - - if (nat->nat_ptr != NULL) - nifq = nat->nat_ptr->in_tqehead[rev]; - else - nifq = NULL; - - if (nifq == NULL) { - switch (nat->nat_p) - { - case IPPROTO_UDP : - nifq = &nat_udptq; - break; - case IPPROTO_ICMP : - nifq = &nat_icmptq; - break; - case IPPROTO_TCP : - nifq = nat_tqb + nat->nat_tqe.tqe_state[rev]; - break; - default : - nifq = &nat_iptq; - break; - } - } - - oifq = nat->nat_tqe.tqe_ifq; - /* - * If it's currently on a timeout queue, move it from one queue to - * another, else put it on the end of the newly determined queue. - */ - if (oifq != NULL) - fr_movequeue(&nat->nat_tqe, oifq, nifq); - else - fr_queueappend(&nat->nat_tqe, nifq, nat); - return; -} diff --git a/contrib/ipfilter/ip_nat.h b/contrib/ipfilter/ip_nat.h deleted file mode 100644 index 09cc11989a11..000000000000 --- a/contrib/ipfilter/ip_nat.h +++ /dev/null @@ -1,477 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1995-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_nat.h 1.5 2/4/96 - * Id: ip_nat.h,v 2.90.2.9 2005/03/28 11:09:55 darrenr Exp - */ - -#ifndef __IP_NAT_H__ -#define __IP_NAT_H__ - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#if defined(__STDC__) || defined(__GNUC__) -#define SIOCADNAT _IOW('r', 60, struct ipfobj) -#define SIOCRMNAT _IOW('r', 61, struct ipfobj) -#define SIOCGNATS _IOWR('r', 62, struct ipfobj) -#define SIOCGNATL _IOWR('r', 63, struct ipfobj) -#define SIOCPROXY _IOWR('r', 64, struct ap_control) -#else -#define SIOCADNAT _IOW(r, 60, struct ipfobj) -#define SIOCRMNAT _IOW(r, 61, struct ipfobj) -#define SIOCGNATS _IOWR(r, 62, struct ipfobj) -#define SIOCGNATL _IOWR(r, 63, struct ipfobj) -#define SIOCPROXY _IOWR(r, 64, struct ap_control) -#endif - -#undef LARGE_NAT /* define this if you're setting up a system to NAT - * LARGE numbers of networks/hosts - i.e. in the - * hundreds or thousands. In such a case, you should - * also change the RDR_SIZE and NAT_SIZE below to more - * appropriate sizes. The figures below were used for - * a setup with 1000-2000 networks to NAT. - */ -#ifndef NAT_SIZE -# ifdef LARGE_NAT -# define NAT_SIZE 2047 -# else -# define NAT_SIZE 127 -# endif -#endif -#ifndef RDR_SIZE -# ifdef LARGE_NAT -# define RDR_SIZE 2047 -# else -# define RDR_SIZE 127 -# endif -#endif -#ifndef HOSTMAP_SIZE -# ifdef LARGE_NAT -# define HOSTMAP_SIZE 8191 -# else -# define HOSTMAP_SIZE 2047 -# endif -#endif -#ifndef NAT_TABLE_MAX -/* - * This is newly introduced and for the sake of "least surprise", the numbers - * present aren't what we'd normally use for creating a proper hash table. - */ -# ifdef LARGE_NAT -# define NAT_TABLE_MAX 180000 -# else -# define NAT_TABLE_MAX 30000 -# endif -#endif -#ifndef NAT_TABLE_SZ -# ifdef LARGE_NAT -# define NAT_TABLE_SZ 16383 -# else -# define NAT_TABLE_SZ 2047 -# endif -#endif -#ifndef APR_LABELLEN -#define APR_LABELLEN 16 -#endif -#define NAT_HW_CKSUM 0x80000000 - -#define DEF_NAT_AGE 1200 /* 10 minutes (600 seconds) */ - -struct ipstate; -struct ap_session; - -typedef struct nat { - ipfmutex_t nat_lock; - struct nat *nat_next; - struct nat **nat_pnext; - struct nat *nat_hnext[2]; - struct nat **nat_phnext[2]; - struct hostmap *nat_hm; - void *nat_data; - struct nat **nat_me; - struct ipstate *nat_state; - struct ap_session *nat_aps; /* proxy session */ - frentry_t *nat_fr; /* filter rule ptr if appropriate */ - struct ipnat *nat_ptr; /* pointer back to the rule */ - void *nat_ifps[2]; - void *nat_sync; - ipftqent_t nat_tqe; - u_32_t nat_flags; - u_32_t nat_sumd[2]; /* ip checksum delta for data segment*/ - u_32_t nat_ipsumd; /* ip checksum delta for ip header */ - u_32_t nat_mssclamp; /* if != zero clamp MSS to this */ - i6addr_t nat_inip6; - i6addr_t nat_outip6; - i6addr_t nat_oip6; /* other ip */ - U_QUAD_T nat_pkts[2]; - U_QUAD_T nat_bytes[2]; - union { - udpinfo_t nat_unu; - tcpinfo_t nat_unt; - icmpinfo_t nat_uni; - greinfo_t nat_ugre; - } nat_un; - u_short nat_oport; /* other port */ - u_short nat_use; - u_char nat_p; /* protocol for NAT */ - int nat_dir; - int nat_ref; /* reference count */ - int nat_hv[2]; - char nat_ifnames[2][LIFNAMSIZ]; - int nat_rev; /* 0 = forward, 1 = reverse */ -} nat_t; - -#define nat_inip nat_inip6.in4 -#define nat_outip nat_outip6.in4 -#define nat_oip nat_oip6.in4 -#define nat_age nat_tqe.tqe_die -#define nat_inport nat_un.nat_unt.ts_sport -#define nat_outport nat_un.nat_unt.ts_dport -#define nat_type nat_un.nat_uni.ici_type -#define nat_seq nat_un.nat_uni.ici_seq -#define nat_id nat_un.nat_uni.ici_id -#define nat_tcpstate nat_tqe.tqe_state - -/* - * Values for nat_dir - */ -#define NAT_INBOUND 0 -#define NAT_OUTBOUND 1 - -/* - * Definitions for nat_flags - */ -#define NAT_TCP 0x0001 /* IPN_TCP */ -#define NAT_UDP 0x0002 /* IPN_UDP */ -#define NAT_ICMPERR 0x0004 /* IPN_ICMPERR */ -#define NAT_ICMPQUERY 0x0008 /* IPN_ICMPQUERY */ -#define NAT_SEARCH 0x0010 -#define NAT_SLAVE 0x0020 /* Slave connection for a proxy */ -#define NAT_NOTRULEPORT 0x0040 - -#define NAT_TCPUDP (NAT_TCP|NAT_UDP) -#define NAT_TCPUDPICMP (NAT_TCP|NAT_UDP|NAT_ICMPERR) -#define NAT_TCPUDPICMPQ (NAT_TCP|NAT_UDP|NAT_ICMPQUERY) -#define NAT_FROMRULE (NAT_TCP|NAT_UDP) - -/* 0x0100 reserved for FI_W_SPORT */ -/* 0x0200 reserved for FI_W_DPORT */ -/* 0x0400 reserved for FI_W_SADDR */ -/* 0x0800 reserved for FI_W_DADDR */ -/* 0x1000 reserved for FI_W_NEWFR */ -/* 0x2000 reserved for SI_CLONE */ -/* 0x4000 reserved for SI_CLONED */ -/* 0x8000 reserved for SI_IGNOREPKT */ - -#define NAT_DEBUG 0x800000 - -typedef struct ipnat { - struct ipnat *in_next; /* NAT rule list next */ - struct ipnat *in_rnext; /* rdr rule hash next */ - struct ipnat **in_prnext; /* prior rdr next ptr */ - struct ipnat *in_mnext; /* map rule hash next */ - struct ipnat **in_pmnext; /* prior map next ptr */ - struct ipftq *in_tqehead[2]; - void *in_ifps[2]; - void *in_apr; - char *in_comment; - i6addr_t in_next6; - u_long in_space; - u_long in_hits; - u_int in_use; - u_int in_hv; - int in_flineno; /* conf. file line number */ - u_short in_pnext; - u_char in_v; - u_char in_xxx; - /* From here to the end is covered by IPN_CMPSIZ */ - u_32_t in_flags; - u_32_t in_mssclamp; /* if != 0 clamp MSS to this */ - u_int in_age[2]; - int in_redir; /* see below for values */ - int in_p; /* protocol. */ - i6addr_t in_in[2]; - i6addr_t in_out[2]; - i6addr_t in_src[2]; - frtuc_t in_tuc; - u_short in_port[2]; - u_short in_ppip; /* ports per IP. */ - u_short in_ippip; /* IP #'s per IP# */ - char in_ifnames[2][LIFNAMSIZ]; - char in_plabel[APR_LABELLEN]; /* proxy label. */ - ipftag_t in_tag; -} ipnat_t; - -#define in_pmin in_port[0] /* Also holds static redir port */ -#define in_pmax in_port[1] -#define in_nextip in_next6.in4 -#define in_nip in_next6.in4.s_addr -#define in_inip in_in[0].in4.s_addr -#define in_inmsk in_in[1].in4.s_addr -#define in_outip in_out[0].in4.s_addr -#define in_outmsk in_out[1].in4.s_addr -#define in_srcip in_src[0].in4.s_addr -#define in_srcmsk in_src[1].in4.s_addr -#define in_scmp in_tuc.ftu_scmp -#define in_dcmp in_tuc.ftu_dcmp -#define in_stop in_tuc.ftu_stop -#define in_dtop in_tuc.ftu_dtop -#define in_sport in_tuc.ftu_sport -#define in_dport in_tuc.ftu_dport - -/* - * Bit definitions for in_flags - */ -#define IPN_ANY 0x00000 -#define IPN_TCP 0x00001 -#define IPN_UDP 0x00002 -#define IPN_TCPUDP (IPN_TCP|IPN_UDP) -#define IPN_ICMPERR 0x00004 -#define IPN_TCPUDPICMP (IPN_TCP|IPN_UDP|IPN_ICMPERR) -#define IPN_ICMPQUERY 0x00008 -#define IPN_TCPUDPICMPQ (IPN_TCP|IPN_UDP|IPN_ICMPQUERY) -#define IPN_RF (IPN_TCPUDP|IPN_DELETE|IPN_ICMPERR) -#define IPN_AUTOPORTMAP 0x00010 -#define IPN_IPRANGE 0x00020 -#define IPN_FILTER 0x00040 -#define IPN_SPLIT 0x00080 -#define IPN_ROUNDR 0x00100 -#define IPN_NOTSRC 0x04000 -#define IPN_NOTDST 0x08000 -#define IPN_DYNSRCIP 0x10000 /* dynamic src IP# */ -#define IPN_DYNDSTIP 0x20000 /* dynamic dst IP# */ -#define IPN_DELETE 0x40000 -#define IPN_STICKY 0x80000 -#define IPN_FRAG 0x100000 -#define IPN_FIXEDDPORT 0x200000 -#define IPN_FINDFORWARD 0x400000 -#define IPN_IN 0x800000 -#define IPN_USERFLAGS (IPN_TCPUDP|IPN_AUTOPORTMAP|IPN_IPRANGE|IPN_SPLIT|\ - IPN_ROUNDR|IPN_FILTER|IPN_NOTSRC|IPN_NOTDST|\ - IPN_FRAG|IPN_STICKY|IPN_FIXEDDPORT|IPN_ICMPQUERY) - -/* - * Values for in_redir - */ -#define NAT_MAP 0x01 -#define NAT_REDIRECT 0x02 -#define NAT_BIMAP (NAT_MAP|NAT_REDIRECT) -#define NAT_MAPBLK 0x04 - -#define MAPBLK_MINPORT 1024 /* don't use reserved ports for src port */ -#define USABLE_PORTS (65536 - MAPBLK_MINPORT) - -#define IPN_CMPSIZ (sizeof(ipnat_t) - offsetof(ipnat_t, in_flags)) - -typedef struct natlookup { - struct in_addr nl_inip; - struct in_addr nl_outip; - struct in_addr nl_realip; - int nl_flags; - u_short nl_inport; - u_short nl_outport; - u_short nl_realport; -} natlookup_t; - - -typedef struct nat_save { - void *ipn_next; - struct nat ipn_nat; - struct ipnat ipn_ipnat; - struct frentry ipn_fr; - int ipn_dsize; - char ipn_data[4]; -} nat_save_t; - -#define ipn_rule ipn_nat.nat_fr - -typedef struct natget { - void *ng_ptr; - int ng_sz; -} natget_t; - - -typedef struct nattrpnt { - struct in_addr tr_dstip; /* real destination IP# */ - struct in_addr tr_srcip; /* real source IP# */ - struct in_addr tr_locip; /* local source IP# */ - u_int tr_flags; - int tr_expire; - u_short tr_dstport; /* real destination port# */ - u_short tr_srcport; /* real source port# */ - u_short tr_locport; /* local source port# */ - struct nattrpnt *tr_hnext; - struct nattrpnt **tr_phnext; - struct nattrpnt *tr_next; - struct nattrpnt **tr_pnext; /* previous next */ -} nattrpnt_t; - -#define TN_CMPSIZ offsetof(nattrpnt_t, tr_hnext) - - -/* - * This structure gets used to help NAT sessions keep the same NAT rule (and - * thus translation for IP address) when: - * (a) round-robin redirects are in use - * (b) different IP add - */ -typedef struct hostmap { - struct hostmap *hm_next; - struct hostmap **hm_pnext; - struct ipnat *hm_ipnat; - struct in_addr hm_srcip; - struct in_addr hm_dstip; - struct in_addr hm_mapip; - u_32_t hm_port; - int hm_ref; -} hostmap_t; - - -/* - * Structure used to pass information in to nat_newmap and nat_newrdr. - */ -typedef struct natinfo { - ipnat_t *nai_np; - u_32_t nai_sum1; - u_32_t nai_sum2; - u_32_t nai_nflags; - u_32_t nai_flags; - struct in_addr nai_ip; - u_short nai_port; - u_short nai_nport; - u_short nai_sport; - u_short nai_dport; -} natinfo_t; - - -typedef struct natstat { - u_long ns_mapped[2]; - u_long ns_rules; - u_long ns_added; - u_long ns_expire; - u_long ns_inuse; - u_long ns_logged; - u_long ns_logfail; - u_long ns_memfail; - u_long ns_badnat; - u_long ns_addtrpnt; - nat_t **ns_table[2]; - hostmap_t **ns_maptable; - ipnat_t *ns_list; - void *ns_apslist; - u_int ns_wilds; - u_int ns_nattab_sz; - u_int ns_nattab_max; - u_int ns_rultab_sz; - u_int ns_rdrtab_sz; - u_int ns_trpntab_sz; - u_int ns_hostmap_sz; - nat_t *ns_instances; - nattrpnt_t *ns_trpntlist; - u_long *ns_bucketlen[2]; -} natstat_t; - -typedef struct natlog { - struct in_addr nl_origip; - struct in_addr nl_outip; - struct in_addr nl_inip; - u_short nl_origport; - u_short nl_outport; - u_short nl_inport; - u_short nl_type; - int nl_rule; - U_QUAD_T nl_pkts[2]; - U_QUAD_T nl_bytes[2]; - u_char nl_p; -} natlog_t; - - -#define NL_NEWMAP NAT_MAP -#define NL_NEWRDR NAT_REDIRECT -#define NL_NEWBIMAP NAT_BIMAP -#define NL_NEWBLOCK NAT_MAPBLK -#define NL_CLONE 0xfffd -#define NL_FLUSH 0xfffe -#define NL_EXPIRE 0xffff - -#define NAT_HASH_FN(k,l,m) (((k) + ((k) >> 12) + l) % (m)) - -#define LONG_SUM(in) (((in) & 0xffff) + ((in) >> 16)) - -#define CALC_SUMD(s1, s2, sd) { \ - (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ - (s2) = ((s2) & 0xffff) + ((s2) >> 16); \ - /* Do it twice */ \ - (s1) = ((s1) & 0xffff) + ((s1) >> 16); \ - (s2) = ((s2) & 0xffff) + ((s2) >> 16); \ - /* Because ~1 == -2, We really need ~1 == -1 */ \ - if ((s1) > (s2)) (s2)--; \ - (sd) = (s2) - (s1); \ - (sd) = ((sd) & 0xffff) + ((sd) >> 16); } - -#define NAT_SYSSPACE 0x80000000 -#define NAT_LOCKHELD 0x40000000 - - -extern u_int ipf_nattable_sz; -extern u_int ipf_nattable_max; -extern u_int ipf_natrules_sz; -extern u_int ipf_rdrrules_sz; -extern u_int ipf_hostmap_sz; -extern u_int fr_nat_maxbucket; -extern u_int fr_nat_maxbucket_reset; -extern int fr_nat_lock; -extern void fr_natsync __P((void *)); -extern u_long fr_defnatage; -extern u_long fr_defnaticmpage; -extern u_long fr_defnatipage; - /* nat_table[0] -> hashed list sorted by inside (ip, port) */ - /* nat_table[1] -> hashed list sorted by outside (ip, port) */ -extern nat_t **nat_table[2]; -extern nat_t *nat_instances; -extern ipnat_t *nat_list; -extern ipnat_t **nat_rules; -extern ipnat_t **rdr_rules; -extern ipftq_t *nat_utqe; -extern natstat_t nat_stats; - -#if defined(__OpenBSD__) -extern void nat_ifdetach __P((void *)); -#endif -extern int fr_nat_ioctl __P((caddr_t, ioctlcmd_t, int)); -extern int fr_natinit __P((void)); -extern nat_t *nat_new __P((fr_info_t *, ipnat_t *, nat_t **, u_int, int)); -extern nat_t *nat_outlookup __P((fr_info_t *, u_int, u_int, struct in_addr, - struct in_addr)); -extern void fix_datacksum __P((u_short *, u_32_t)); -extern nat_t *nat_inlookup __P((fr_info_t *, u_int, u_int, struct in_addr, - struct in_addr)); -extern nat_t *nat_tnlookup __P((fr_info_t *, int)); -extern nat_t *nat_maplookup __P((void *, u_int, struct in_addr, - struct in_addr)); -extern nat_t *nat_lookupredir __P((natlookup_t *)); -extern nat_t *nat_icmperrorlookup __P((fr_info_t *, int)); -extern nat_t *nat_icmperror __P((fr_info_t *, u_int *, int)); -extern int nat_insert __P((nat_t *, int)); - -extern int fr_checknatout __P((fr_info_t *, u_32_t *)); -extern int fr_natout __P((fr_info_t *, nat_t *, int, u_32_t)); -extern int fr_checknatin __P((fr_info_t *, u_32_t *)); -extern int fr_natin __P((fr_info_t *, nat_t *, int, u_32_t)); -extern void fr_natunload __P((void)); -extern void fr_natexpire __P((void)); -extern void nat_log __P((struct nat *, u_int)); -extern void fix_incksum __P((fr_info_t *, u_short *, u_32_t)); -extern void fix_outcksum __P((fr_info_t *, u_short *, u_32_t)); -extern void fr_natderef __P((nat_t **)); -extern u_short *nat_proto __P((fr_info_t *, nat_t *, u_int)); -extern void nat_update __P((fr_info_t *, nat_t *, ipnat_t *)); -extern void fr_setnatqueue __P((nat_t *, int)); - -#endif /* __IP_NAT_H__ */ diff --git a/contrib/ipfilter/ip_netbios_pxy.c b/contrib/ipfilter/ip_netbios_pxy.c deleted file mode 100644 index 0ff6d2563891..000000000000 --- a/contrib/ipfilter/ip_netbios_pxy.c +++ /dev/null @@ -1,122 +0,0 @@ -/* $NetBSD$ */ - -/* - * Simple netbios-dgm transparent proxy for in-kernel use. - * For use with the NAT code. - * Id: ip_netbios_pxy.c,v 2.8 2003/12/01 02:52:16 darrenr Exp - */ - -/*- - * Copyright (c) 2002-2003 Paul J. Ledbetter III - * 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. - * - * Id: ip_netbios_pxy.c,v 2.8 2003/12/01 02:52:16 darrenr Exp - */ - -#define IPF_NETBIOS_PROXY - -int ippr_netbios_init __P((void)); -void ippr_netbios_fini __P((void)); -int ippr_netbios_out __P((fr_info_t *, ap_session_t *, nat_t *)); - -static frentry_t netbiosfr; - -int netbios_proxy_init = 0; - -/* - * Initialize local structures. - */ -int ippr_netbios_init() -{ - bzero((char *)&netbiosfr, sizeof(netbiosfr)); - netbiosfr.fr_ref = 1; - netbiosfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&netbiosfr.fr_lock, "NETBIOS proxy rule lock"); - netbios_proxy_init = 1; - - return 0; -} - - -void ippr_netbios_fini() -{ - if (netbios_proxy_init == 1) { - MUTEX_DESTROY(&netbiosfr.fr_lock); - netbios_proxy_init = 0; - } -} - - -int ippr_netbios_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - char dgmbuf[6]; - int off, dlen; - udphdr_t *udp; - ip_t *ip; - mb_t *m; - - aps = aps; /* LINT */ - nat = nat; /* LINT */ - - ip = fin->fin_ip; - m = *(mb_t **)fin->fin_mp; - off = fin->fin_hlen + sizeof(udphdr_t); - dlen = M_LEN(m); - dlen -= off; - - /* - * no net bios datagram could possibly be shorter than this - */ - if (dlen < 11) - return 0; - - udp = (udphdr_t *)fin->fin_dp; - - /* - * move past the - * ip header; - * udp header; - * 4 bytes into the net bios dgm header. - * According to rfc1002, this should be the exact location of - * the source address/port - */ - off += 4; - - /* Copy NATed source Address/port*/ - dgmbuf[0] = (char)((ip->ip_src.s_addr ) &0xFF); - dgmbuf[1] = (char)((ip->ip_src.s_addr >> 8) &0xFF); - dgmbuf[2] = (char)((ip->ip_src.s_addr >> 16)&0xFF); - dgmbuf[3] = (char)((ip->ip_src.s_addr >> 24)&0xFF); - - dgmbuf[4] = (char)((udp->uh_sport )&0xFF); - dgmbuf[5] = (char)((udp->uh_sport >> 8)&0xFF); - - /* replace data in packet */ - COPYBACK(m, off, sizeof(dgmbuf), dgmbuf); - - return 0; -} diff --git a/contrib/ipfilter/ip_pool.c b/contrib/ipfilter/ip_pool.c deleted file mode 100644 index b6e111bdd946..000000000000 --- a/contrib/ipfilter/ip_pool.c +++ /dev/null @@ -1,786 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#if defined(__osf__) -# define _PROTO_NET_H_ -#endif -#include -#include -#include -#include -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#else -# include -# if defined(NetBSD) && (__NetBSD_Version__ >= 104000000) -# include -# endif -#endif -#include -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) && (!defined(__SVR4) && !defined(__svr4__)) -# include -#endif -#if defined(__SVR4) || defined(__svr4__) -# include -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include -#endif - -#if (defined(__osf__) || defined(__hpux) || defined(__sgi)) && defined(_KERNEL) -# ifdef __osf__ -# include -# endif -# include "radix_ipf_local.h" -# define _RADIX_H_ -#endif -#include -#include - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_pool.h" - -#if defined(IPFILTER_LOOKUP) && defined(_KERNEL) && \ - ((BSD >= 198911) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi)) -static int rn_freenode __P((struct radix_node *, void *)); -#endif - -/* END OF INCLUDES */ - -#if !defined(lint) -static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_pool.c,v 2.55.2.12 2005/02/01 04:04:46 darrenr Exp"; -#endif - -#ifdef IPFILTER_LOOKUP - -# ifndef RADIX_NODE_HEAD_LOCK -# define RADIX_NODE_HEAD_LOCK(x) ; -# endif -# ifndef RADIX_NODE_HEAD_UNLOCK -# define RADIX_NODE_HEAD_UNLOCK(x) ; -# endif - -ip_pool_stat_t ipoolstat; -ipfrwlock_t ip_poolrw; - -/* - * Binary tree routines from Sedgewick and enhanced to do ranges of addresses. - * NOTE: Insertion *MUST* be from greatest range to least for it to work! - * These should be replaced, eventually, by something else - most notably a - * interval searching method. The important feature is to be able to find - * the best match. - * - * So why not use a radix tree for this? As the first line implies, it - * has been written to work with a _range_ of addresses. A range is not - * necessarily a match with any given netmask so what we end up dealing - * with is an interval tree. Implementations of these are hard to find - * and the one herein is far from bug free. - * - * Sigh, in the end I became convinced that the bugs the code contained did - * not make it worthwhile not using radix trees. For now the radix tree from - * 4.4 BSD is used, but this is not viewed as a long term solution. - */ -ip_pool_t *ip_pool_list[IPL_LOGSIZE] = { NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL }; - - -#ifdef TEST_POOL -void treeprint __P((ip_pool_t *)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - addrfamily_t a, b; - iplookupop_t op; - ip_pool_t *ipo; - i6addr_t ip; - - RWLOCK_INIT(&ip_poolrw, "poolrw"); - ip_pool_init(); - - bzero((char *)&a, sizeof(a)); - bzero((char *)&b, sizeof(b)); - bzero((char *)&ip, sizeof(ip)); - bzero((char *)&op, sizeof(op)); - strcpy(op.iplo_name, "0"); - - if (ip_pool_create(&op) == 0) - ipo = ip_pool_find(0, "0"); - - a.adf_addr.in4.s_addr = 0x0a010203; - b.adf_addr.in4.s_addr = 0xffffffff; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - - a.adf_addr.in4.s_addr = 0x0a000000; - b.adf_addr.in4.s_addr = 0xff000000; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - - a.adf_addr.in4.s_addr = 0x0a010100; - b.adf_addr.in4.s_addr = 0xffffff00; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - - a.adf_addr.in4.s_addr = 0x0a010200; - b.adf_addr.in4.s_addr = 0xffffff00; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 0); - - a.adf_addr.in4.s_addr = 0x0a010000; - b.adf_addr.in4.s_addr = 0xffff0000; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - - a.adf_addr.in4.s_addr = 0x0a01020f; - b.adf_addr.in4.s_addr = 0xffffffff; - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); - ip_pool_insert(ipo, &a.adf_addr, &b.adf_addr, 1); -#ifdef DEBUG_POOL -treeprint(ipo); -#endif - ip.in4.s_addr = 0x0a00aabb; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a000001; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a000101; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010001; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010101; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010201; - printf("search(%#x) = %d (0)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a010203; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0a01020f; - printf("search(%#x) = %d (1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - - ip.in4.s_addr = 0x0b00aabb; - printf("search(%#x) = %d (-1)\n", ip.in4.s_addr, - ip_pool_search(ipo, 4, &ip)); - -#ifdef DEBUG_POOL -treeprint(ipo); -#endif - - ip_pool_fini(); - - return 0; -} - - -void -treeprint(ipo) -ip_pool_t *ipo; -{ - ip_pool_node_t *c; - - for (c = ipo->ipo_list; c != NULL; c = c->ipn_next) - printf("Node %p(%s) (%#x/%#x) = %d hits %lu\n", - c, c->ipn_name, c->ipn_addr.adf_addr.in4.s_addr, - c->ipn_mask.adf_addr.in4.s_addr, - c->ipn_info, c->ipn_hits); -} -#endif /* TEST_POOL */ - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_init */ -/* Returns: int - 0 = success, else error */ -/* */ -/* Initialise the routing table data structures where required. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_init() -{ - - bzero((char *)&ipoolstat, sizeof(ipoolstat)); - -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_init(); -#endif - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_fini */ -/* Returns: int - 0 = success, else error */ -/* Locks: WRITE(ipf_global) */ -/* */ -/* Clean up all the pool data structures allocated and call the cleanup */ -/* function for the radix tree that supports the pools. ip_pool_destroy() is*/ -/* used to delete the pools one by one to ensure they're properly freed up. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_fini() -{ - ip_pool_t *p, *q; - iplookupop_t op; - int i; - - ASSERT(rw_read_locked(&ipf_global.ipf_lk) == 0); - - for (i = 0; i <= IPL_LOGMAX; i++) { - for (q = ip_pool_list[i]; (p = q) != NULL; ) { - op.iplo_unit = i; - (void)strncpy(op.iplo_name, p->ipo_name, - sizeof(op.iplo_name)); - q = p->ipo_next; - (void) ip_pool_destroy(&op); - } - } - -#if (!defined(_KERNEL) || (BSD < 199306)) - rn_fini(); -#endif -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_statistics */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - pointer to lookup operation arguments */ -/* */ -/* Copy the current statistics out into user space, collecting pool list */ -/* pointers as appropriate for later use. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_statistics(op) -iplookupop_t *op; -{ - ip_pool_stat_t stats; - int unit, i, err = 0; - - if (op->iplo_size != sizeof(ipoolstat)) - return EINVAL; - - bcopy((char *)&ipoolstat, (char *)&stats, sizeof(stats)); - unit = op->iplo_unit; - if (unit == IPL_LOGALL) { - for (i = 0; i < IPL_LOGSIZE; i++) - stats.ipls_list[i] = ip_pool_list[i]; - } else if (unit >= 0 && unit < IPL_LOGSIZE) { - if (op->iplo_name[0] != '\0') - stats.ipls_list[unit] = ip_pool_find(unit, - op->iplo_name); - else - stats.ipls_list[unit] = ip_pool_list[unit]; - } else - err = EINVAL; - if (err == 0) - err = COPYOUT(&stats, op->iplo_struct, sizeof(stats)); - return err; -} - - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_find */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* */ -/* Find a matching pool inside the collection of pools for a particular */ -/* device, indicated by the unit number. */ -/* ------------------------------------------------------------------------ */ -void *ip_pool_find(unit, name) -int unit; -char *name; -{ - ip_pool_t *p; - - for (p = ip_pool_list[unit]; p != NULL; p = p->ipo_next) - if (strncmp(p->ipo_name, name, sizeof(p->ipo_name)) == 0) - break; - return p; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_findeq */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* addr(I) - pointer to address information to delete */ -/* mask(I) - */ -/* */ -/* Searches for an exact match of an entry in the pool. */ -/* ------------------------------------------------------------------------ */ -ip_pool_node_t *ip_pool_findeq(ipo, addr, mask) -ip_pool_t *ipo; -addrfamily_t *addr, *mask; -{ - struct radix_node *n; -#ifdef USE_SPL - int s; - - SPL_NET(s); -#endif - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - n = ipo->ipo_head->rnh_lookup(addr, mask, ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - SPL_X(s); - return (ip_pool_node_t *)n; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_search */ -/* Returns: int - 0 == +ve match, -1 == error, 1 == -ve/no match */ -/* Parameters: tptr(I) - pointer to the pool to search */ -/* version(I) - IP protocol version (4 or 6) */ -/* dptr(I) - pointer to address information */ -/* */ -/* Search the pool for a given address and return a search result. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_search(tptr, version, dptr) -void *tptr; -int version; -void *dptr; -{ - struct radix_node *rn; - ip_pool_node_t *m; - i6addr_t *addr; - addrfamily_t v; - ip_pool_t *ipo; - int rv; - - ipo = tptr; - if (ipo == NULL) - return -1; - - rv = 1; - m = NULL; - addr = (i6addr_t *)dptr; - bzero(&v, sizeof(v)); - v.adf_len = offsetof(addrfamily_t, adf_addr); - - if (version == 4) { - v.adf_len += sizeof(addr->in4); - v.adf_addr.in4 = addr->in4; -#ifdef USE_INET6 - } else if (version == 6) { - v.adf_len += sizeof(addr->in6); - v.adf_addr.in6 = addr->in6; -#endif - } else - return -1; - - READ_ENTER(&ip_poolrw); - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - rn = ipo->ipo_head->rnh_matchaddr(&v, ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - - if ((rn != NULL) && ((rn->rn_flags & RNF_ROOT) == 0)) { - m = (ip_pool_node_t *)rn; - ipo->ipo_hits++; - m->ipn_hits++; - rv = m->ipn_info; - } - RWLOCK_EXIT(&ip_poolrw); - return rv; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_insert */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool getting the new node. */ -/* addr(I) - address being added as a node */ -/* mask(I) - netmask to with the node being added */ -/* info(I) - extra information to store in this node. */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Add another node to the pool given by ipo. The three parameters passed */ -/* in (addr, mask, info) shold all be stored in the node. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_insert(ipo, addr, mask, info) -ip_pool_t *ipo; -i6addr_t *addr, *mask; -int info; -{ - struct radix_node *rn; - ip_pool_node_t *x; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - KMALLOC(x, ip_pool_node_t *); - if (x == NULL) { - return ENOMEM; - } - - bzero(x, sizeof(*x)); - - x->ipn_info = info; - (void)strncpy(x->ipn_name, ipo->ipo_name, sizeof(x->ipn_name)); - - bcopy(addr, &x->ipn_addr.adf_addr, sizeof(*addr)); - x->ipn_addr.adf_len = sizeof(x->ipn_addr); - bcopy(mask, &x->ipn_mask.adf_addr, sizeof(*mask)); - x->ipn_mask.adf_len = sizeof(x->ipn_mask); - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - rn = ipo->ipo_head->rnh_addaddr(&x->ipn_addr, &x->ipn_mask, - ipo->ipo_head, x->ipn_nodes); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); -#ifdef DEBUG_POOL - printf("Added %p at %p\n", x, rn); -#endif - - if (rn == NULL) { - KFREE(x); - return ENOMEM; - } - - x->ipn_next = ipo->ipo_list; - x->ipn_pnext = &ipo->ipo_list; - if (ipo->ipo_list != NULL) - ipo->ipo_list->ipn_pnext = &x->ipn_next; - ipo->ipo_list = x; - - ipoolstat.ipls_nodes++; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_create */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - pointer to iplookup struct with call details */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Creates a new group according to the paramters passed in via the */ -/* iplookupop structure. Does not check to see if the group already exists */ -/* when being inserted - assume this has already been done. If the pool is */ -/* marked as being anonymous, give it a new, unique, identifier. Call any */ -/* other functions required to initialise the structure. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_create(op) -iplookupop_t *op; -{ - char name[FR_GROUPLEN]; - int poolnum, unit; - ip_pool_t *h; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - KMALLOC(h, ip_pool_t *); - if (h == NULL) - return ENOMEM; - bzero(h, sizeof(*h)); - - if (rn_inithead((void **)&h->ipo_head, - offsetof(addrfamily_t, adf_addr) << 3) == 0) { - KFREE(h); - return ENOMEM; - } - - unit = op->iplo_unit; - - if ((op->iplo_arg & IPOOL_ANON) != 0) { - ip_pool_t *p; - - poolnum = IPOOL_ANON; - -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%x", poolnum); -#else - (void)sprintf(name, "%x", poolnum); -#endif - - for (p = ip_pool_list[unit]; p != NULL; ) { - if (strncmp(name, p->ipo_name, - sizeof(p->ipo_name)) == 0) { - poolnum++; -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(name, sizeof(name), "%x", poolnum); -#else - (void)sprintf(name, "%x", poolnum); -#endif - p = ip_pool_list[unit]; - } else - p = p->ipo_next; - } - - (void)strncpy(h->ipo_name, name, sizeof(h->ipo_name)); - } else { - (void) strncpy(h->ipo_name, op->iplo_name, sizeof(h->ipo_name)); - } - - h->ipo_ref = 1; - h->ipo_list = NULL; - h->ipo_unit = unit; - h->ipo_next = ip_pool_list[unit]; - if (ip_pool_list[unit] != NULL) - ip_pool_list[unit]->ipo_pnext = &h->ipo_next; - h->ipo_pnext = &ip_pool_list[unit]; - ip_pool_list[unit] = h; - - ipoolstat.ipls_pools++; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_remove */ -/* Returns: int - 0 = success, else error */ -/* Parameters: ipo(I) - pointer to the pool to remove the node from. */ -/* ipe(I) - address being deleted as a node */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Add another node to the pool given by ipo. The three parameters passed */ -/* in (addr, mask, info) shold all be stored in the node. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_remove(ipo, ipe) -ip_pool_t *ipo; -ip_pool_node_t *ipe; -{ - ip_pool_node_t **ipp, *n; - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - for (ipp = &ipo->ipo_list; (n = *ipp) != NULL; ipp = &n->ipn_next) { - if (ipe == n) { - *n->ipn_pnext = n->ipn_next; - if (n->ipn_next) - n->ipn_next->ipn_pnext = n->ipn_pnext; - break; - } - } - - if (n == NULL) - return ENOENT; - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, - ipo->ipo_head); - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - KFREE(n); - - ipoolstat.ipls_nodes--; - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_destroy */ -/* Returns: int - 0 = success, else error */ -/* Parameters: op(I) - information about the pool to remove */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ -/* */ -/* Search for a pool using paramters passed in and if it's not otherwise */ -/* busy, free it. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ -/* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_destroy(op) -iplookupop_t *op; -{ - ip_pool_t *ipo; - - ipo = ip_pool_find(op->iplo_unit, op->iplo_name); - if (ipo == NULL) - return ESRCH; - - if (ipo->ipo_ref != 1) - return EBUSY; - - ip_pool_free(ipo); - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_flush */ -/* Returns: int - number of pools deleted */ -/* Parameters: fp(I) - which pool(s) to flush */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ -/* */ -/* Free all pools associated with the device that matches the unit number */ -/* passed in with operation. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ -/* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ -/* ------------------------------------------------------------------------ */ -int ip_pool_flush(fp) -iplookupflush_t *fp; -{ - int i, num = 0, unit, err; - ip_pool_t *p, *q; - iplookupop_t op; - - unit = fp->iplf_unit; - - for (i = 0; i <= IPL_LOGMAX; i++) { - if (unit != IPLT_ALL && i != unit) - continue; - for (q = ip_pool_list[i]; (p = q) != NULL; ) { - op.iplo_unit = i; - (void)strncpy(op.iplo_name, p->ipo_name, - sizeof(op.iplo_name)); - q = p->ipo_next; - err = ip_pool_destroy(&op); - if (err == 0) - num++; - else - break; - } - } - return num; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_free */ -/* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) or WRITE(ipf_global) */ -/* */ -/* Deletes the pool strucutre passed in from the list of pools and deletes */ -/* all of the address information stored in it, including any tree data */ -/* structures also allocated. */ -/* */ -/* NOTE: Because this function is called out of ipldetach() where ip_poolrw */ -/* may not be initialised, we can't use an ASSERT to enforce the locking */ -/* assertion that one of the two (ip_poolrw,ipf_global) is held. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_free(ipo) -ip_pool_t *ipo; -{ - ip_pool_node_t *n; - - RADIX_NODE_HEAD_LOCK(ipo->ipo_head); - while ((n = ipo->ipo_list) != NULL) { - ipo->ipo_head->rnh_deladdr(&n->ipn_addr, &n->ipn_mask, - ipo->ipo_head); - - *n->ipn_pnext = n->ipn_next; - if (n->ipn_next) - n->ipn_next->ipn_pnext = n->ipn_pnext; - - KFREE(n); - - ipoolstat.ipls_nodes--; - } - RADIX_NODE_HEAD_UNLOCK(ipo->ipo_head); - - ipo->ipo_list = NULL; - if (ipo->ipo_next != NULL) - ipo->ipo_next->ipo_pnext = ipo->ipo_pnext; - *ipo->ipo_pnext = ipo->ipo_next; - rn_freehead(ipo->ipo_head); - KFREE(ipo); - - ipoolstat.ipls_pools--; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ip_pool_deref */ -/* Returns: void */ -/* Parameters: ipo(I) - pointer to pool structure */ -/* Locks: WRITE(ip_poolrw) */ -/* */ -/* Drop the number of known references to this pool structure by one and if */ -/* we arrive at zero known references, free it. */ -/* ------------------------------------------------------------------------ */ -void ip_pool_deref(ipo) -ip_pool_t *ipo; -{ - - ASSERT(rw_read_locked(&ip_poolrw.ipf_lk) == 0); - - ipo->ipo_ref--; - if (ipo->ipo_ref == 0) - ip_pool_free(ipo); -} - - -# if defined(_KERNEL) && ((BSD >= 198911) && !defined(__osf__) && \ - !defined(__hpux) && !defined(__sgi)) -static int -rn_freenode(struct radix_node *n, void *p) -{ - struct radix_node_head *rnh = p; - struct radix_node *d; - - d = rnh->rnh_deladdr(n->rn_key, NULL, rnh); - if (d != NULL) { - FreeS(d, max_keylen + 2 * sizeof (*d)); - } - return 0; -} - - -void -rn_freehead(rnh) - struct radix_node_head *rnh; -{ - - RADIX_NODE_HEAD_LOCK(rnh); - (*rnh->rnh_walktree)(rnh, rn_freenode, rnh); - - rnh->rnh_addaddr = NULL; - rnh->rnh_deladdr = NULL; - rnh->rnh_matchaddr = NULL; - rnh->rnh_lookup = NULL; - rnh->rnh_walktree = NULL; - RADIX_NODE_HEAD_UNLOCK(rnh); - - Free(rnh); -} -# endif - -#endif /* IPFILTER_LOOKUP */ diff --git a/contrib/ipfilter/ip_pool.h b/contrib/ipfilter/ip_pool.h deleted file mode 100644 index 3e3c07355229..000000000000 --- a/contrib/ipfilter/ip_pool.h +++ /dev/null @@ -1,87 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_pool.h,v 2.26.2.2 2004/03/23 12:44:34 darrenr Exp - */ - -#ifndef __IP_POOL_H__ -#define __IP_POOL_H__ - -#if defined(_KERNEL) && !defined(__osf__) && !defined(__hpux) && \ - !defined(linux) && !defined(sun) -# include -extern void rn_freehead __P((struct radix_node_head *)); -# define FreeS(p, z) KFREES(p, z) -extern int max_keylen; -#else -# if defined(__osf__) || defined(__hpux) -# include "radix_ipf_local.h" -# define radix_mask ipf_radix_mask -# define radix_node ipf_radix_node -# define radix_node_head ipf_radix_node_head -# else -# include "radix_ipf.h" -# endif -#endif -#include "netinet/ip_lookup.h" - -#define IP_POOL_NOMATCH 0 -#define IP_POOL_POSITIVE 1 - -typedef struct ip_pool_node { - struct radix_node ipn_nodes[2]; - addrfamily_t ipn_addr; - addrfamily_t ipn_mask; - int ipn_info; - char ipn_name[FR_GROUPLEN]; - u_long ipn_hits; - struct ip_pool_node *ipn_next, **ipn_pnext; -} ip_pool_node_t; - - -typedef struct ip_pool_s { - struct ip_pool_s *ipo_next; - struct ip_pool_s **ipo_pnext; - struct radix_node_head *ipo_head; - ip_pool_node_t *ipo_list; - u_long ipo_hits; - int ipo_unit; - int ipo_flags; - int ipo_ref; - char ipo_name[FR_GROUPLEN]; -} ip_pool_t; - -#define IPOOL_ANON 0x80000000 - - -typedef struct ip_pool_stat { - u_long ipls_pools; - u_long ipls_tables; - u_long ipls_nodes; - ip_pool_t *ipls_list[IPL_LOGSIZE]; -} ip_pool_stat_t; - - -extern ip_pool_stat_t ipoolstat; -extern ip_pool_t *ip_pool_list[IPL_LOGSIZE]; - -extern int ip_pool_search __P((void *, int, void *)); -extern int ip_pool_init __P((void)); -extern void ip_pool_fini __P((void)); -extern int ip_pool_create __P((iplookupop_t *)); -extern int ip_pool_insert __P((ip_pool_t *, i6addr_t *, i6addr_t *, int)); -extern int ip_pool_remove __P((ip_pool_t *, ip_pool_node_t *)); -extern int ip_pool_destroy __P((iplookupop_t *)); -extern void ip_pool_free __P((ip_pool_t *)); -extern void ip_pool_deref __P((ip_pool_t *)); -extern void *ip_pool_find __P((int, char *)); -extern ip_pool_node_t *ip_pool_findeq __P((ip_pool_t *, - addrfamily_t *, addrfamily_t *)); -extern int ip_pool_flush __P((iplookupflush_t *)); -extern int ip_pool_statistics __P((iplookupop_t *)); - -#endif /* __IP_POOL_H__ */ diff --git a/contrib/ipfilter/ip_pptp_pxy.c b/contrib/ipfilter/ip_pptp_pxy.c deleted file mode 100644 index 2511a17600d6..000000000000 --- a/contrib/ipfilter/ip_pptp_pxy.c +++ /dev/null @@ -1,527 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2002-2003 by Darren Reed - * - * Simple PPTP transparent proxy for in-kernel use. For use with the NAT - * code. - * - * Id: ip_pptp_pxy.c,v 2.10.2.9 2005/03/16 18:17:34 darrenr Exp - * - */ -#define IPF_PPTP_PROXY - -typedef struct pptp_hdr { - u_short pptph_len; - u_short pptph_type; - u_32_t pptph_cookie; -} pptp_hdr_t; - -#define PPTP_MSGTYPE_CTL 1 -#define PPTP_MTCTL_STARTREQ 1 -#define PPTP_MTCTL_STARTREP 2 -#define PPTP_MTCTL_STOPREQ 3 -#define PPTP_MTCTL_STOPREP 4 -#define PPTP_MTCTL_ECHOREQ 5 -#define PPTP_MTCTL_ECHOREP 6 -#define PPTP_MTCTL_OUTREQ 7 -#define PPTP_MTCTL_OUTREP 8 -#define PPTP_MTCTL_INREQ 9 -#define PPTP_MTCTL_INREP 10 -#define PPTP_MTCTL_INCONNECT 11 -#define PPTP_MTCTL_CLEAR 12 -#define PPTP_MTCTL_DISCONNECT 13 -#define PPTP_MTCTL_WANERROR 14 -#define PPTP_MTCTL_LINKINFO 15 - - -int ippr_pptp_init __P((void)); -void ippr_pptp_fini __P((void)); -int ippr_pptp_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_pptp_del __P((ap_session_t *)); -int ippr_pptp_inout __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_pptp_donatstate __P((fr_info_t *, nat_t *, pptp_pxy_t *)); -int ippr_pptp_message __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); -int ippr_pptp_nextmessage __P((fr_info_t *, nat_t *, pptp_pxy_t *, int)); -int ippr_pptp_mctl __P((fr_info_t *, nat_t *, pptp_pxy_t *, pptp_side_t *)); - -static frentry_t pptpfr; - -int pptp_proxy_init = 0; -int ippr_pptp_debug = 0; -int ippr_pptp_gretimeout = IPF_TTLVAL(120); /* 2 minutes */ - - -/* - * PPTP application proxy initialization. - */ -int ippr_pptp_init() -{ - bzero((char *)&pptpfr, sizeof(pptpfr)); - pptpfr.fr_ref = 1; - pptpfr.fr_age[0] = ippr_pptp_gretimeout; - pptpfr.fr_age[1] = ippr_pptp_gretimeout; - pptpfr.fr_flags = FR_OUTQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&pptpfr.fr_lock, "PPTP proxy rule lock"); - pptp_proxy_init = 1; - - return 0; -} - - -void ippr_pptp_fini() -{ - if (pptp_proxy_init == 1) { - MUTEX_DESTROY(&pptpfr.fr_lock); - pptp_proxy_init = 0; - } -} - - -/* - * Setup for a new PPTP proxy. - */ -int ippr_pptp_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - pptp_pxy_t *pptp; - ipnat_t *ipn; - ip_t *ip; - int off; - - ip = fin->fin_ip; - off = fin->fin_hlen + sizeof(udphdr_t); - - if (nat_outlookup(fin, 0, IPPROTO_GRE, nat->nat_inip, - ip->ip_dst) != NULL) { - if (ippr_pptp_debug > 0) - printf("ippr_pptp_new: GRE session already exists\n"); - return -1; - } - - aps->aps_psiz = sizeof(*pptp); - KMALLOCS(aps->aps_data, pptp_pxy_t *, sizeof(*pptp)); - if (aps->aps_data == NULL) { - if (ippr_pptp_debug > 0) - printf("ippr_pptp_new: malloc for aps_data failed\n"); - return -1; - } - - /* - * Create NAT rule against which the tunnel/transport mapping is - * created. This is required because the current NAT rule does not - * describe GRE but TCP instead. - */ - pptp = aps->aps_data; - bzero((char *)pptp, sizeof(*pptp)); - ipn = &pptp->pptp_rule; - ipn->in_ifps[0] = fin->fin_ifp; - ipn->in_apr = NULL; - ipn->in_use = 1; - ipn->in_hits = 1; - ipn->in_ippip = 1; - if (nat->nat_dir == NAT_OUTBOUND) { - ipn->in_nip = ntohl(nat->nat_outip.s_addr); - ipn->in_outip = fin->fin_saddr; - ipn->in_redir = NAT_MAP; - } else if (nat->nat_dir == NAT_INBOUND) { - ipn->in_nip = 0; - ipn->in_outip = nat->nat_outip.s_addr; - ipn->in_redir = NAT_REDIRECT; - } - ipn->in_inip = nat->nat_inip.s_addr; - ipn->in_inmsk = 0xffffffff; - ipn->in_outmsk = 0xffffffff; - ipn->in_srcip = fin->fin_saddr; - ipn->in_srcmsk = 0xffffffff; - bcopy(nat->nat_ptr->in_ifnames[0], ipn->in_ifnames[0], - sizeof(ipn->in_ifnames[0])); - ipn->in_p = IPPROTO_GRE; - - pptp->pptp_side[0].pptps_wptr = pptp->pptp_side[0].pptps_buffer; - pptp->pptp_side[1].pptps_wptr = pptp->pptp_side[1].pptps_buffer; - return 0; -} - - -void ippr_pptp_donatstate(fin, nat, pptp) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -{ - fr_info_t fi; - grehdr_t gre; - nat_t *nat2; - u_char p; - ip_t *ip; - - ip = fin->fin_ip; - p = ip->ip_p; - - nat2 = pptp->pptp_nat; - if ((nat2 == NULL) || (pptp->pptp_state == NULL)) { - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - bzero((char *)&gre, sizeof(gre)); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_fi.fi_p = IPPROTO_GRE; - fi.fin_fr = &pptpfr; - if ((nat->nat_dir == NAT_OUTBOUND && fin->fin_out) || - (nat->nat_dir == NAT_INBOUND && !fin->fin_out)) { - fi.fin_data[0] = pptp->pptp_call[0]; - fi.fin_data[1] = pptp->pptp_call[1]; - } else { - fi.fin_data[0] = pptp->pptp_call[1]; - fi.fin_data[1] = pptp->pptp_call[0]; - } - ip = fin->fin_ip; - ip->ip_p = IPPROTO_GRE; - fi.fin_flx &= ~(FI_TCPUDP|FI_STATE|FI_FRAG); - fi.fin_flx |= FI_IGNORE; - fi.fin_dp = &gre; - gre.gr_flags = htons(1 << 13); - if (fin->fin_out && nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_saddr = fin->fin_fi.fi_daddr; - fi.fin_fi.fi_daddr = nat->nat_outip.s_addr; - } else if (!fin->fin_out && nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - fi.fin_fi.fi_daddr = fin->fin_fi.fi_saddr; - } - } - - /* - * Update NAT timeout/create NAT if missing. - */ - if (nat2 != NULL) - fr_queueback(&nat2->nat_tqe); - else { - nat2 = nat_new(&fi, &pptp->pptp_rule, &pptp->pptp_nat, - NAT_SLAVE, nat->nat_dir); - pptp->pptp_nat = nat2; - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, 0); - nat_update(&fi, nat2, nat2->nat_ptr); - } - } - - READ_ENTER(&ipf_state); - if (pptp->pptp_state != NULL) { - fr_queueback(&pptp->pptp_state->is_sti); - RWLOCK_EXIT(&ipf_state); - } else { - RWLOCK_EXIT(&ipf_state); - if (nat->nat_dir == NAT_INBOUND) - fi.fin_fi.fi_daddr = nat2->nat_inip.s_addr; - else - fi.fin_fi.fi_saddr = nat2->nat_inip.s_addr; - fi.fin_ifp = NULL; - pptp->pptp_state = fr_addstate(&fi, &pptp->pptp_state, - 0); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_p = p; - return; -} - - -/* - * Try and build up the next PPTP message in the TCP stream and if we can - * build it up completely (fits in our buffer) then pass it off to the message - * parsing function. - */ -int ippr_pptp_nextmessage(fin, nat, pptp, rev) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -int rev; -{ - static char *funcname = "ippr_pptp_nextmessage"; - pptp_side_t *pptps; - u_32_t start, end; - pptp_hdr_t *hdr; - tcphdr_t *tcp; - int dlen, off; - u_short len; - char *msg; - - tcp = fin->fin_dp; - dlen = fin->fin_dlen - (TCP_OFF(tcp) << 2); - start = ntohl(tcp->th_seq); - pptps = &pptp->pptp_side[rev]; - off = (char *)tcp - (char *)fin->fin_ip + (TCP_OFF(tcp) << 2) + - fin->fin_ipoff; - - if (dlen <= 0) - return 0; - /* - * If the complete data packet is before what we expect to see - * "next", just ignore it as the chances are we've already seen it. - * The next if statement following this one really just causes packets - * ahead of what we've seen to be dropped, implying that something in - * the middle went missing and we want to see that first. - */ - end = start + dlen; - if (pptps->pptps_next > end && pptps->pptps_next > start) - return 0; - - if (pptps->pptps_next != start) { - if (ippr_pptp_debug > 5) - printf("%s: next (%x) != start (%x)\n", funcname, - pptps->pptps_next, start); - return -1; - } - - msg = (char *)fin->fin_dp + (TCP_OFF(tcp) << 2); - - while (dlen > 0) { - off += pptps->pptps_bytes; - if (pptps->pptps_gothdr == 0) { - /* - * PPTP has an 8 byte header that inclues the cookie. - * The start of every message should include one and - * it should match 1a2b3c4d. Byte order is ignored, - * deliberately, when printing out the error. - */ - len = MIN(8 - pptps->pptps_bytes, dlen); - COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr); - pptps->pptps_bytes += len; - pptps->pptps_wptr += len; - hdr = (pptp_hdr_t *)pptps->pptps_buffer; - if (pptps->pptps_bytes == 8) { - pptps->pptps_next += 8; - if (ntohl(hdr->pptph_cookie) != 0x1a2b3c4d) { - if (ippr_pptp_debug > 1) - printf("%s: bad cookie (%x)\n", - funcname, - hdr->pptph_cookie); - return -1; - } - } - dlen -= len; - msg += len; - off += len; - - pptps->pptps_gothdr = 1; - len = ntohs(hdr->pptph_len); - pptps->pptps_len = len; - pptps->pptps_nexthdr += len; - - /* - * If a message is too big for the buffer, just set - * the fields for the next message to come along. - * The messages defined in RFC 2637 will not exceed - * 512 bytes (in total length) so this is likely a - * bad data packet, anyway. - */ - if (len > sizeof(pptps->pptps_buffer)) { - if (ippr_pptp_debug > 3) - printf("%s: message too big (%d)\n", - funcname, len); - pptps->pptps_next = pptps->pptps_nexthdr; - pptps->pptps_wptr = pptps->pptps_buffer; - pptps->pptps_gothdr = 0; - pptps->pptps_bytes = 0; - pptps->pptps_len = 0; - break; - } - } - - len = MIN(pptps->pptps_len - pptps->pptps_bytes, dlen); - COPYDATA(fin->fin_m, off, len, pptps->pptps_wptr); - pptps->pptps_bytes += len; - pptps->pptps_wptr += len; - pptps->pptps_next += len; - - if (pptps->pptps_len > pptps->pptps_bytes) - break; - - ippr_pptp_message(fin, nat, pptp, pptps); - pptps->pptps_wptr = pptps->pptps_buffer; - pptps->pptps_gothdr = 0; - pptps->pptps_bytes = 0; - pptps->pptps_len = 0; - - start += len; - msg += len; - dlen -= len; - } - - return 0; -} - - -/* - * handle a complete PPTP message - */ -int ippr_pptp_message(fin, nat, pptp, pptps) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -pptp_side_t *pptps; -{ - pptp_hdr_t *hdr = (pptp_hdr_t *)pptps->pptps_buffer; - - switch (ntohs(hdr->pptph_type)) - { - case PPTP_MSGTYPE_CTL : - ippr_pptp_mctl(fin, nat, pptp, pptps); - break; - - default : - break; - } - return 0; -} - - -/* - * handle a complete PPTP control message - */ -int ippr_pptp_mctl(fin, nat, pptp, pptps) -fr_info_t *fin; -nat_t *nat; -pptp_pxy_t *pptp; -pptp_side_t *pptps; -{ - u_short *buffer = (u_short *)(pptps->pptps_buffer); - pptp_side_t *pptpo; - - if (pptps == &pptp->pptp_side[0]) - pptpo = &pptp->pptp_side[1]; - else - pptpo = &pptp->pptp_side[0]; - - /* - * Breakout to handle all the various messages. Most are just state - * transition. - */ - switch (ntohs(buffer[4])) - { - case PPTP_MTCTL_STARTREQ : - pptps->pptps_state = PPTP_MTCTL_STARTREQ; - break; - case PPTP_MTCTL_STARTREP : - if (pptpo->pptps_state == PPTP_MTCTL_STARTREQ) - pptps->pptps_state = PPTP_MTCTL_STARTREP; - break; - case PPTP_MTCTL_STOPREQ : - pptps->pptps_state = PPTP_MTCTL_STOPREQ; - break; - case PPTP_MTCTL_STOPREP : - if (pptpo->pptps_state == PPTP_MTCTL_STOPREQ) - pptps->pptps_state = PPTP_MTCTL_STOPREP; - break; - case PPTP_MTCTL_ECHOREQ : - pptps->pptps_state = PPTP_MTCTL_ECHOREQ; - break; - case PPTP_MTCTL_ECHOREP : - if (pptpo->pptps_state == PPTP_MTCTL_ECHOREQ) - pptps->pptps_state = PPTP_MTCTL_ECHOREP; - break; - case PPTP_MTCTL_OUTREQ : - pptps->pptps_state = PPTP_MTCTL_OUTREQ; - break; - case PPTP_MTCTL_OUTREP : - if (pptpo->pptps_state == PPTP_MTCTL_OUTREQ) { - pptps->pptps_state = PPTP_MTCTL_OUTREP; - pptp->pptp_call[0] = buffer[7]; - pptp->pptp_call[1] = buffer[6]; - ippr_pptp_donatstate(fin, nat, pptp); - } - break; - case PPTP_MTCTL_INREQ : - pptps->pptps_state = PPTP_MTCTL_INREQ; - break; - case PPTP_MTCTL_INREP : - if (pptpo->pptps_state == PPTP_MTCTL_INREQ) { - pptps->pptps_state = PPTP_MTCTL_INREP; - pptp->pptp_call[0] = buffer[7]; - pptp->pptp_call[1] = buffer[6]; - ippr_pptp_donatstate(fin, nat, pptp); - } - break; - case PPTP_MTCTL_INCONNECT : - pptps->pptps_state = PPTP_MTCTL_INCONNECT; - break; - case PPTP_MTCTL_CLEAR : - pptps->pptps_state = PPTP_MTCTL_CLEAR; - break; - case PPTP_MTCTL_DISCONNECT : - pptps->pptps_state = PPTP_MTCTL_DISCONNECT; - break; - case PPTP_MTCTL_WANERROR : - pptps->pptps_state = PPTP_MTCTL_WANERROR; - break; - case PPTP_MTCTL_LINKINFO : - pptps->pptps_state = PPTP_MTCTL_LINKINFO; - break; - } - - return 0; -} - - -/* - * For outgoing PPTP packets. refresh timeouts for NAT & state entries, if - * we can. If they have disappeared, recreate them. - */ -int ippr_pptp_inout(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - pptp_pxy_t *pptp; - tcphdr_t *tcp; - int rev; - - if ((fin->fin_out == 1) && (nat->nat_dir == NAT_INBOUND)) - rev = 1; - else if ((fin->fin_out == 0) && (nat->nat_dir == NAT_OUTBOUND)) - rev = 1; - else - rev = 0; - - tcp = (tcphdr_t *)fin->fin_dp; - if ((tcp->th_flags & TH_OPENING) == TH_OPENING) { - pptp = (pptp_pxy_t *)aps->aps_data; - pptp->pptp_side[1 - rev].pptps_next = ntohl(tcp->th_ack); - pptp->pptp_side[1 - rev].pptps_nexthdr = ntohl(tcp->th_ack); - pptp->pptp_side[rev].pptps_next = ntohl(tcp->th_seq) + 1; - pptp->pptp_side[rev].pptps_nexthdr = ntohl(tcp->th_seq) + 1; - } - return ippr_pptp_nextmessage(fin, nat, (pptp_pxy_t *)aps->aps_data, - rev); -} - - -/* - * clean up after ourselves. - */ -void ippr_pptp_del(aps) -ap_session_t *aps; -{ - pptp_pxy_t *pptp; - - pptp = aps->aps_data; - - if (pptp != NULL) { - /* - * Don't bother changing any of the NAT structure details, - * *_del() is on a callback from aps_free(), from nat_delete() - */ - - READ_ENTER(&ipf_state); - if (pptp->pptp_state != NULL) { - pptp->pptp_state->is_die = fr_ticks + 1; - pptp->pptp_state->is_me = NULL; - fr_queuefront(&pptp->pptp_state->is_sti); - } - RWLOCK_EXIT(&ipf_state); - - pptp->pptp_state = NULL; - pptp->pptp_nat = NULL; - } -} diff --git a/contrib/ipfilter/ip_proxy.c b/contrib/ipfilter/ip_proxy.c deleted file mode 100644 index 18bc4e1fce5a..000000000000 --- a/contrib/ipfilter/ip_proxy.c +++ /dev/null @@ -1,854 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1997-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#include -#include -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) -# if !defined(__NetBSD__) && !defined(sun) && !defined(__osf__) && \ - !defined(__OpenBSD__) && !defined(__hpux) && !defined(__sgi) -# include -# endif -# include -# if !defined(__SVR4) && !defined(__svr4__) -# include -# endif -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include -# include -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#else -# include -#endif -#if defined(__SVR4) || defined(__svr4__) -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif -#if __FreeBSD__ > 2 -# include -#endif -#include -#ifdef sun -# include -#endif -#include -#include -#include -#include -#ifndef linux -# include -#endif -#include -#include -#include -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#if (__FreeBSD_version >= 300000) -# include -#endif - -#include "netinet/ip_ftp_pxy.c" -#include "netinet/ip_rcmd_pxy.c" -# include "netinet/ip_pptp_pxy.c" -#if defined(_KERNEL) -# include "netinet/ip_irc_pxy.c" -# include "netinet/ip_raudio_pxy.c" -# include "netinet/ip_h323_pxy.c" -# ifdef IPFILTER_PRO -# include "netinet/ip_msnrpc_pxy.c" -# endif -# include "netinet/ip_netbios_pxy.c" -#endif -#include "netinet/ip_ipsec_pxy.c" -#include "netinet/ip_rpcb_pxy.c" - -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_proxy.c,v 2.62.2.12 2005/03/03 14:28:24 darrenr Exp"; -#endif - -static int appr_fixseqack __P((fr_info_t *, ip_t *, ap_session_t *, int )); - -#define AP_SESS_SIZE 53 - -#if defined(_KERNEL) -int ipf_proxy_debug = 0; -#else -int ipf_proxy_debug = 2; -#endif -ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -ap_session_t *ap_sess_list = NULL; -aproxy_t *ap_proxylist = NULL; -aproxy_t ap_proxies[] = { -#ifdef IPF_FTP_PROXY - { NULL, "ftp", (char)IPPROTO_TCP, 0, 0, ippr_ftp_init, ippr_ftp_fini, - ippr_ftp_new, NULL, ippr_ftp_in, ippr_ftp_out, NULL }, -#endif -#ifdef IPF_IRC_PROXY - { NULL, "irc", (char)IPPROTO_TCP, 0, 0, ippr_irc_init, ippr_irc_fini, - ippr_irc_new, NULL, NULL, ippr_irc_out, NULL, NULL }, -#endif -#ifdef IPF_RCMD_PROXY - { NULL, "rcmd", (char)IPPROTO_TCP, 0, 0, ippr_rcmd_init, ippr_rcmd_fini, - ippr_rcmd_new, NULL, ippr_rcmd_in, ippr_rcmd_out, NULL, NULL }, -#endif -#ifdef IPF_RAUDIO_PROXY - { NULL, "raudio", (char)IPPROTO_TCP, 0, 0, ippr_raudio_init, ippr_raudio_fini, - ippr_raudio_new, NULL, ippr_raudio_in, ippr_raudio_out, NULL, NULL }, -#endif -#ifdef IPF_MSNRPC_PROXY - { NULL, "msnrpc", (char)IPPROTO_TCP, 0, 0, ippr_msnrpc_init, ippr_msnrpc_fini, - ippr_msnrpc_new, NULL, ippr_msnrpc_in, ippr_msnrpc_out, NULL, NULL }, -#endif -#ifdef IPF_NETBIOS_PROXY - { NULL, "netbios", (char)IPPROTO_UDP, 0, 0, ippr_netbios_init, ippr_netbios_fini, - NULL, NULL, NULL, ippr_netbios_out, NULL, NULL }, -#endif -#ifdef IPF_IPSEC_PROXY - { NULL, "ipsec", (char)IPPROTO_UDP, 0, 0, - ippr_ipsec_init, ippr_ipsec_fini, ippr_ipsec_new, ippr_ipsec_del, - ippr_ipsec_inout, ippr_ipsec_inout, ippr_ipsec_match, NULL }, -#endif -#ifdef IPF_PPTP_PROXY - { NULL, "pptp", (char)IPPROTO_TCP, 0, 0, - ippr_pptp_init, ippr_pptp_fini, ippr_pptp_new, ippr_pptp_del, - ippr_pptp_inout, ippr_pptp_inout, NULL, NULL }, -#endif -#ifdef IPF_H323_PROXY - { NULL, "h323", (char)IPPROTO_TCP, 0, 0, ippr_h323_init, ippr_h323_fini, - ippr_h323_new, ippr_h323_del, ippr_h323_in, NULL, NULL }, - { NULL, "h245", (char)IPPROTO_TCP, 0, 0, NULL, NULL, - ippr_h245_new, NULL, NULL, ippr_h245_out, NULL }, -#endif -#ifdef IPF_RPCB_PROXY -# if 0 - { NULL, "rpcbt", (char)IPPROTO_TCP, 0, 0, - ippr_rpcb_init, ippr_rpcb_fini, ippr_rpcb_new, ippr_rpcb_del, - ippr_rpcb_in, ippr_rpcb_out, NULL, NULL }, -# endif - { NULL, "rpcbu", (char)IPPROTO_UDP, 0, 0, - ippr_rpcb_init, ippr_rpcb_fini, ippr_rpcb_new, ippr_rpcb_del, - ippr_rpcb_in, ippr_rpcb_out, NULL, NULL }, -#endif - { NULL, "", '\0', 0, 0, NULL, NULL, NULL, NULL } -}; - -/* - * Dynamically add a new kernel proxy. Ensure that it is unique in the - * collection compiled in and dynamically added. - */ -int appr_add(ap) -aproxy_t *ap; -{ - aproxy_t *a; - - for (a = ap_proxies; a->apr_p; a++) - if ((a->apr_p == ap->apr_p) && - !strncmp(a->apr_label, ap->apr_label, - sizeof(ap->apr_label))) { - if (ipf_proxy_debug > 1) - printf("appr_add: %s/%d already present (B)\n", - a->apr_label, a->apr_p); - return -1; - } - - for (a = ap_proxylist; a->apr_p; a = a->apr_next) - if ((a->apr_p == ap->apr_p) && - !strncmp(a->apr_label, ap->apr_label, - sizeof(ap->apr_label))) { - if (ipf_proxy_debug > 1) - printf("appr_add: %s/%d already present (D)\n", - a->apr_label, a->apr_p); - return -1; - } - ap->apr_next = ap_proxylist; - ap_proxylist = ap; - if (ap->apr_init != NULL) - return (*ap->apr_init)(); - return 0; -} - - -/* - * Check to see if the proxy this control request has come through for - * exists, and if it does and it has a control function then invoke that - * control function. - */ -int appr_ctl(ctl) -ap_ctl_t *ctl; -{ - aproxy_t *a; - int error; - - a = appr_lookup(ctl->apc_p, ctl->apc_label); - if (a == NULL) { - if (ipf_proxy_debug > 1) - printf("appr_ctl: can't find %s/%d\n", - ctl->apc_label, ctl->apc_p); - error = ESRCH; - } else if (a->apr_ctl == NULL) { - if (ipf_proxy_debug > 1) - printf("appr_ctl: no ctl function for %s/%d\n", - ctl->apc_label, ctl->apc_p); - error = ENXIO; - } else { - error = (*a->apr_ctl)(a, ctl); - if ((error != 0) && (ipf_proxy_debug > 1)) - printf("appr_ctl: %s/%d ctl error %d\n", - a->apr_label, a->apr_p, error); - } - return error; -} - - -/* - * Delete a proxy that has been added dynamically from those available. - * If it is in use, return 1 (do not destroy NOW), not in use 0 or -1 - * if it cannot be matched. - */ -int appr_del(ap) -aproxy_t *ap; -{ - aproxy_t *a, **app; - - for (app = &ap_proxylist; ((a = *app) != NULL); app = &a->apr_next) - if (a == ap) { - a->apr_flags |= APR_DELETE; - *app = a->apr_next; - if (ap->apr_ref != 0) { - if (ipf_proxy_debug > 2) - printf("appr_del: orphaning %s/%d\n", - ap->apr_label, ap->apr_p); - return 1; - } - return 0; - } - if (ipf_proxy_debug > 1) - printf("appr_del: proxy %lx not found\n", (u_long)ap); - return -1; -} - - -/* - * Return 1 if the packet is a good match against a proxy, else 0. - */ -int appr_ok(fin, tcp, nat) -fr_info_t *fin; -tcphdr_t *tcp; -ipnat_t *nat; -{ - aproxy_t *apr = nat->in_apr; - u_short dport = nat->in_dport; - - if ((apr == NULL) || (apr->apr_flags & APR_DELETE) || - (fin->fin_p != apr->apr_p)) - return 0; - if ((tcp == NULL) && dport) - return 0; - return 1; -} - - -int appr_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - ap_ctl_t ctl; - caddr_t ptr; - int error; - - mode = mode; /* LINT */ - - switch (cmd) - { - case SIOCPROXY : - BCOPYIN(data, &ctl, sizeof(ctl)); - ptr = NULL; - - if (ctl.apc_dsize > 0) { - KMALLOCS(ptr, caddr_t, ctl.apc_dsize); - if (ptr == NULL) - error = ENOMEM; - else { - error = copyinptr(ctl.apc_data, ptr, - ctl.apc_dsize); - if (error == 0) - ctl.apc_data = ptr; - } - } else { - ctl.apc_data = NULL; - error = 0; - } - - if (error == 0) - error = appr_ctl(&ctl); - - if ((ctl.apc_dsize > 0) && (ptr != NULL) && - (ctl.apc_data == ptr)) { - KFREES(ptr, ctl.apc_dsize); - } - break; - - default : - error = EINVAL; - } - return error; -} - - -/* - * If a proxy has a match function, call that to do extended packet - * matching. - */ -int appr_match(fin, nat) -fr_info_t *fin; -nat_t *nat; -{ - aproxy_t *apr; - ipnat_t *ipn; - int result; - - ipn = nat->nat_ptr; - if (ipf_proxy_debug > 8) - printf("appr_match(%lx,%lx) aps %lx ptr %lx\n", - (u_long)fin, (u_long)nat, (u_long)nat->nat_aps, - (u_long)ipn); - - if ((fin->fin_flx & (FI_SHORT|FI_BAD)) != 0) { - if (ipf_proxy_debug > 0) - printf("appr_match: flx 0x%x (BAD|SHORT)\n", - fin->fin_flx); - return -1; - } - - apr = ipn->in_apr; - if ((apr == NULL) || (apr->apr_flags & APR_DELETE)) { - if (ipf_proxy_debug > 0) - printf("appr_match:apr %lx apr_flags 0x%x\n", - (u_long)apr, apr ? apr->apr_flags : 0); - return -1; - } - - if (apr->apr_match != NULL) { - result = (*apr->apr_match)(fin, nat->nat_aps, nat); - if (result != 0) { - if (ipf_proxy_debug > 4) - printf("appr_match: result %d\n", result); - return -1; - } - } - return 0; -} - - -/* - * Allocate a new application proxy structure and fill it in with the - * relevant details. call the init function once complete, prior to - * returning. - */ -int appr_new(fin, nat) -fr_info_t *fin; -nat_t *nat; -{ - register ap_session_t *aps; - aproxy_t *apr; - - if (ipf_proxy_debug > 8) - printf("appr_new(%lx,%lx) \n", (u_long)fin, (u_long)nat); - - if ((nat->nat_ptr == NULL) || (nat->nat_aps != NULL)) { - if (ipf_proxy_debug > 0) - printf("appr_new: nat_ptr %lx nat_aps %lx\n", - (u_long)nat->nat_ptr, (u_long)nat->nat_aps); - return -1; - } - - apr = nat->nat_ptr->in_apr; - - if ((apr->apr_flags & APR_DELETE) || - (fin->fin_p != apr->apr_p)) { - if (ipf_proxy_debug > 2) - printf("appr_new: apr_flags 0x%x p %d/%d\n", - apr->apr_flags, fin->fin_p, apr->apr_p); - return -1; - } - - KMALLOC(aps, ap_session_t *); - if (!aps) { - if (ipf_proxy_debug > 0) - printf("appr_new: malloc failed (%lu)\n", - (u_long)sizeof(ap_session_t)); - return -1; - } - - bzero((char *)aps, sizeof(*aps)); - aps->aps_p = fin->fin_p; - aps->aps_data = NULL; - aps->aps_apr = apr; - aps->aps_psiz = 0; - if (apr->apr_new != NULL) - if ((*apr->apr_new)(fin, aps, nat) == -1) { - if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) { - KFREES(aps->aps_data, aps->aps_psiz); - } - KFREE(aps); - if (ipf_proxy_debug > 2) - printf("appr_new: new(%lx) failed\n", - (u_long)apr->apr_new); - return -1; - } - aps->aps_nat = nat; - aps->aps_next = ap_sess_list; - ap_sess_list = aps; - nat->nat_aps = aps; - - return 0; -} - - -/* - * Check to see if a packet should be passed through an active proxy routine - * if one has been setup for it. We don't need to check the checksum here if - * IPFILTER_CKSUM is defined because if it is, a failed check causes FI_BAD - * to be set. - */ -int appr_check(fin, nat) -fr_info_t *fin; -nat_t *nat; -{ -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) -# if defined(ICK_VALID) - mb_t *m; -# endif - int dosum = 1; -#endif - tcphdr_t *tcp = NULL; - udphdr_t *udp = NULL; - ap_session_t *aps; - aproxy_t *apr; - ip_t *ip; - short rv; - int err; -#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) - u_32_t s1, s2, sd; -#endif - - if (fin->fin_flx & FI_BAD) { - if (ipf_proxy_debug > 0) - printf("appr_check: flx 0x%x (BAD)\n", fin->fin_flx); - return -1; - } - -#ifndef IPFILTER_CKSUM - if ((fin->fin_out == 0) && (fr_checkl4sum(fin) == -1)) { - if (ipf_proxy_debug > 0) - printf("appr_check: l4 checksum failure %d\n", - fin->fin_p); - if (fin->fin_p == IPPROTO_TCP) - frstats[fin->fin_out].fr_tcpbad++; - return -1; - } -#endif - - aps = nat->nat_aps; - if ((aps != NULL) && (aps->aps_p == fin->fin_p)) { - /* - * If there is data in this packet to be proxied then try and - * get it all into the one buffer, else drop it. - */ -#if defined(MENTAT) || defined(HAVE_M_PULLDOWN) - if ((fin->fin_dlen > 0) && !(fin->fin_flx & FI_COALESCE)) - if (fr_coalesce(fin) == -1) { - if (ipf_proxy_debug > 0) - printf("appr_check: fr_coalesce failed %x\n", fin->fin_flx); - return -1; - } -#endif - ip = fin->fin_ip; - - switch (fin->fin_p) - { - case IPPROTO_TCP : - tcp = (tcphdr_t *)fin->fin_dp; - -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) && defined(ICK_VALID) - m = fin->fin_qfm; - if (dohwcksum && (m->b_ick_flag == ICK_VALID)) - dosum = 0; -#endif - /* - * Don't bother the proxy with these...or in fact, - * should we free up proxy stuff when seen? - */ - if ((fin->fin_tcpf & TH_RST) != 0) - break; - /*FALLTHROUGH*/ - case IPPROTO_UDP : - udp = (udphdr_t *)fin->fin_dp; - break; - default : - break; - } - - apr = aps->aps_apr; - err = 0; - if (fin->fin_out != 0) { - if (apr->apr_outpkt != NULL) - err = (*apr->apr_outpkt)(fin, aps, nat); - } else { - if (apr->apr_inpkt != NULL) - err = (*apr->apr_inpkt)(fin, aps, nat); - } - - rv = APR_EXIT(err); - if (((ipf_proxy_debug > 0) && (rv != 0)) || - (ipf_proxy_debug > 8)) - printf("appr_check: out %d err %x rv %d\n", - fin->fin_out, err, rv); - if (rv == 1) - return -1; - - if (rv == 2) { - appr_free(apr); - nat->nat_aps = NULL; - return -1; - } - - /* - * If err != 0 then the data size of the packet has changed - * so we need to recalculate the header checksums for the - * packet. - */ -#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) - if (err != 0) { - short adjlen = err & 0xffff; - - s1 = LONG_SUM(ip->ip_len - adjlen); - s2 = LONG_SUM(ip->ip_len); - CALC_SUMD(s1, s2, sd); - fix_outcksum(fin, &ip->ip_sum, sd); - } -#endif - - /* - * For TCP packets, we may need to adjust the sequence and - * acknowledgement numbers to reflect changes in size of the - * data stream. - * - * For both TCP and UDP, recalculate the layer 4 checksum, - * regardless, as we can't tell (here) if data has been - * changed or not. - */ - if (tcp != NULL) { - err = appr_fixseqack(fin, ip, aps, APR_INC(err)); -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) - if (dosum) - tcp->th_sum = fr_cksum(fin->fin_qfm, ip, - IPPROTO_TCP, tcp); -#else - tcp->th_sum = fr_cksum(fin->fin_m, ip, - IPPROTO_TCP, tcp); -#endif - } else if ((udp != NULL) && (udp->uh_sum != 0)) { -#if SOLARIS && defined(_KERNEL) && (SOLARIS2 >= 6) - if (dosum) - udp->uh_sum = fr_cksum(fin->fin_qfm, ip, - IPPROTO_UDP, udp); -#else - udp->uh_sum = fr_cksum(fin->fin_m, ip, - IPPROTO_UDP, udp); -#endif - } - aps->aps_bytes += fin->fin_plen; - aps->aps_pkts++; - return 1; - } - return 0; -} - - -/* - * Search for an proxy by the protocol it is being used with and its name. - */ -aproxy_t *appr_lookup(pr, name) -u_int pr; -char *name; -{ - aproxy_t *ap; - - if (ipf_proxy_debug > 8) - printf("appr_lookup(%d,%s)\n", pr, name); - - for (ap = ap_proxies; ap->apr_p; ap++) - if ((ap->apr_p == pr) && - !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) { - ap->apr_ref++; - return ap; - } - - for (ap = ap_proxylist; ap; ap = ap->apr_next) - if ((ap->apr_p == pr) && - !strncmp(name, ap->apr_label, sizeof(ap->apr_label))) { - ap->apr_ref++; - return ap; - } - if (ipf_proxy_debug > 2) - printf("appr_lookup: failed for %d/%s\n", pr, name); - return NULL; -} - - -void appr_free(ap) -aproxy_t *ap; -{ - ap->apr_ref--; -} - - -void aps_free(aps) -ap_session_t *aps; -{ - ap_session_t *a, **ap; - aproxy_t *apr; - - if (!aps) - return; - - for (ap = &ap_sess_list; ((a = *ap) != NULL); ap = &a->aps_next) - if (a == aps) { - *ap = a->aps_next; - break; - } - - apr = aps->aps_apr; - if ((apr != NULL) && (apr->apr_del != NULL)) - (*apr->apr_del)(aps); - - if ((aps->aps_data != NULL) && (aps->aps_psiz != 0)) - KFREES(aps->aps_data, aps->aps_psiz); - KFREE(aps); -} - - -/* - * returns 2 if ack or seq number in TCP header is changed, returns 0 otherwise - */ -static int appr_fixseqack(fin, ip, aps, inc) -fr_info_t *fin; -ip_t *ip; -ap_session_t *aps; -int inc; -{ - int sel, ch = 0, out, nlen; - u_32_t seq1, seq2; - tcphdr_t *tcp; - short inc2; - - tcp = (tcphdr_t *)fin->fin_dp; - out = fin->fin_out; - /* - * ip_len has already been adjusted by 'inc'. - */ - nlen = ip->ip_len; - nlen -= (IP_HL(ip) << 2) + (TCP_OFF(tcp) << 2); - - inc2 = inc; - inc = (int)inc2; - - if (out != 0) { - seq1 = (u_32_t)ntohl(tcp->th_seq); - sel = aps->aps_sel[out]; - - /* switch to other set ? */ - if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && - (seq1 > aps->aps_seqmin[!sel])) { - if (ipf_proxy_debug > 7) - printf("proxy out switch set seq %d -> %d %x > %x\n", - sel, !sel, seq1, - aps->aps_seqmin[!sel]); - sel = aps->aps_sel[out] = !sel; - } - - if (aps->aps_seqoff[sel]) { - seq2 = aps->aps_seqmin[sel] - aps->aps_seqoff[sel]; - if (seq1 > seq2) { - seq2 = aps->aps_seqoff[sel]; - seq1 += seq2; - tcp->th_seq = htonl(seq1); - ch = 1; - } - } - - if (inc && (seq1 > aps->aps_seqmin[!sel])) { - aps->aps_seqmin[sel] = seq1 + nlen - 1; - aps->aps_seqoff[sel] = aps->aps_seqoff[sel] + inc; - if (ipf_proxy_debug > 7) - printf("proxy seq set %d at %x to %d + %d\n", - sel, aps->aps_seqmin[sel], - aps->aps_seqoff[sel], inc); - } - - /***/ - - seq1 = ntohl(tcp->th_ack); - sel = aps->aps_sel[1 - out]; - - /* switch to other set ? */ - if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && - (seq1 > aps->aps_ackmin[!sel])) { - if (ipf_proxy_debug > 7) - printf("proxy out switch set ack %d -> %d %x > %x\n", - sel, !sel, seq1, - aps->aps_ackmin[!sel]); - sel = aps->aps_sel[1 - out] = !sel; - } - - if (aps->aps_ackoff[sel] && (seq1 > aps->aps_ackmin[sel])) { - seq2 = aps->aps_ackoff[sel]; - tcp->th_ack = htonl(seq1 - seq2); - ch = 1; - } - } else { - seq1 = ntohl(tcp->th_seq); - sel = aps->aps_sel[out]; - - /* switch to other set ? */ - if ((aps->aps_ackmin[!sel] > aps->aps_ackmin[sel]) && - (seq1 > aps->aps_ackmin[!sel])) { - if (ipf_proxy_debug > 7) - printf("proxy in switch set ack %d -> %d %x > %x\n", - sel, !sel, seq1, aps->aps_ackmin[!sel]); - sel = aps->aps_sel[out] = !sel; - } - - if (aps->aps_ackoff[sel]) { - seq2 = aps->aps_ackmin[sel] - aps->aps_ackoff[sel]; - if (seq1 > seq2) { - seq2 = aps->aps_ackoff[sel]; - seq1 += seq2; - tcp->th_seq = htonl(seq1); - ch = 1; - } - } - - if (inc && (seq1 > aps->aps_ackmin[!sel])) { - aps->aps_ackmin[!sel] = seq1 + nlen - 1; - aps->aps_ackoff[!sel] = aps->aps_ackoff[sel] + inc; - - if (ipf_proxy_debug > 7) - printf("proxy ack set %d at %x to %d + %d\n", - !sel, aps->aps_seqmin[!sel], - aps->aps_seqoff[sel], inc); - } - - /***/ - - seq1 = ntohl(tcp->th_ack); - sel = aps->aps_sel[1 - out]; - - /* switch to other set ? */ - if ((aps->aps_seqmin[!sel] > aps->aps_seqmin[sel]) && - (seq1 > aps->aps_seqmin[!sel])) { - if (ipf_proxy_debug > 7) - printf("proxy in switch set seq %d -> %d %x > %x\n", - sel, !sel, seq1, aps->aps_seqmin[!sel]); - sel = aps->aps_sel[1 - out] = !sel; - } - - if (aps->aps_seqoff[sel] != 0) { - if (ipf_proxy_debug > 7) - printf("sel %d seqoff %d seq1 %x seqmin %x\n", - sel, aps->aps_seqoff[sel], seq1, - aps->aps_seqmin[sel]); - if (seq1 > aps->aps_seqmin[sel]) { - seq2 = aps->aps_seqoff[sel]; - tcp->th_ack = htonl(seq1 - seq2); - ch = 1; - } - } - } - - if (ipf_proxy_debug > 8) - printf("appr_fixseqack: seq %x ack %x\n", - ntohl(tcp->th_seq), ntohl(tcp->th_ack)); - return ch ? 2 : 0; -} - - -/* - * Initialise hook for kernel application proxies. - * Call the initialise routine for all the compiled in kernel proxies. - */ -int appr_init() -{ - aproxy_t *ap; - int err = 0; - - for (ap = ap_proxies; ap->apr_p; ap++) { - if (ap->apr_init != NULL) { - err = (*ap->apr_init)(); - if (err != 0) - break; - } - } - return err; -} - - -/* - * Unload hook for kernel application proxies. - * Call the finialise routine for all the compiled in kernel proxies. - */ -void appr_unload() -{ - aproxy_t *ap; - - for (ap = ap_proxies; ap->apr_p; ap++) - if (ap->apr_fini != NULL) - (*ap->apr_fini)(); - for (ap = ap_proxylist; ap; ap = ap->apr_next) - if (ap->apr_fini != NULL) - (*ap->apr_fini)(); -} diff --git a/contrib/ipfilter/ip_proxy.h b/contrib/ipfilter/ip_proxy.h deleted file mode 100644 index 8e53c988cc95..000000000000 --- a/contrib/ipfilter/ip_proxy.h +++ /dev/null @@ -1,453 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1997-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_proxy.h,v 2.31.2.2 2005/03/12 19:33:48 darrenr Exp - */ - -#ifndef __IP_PROXY_H__ -#define __IP_PROXY_H__ - -#ifndef SOLARIS -#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4))) -#endif - -#ifndef APR_LABELLEN -#define APR_LABELLEN 16 -#endif -#define AP_SESS_SIZE 53 - -struct nat; -struct ipnat; - -typedef struct ap_tcp { - u_short apt_sport; /* source port */ - u_short apt_dport; /* destination port */ - short apt_sel[2]; /* {seq,ack}{off,min} set selector */ - short apt_seqoff[2]; /* sequence # difference */ - tcp_seq apt_seqmin[2]; /* don't change seq-off until after this */ - short apt_ackoff[2]; /* sequence # difference */ - tcp_seq apt_ackmin[2]; /* don't change seq-off until after this */ - u_char apt_state[2]; /* connection state */ -} ap_tcp_t; - -typedef struct ap_udp { - u_short apu_sport; /* source port */ - u_short apu_dport; /* destination port */ -} ap_udp_t; - -typedef struct ap_session { - struct aproxy *aps_apr; - union { - struct ap_tcp apu_tcp; - struct ap_udp apu_udp; - } aps_un; - u_int aps_flags; - U_QUAD_T aps_bytes; /* bytes sent */ - U_QUAD_T aps_pkts; /* packets sent */ - void *aps_nat; /* pointer back to nat struct */ - void *aps_data; /* private data */ - int aps_p; /* protocol */ - int aps_psiz; /* size of private data */ - struct ap_session *aps_hnext; - struct ap_session *aps_next; -} ap_session_t; - -#define aps_sport aps_un.apu_tcp.apt_sport -#define aps_dport aps_un.apu_tcp.apt_dport -#define aps_sel aps_un.apu_tcp.apt_sel -#define aps_seqoff aps_un.apu_tcp.apt_seqoff -#define aps_seqmin aps_un.apu_tcp.apt_seqmin -#define aps_state aps_un.apu_tcp.apt_state -#define aps_ackoff aps_un.apu_tcp.apt_ackoff -#define aps_ackmin aps_un.apu_tcp.apt_ackmin - - -typedef struct ap_control { - char apc_label[APR_LABELLEN]; - u_char apc_p; - /* - * The following fields are upto the proxy's apr_ctl routine to deal - * with. When the proxy gets this in kernel space, apc_data will - * point to a malloc'd region of memory of apc_dsize bytes. If the - * proxy wants to keep that memory, it must set apc_data to NULL - * before it returns. It is expected if this happens that it will - * take care to free it in apr_fini or otherwise as appropriate. - * apc_cmd is provided as a standard place to put simple commands, - * with apc_arg being available to put a simple arg. - */ - u_long apc_cmd; - u_long apc_arg; - void *apc_data; - size_t apc_dsize; -} ap_ctl_t; - - -typedef struct aproxy { - struct aproxy *apr_next; - char apr_label[APR_LABELLEN]; /* Proxy label # */ - u_char apr_p; /* protocol */ - int apr_ref; /* +1 per rule referencing it */ - int apr_flags; - int (* apr_init) __P((void)); - void (* apr_fini) __P((void)); - int (* apr_new) __P((fr_info_t *, ap_session_t *, struct nat *)); - void (* apr_del) __P((ap_session_t *)); - int (* apr_inpkt) __P((fr_info_t *, ap_session_t *, struct nat *)); - int (* apr_outpkt) __P((fr_info_t *, ap_session_t *, struct nat *)); - int (* apr_match) __P((fr_info_t *, ap_session_t *, struct nat *)); - int (* apr_ctl) __P((struct aproxy *, struct ap_control *)); -} aproxy_t; - -#define APR_DELETE 1 - -#define APR_ERR(x) ((x) << 16) -#define APR_EXIT(x) (((x) >> 16) & 0xffff) -#define APR_INC(x) ((x) & 0xffff) - -/* - * Generic #define's to cover missing things in the kernel - */ -#ifndef isdigit -#define isdigit(x) ((x) >= '0' && (x) <= '9') -#endif -#ifndef isupper -#define isupper(x) (((unsigned)(x) >= 'A') && ((unsigned)(x) <= 'Z')) -#endif -#ifndef islower -#define islower(x) (((unsigned)(x) >= 'a') && ((unsigned)(x) <= 'z')) -#endif -#ifndef isalpha -#define isalpha(x) (isupper(x) || islower(x)) -#endif -#ifndef toupper -#define toupper(x) (isupper(x) ? (x) : (x) - 'a' + 'A') -#endif -#ifndef isspace -#define isspace(x) (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \ - ((x) == '\t') || ((x) == '\b')) -#endif - -/* - * This is the scratch buffer size used to hold strings from the TCP stream - * that we may want to parse. It's an arbitrary size, really, but it must - * be at least as large as IPF_FTPBUFSZ. - */ -#define FTP_BUFSZ 120 - -/* - * This buffer, however, doesn't need to be nearly so big. It just needs to - * be able to squeeze in the largest command it needs to rewrite, Which ones - * does it rewrite? EPRT, PORT, 227 replies. - */ -#define IPF_FTPBUFSZ 80 /* This *MUST* be >= 53! */ - -typedef struct ftpside { - char *ftps_rptr; - char *ftps_wptr; - void *ftps_ifp; - u_32_t ftps_seq[2]; - u_32_t ftps_len; - int ftps_junk; /* 2 = no cr/lf yet, 1 = cannot parse */ - int ftps_cmds; - char ftps_buf[FTP_BUFSZ]; -} ftpside_t; - -typedef struct ftpinfo { - int ftp_passok; - int ftp_incok; - ftpside_t ftp_side[2]; -} ftpinfo_t; - - -/* - * For the irc proxy. - */ -typedef struct ircinfo { - size_t irc_len; - char *irc_snick; - char *irc_dnick; - char *irc_type; - char *irc_arg; - char *irc_addr; - u_32_t irc_ipnum; - u_short irc_port; -} ircinfo_t; - - -/* - * Real audio proxy structure and #defines - */ -typedef struct raudio_s { - int rap_seenpna; - int rap_seenver; - int rap_version; - int rap_eos; /* End Of Startup */ - int rap_gotid; - int rap_gotlen; - int rap_mode; - int rap_sdone; - u_short rap_plport; - u_short rap_prport; - u_short rap_srport; - char rap_svr[19]; - u_32_t rap_sbf; /* flag to indicate which of the 19 bytes have - * been filled - */ - tcp_seq rap_sseq; -} raudio_t; - -#define RA_ID_END 0 -#define RA_ID_UDP 1 -#define RA_ID_ROBUST 7 - -#define RAP_M_UDP 1 -#define RAP_M_ROBUST 2 -#define RAP_M_TCP 4 -#define RAP_M_UDP_ROBUST (RAP_M_UDP|RAP_M_ROBUST) - - -/* - * MSN RPC proxy - */ -typedef struct msnrpcinfo { - u_int mri_flags; - int mri_cmd[2]; - u_int mri_valid; - struct in_addr mri_raddr; - u_short mri_rport; -} msnrpcinfo_t; - - -/* - * IPSec proxy - */ -typedef u_32_t ipsec_cookie_t[2]; - -typedef struct ipsec_pxy { - ipsec_cookie_t ipsc_icookie; - ipsec_cookie_t ipsc_rcookie; - int ipsc_rckset; - ipnat_t ipsc_rule; - nat_t *ipsc_nat; - ipstate_t *ipsc_state; -} ipsec_pxy_t; - -/* - * PPTP proxy - */ -typedef struct pptp_side { - u_32_t pptps_nexthdr; - u_32_t pptps_next; - int pptps_state; - int pptps_gothdr; - int pptps_len; - int pptps_bytes; - char *pptps_wptr; - char pptps_buffer[512]; -} pptp_side_t; - -typedef struct pptp_pxy { - ipnat_t pptp_rule; - nat_t *pptp_nat; - ipstate_t *pptp_state; - u_short pptp_call[2]; - pptp_side_t pptp_side[2]; -} pptp_pxy_t; - - -/* - * Sun RPCBIND proxy - */ -#define RPCB_MAXMSG 888 -#define RPCB_RES_PMAP 0 /* Response contains a v2 port. */ -#define RPCB_RES_STRING 1 /* " " " v3 (GETADDR) string. */ -#define RPCB_RES_LIST 2 /* " " " v4 (GETADDRLIST) list. */ -#define RPCB_MAXREQS 32 /* Arbitrary limit on tracked transactions */ - -#define RPCB_REQMIN 40 -#define RPCB_REQMAX 888 -#define RPCB_REPMIN 20 -#define RPCB_REPMAX 604 /* XXX double check this! */ - -/* - * These macros determine the number of bytes between p and the end of - * r->rs_buf relative to l. - */ -#define RPCB_BUF_END(r) (char *)((r)->rm_msgbuf + (r)->rm_buflen) -#define RPCB_BUF_GEQ(r, p, l) \ - ((RPCB_BUF_END((r)) > (char *)(p)) && \ - ((RPCB_BUF_END((r)) - (char *)(p)) >= (l))) -#define RPCB_BUF_EQ(r, p, l) \ - (RPCB_BUF_END((r)) == ((char *)(p) + (l))) - -/* - * The following correspond to RPC(B) detailed in RFC183[13]. - */ -#define RPCB_CALL 0 -#define RPCB_REPLY 1 -#define RPCB_MSG_VERSION 2 -#define RPCB_PROG 100000 -#define RPCB_GETPORT 3 -#define RPCB_GETADDR 3 -#define RPCB_GETADDRLIST 11 -#define RPCB_MSG_ACCEPTED 0 -#define RPCB_MSG_DENIED 1 - -/* BEGIN (Generic XDR structures) */ -typedef struct xdr_string { - u_32_t *xs_len; - char *xs_str; -} xdr_string_t; - -typedef struct xdr_auth { - /* u_32_t xa_flavor; */ - xdr_string_t xa_string; -} xdr_auth_t; - -typedef struct xdr_uaddr { - u_32_t xu_ip; - u_short xu_port; - xdr_string_t xu_str; -} xdr_uaddr_t; - -typedef struct xdr_proto { - u_int xp_proto; - xdr_string_t xp_str; -} xdr_proto_t; - -#define xu_xslen xu_str.xs_len -#define xu_xsstr xu_str.xs_str -#define xp_xslen xp_str.xs_len -#define xp_xsstr xp_str.xs_str -/* END (Generic XDR structures) */ - -/* BEGIN (RPC call structures) */ -typedef struct pmap_args { - /* u_32_t pa_prog; */ - /* u_32_t pa_vers; */ - u_32_t *pa_prot; - /* u_32_t pa_port; */ -} pmap_args_t; - -typedef struct rpcb_args { - /* u_32_t *ra_prog; */ - /* u_32_t *ra_vers; */ - xdr_proto_t ra_netid; - xdr_uaddr_t ra_maddr; - /* xdr_string_t ra_owner; */ -} rpcb_args_t; - -typedef struct rpc_call { - /* u_32_t rc_rpcvers; */ - /* u_32_t rc_prog; */ - u_32_t *rc_vers; - u_32_t *rc_proc; - xdr_auth_t rc_authcred; - xdr_auth_t rc_authverf; - union { - pmap_args_t ra_pmapargs; - rpcb_args_t ra_rpcbargs; - } rpcb_args; -} rpc_call_t; - -#define rc_pmapargs rpcb_args.ra_pmapargs -#define rc_rpcbargs rpcb_args.ra_rpcbargs -/* END (RPC call structures) */ - -/* BEGIN (RPC reply structures) */ -typedef struct rpcb_entry { - xdr_uaddr_t re_maddr; - xdr_proto_t re_netid; - /* u_32_t re_semantics; */ - xdr_string_t re_family; - xdr_proto_t re_proto; - u_32_t *re_more; /* 1 == another entry follows */ -} rpcb_entry_t; - -typedef struct rpcb_listp { - u_32_t *rl_list; /* 1 == list follows */ - int rl_cnt; - rpcb_entry_t rl_entries[2]; /* TCP / UDP only */ -} rpcb_listp_t; - -typedef struct rpc_resp { - /* u_32_t rr_acceptdeny; */ - /* Omitted 'message denied' fork; we don't care about rejects. */ - xdr_auth_t rr_authverf; - /* u_32_t *rr_astat; */ - union { - u_32_t *resp_pmap; - xdr_uaddr_t resp_getaddr; - rpcb_listp_t resp_getaddrlist; - } rpcb_reply; -} rpc_resp_t; - -#define rr_v2 rpcb_reply.resp_pmap -#define rr_v3 rpcb_reply.resp_getaddr -#define rr_v4 rpcb_reply.resp_getaddrlist -/* END (RPC reply structures) */ - -/* BEGIN (RPC message structure & macros) */ -typedef struct rpc_msg { - char rm_msgbuf[RPCB_MAXMSG]; /* RPCB data buffer */ - u_int rm_buflen; - u_32_t *rm_xid; - /* u_32_t Call vs Reply */ - union { - rpc_call_t rb_call; - rpc_resp_t rb_resp; - } rm_body; -} rpc_msg_t; - -#define rm_call rm_body.rb_call -#define rm_resp rm_body.rb_resp -/* END (RPC message structure & macros) */ - -/* - * These code paths aren't hot enough to warrant per transaction - * mutexes. - */ -typedef struct rpcb_xact { - struct rpcb_xact *rx_next; - struct rpcb_xact **rx_pnext; - u_32_t rx_xid; /* RPC transmission ID */ - u_int rx_type; /* RPCB response type */ - u_int rx_ref; /* reference count */ - u_int rx_proto; /* transport protocol (v2 only) */ -} rpcb_xact_t; - -typedef struct rpcb_session { - ipfmutex_t rs_rxlock; - rpcb_xact_t *rs_rxlist; -} rpcb_session_t; - -/* - * For an explanation, please see the following: - * RFC1832 - Sections 3.11, 4.4, and 4.5. - */ -#define XDRALIGN(x) ((((x) % 4) != 0) ? ((((x) + 3) / 4) * 4) : (x)) - -extern ap_session_t *ap_sess_tab[AP_SESS_SIZE]; -extern ap_session_t *ap_sess_list; -extern aproxy_t ap_proxies[]; -extern int ippr_ftp_pasvonly; - -extern int appr_add __P((aproxy_t *)); -extern int appr_ctl __P((ap_ctl_t *)); -extern int appr_del __P((aproxy_t *)); -extern int appr_init __P((void)); -extern void appr_unload __P((void)); -extern int appr_ok __P((fr_info_t *, tcphdr_t *, struct ipnat *)); -extern int appr_match __P((fr_info_t *, struct nat *)); -extern void appr_free __P((aproxy_t *)); -extern void aps_free __P((ap_session_t *)); -extern int appr_check __P((fr_info_t *, struct nat *)); -extern aproxy_t *appr_lookup __P((u_int, char *)); -extern int appr_new __P((fr_info_t *, struct nat *)); -extern int appr_ioctl __P((caddr_t, ioctlcmd_t, int)); - -#endif /* __IP_PROXY_H__ */ diff --git a/contrib/ipfilter/ip_raudio_pxy.c b/contrib/ipfilter/ip_raudio_pxy.c deleted file mode 100644 index 260fcd465856..000000000000 --- a/contrib/ipfilter/ip_raudio_pxy.c +++ /dev/null @@ -1,338 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1998-2003 by Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_raudio_pxy.c,v 1.40.2.3 2005/02/04 10:22:55 darrenr Exp - */ - -#define IPF_RAUDIO_PROXY - - -int ippr_raudio_init __P((void)); -void ippr_raudio_fini __P((void)); -int ippr_raudio_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_raudio_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_raudio_out __P((fr_info_t *, ap_session_t *, nat_t *)); - -static frentry_t raudiofr; - -int raudio_proxy_init = 0; - - -/* - * Real Audio application proxy initialization. - */ -int ippr_raudio_init() -{ - bzero((char *)&raudiofr, sizeof(raudiofr)); - raudiofr.fr_ref = 1; - raudiofr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&raudiofr.fr_lock, "Real Audio proxy rule lock"); - raudio_proxy_init = 1; - - return 0; -} - - -void ippr_raudio_fini() -{ - if (raudio_proxy_init == 1) { - MUTEX_DESTROY(&raudiofr.fr_lock); - raudio_proxy_init = 0; - } -} - - -/* - * Setup for a new proxy to handle Real Audio. - */ -int ippr_raudio_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - raudio_t *rap; - - KMALLOCS(aps->aps_data, void *, sizeof(raudio_t)); - if (aps->aps_data == NULL) - return -1; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - bzero(aps->aps_data, sizeof(raudio_t)); - rap = aps->aps_data; - aps->aps_psiz = sizeof(raudio_t); - rap->rap_mode = RAP_M_TCP; /* default is for TCP */ - return 0; -} - - - -int ippr_raudio_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - raudio_t *rap = aps->aps_data; - unsigned char membuf[512 + 1], *s; - u_short id = 0; - tcphdr_t *tcp; - int off, dlen; - int len = 0; - mb_t *m; - - nat = nat; /* LINT */ - - /* - * If we've already processed the start messages, then nothing left - * for the proxy to do. - */ - if (rap->rap_eos == 1) - return 0; - - m = fin->fin_m; - tcp = (tcphdr_t *)fin->fin_dp; - off = (char *)tcp - (char *)fin->fin_ip; - off += (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - -#ifdef __sgi - dlen = fin->fin_plen - off; -#else - dlen = MSGDSIZE(m) - off; -#endif - if (dlen <= 0) - return 0; - - if (dlen > sizeof(membuf)) - dlen = sizeof(membuf); - - bzero((char *)membuf, sizeof(membuf)); - COPYDATA(m, off, dlen, (char *)membuf); - /* - * In all the startup parsing, ensure that we don't go outside - * the packet buffer boundary. - */ - /* - * Look for the start of connection "PNA" string if not seen yet. - */ - if (rap->rap_seenpna == 0) { - s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen); - if (s == NULL) - return 0; - s += 3; - rap->rap_seenpna = 1; - } else - s = membuf; - - /* - * Directly after the PNA will be the version number of this - * connection. - */ - if (rap->rap_seenpna == 1 && rap->rap_seenver == 0) { - if ((s + 1) - membuf < dlen) { - rap->rap_version = (*s << 8) | *(s + 1); - s += 2; - rap->rap_seenver = 1; - } else - return 0; - } - - /* - * Now that we've been past the PNA and version number, we're into the - * startup messages block. This ends when a message with an ID of 0. - */ - while ((rap->rap_eos == 0) && ((s + 1) - membuf < dlen)) { - if (rap->rap_gotid == 0) { - id = (*s << 8) | *(s + 1); - s += 2; - rap->rap_gotid = 1; - if (id == RA_ID_END) { - rap->rap_eos = 1; - break; - } - } else if (rap->rap_gotlen == 0) { - len = (*s << 8) | *(s + 1); - s += 2; - rap->rap_gotlen = 1; - } - - if (rap->rap_gotid == 1 && rap->rap_gotlen == 1) { - if (id == RA_ID_UDP) { - rap->rap_mode &= ~RAP_M_TCP; - rap->rap_mode |= RAP_M_UDP; - rap->rap_plport = (*s << 8) | *(s + 1); - } else if (id == RA_ID_ROBUST) { - rap->rap_mode |= RAP_M_ROBUST; - rap->rap_prport = (*s << 8) | *(s + 1); - } - s += len; - rap->rap_gotlen = 0; - rap->rap_gotid = 0; - } - } - return 0; -} - - -int ippr_raudio_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - unsigned char membuf[IPF_MAXPORTLEN + 1], *s; - tcphdr_t *tcp, tcph, *tcp2 = &tcph; - raudio_t *rap = aps->aps_data; - struct in_addr swa, swb; - int off, dlen, slen; - int a1, a2, a3, a4; - u_short sp, dp; - fr_info_t fi; - tcp_seq seq; - nat_t *nat2; - u_char swp; - ip_t *ip; - mb_t *m; - - /* - * Wait until we've seen the end of the start messages and even then - * only proceed further if we're using UDP. If they want to use TCP - * then data is sent back on the same channel that is already open. - */ - if (rap->rap_sdone != 0) - return 0; - - m = fin->fin_m; - tcp = (tcphdr_t *)fin->fin_dp; - off = (char *)tcp - (char *)fin->fin_ip; - off += (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - -#ifdef __sgi - dlen = fin->fin_plen - off; -#else - dlen = MSGDSIZE(m) - off; -#endif - if (dlen <= 0) - return 0; - - if (dlen > sizeof(membuf)) - dlen = sizeof(membuf); - - bzero((char *)membuf, sizeof(membuf)); - COPYDATA(m, off, dlen, (char *)membuf); - - seq = ntohl(tcp->th_seq); - /* - * Check to see if the data in this packet is of interest to us. - * We only care for the first 19 bytes coming back from the server. - */ - if (rap->rap_sseq == 0) { - s = (u_char *)memstr("PNA", (char *)membuf, 3, dlen); - if (s == NULL) - return 0; - a1 = s - membuf; - dlen -= a1; - a1 = 0; - rap->rap_sseq = seq; - a2 = MIN(dlen, sizeof(rap->rap_svr)); - } else if (seq <= rap->rap_sseq + sizeof(rap->rap_svr)) { - /* - * seq # which is the start of data and from that the offset - * into the buffer array. - */ - a1 = seq - rap->rap_sseq; - a2 = MIN(dlen, sizeof(rap->rap_svr)); - a2 -= a1; - s = membuf; - } else - return 0; - - for (a3 = a1, a4 = a2; (a4 > 0) && (a3 < 19) && (a3 >= 0); a4--,a3++) { - rap->rap_sbf |= (1 << a3); - rap->rap_svr[a3] = *s++; - } - - if ((rap->rap_sbf != 0x7ffff) || (!rap->rap_eos)) /* 19 bits */ - return 0; - rap->rap_sdone = 1; - - s = (u_char *)rap->rap_svr + 11; - if (((*s << 8) | *(s + 1)) == RA_ID_ROBUST) { - s += 2; - rap->rap_srport = (*s << 8) | *(s + 1); - } - - ip = fin->fin_ip; - swp = ip->ip_p; - swa = ip->ip_src; - swb = ip->ip_dst; - - ip->ip_p = IPPROTO_UDP; - ip->ip_src = nat->nat_inip; - ip->ip_dst = nat->nat_oip; - - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - bzero((char *)tcp2, sizeof(*tcp2)); - TCP_OFF_A(tcp2, 5); - fi.fin_state = NULL; - fi.fin_nat = NULL; - fi.fin_flx |= FI_IGNORE; - fi.fin_dp = (char *)tcp2; - fi.fin_fr = &raudiofr; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - tcp2->th_win = htons(8192); - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp); - - if (((rap->rap_mode & RAP_M_UDP_ROBUST) == RAP_M_UDP_ROBUST) && - (rap->rap_srport != 0)) { - dp = rap->rap_srport; - sp = rap->rap_prport; - tcp2->th_sport = htons(sp); - tcp2->th_dport = htons(dp); - fi.fin_data[0] = dp; - fi.fin_data[1] = sp; - fi.fin_out = 0; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, - NAT_SLAVE|IPN_UDP | (sp ? 0 : SI_W_SPORT), - NAT_OUTBOUND); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_UDP); - nat_update(&fi, nat2, nat2->nat_ptr); - - (void) fr_addstate(&fi, NULL, (sp ? 0 : SI_W_SPORT)); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - } - - if ((rap->rap_mode & RAP_M_UDP) == RAP_M_UDP) { - sp = rap->rap_plport; - tcp2->th_sport = htons(sp); - tcp2->th_dport = 0; /* XXX - don't specify remote port */ - fi.fin_data[0] = sp; - fi.fin_data[1] = 0; - fi.fin_out = 1; - nat2 = nat_new(&fi, nat->nat_ptr, NULL, - NAT_SLAVE|IPN_UDP|SI_W_DPORT, - NAT_OUTBOUND); - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_UDP); - nat_update(&fi, nat2, nat2->nat_ptr); - - (void) fr_addstate(&fi, NULL, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - } - - ip->ip_p = swp; - ip->ip_len = slen; - ip->ip_src = swa; - ip->ip_dst = swb; - return 0; -} diff --git a/contrib/ipfilter/ip_rcmd_pxy.c b/contrib/ipfilter/ip_rcmd_pxy.c deleted file mode 100644 index b7904c8b1356..000000000000 --- a/contrib/ipfilter/ip_rcmd_pxy.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1998-2003 by Darren Reed - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Id: ip_rcmd_pxy.c,v 1.41.2.4 2005/02/04 10:22:55 darrenr Exp - * - * Simple RCMD transparent proxy for in-kernel use. For use with the NAT - * code. - */ - -#define IPF_RCMD_PROXY - - -int ippr_rcmd_init __P((void)); -void ippr_rcmd_fini __P((void)); -int ippr_rcmd_new __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_rcmd_out __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_rcmd_in __P((fr_info_t *, ap_session_t *, nat_t *)); -u_short ipf_rcmd_atoi __P((char *)); -int ippr_rcmd_portmsg __P((fr_info_t *, ap_session_t *, nat_t *)); - -static frentry_t rcmdfr; - -int rcmd_proxy_init = 0; - - -/* - * RCMD application proxy initialization. - */ -int ippr_rcmd_init() -{ - bzero((char *)&rcmdfr, sizeof(rcmdfr)); - rcmdfr.fr_ref = 1; - rcmdfr.fr_flags = FR_INQUE|FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&rcmdfr.fr_lock, "RCMD proxy rule lock"); - rcmd_proxy_init = 1; - - return 0; -} - - -void ippr_rcmd_fini() -{ - if (rcmd_proxy_init == 1) { - MUTEX_DESTROY(&rcmdfr.fr_lock); - rcmd_proxy_init = 0; - } -} - - -/* - * Setup for a new RCMD proxy. - */ -int ippr_rcmd_new(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - tcphdr_t *tcp = (tcphdr_t *)fin->fin_dp; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - aps->aps_psiz = sizeof(u_32_t); - KMALLOCS(aps->aps_data, u_32_t *, sizeof(u_32_t)); - if (aps->aps_data == NULL) { -#ifdef IP_RCMD_PROXY_DEBUG - printf("ippr_rcmd_new:KMALLOCS(%d) failed\n", sizeof(u_32_t)); -#endif - return -1; - } - *(u_32_t *)aps->aps_data = 0; - aps->aps_sport = tcp->th_sport; - aps->aps_dport = tcp->th_dport; - return 0; -} - - -/* - * ipf_rcmd_atoi - implement a simple version of atoi - */ -u_short ipf_rcmd_atoi(ptr) -char *ptr; -{ - register char *s = ptr, c; - register u_short i = 0; - - while (((c = *s++) != '\0') && ISDIGIT(c)) { - i *= 10; - i += c - '0'; - } - return i; -} - - -int ippr_rcmd_portmsg(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - tcphdr_t *tcp, tcph, *tcp2 = &tcph; - struct in_addr swip, swip2; - int off, dlen, nflags; - char portbuf[8], *s; - fr_info_t fi; - u_short sp; - nat_t *nat2; - ip_t *ip; - mb_t *m; - - tcp = (tcphdr_t *)fin->fin_dp; - - if (tcp->th_flags & TH_SYN) { - *(u_32_t *)aps->aps_data = htonl(ntohl(tcp->th_seq) + 1); - return 0; - } - - if ((*(u_32_t *)aps->aps_data != 0) && - (tcp->th_seq != *(u_32_t *)aps->aps_data)) - return 0; - - m = fin->fin_m; - ip = fin->fin_ip; - off = (char *)tcp - (char *)ip + (TCP_OFF(tcp) << 2) + fin->fin_ipoff; - -#ifdef __sgi - dlen = fin->fin_plen - off; -#else - dlen = MSGDSIZE(m) - off; -#endif - if (dlen <= 0) - return 0; - - bzero(portbuf, sizeof(portbuf)); - COPYDATA(m, off, MIN(sizeof(portbuf), dlen), portbuf); - - portbuf[sizeof(portbuf) - 1] = '\0'; - s = portbuf; - sp = ipf_rcmd_atoi(s); - if (sp == 0) { -#ifdef IP_RCMD_PROXY_DEBUG - printf("ippr_rcmd_portmsg:sp == 0 dlen %d [%s]\n", - dlen, portbuf); -#endif - return 0; - } - - /* - * Add skeleton NAT entry for connection which will come back the - * other way. - */ - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_flx |= FI_IGNORE; - fi.fin_data[0] = sp; - fi.fin_data[1] = 0; - if (nat->nat_dir == NAT_OUTBOUND) - nat2 = nat_outlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - else - nat2 = nat_inlookup(&fi, NAT_SEARCH|IPN_TCP, nat->nat_p, - nat->nat_inip, nat->nat_oip); - if (nat2 == NULL) { - int slen; - - slen = ip->ip_len; - ip->ip_len = fin->fin_hlen + sizeof(*tcp); - bzero((char *)tcp2, sizeof(*tcp2)); - tcp2->th_win = htons(8192); - tcp2->th_sport = htons(sp); - tcp2->th_dport = 0; /* XXX - don't specify remote port */ - TCP_OFF_A(tcp2, 5); - tcp2->th_flags = TH_SYN; - fi.fin_dp = (char *)tcp2; - fi.fin_fr = &rcmdfr; - fi.fin_dlen = sizeof(*tcp2); - fi.fin_plen = fi.fin_hlen + sizeof(*tcp2); - fi.fin_flx &= FI_LOWTTL|FI_FRAG|FI_TCPUDP|FI_OPTIONS|FI_IGNORE; - nflags = NAT_SLAVE|IPN_TCP|SI_W_DPORT; - - swip = ip->ip_src; - swip2 = ip->ip_dst; - - if (nat->nat_dir == NAT_OUTBOUND) { - fi.fin_fi.fi_saddr = nat->nat_inip.s_addr; - ip->ip_src = nat->nat_inip; - } else { - fi.fin_fi.fi_saddr = nat->nat_oip.s_addr; - ip->ip_src = nat->nat_oip; - nflags |= NAT_NOTRULEPORT; - } - - nat2 = nat_new(&fi, nat->nat_ptr, NULL, nflags, nat->nat_dir); - - if (nat2 != NULL) { - (void) nat_proto(&fi, nat2, IPN_TCP); - nat_update(&fi, nat2, nat2->nat_ptr); - fi.fin_ifp = NULL; - if (nat->nat_dir == NAT_INBOUND) { - fi.fin_fi.fi_daddr = nat->nat_inip.s_addr; - ip->ip_dst = nat->nat_inip; - } - (void) fr_addstate(&fi, &nat2->nat_state, SI_W_DPORT); - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - ip->ip_len = slen; - ip->ip_src = swip; - ip->ip_dst = swip2; - } - return 0; -} - - -int ippr_rcmd_out(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - if (nat->nat_dir == NAT_OUTBOUND) - return ippr_rcmd_portmsg(fin, aps, nat); - return 0; -} - - -int ippr_rcmd_in(fin, aps, nat) -fr_info_t *fin; -ap_session_t *aps; -nat_t *nat; -{ - if (nat->nat_dir == NAT_INBOUND) - return ippr_rcmd_portmsg(fin, aps, nat); - return 0; -} diff --git a/contrib/ipfilter/ip_rpcb_pxy.c b/contrib/ipfilter/ip_rpcb_pxy.c deleted file mode 100644 index 5d0a1ee43dac..000000000000 --- a/contrib/ipfilter/ip_rpcb_pxy.c +++ /dev/null @@ -1,1460 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2002-2003 by Ryan Beasley - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* - * Overview: - * This is an in-kernel application proxy for Sun's RPCBIND (nee portmap) - * protocol as defined in RFC1833. It is far from complete, mostly - * lacking in less-likely corner cases, but it's definitely functional. - * - * Invocation: - * rdr /32 port -> port udp proxy rpcbu - * - * If the host running IP Filter is the same as the RPC server, it's - * perfectly legal for both the internal and external addresses and ports - * to match. - * - * When triggered by appropriate IP NAT rules, this proxy works by - * examining data contained in received packets. Requests and replies are - * modified, NAT and state table entries created, etc., as necessary. - */ -/* - * TODO / NOTES - * - * o Must implement locking to protect proxy session data. - * o Fragmentation isn't supported. - * o Only supports UDP. - * o Doesn't support multiple RPC records in a single request. - * o Errors should be more fine-grained. (e.g., malloc failure vs. - * illegal RPCB request / reply) - * o Even with the limit on the total amount of recorded transactions, - * should there be a timeout on transaction removal? - * o There is a potential collision between cloning, wildcard NAT and - * state entries. There should be an appr_getport routine for - * to avoid this. - * o The enclosed hack of STREAMS support is pretty sick and most likely - * broken. - * - * Id: ip_rpcb_pxy.c,v 2.25.2.3 2005/02/04 10:22:56 darrenr Exp - */ - -#define IPF_RPCB_PROXY - -/* - * Function prototypes - */ -int ippr_rpcb_init __P((void)); -void ippr_rpcb_fini __P((void)); -int ippr_rpcb_new __P((fr_info_t *, ap_session_t *, nat_t *)); -void ippr_rpcb_del __P((ap_session_t *)); -int ippr_rpcb_in __P((fr_info_t *, ap_session_t *, nat_t *)); -int ippr_rpcb_out __P((fr_info_t *, ap_session_t *, nat_t *)); - -static void ippr_rpcb_flush __P((rpcb_session_t *)); -static int ippr_rpcb_decodereq __P((fr_info_t *, nat_t *, - rpcb_session_t *, rpc_msg_t *)); -static int ippr_rpcb_skipauth __P((rpc_msg_t *, xdr_auth_t *, u_32_t **)); -static int ippr_rpcb_insert __P((rpcb_session_t *, rpcb_xact_t *)); -static int ippr_rpcb_xdrrpcb __P((rpc_msg_t *, u_32_t *, rpcb_args_t *)); -static int ippr_rpcb_getuaddr __P((rpc_msg_t *, xdr_uaddr_t *, - u_32_t **)); -static u_int ippr_rpcb_atoi __P((char *)); -static int ippr_rpcb_modreq __P((fr_info_t *, nat_t *, rpc_msg_t *, - mb_t *, u_int)); -static int ippr_rpcb_decoderep __P((fr_info_t *, nat_t *, - rpcb_session_t *, rpc_msg_t *, rpcb_xact_t **)); -static rpcb_xact_t * ippr_rpcb_lookup __P((rpcb_session_t *, u_32_t)); -static void ippr_rpcb_deref __P((rpcb_session_t *, rpcb_xact_t *)); -static int ippr_rpcb_getproto __P((rpc_msg_t *, xdr_proto_t *, - u_32_t **)); -static int ippr_rpcb_getnat __P((fr_info_t *, nat_t *, u_int, u_int)); -static int ippr_rpcb_modv3 __P((fr_info_t *, nat_t *, rpc_msg_t *, - mb_t *, u_int)); -static int ippr_rpcb_modv4 __P((fr_info_t *, nat_t *, rpc_msg_t *, - mb_t *, u_int)); -static void ippr_rpcb_fixlen __P((fr_info_t *, int)); - -/* - * Global variables - */ -static frentry_t rpcbfr; /* Skeleton rule for reference by entities - this proxy creates. */ -static int rpcbcnt; /* Upper bound of allocated RPCB sessions. */ - /* XXX rpcbcnt still requires locking. */ - -int rpcb_proxy_init = 0; - - -/* - * Since rpc_msg contains only pointers, one should use this macro as a - * handy way to get to the goods. (In case you're wondering about the name, - * this started as BYTEREF -> BREF -> B.) - */ -#define B(r) (u_32_t)ntohl(*(r)) - -/* - * Public subroutines - */ - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_init */ -/* Returns: int - 0 == success */ -/* Parameters: (void) */ -/* */ -/* Initialize the filter rule entry and session limiter. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_init() -{ - rpcbcnt = 0; - - bzero((char *)&rpcbfr, sizeof(rpcbfr)); - rpcbfr.fr_ref = 1; - rpcbfr.fr_flags = FR_PASS|FR_QUICK|FR_KEEPSTATE; - MUTEX_INIT(&rpcbfr.fr_lock, "ipf Sun RPCB proxy rule lock"); - rpcb_proxy_init = 1; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_fini */ -/* Returns: void */ -/* Parameters: (void) */ -/* */ -/* Destroy rpcbfr's mutex to avoid a lock leak. */ -/* -------------------------------------------------------------------- */ -void -ippr_rpcb_fini() -{ - if (rpcb_proxy_init == 1) { - MUTEX_DESTROY(&rpcbfr.fr_lock); - rpcb_proxy_init = 0; - } -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_new */ -/* Returns: int - -1 == failure, 0 == success */ -/* Parameters: fin(I) - pointer to packet information */ -/* aps(I) - pointer to proxy session structure */ -/* nat(I) - pointer to NAT session structure */ -/* */ -/* Allocate resources for per-session proxy structures. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_new(fin, aps, nat) - fr_info_t *fin; - ap_session_t *aps; - nat_t *nat; -{ - rpcb_session_t *rs; - - fin = fin; /* LINT */ - nat = nat; /* LINT */ - - KMALLOC(rs, rpcb_session_t *); - if (rs == NULL) - return(-1); - - bzero((char *)rs, sizeof(*rs)); - MUTEX_INIT(&rs->rs_rxlock, "ipf Sun RPCB proxy session lock"); - - aps->aps_data = rs; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_del */ -/* Returns: void */ -/* Parameters: aps(I) - pointer to proxy session structure */ -/* */ -/* Free up a session's list of RPCB requests. */ -/* -------------------------------------------------------------------- */ -void -ippr_rpcb_del(aps) - ap_session_t *aps; -{ - rpcb_session_t *rs; - rs = (rpcb_session_t *)aps->aps_data; - - MUTEX_ENTER(&rs->rs_rxlock); - ippr_rpcb_flush(rs); - MUTEX_EXIT(&rs->rs_rxlock); - MUTEX_DESTROY(&rs->rs_rxlock); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_in */ -/* Returns: int - APR_ERR(1) == drop the packet, */ -/* APR_ERR(2) == kill the proxy session, */ -/* else change in packet length (in bytes) */ -/* Parameters: fin(I) - pointer to packet information */ -/* ip(I) - pointer to packet header */ -/* aps(I) - pointer to proxy session structure */ -/* nat(I) - pointer to NAT session structure */ -/* */ -/* Given a presumed RPCB request, perform some minor tests and pass off */ -/* for decoding. Also pass packet off for a rewrite if necessary. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_in(fin, aps, nat) - fr_info_t *fin; - ap_session_t *aps; - nat_t *nat; -{ - rpc_msg_t rpcmsg, *rm; - rpcb_session_t *rs; - u_int off, dlen; - mb_t *m; - int rv; - - /* Disallow fragmented or illegally short packets. */ - if ((fin->fin_flx & (FI_FRAG|FI_SHORT)) != 0) - return(APR_ERR(1)); - - /* Perform basic variable initialization. */ - rs = (rpcb_session_t *)aps->aps_data; - - m = fin->fin_m; - off = (char *)fin->fin_dp - (char *)fin->fin_ip; - off += sizeof(udphdr_t) + fin->fin_ipoff; - dlen = fin->fin_dlen - sizeof(udphdr_t); - - /* Disallow packets outside legal range for supported requests. */ - if ((dlen < RPCB_REQMIN) || (dlen > RPCB_REQMAX)) - return(APR_ERR(1)); - - /* Copy packet over to convenience buffer. */ - rm = &rpcmsg; - bzero((char *)rm, sizeof(*rm)); - COPYDATA(m, off, dlen, (caddr_t)&rm->rm_msgbuf); - rm->rm_buflen = dlen; - - /* Send off to decode request. */ - rv = ippr_rpcb_decodereq(fin, nat, rs, rm); - - switch(rv) - { - case -1: - return(APR_ERR(1)); - /*NOTREACHED*/ - break; - case 0: - break; - case 1: - rv = ippr_rpcb_modreq(fin, nat, rm, m, off); - break; - default: - /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_req)", rv)); - } - - return(rv); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_out */ -/* Returns: int - APR_ERR(1) == drop the packet, */ -/* APR_ERR(2) == kill the proxy session, */ -/* else change in packet length (in bytes) */ -/* Parameters: fin(I) - pointer to packet information */ -/* ip(I) - pointer to packet header */ -/* aps(I) - pointer to proxy session structure */ -/* nat(I) - pointer to NAT session structure */ -/* */ -/* Given a presumed RPCB reply, perform some minor tests and pass off */ -/* for decoding. If the message indicates a successful request with */ -/* valid addressing information, create NAT and state structures to */ -/* allow direct communication between RPC client and server. */ -/* -------------------------------------------------------------------- */ -int -ippr_rpcb_out(fin, aps, nat) - fr_info_t *fin; - ap_session_t *aps; - nat_t *nat; -{ - rpc_msg_t rpcmsg, *rm; - rpcb_session_t *rs; - rpcb_xact_t *rx; - u_int off, dlen; - int rv, diff; - mb_t *m; - - /* Disallow fragmented or illegally short packets. */ - if ((fin->fin_flx & (FI_FRAG|FI_SHORT)) != 0) - return(APR_ERR(1)); - - /* Perform basic variable initialization. */ - rs = (rpcb_session_t *)aps->aps_data; - - m = fin->fin_m; - off = (char *)fin->fin_dp - (char *)fin->fin_ip; - off += sizeof(udphdr_t) + fin->fin_ipoff; - dlen = fin->fin_dlen - sizeof(udphdr_t); - diff = 0; - - /* Disallow packets outside legal range for supported requests. */ - if ((dlen < RPCB_REPMIN) || (dlen > RPCB_REPMAX)) - return(APR_ERR(1)); - - /* Copy packet over to convenience buffer. */ - rm = &rpcmsg; - bzero((char *)rm, sizeof(*rm)); - COPYDATA(m, off, dlen, (caddr_t)&rm->rm_msgbuf); - rm->rm_buflen = dlen; - - /* Send off to decode reply. */ - rv = ippr_rpcb_decoderep(fin, nat, rs, rm, &rx); - - switch(rv) - { - case -1: /* Bad packet */ - if (rx != NULL) { - MUTEX_ENTER(&rs->rs_rxlock); - ippr_rpcb_deref(rs, rx); - MUTEX_EXIT(&rs->rs_rxlock); - } - return(APR_ERR(1)); - /*NOTREACHED*/ - break; - case 0: /* Negative reply / request rejected */ - break; - case 1: /* Positive reply */ - /* - * With the IP address embedded in a GETADDR(LIST) reply, - * we'll need to rewrite the packet in the very possible - * event that the internal & external addresses aren't the - * same. (i.e., this box is either a router or rpcbind - * only listens on loopback.) - */ - if (nat->nat_inip.s_addr != nat->nat_outip.s_addr) { - if (rx->rx_type == RPCB_RES_STRING) - diff = ippr_rpcb_modv3(fin, nat, rm, m, off); - else if (rx->rx_type == RPCB_RES_LIST) - diff = ippr_rpcb_modv4(fin, nat, rm, m, off); - } - break; - default: - /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rv %d (ippr_rpcb_decoderep)", rv)); - } - - if (rx != NULL) { - MUTEX_ENTER(&rs->rs_rxlock); - /* XXX Gross hack - I'm overloading the reference - * counter to deal with both threads and retransmitted - * requests. One deref signals that this thread is - * finished with rx, and the other signals that we've - * processed its reply. - */ - ippr_rpcb_deref(rs, rx); - ippr_rpcb_deref(rs, rx); - MUTEX_EXIT(&rs->rs_rxlock); - } - - return(diff); -} - -/* - * Private support subroutines - */ - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_flush */ -/* Returns: void */ -/* Parameters: rs(I) - pointer to RPCB session structure */ -/* */ -/* Simply flushes the list of outstanding transactions, if any. */ -/* -------------------------------------------------------------------- */ -static void -ippr_rpcb_flush(rs) - rpcb_session_t *rs; -{ - rpcb_xact_t *r1, *r2; - - r1 = rs->rs_rxlist; - if (r1 == NULL) - return; - - while (r1 != NULL) { - r2 = r1; - r1 = r1->rx_next; - KFREE(r2); - } -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_decodereq */ -/* Returns: int - -1 == bad request or critical failure, */ -/* 0 == request successfully decoded, */ -/* 1 == request successfully decoded; requires */ -/* address rewrite/modification */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session structure */ -/* rs(I) - pointer to RPCB session structure */ -/* rm(I) - pointer to RPC message structure */ -/* */ -/* Take a presumed RPCB request, decode it, and store the results in */ -/* the transaction list. If the internal target address needs to be */ -/* modified, store its location in ptr. */ -/* WARNING: It's the responsibility of the caller to make sure there */ -/* is enough room in rs_buf for the basic RPC message "preamble". */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_decodereq(fin, nat, rs, rm) - fr_info_t *fin; - nat_t *nat; - rpcb_session_t *rs; - rpc_msg_t *rm; -{ - rpcb_args_t *ra; - u_32_t xdr, *p; - rpc_call_t *rc; - rpcb_xact_t rx; - int mod; - - p = (u_32_t *)rm->rm_msgbuf; - mod = 0; - - bzero((char *)&rx, sizeof(rx)); - rc = &rm->rm_call; - - rm->rm_xid = p; - rx.rx_xid = B(p++); /* Record this message's XID. */ - - /* Parse out and test the RPC header. */ - if ((B(p++) != RPCB_CALL) || - (B(p++) != RPCB_MSG_VERSION) || - (B(p++) != RPCB_PROG)) - return(-1); - - /* Record the RPCB version and procedure. */ - rc->rc_vers = p++; - rc->rc_proc = p++; - - /* Bypass RPC authentication stuff. */ - if (ippr_rpcb_skipauth(rm, &rc->rc_authcred, &p) != 0) - return(-1); - if (ippr_rpcb_skipauth(rm, &rc->rc_authverf, &p) != 0) - return(-1); - - /* Compare RPCB version and procedure numbers. */ - switch(B(rc->rc_vers)) - { - case 2: - /* This proxy only supports PMAP_GETPORT. */ - if (B(rc->rc_proc) != RPCB_GETPORT) - return(-1); - - /* Portmap requests contain four 4 byte parameters. */ - if (RPCB_BUF_EQ(rm, p, 16) == 0) - return(-1); - - p += 2; /* Skip requested program and version numbers. */ - - /* Sanity check the requested protocol. */ - xdr = B(p); - if (!(xdr == IPPROTO_UDP || xdr == IPPROTO_TCP)) - return(-1); - - rx.rx_type = RPCB_RES_PMAP; - rx.rx_proto = xdr; - break; - case 3: - case 4: - /* GETADDRLIST is exclusive to v4; GETADDR for v3 & v4 */ - switch(B(rc->rc_proc)) - { - case RPCB_GETADDR: - rx.rx_type = RPCB_RES_STRING; - rx.rx_proto = (u_int)fin->fin_p; - break; - case RPCB_GETADDRLIST: - if (B(rc->rc_vers) != 4) - return(-1); - rx.rx_type = RPCB_RES_LIST; - break; - default: - return(-1); - } - - ra = &rc->rc_rpcbargs; - - /* Decode the 'struct rpcb' request. */ - if (ippr_rpcb_xdrrpcb(rm, p, ra) != 0) - return(-1); - - /* Are the target address & port valid? */ - if ((ra->ra_maddr.xu_ip != nat->nat_outip.s_addr) || - (ra->ra_maddr.xu_port != nat->nat_outport)) - return(-1); - - /* Do we need to rewrite this packet? */ - if ((nat->nat_outip.s_addr != nat->nat_inip.s_addr) || - (nat->nat_outport != nat->nat_inport)) - mod = 1; - break; - default: - return(-1); - } - - MUTEX_ENTER(&rs->rs_rxlock); - if (ippr_rpcb_insert(rs, &rx) != 0) { - MUTEX_EXIT(&rs->rs_rxlock); - return(-1); - } - MUTEX_EXIT(&rs->rs_rxlock); - - return(mod); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_skipauth */ -/* Returns: int -- -1 == illegal auth parameters (lengths) */ -/* 0 == valid parameters, pointer advanced */ -/* Parameters: rm(I) - pointer to RPC message structure */ -/* auth(I) - pointer to RPC auth structure */ -/* buf(IO) - pointer to location within convenience buffer */ -/* */ -/* Record auth data length & location of auth data, then advance past */ -/* it. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_skipauth(rm, auth, buf) - rpc_msg_t *rm; - xdr_auth_t *auth; - u_32_t **buf; -{ - u_32_t *p, xdr; - - p = *buf; - - /* Make sure we have enough space for expected fixed auth parms. */ - if (RPCB_BUF_GEQ(rm, p, 8) == 0) - return(-1); - - p++; /* We don't care about auth_flavor. */ - - auth->xa_string.xs_len = p; - xdr = B(p++); /* Length of auth_data */ - - /* Test for absurdity / illegality of auth_data length. */ - if ((XDRALIGN(xdr) < xdr) || (RPCB_BUF_GEQ(rm, p, XDRALIGN(xdr)) == 0)) - return(-1); - - auth->xa_string.xs_str = (char *)p; - - p += XDRALIGN(xdr); /* Advance our location. */ - - *buf = (u_32_t *)p; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_insert */ -/* Returns: int -- -1 == list insertion failed, */ -/* 0 == item successfully added */ -/* Parameters: rs(I) - pointer to RPCB session structure */ -/* rx(I) - pointer to RPCB transaction structure */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_insert(rs, rx) - rpcb_session_t *rs; - rpcb_xact_t *rx; -{ - rpcb_xact_t *rxp; - - rxp = ippr_rpcb_lookup(rs, rx->rx_xid); - if (rxp != NULL) { - ++rxp->rx_ref; - return(0); - } - - if (rpcbcnt == RPCB_MAXREQS) - return(-1); - - KMALLOC(rxp, rpcb_xact_t *); - if (rxp == NULL) - return(-1); - - bcopy((char *)rx, (char *)rxp, sizeof(*rx)); - - if (rs->rs_rxlist != NULL) - rs->rs_rxlist->rx_pnext = &rxp->rx_next; - - rxp->rx_pnext = &rs->rs_rxlist; - rxp->rx_next = rs->rs_rxlist; - rs->rs_rxlist = rxp; - - rxp->rx_ref = 1; - - ++rpcbcnt; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_xdrrpcb */ -/* Returns: int -- -1 == failure to properly decode the request */ -/* 0 == rpcb successfully decoded */ -/* Parameters: rs(I) - pointer to RPCB session structure */ -/* p(I) - pointer to location within session buffer */ -/* rpcb(O) - pointer to rpcb (xdr type) structure */ -/* */ -/* Decode a XDR encoded rpcb structure and record its contents in rpcb */ -/* within only the context of TCP/UDP over IP networks. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_xdrrpcb(rm, p, ra) - rpc_msg_t *rm; - u_32_t *p; - rpcb_args_t *ra; -{ - if (!RPCB_BUF_GEQ(rm, p, 20)) - return(-1); - - /* Bypass target program & version. */ - p += 2; - - /* Decode r_netid. Must be "tcp" or "udp". */ - if (ippr_rpcb_getproto(rm, &ra->ra_netid, &p) != 0) - return(-1); - - /* Decode r_maddr. */ - if (ippr_rpcb_getuaddr(rm, &ra->ra_maddr, &p) != 0) - return(-1); - - /* Advance to r_owner and make sure it's empty. */ - if (!RPCB_BUF_EQ(rm, p, 4) || (B(p) != 0)) - return(-1); - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getuaddr */ -/* Returns: int -- -1 == illegal string, */ -/* 0 == string parsed; contents recorded */ -/* Parameters: rm(I) - pointer to RPC message structure */ -/* xu(I) - pointer to universal address structure */ -/* p(IO) - pointer to location within message buffer */ -/* */ -/* Decode the IP address / port at p and record them in xu. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_getuaddr(rm, xu, p) - rpc_msg_t *rm; - xdr_uaddr_t *xu; - u_32_t **p; -{ - char *c, *i, *b, *pp; - u_int d, dd, l, t; - char uastr[24]; - - /* Test for string length. */ - if (!RPCB_BUF_GEQ(rm, *p, 4)) - return(-1); - - xu->xu_xslen = (*p)++; - xu->xu_xsstr = (char *)*p; - - /* Length check */ - l = B(xu->xu_xslen); - if (l < 11 || l > 23 || !RPCB_BUF_GEQ(rm, *p, XDRALIGN(l))) - return(-1); - - /* Advance p */ - *(char **)p += XDRALIGN(l); - - /* Copy string to local buffer & terminate C style */ - bcopy(xu->xu_xsstr, uastr, l); - uastr[l] = '\0'; - - i = (char *)&xu->xu_ip; - pp = (char *)&xu->xu_port; - - /* - * Expected format: a.b.c.d.e.f where [a-d] correspond to bytes of - * an IP address and [ef] are the bytes of a L4 port. - */ - if (!(ISDIGIT(uastr[0]) && ISDIGIT(uastr[l-1]))) - return(-1); - b = uastr; - for (c = &uastr[1], d = 0, dd = 0; c < &uastr[l-1]; c++) { - if (ISDIGIT(*c)) { - dd = 0; - continue; - } - if (*c == '.') { - if (dd != 0) - return(-1); - - /* Check for ASCII byte. */ - *c = '\0'; - t = ippr_rpcb_atoi(b); - if (t > 255) - return(-1); - - /* Aim b at beginning of the next byte. */ - b = c + 1; - - /* Switch off IP addr vs port parsing. */ - if (d < 4) - i[d++] = t & 0xff; - else - pp[d++ - 4] = t & 0xff; - - dd = 1; - continue; - } - return(-1); - } - if (d != 5) /* String must contain exactly 5 periods. */ - return(-1); - - /* Handle the last byte (port low byte) */ - t = ippr_rpcb_atoi(b); - if (t > 255) - return(-1); - pp[d - 4] = t & 0xff; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_atoi (XXX should be generic for all proxies) */ -/* Returns: int -- integer representation of supplied string */ -/* Parameters: ptr(I) - input string */ -/* */ -/* Simple version of atoi(3) ripped from ip_rcmd_pxy.c. */ -/* -------------------------------------------------------------------- */ -static u_int -ippr_rpcb_atoi(ptr) - char *ptr; -{ - register char *s = ptr, c; - register u_int i = 0; - - while (((c = *s++) != '\0') && ISDIGIT(c)) { - i *= 10; - i += c - '0'; - } - return i; -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modreq */ -/* Returns: int -- change in datagram length */ -/* APR_ERR(2) - critical failure */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session */ -/* rm(I) - pointer to RPC message structure */ -/* m(I) - pointer to mbuf chain */ -/* off(I) - current offset within mbuf chain */ -/* */ -/* When external and internal addresses differ, we rewrite the former */ -/* with the latter. (This is exclusive to protocol versions 3 & 4). */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_modreq(fin, nat, rm, m, off) - fr_info_t *fin; - nat_t *nat; - rpc_msg_t *rm; - mb_t *m; - u_int off; -{ - u_int len, xlen, pos, bogo; - rpcb_args_t *ra; - char uaddr[24]; - udphdr_t *udp; - char *i, *p; - int diff; - - ra = &rm->rm_call.rc_rpcbargs; - i = (char *)&nat->nat_inip.s_addr; - p = (char *)&nat->nat_inport; - - /* Form new string. */ - bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(uaddr, sizeof(uaddr), -#else - (void) sprintf(uaddr, -#endif - "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff, - i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff); - len = strlen(uaddr); - xlen = XDRALIGN(len); - - /* Determine mbuf offset to start writing to. */ - pos = (char *)ra->ra_maddr.xu_xslen - rm->rm_msgbuf; - off += pos; - - /* Write new string length. */ - bogo = htonl(len); - COPYBACK(m, off, 4, (caddr_t)&bogo); - off += 4; - - /* Write new string. */ - COPYBACK(m, off, xlen, uaddr); - off += xlen; - - /* Write in zero r_owner. */ - bogo = 0; - COPYBACK(m, off, 4, (caddr_t)&bogo); - - /* Determine difference in data lengths. */ - diff = xlen - XDRALIGN(B(ra->ra_maddr.xu_xslen)); - - /* - * If our new string has a different length, make necessary - * adjustments. - */ - if (diff != 0) { - udp = fin->fin_dp; - udp->uh_ulen = htons(ntohs(udp->uh_ulen) + diff); - fin->fin_ip->ip_len += diff; - fin->fin_dlen += diff; - fin->fin_plen += diff; - /* XXX Storage lengths. */ - } - - return(diff); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_decoderep */ -/* Returns: int - -1 == bad request or critical failure, */ -/* 0 == valid, negative reply */ -/* 1 == vaddlid, positive reply; needs no changes */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session structure */ -/* rs(I) - pointer to RPCB session structure */ -/* rm(I) - pointer to RPC message structure */ -/* rxp(O) - pointer to RPCB transaction structure */ -/* */ -/* Take a presumed RPCB reply, extract the XID, search for the original */ -/* request information, and determine whether the request was accepted */ -/* or rejected. With a valid accepted reply, go ahead and create NAT */ -/* and state entries, and finish up by rewriting the packet as */ -/* required. */ -/* */ -/* WARNING: It's the responsibility of the caller to make sure there */ -/* is enough room in rs_buf for the basic RPC message "preamble". */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_decoderep(fin, nat, rs, rm, rxp) - fr_info_t *fin; - nat_t *nat; - rpcb_session_t *rs; - rpc_msg_t *rm; - rpcb_xact_t **rxp; -{ - rpcb_listp_t *rl; - rpcb_entry_t *re; - rpcb_xact_t *rx; - u_32_t xdr, *p; - rpc_resp_t *rr; - int rv, cnt; - - p = (u_32_t *)rm->rm_msgbuf; - - bzero((char *)&rx, sizeof(rx)); - rr = &rm->rm_resp; - - rm->rm_xid = p; - xdr = B(p++); /* Record this message's XID. */ - - /* Lookup XID */ - MUTEX_ENTER(&rs->rs_rxlock); - if ((rx = ippr_rpcb_lookup(rs, xdr)) == NULL) { - MUTEX_EXIT(&rs->rs_rxlock); - return(-1); - } - ++rx->rx_ref; /* per thread reference */ - MUTEX_EXIT(&rs->rs_rxlock); - - *rxp = rx; - - /* Test call vs reply */ - if (B(p++) != RPCB_REPLY) - return(-1); - - /* Test reply_stat */ - switch(B(p++)) - { - case RPCB_MSG_DENIED: - return(0); - case RPCB_MSG_ACCEPTED: - break; - default: - return(-1); - } - - /* Bypass RPC authentication stuff. */ - if (ippr_rpcb_skipauth(rm, &rr->rr_authverf, &p) != 0) - return(-1); - - /* Test accept status */ - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - if (B(p++) != 0) - return(0); - - /* Parse out the expected reply */ - switch(rx->rx_type) - { - case RPCB_RES_PMAP: - /* There must be only one 4 byte argument. */ - if (!RPCB_BUF_EQ(rm, p, 4)) - return(-1); - - rr->rr_v2 = p; - xdr = B(rr->rr_v2); - - /* Reply w/ a 0 port indicates service isn't registered */ - if (xdr == 0) - return(0); - - /* Is the value sane? */ - if (xdr > 65535) - return(-1); - - /* Create NAT & state table entries. */ - if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, (u_int)xdr) != 0) - return(-1); - break; - case RPCB_RES_STRING: - /* Expecting a XDR string; need 4 bytes for length */ - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - - rr->rr_v3.xu_str.xs_len = p++; - rr->rr_v3.xu_str.xs_str = (char *)p; - - xdr = B(rr->rr_v3.xu_xslen); - - /* A null string indicates an unregistered service */ - if ((xdr == 0) && RPCB_BUF_EQ(rm, p, 0)) - return(0); - - /* Decode the target IP address / port. */ - if (ippr_rpcb_getuaddr(rm, &rr->rr_v3, &p) != 0) - return(-1); - - /* Validate the IP address and port contained. */ - if (nat->nat_inip.s_addr != rr->rr_v3.xu_ip) - return(-1); - - /* Create NAT & state table entries. */ - if (ippr_rpcb_getnat(fin, nat, rx->rx_proto, - (u_int)rr->rr_v3.xu_port) != 0) - return(-1); - break; - case RPCB_RES_LIST: - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - /* rpcb_entry_list_ptr */ - switch(B(p)) - { - case 0: - return(0); - /*NOTREACHED*/ - break; - case 1: - break; - default: - return(-1); - } - rl = &rr->rr_v4; - rl->rl_list = p++; - cnt = 0; - - for(;;) { - re = &rl->rl_entries[rl->rl_cnt]; - if (ippr_rpcb_getuaddr(rm, &re->re_maddr, &p) != 0) - return(-1); - if (ippr_rpcb_getproto(rm, &re->re_netid, &p) != 0) - return(-1); - /* re_semantics & re_pfamily length */ - if (!RPCB_BUF_GEQ(rm, p, 12)) - return(-1); - p++; /* Skipping re_semantics. */ - xdr = B(p++); - if ((xdr != 4) || strncmp((char *)p, "inet", 4)) - return(-1); - p++; - if (ippr_rpcb_getproto(rm, &re->re_proto, &p) != 0) - return(-1); - if (!RPCB_BUF_GEQ(rm, p, 4)) - return(-1); - re->re_more = p; - if (B(re->re_more) > 1) /* 0,1 only legal values */ - return(-1); - ++rl->rl_cnt; - ++cnt; - if (B(re->re_more) == 0) - break; - /* Replies in max out at 2; TCP and/or UDP */ - if (cnt > 2) - return(-1); - p++; - } - - for(rl->rl_cnt = 0; rl->rl_cnt < cnt; rl->rl_cnt++) { - re = &rl->rl_entries[rl->rl_cnt]; - rv = ippr_rpcb_getnat(fin, nat, - re->re_proto.xp_proto, - (u_int)re->re_maddr.xu_port); - if (rv != 0) - return(-1); - } - break; - default: - /*CONSTANTCONDITION*/ - IPF_PANIC(1, ("illegal rx_type %d", rx->rx_type)); - } - - return(1); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_lookup */ -/* Returns: rpcb_xact_t * - NULL == no matching record, */ -/* else pointer to relevant entry */ -/* Parameters: rs(I) - pointer to RPCB session */ -/* xid(I) - XID to look for */ -/* -------------------------------------------------------------------- */ -static rpcb_xact_t * -ippr_rpcb_lookup(rs, xid) - rpcb_session_t *rs; - u_32_t xid; -{ - rpcb_xact_t *rx; - - if (rs->rs_rxlist == NULL) - return(NULL); - - for (rx = rs->rs_rxlist; rx != NULL; rx = rx->rx_next) - if (rx->rx_xid == xid) - break; - - return(rx); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_deref */ -/* Returns: (void) */ -/* Parameters: rs(I) - pointer to RPCB session */ -/* rx(I) - pointer to RPC transaction struct to remove */ -/* force(I) - indicates to delete entry regardless of */ -/* reference count */ -/* Locking: rs->rs_rxlock must be held write only */ -/* */ -/* Free the RPCB transaction record rx from the chain of entries. */ -/* -------------------------------------------------------------------- */ -static void -ippr_rpcb_deref(rs, rx) - rpcb_session_t *rs; - rpcb_xact_t *rx; -{ - rs = rs; /* LINT */ - - if (rx == NULL) - return; - - if (--rx->rx_ref != 0) - return; - - if (rx->rx_next != NULL) - rx->rx_next->rx_pnext = rx->rx_pnext; - - *rx->rx_pnext = rx->rx_next; - - KFREE(rx); - - --rpcbcnt; -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getproto */ -/* Returns: int - -1 == illegal protocol/netid, */ -/* 0 == legal protocol/netid */ -/* Parameters: rm(I) - pointer to RPC message structure */ -/* xp(I) - pointer to netid structure */ -/* p(IO) - pointer to location within packet buffer */ -/* */ -/* Decode netid/proto stored at p and record its numeric value. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_getproto(rm, xp, p) - rpc_msg_t *rm; - xdr_proto_t *xp; - u_32_t **p; -{ - u_int len; - - /* Must have 4 bytes for length & 4 bytes for "tcp" or "udp". */ - if (!RPCB_BUF_GEQ(rm, p, 8)) - return(-1); - - xp->xp_xslen = (*p)++; - xp->xp_xsstr = (char *)*p; - - /* Test the string length. */ - len = B(xp->xp_xslen); - if (len != 3) - return(-1); - - /* Test the actual string & record the protocol accordingly. */ - if (!strncmp((char *)xp->xp_xsstr, "tcp\0", 4)) - xp->xp_proto = IPPROTO_TCP; - else if (!strncmp((char *)xp->xp_xsstr, "udp\0", 4)) - xp->xp_proto = IPPROTO_UDP; - else { - return(-1); - } - - /* Advance past the string. */ - (*p)++; - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_getnat */ -/* Returns: int -- -1 == failed to create table entries, */ -/* 0 == success */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT table entry */ -/* proto(I) - transport protocol for new entries */ -/* port(I) - new port to use w/ wildcard table entries */ -/* */ -/* Create state and NAT entries to handle an anticipated connection */ -/* attempt between RPC client and server. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_getnat(fin, nat, proto, port) - fr_info_t *fin; - nat_t *nat; - u_int proto; - u_int port; -{ - ipnat_t *ipn, ipnat; - tcphdr_t tcp; - ipstate_t *is; - fr_info_t fi; - nat_t *natl; - int nflags; - - ipn = nat->nat_ptr; - - /* Generate dummy fr_info */ - bcopy((char *)fin, (char *)&fi, sizeof(fi)); - fi.fin_out = 0; - fi.fin_src = fin->fin_dst; - fi.fin_dst = nat->nat_outip; - fi.fin_p = proto; - fi.fin_sport = 0; - fi.fin_dport = port & 0xffff; - fi.fin_flx |= FI_IGNORE; - - bzero((char *)&tcp, sizeof(tcp)); - tcp.th_dport = htons(port); - - if (proto == IPPROTO_TCP) { - tcp.th_win = htons(8192); - TCP_OFF_A(&tcp, sizeof(tcphdr_t) >> 2); - fi.fin_dlen = sizeof(tcphdr_t); - tcp.th_flags = TH_SYN; - nflags = NAT_TCP; - } else { - fi.fin_dlen = sizeof(udphdr_t); - nflags = NAT_UDP; - } - - nflags |= SI_W_SPORT|NAT_SEARCH; - fi.fin_dp = &tcp; - fi.fin_plen = fi.fin_hlen + fi.fin_dlen; - - /* - * Search for existing NAT & state entries. Pay close attention to - * mutexes / locks grabbed from lookup routines, as not doing so could - * lead to bad things. - * - * If successful, fr_stlookup returns with ipf_state locked. We have - * no use for this lock, so simply unlock it if necessary. - */ - is = fr_stlookup(&fi, &tcp, NULL); - if (is != NULL) - RWLOCK_EXIT(&ipf_state); - - RWLOCK_EXIT(&ipf_nat); - - WRITE_ENTER(&ipf_nat); - natl = nat_inlookup(&fi, nflags, proto, fi.fin_src, fi.fin_dst); - - if ((natl != NULL) && (is != NULL)) { - MUTEX_DOWNGRADE(&ipf_nat); - return(0); - } - - /* Slightly modify the following structures for actual use in creating - * NAT and/or state entries. We're primarily concerned with stripping - * flags that may be detrimental to the creation process or simply - * shouldn't be associated with a table entry. - */ - fi.fin_fr = &rpcbfr; - fi.fin_flx &= ~FI_IGNORE; - nflags &= ~NAT_SEARCH; - - if (natl == NULL) { - /* XXX Since we're just copying the original ipn contents - * back, would we be better off just sending a pointer to - * the 'temp' copy off to nat_new instead? - */ - /* Generate template/bogus NAT rule. */ - bcopy((char *)ipn, (char *)&ipnat, sizeof(ipnat)); - ipn->in_flags = nflags & IPN_TCPUDP; - ipn->in_apr = NULL; - ipn->in_p = proto; - ipn->in_pmin = htons(fi.fin_dport); - ipn->in_pmax = htons(fi.fin_dport); - ipn->in_pnext = htons(fi.fin_dport); - ipn->in_space = 1; - ipn->in_ippip = 1; - if (ipn->in_flags & IPN_FILTER) { - ipn->in_scmp = 0; - ipn->in_dcmp = 0; - } - *ipn->in_plabel = '\0'; - - /* Create NAT entry. return NULL if this fails. */ - natl = nat_new(&fi, ipn, NULL, nflags|SI_CLONE|NAT_SLAVE, - NAT_INBOUND); - - bcopy((char *)&ipnat, (char *)ipn, sizeof(ipnat)); - - if (natl == NULL) { - MUTEX_DOWNGRADE(&ipf_nat); - return(-1); - } - - ipn->in_use++; - (void) nat_proto(&fi, natl, nflags); - nat_update(&fi, natl, natl->nat_ptr); - } - MUTEX_DOWNGRADE(&ipf_nat); - - if (is == NULL) { - /* Create state entry. Return NULL if this fails. */ - fi.fin_dst = nat->nat_inip; - fi.fin_nat = (void *)natl; - fi.fin_flx |= FI_NATED; - fi.fin_flx &= ~FI_STATE; - nflags &= NAT_TCPUDP; - nflags |= SI_W_SPORT|SI_CLONE; - - is = fr_addstate(&fi, NULL, nflags); - if (is == NULL) { - /* - * XXX nat_delete is private to ip_nat.c. Should - * check w/ Darren about this one. - * - * nat_delete(natl, NL_EXPIRE); - */ - return(-1); - } - if (fi.fin_state != NULL) - fr_statederef(&fi, (ipstate_t **)&fi.fin_state); - } - - return(0); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modv3 */ -/* Returns: int -- change in packet length */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session */ -/* rm(I) - pointer to RPC message structure */ -/* m(I) - pointer to mbuf chain */ -/* off(I) - offset within mbuf chain */ -/* */ -/* Write a new universal address string to this packet, adjusting */ -/* lengths as necessary. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_modv3(fin, nat, rm, m, off) - fr_info_t *fin; - nat_t *nat; - rpc_msg_t *rm; - mb_t *m; - u_int off; -{ - u_int len, xlen, pos, bogo; - rpc_resp_t *rr; - char uaddr[24]; - char *i, *p; - int diff; - - rr = &rm->rm_resp; - i = (char *)&nat->nat_outip.s_addr; - p = (char *)&rr->rr_v3.xu_port; - - /* Form new string. */ - bzero(uaddr, sizeof(uaddr)); /* Just in case we need padding. */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(uaddr, sizeof(uaddr), -#else - (void) sprintf(uaddr, -#endif - "%u.%u.%u.%u.%u.%u", i[0] & 0xff, i[1] & 0xff, - i[2] & 0xff, i[3] & 0xff, p[0] & 0xff, p[1] & 0xff); - len = strlen(uaddr); - xlen = XDRALIGN(len); - - /* Determine mbuf offset to write to. */ - pos = (char *)rr->rr_v3.xu_xslen - rm->rm_msgbuf; - off += pos; - - /* Write new string length. */ - bogo = htonl(len); - COPYBACK(m, off, 4, (caddr_t)&bogo); - off += 4; - - /* Write new string. */ - COPYBACK(m, off, xlen, uaddr); - - /* Determine difference in data lengths. */ - diff = xlen - XDRALIGN(B(rr->rr_v3.xu_xslen)); - - /* - * If our new string has a different length, make necessary - * adjustments. - */ - if (diff != 0) - ippr_rpcb_fixlen(fin, diff); - - return(diff); -} - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_modv4 */ -/* Returns: int -- change in packet length */ -/* Parameters: fin(I) - pointer to packet information */ -/* nat(I) - pointer to NAT session */ -/* rm(I) - pointer to RPC message structure */ -/* m(I) - pointer to mbuf chain */ -/* off(I) - offset within mbuf chain */ -/* */ -/* Write new rpcb_entry list, adjusting lengths as necessary. */ -/* -------------------------------------------------------------------- */ -static int -ippr_rpcb_modv4(fin, nat, rm, m, off) - fr_info_t *fin; - nat_t *nat; - rpc_msg_t *rm; - mb_t *m; - u_int off; -{ - u_int len, xlen, pos, bogo; - rpcb_listp_t *rl; - rpcb_entry_t *re; - rpc_resp_t *rr; - char uaddr[24]; - int diff, cnt; - char *i, *p; - - diff = 0; - rr = &rm->rm_resp; - rl = &rr->rr_v4; - - i = (char *)&nat->nat_outip.s_addr; - - /* Determine mbuf offset to write to. */ - re = &rl->rl_entries[0]; - pos = (char *)re->re_maddr.xu_xslen - rm->rm_msgbuf; - off += pos; - - for (cnt = 0; cnt < rl->rl_cnt; cnt++) { - re = &rl->rl_entries[cnt]; - p = (char *)&re->re_maddr.xu_port; - - /* Form new string. */ - bzero(uaddr, sizeof(uaddr)); /* Just in case we need - padding. */ -#if defined(SNPRINTF) && defined(_KERNEL) - SNPRINTF(uaddr, sizeof(uaddr), -#else - (void) sprintf(uaddr, -#endif - "%u.%u.%u.%u.%u.%u", i[0] & 0xff, - i[1] & 0xff, i[2] & 0xff, i[3] & 0xff, - p[0] & 0xff, p[1] & 0xff); - len = strlen(uaddr); - xlen = XDRALIGN(len); - - /* Write new string length. */ - bogo = htonl(len); - COPYBACK(m, off, 4, (caddr_t)&bogo); - off += 4; - - /* Write new string. */ - COPYBACK(m, off, xlen, uaddr); - off += xlen; - - /* Record any change in length. */ - diff += xlen - XDRALIGN(B(re->re_maddr.xu_xslen)); - - /* If the length changed, copy back the rest of this entry. */ - len = ((char *)re->re_more + 4) - - (char *)re->re_netid.xp_xslen; - if (diff != 0) { - COPYBACK(m, off, len, (caddr_t)re->re_netid.xp_xslen); - } - off += len; - } - - /* - * If our new string has a different length, make necessary - * adjustments. - */ - if (diff != 0) - ippr_rpcb_fixlen(fin, diff); - - return(diff); -} - - -/* -------------------------------------------------------------------- */ -/* Function: ippr_rpcb_fixlen */ -/* Returns: (void) */ -/* Parameters: fin(I) - pointer to packet information */ -/* len(I) - change in packet length */ -/* */ -/* Adjust various packet related lengths held in structure and packet */ -/* header fields. */ -/* -------------------------------------------------------------------- */ -static void -ippr_rpcb_fixlen(fin, len) - fr_info_t *fin; - int len; -{ - udphdr_t *udp; - - udp = fin->fin_dp; - udp->uh_ulen = htons(ntohs(udp->uh_ulen) + len); - fin->fin_ip->ip_len += len; - fin->fin_dlen += len; - fin->fin_plen += len; -} - -#undef B diff --git a/contrib/ipfilter/ip_scan.c b/contrib/ipfilter/ip_scan.c deleted file mode 100644 index 37f6d58ef167..000000000000 --- a/contrib/ipfilter/ip_scan.c +++ /dev/null @@ -1,594 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1995-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#if defined(__hpux) && (HPUXREV >= 1111) && !defined(_KERNEL) -# include -#endif -#include -#include -#include -#if !defined(_KERNEL) -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#else -# include -# if !defined(__svr4__) && !defined(__SVR4) -# include -# endif -#endif -#include -#if !defined(__hpux) && !defined(__osf__) && !defined(linux) -# include -#endif -#ifdef __FreeBSD__ -# include -# include -#else -# include -#endif - -#include -#include -#include -#include - -#include - - -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_state.h" -#include "netinet/ip_scan.h" -/* END OF INCLUDES */ - -#if !defined(lint) -static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_scan.c,v 2.40.2.2 2005/01/18 10:13:16 darrenr Exp"; -#endif - -#ifdef IPFILTER_SCAN /* endif at bottom of file */ - - -ipscan_t *ipsc_list = NULL, - *ipsc_tail = NULL; -ipscanstat_t ipsc_stat; -# ifdef USE_MUTEXES -ipfrwlock_t ipsc_rwlock; -# endif - -# ifndef isalpha -# define isalpha(x) (((x) >= 'A' && 'Z' >= (x)) || \ - ((x) >= 'a' && 'z' >= (x))) -# endif - - -int ipsc_add __P((caddr_t)); -int ipsc_delete __P((caddr_t)); -struct ipscan *ipsc_lookup __P((char *)); -int ipsc_matchstr __P((sinfo_t *, char *, int)); -int ipsc_matchisc __P((ipscan_t *, ipstate_t *, int, int, int *)); -int ipsc_match __P((ipstate_t *)); - - - -int ipsc_init() -{ - RWLOCK_INIT(&ipsc_rwlock, "ip scan rwlock"); - return 0; -} - - -void fr_scanunload() -{ - RW_DESTROY(&ipsc_rwlock); -} - - -int ipsc_add(data) -caddr_t data; -{ - ipscan_t *i, *isc; - int err; - - KMALLOC(isc, ipscan_t *); - if (!isc) - return ENOMEM; - - err = copyinptr(data, isc, sizeof(*isc)); - if (err) - return err; - - WRITE_ENTER(&ipsc_rwlock); - - i = ipsc_lookup(isc->ipsc_tag); - if (i) { - RWLOCK_EXIT(&ipsc_rwlock); - KFREE(isc); - return EEXIST; - } - - if (ipsc_tail) { - ipsc_tail->ipsc_next = isc; - isc->ipsc_pnext = &ipsc_tail->ipsc_next; - ipsc_tail = isc; - } else { - ipsc_list = isc; - ipsc_tail = isc; - isc->ipsc_pnext = &ipsc_list; - } - isc->ipsc_next = NULL; - - isc->ipsc_hits = 0; - isc->ipsc_fref = 0; - isc->ipsc_sref = 0; - isc->ipsc_active = 0; - - ipsc_stat.iscs_entries++; - RWLOCK_EXIT(&ipsc_rwlock); - return 0; -} - - -int ipsc_delete(data) -caddr_t data; -{ - ipscan_t isc, *i; - int err; - - err = copyinptr(data, &isc, sizeof(isc)); - if (err) - return err; - - WRITE_ENTER(&ipsc_rwlock); - - i = ipsc_lookup(isc.ipsc_tag); - if (i == NULL) - err = ENOENT; - else { - if (i->ipsc_fref) { - RWLOCK_EXIT(&ipsc_rwlock); - return EBUSY; - } - - *i->ipsc_pnext = i->ipsc_next; - if (i->ipsc_next) - i->ipsc_next->ipsc_pnext = i->ipsc_pnext; - else { - if (i->ipsc_pnext == &ipsc_list) - ipsc_tail = NULL; - else - ipsc_tail = *(*i->ipsc_pnext)->ipsc_pnext; - } - - ipsc_stat.iscs_entries--; - KFREE(i); - } - RWLOCK_EXIT(&ipsc_rwlock); - return err; -} - - -struct ipscan *ipsc_lookup(tag) -char *tag; -{ - ipscan_t *i; - - for (i = ipsc_list; i; i = i->ipsc_next) - if (!strcmp(i->ipsc_tag, tag)) - return i; - return NULL; -} - - -int ipsc_attachfr(fr) -struct frentry *fr; -{ - ipscan_t *i; - - if (fr->fr_isctag[0]) { - READ_ENTER(&ipsc_rwlock); - i = ipsc_lookup(fr->fr_isctag); - if (i != NULL) { - ATOMIC_INC32(i->ipsc_fref); - } - RWLOCK_EXIT(&ipsc_rwlock); - if (i == NULL) - return ENOENT; - fr->fr_isc = i; - } - return 0; -} - - -int ipsc_attachis(is) -struct ipstate *is; -{ - frentry_t *fr; - ipscan_t *i; - - READ_ENTER(&ipsc_rwlock); - fr = is->is_rule; - if (fr) { - i = fr->fr_isc; - if (!i || (i != (ipscan_t *)-1)) { - is->is_isc = i; - if (i) { - ATOMIC_INC32(i->ipsc_sref); - if (i->ipsc_clen) - is->is_flags |= IS_SC_CLIENT; - else - is->is_flags |= IS_SC_MATCHC; - if (i->ipsc_slen) - is->is_flags |= IS_SC_SERVER; - else - is->is_flags |= IS_SC_MATCHS; - } else - is->is_flags |= (IS_SC_CLIENT|IS_SC_SERVER); - } - } - RWLOCK_EXIT(&ipsc_rwlock); - return 0; -} - - -int ipsc_detachfr(fr) -struct frentry *fr; -{ - ipscan_t *i; - - i = fr->fr_isc; - if (i != NULL) { - ATOMIC_DEC32(i->ipsc_fref); - } - return 0; -} - - -int ipsc_detachis(is) -struct ipstate *is; -{ - ipscan_t *i; - - READ_ENTER(&ipsc_rwlock); - if ((i = is->is_isc) && (i != (ipscan_t *)-1)) { - ATOMIC_DEC32(i->ipsc_sref); - is->is_isc = NULL; - is->is_flags &= ~(IS_SC_CLIENT|IS_SC_SERVER); - } - RWLOCK_EXIT(&ipsc_rwlock); - return 0; -} - - -/* - * 'string' compare for scanning - */ -int ipsc_matchstr(sp, str, n) -sinfo_t *sp; -char *str; -int n; -{ - char *s, *t, *up; - int i = n; - - if (i > sp->s_len) - i = sp->s_len; - up = str; - - for (s = sp->s_txt, t = sp->s_msk; i; i--, s++, t++, up++) - switch ((int)*t) - { - case '.' : - if (*s != *up) - return 1; - break; - case '?' : - if (!ISALPHA(*up) || ((*s & 0x5f) != (*up & 0x5f))) - return 1; - break; - case '*' : - break; - } - return 0; -} - - -/* - * Returns 3 if both server and client match, 2 if just server, - * 1 if just client - */ -int ipsc_matchisc(isc, is, cl, sl, maxm) -ipscan_t *isc; -ipstate_t *is; -int cl, sl, maxm[2]; -{ - int i, j, k, n, ret = 0, flags; - - flags = is->is_flags; - - /* - * If we've already matched more than what is on offer, then - * assume we have a better match already and forget this one. - */ - if (maxm != NULL) { - if (isc->ipsc_clen < maxm[0]) - return 0; - if (isc->ipsc_slen < maxm[1]) - return 0; - j = maxm[0]; - k = maxm[1]; - } else { - j = 0; - k = 0; - } - - if (!isc->ipsc_clen) - ret = 1; - else if (((flags & (IS_SC_MATCHC|IS_SC_CLIENT)) == IS_SC_CLIENT) && - cl && isc->ipsc_clen) { - i = 0; - n = MIN(cl, isc->ipsc_clen); - if ((n > 0) && (!maxm || (n >= maxm[1]))) { - if (!ipsc_matchstr(&isc->ipsc_cl, is->is_sbuf[0], n)) { - i++; - ret |= 1; - if (n > j) - j = n; - } - } - } - - if (!isc->ipsc_slen) - ret |= 2; - else if (((flags & (IS_SC_MATCHS|IS_SC_SERVER)) == IS_SC_SERVER) && - sl && isc->ipsc_slen) { - i = 0; - n = MIN(cl, isc->ipsc_slen); - if ((n > 0) && (!maxm || (n >= maxm[1]))) { - if (!ipsc_matchstr(&isc->ipsc_sl, is->is_sbuf[1], n)) { - i++; - ret |= 2; - if (n > k) - k = n; - } - } - } - - if (maxm && (ret == 3)) { - maxm[0] = j; - maxm[1] = k; - } - return ret; -} - - -int ipsc_match(is) -ipstate_t *is; -{ - int i, j, k, n, cl, sl, maxm[2]; - ipscan_t *isc, *lm; - tcpdata_t *t; - - for (cl = 0, n = is->is_smsk[0]; n & 1; n >>= 1) - cl++; - for (sl = 0, n = is->is_smsk[1]; n & 1; n >>= 1) - sl++; - - j = 0; - isc = is->is_isc; - if (isc != NULL) { - /* - * Known object to scan for. - */ - i = ipsc_matchisc(isc, is, cl, sl, NULL); - if (i & 1) { - is->is_flags |= IS_SC_MATCHC; - is->is_flags &= ~IS_SC_CLIENT; - } else if (cl >= isc->ipsc_clen) - is->is_flags &= ~IS_SC_CLIENT; - if (i & 2) { - is->is_flags |= IS_SC_MATCHS; - is->is_flags &= ~IS_SC_SERVER; - } else if (sl >= isc->ipsc_slen) - is->is_flags &= ~IS_SC_SERVER; - } else { - i = 0; - lm = NULL; - maxm[0] = 0; - maxm[1] = 0; - for (k = 0, isc = ipsc_list; isc; isc = isc->ipsc_next) { - i = ipsc_matchisc(isc, is, cl, sl, maxm); - if (i) { - /* - * We only want to remember the best match - * and the number of times we get a best - * match. - */ - if ((j == 3) && (i < 3)) - continue; - if ((i == 3) && (j != 3)) - k = 1; - else - k++; - j = i; - lm = isc; - } - } - if (k == 1) - isc = lm; - - /* - * No matches or partial matches, so reset the respective - * search flag. - */ - if (!(j & 1)) - is->is_flags &= ~IS_SC_CLIENT; - - if (!(j & 2)) - is->is_flags &= ~IS_SC_SERVER; - - /* - * If we found the best match, then set flags appropriately. - */ - if ((j == 3) && (k == 1)) { - is->is_flags &= ~(IS_SC_SERVER|IS_SC_CLIENT); - is->is_flags |= (IS_SC_MATCHS|IS_SC_MATCHC); - } - } - - /* - * If the acknowledged side of a connection has moved past the data in - * which we are interested, then reset respective flag. - */ - t = &is->is_tcp.ts_data[0]; - if (t->td_end > is->is_s0[0] + 15) - is->is_flags &= ~IS_SC_CLIENT; - - t = &is->is_tcp.ts_data[1]; - if (t->td_end > is->is_s0[1] + 15) - is->is_flags &= ~IS_SC_SERVER; - - /* - * Matching complete ? - */ - j = ISC_A_NONE; - if ((is->is_flags & IS_SC_MATCHALL) == IS_SC_MATCHALL) { - j = isc->ipsc_action; - ipsc_stat.iscs_acted++; - } else if ((is->is_isc != NULL) && - ((is->is_flags & IS_SC_MATCHALL) != IS_SC_MATCHALL) && - !(is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER))) { - /* - * Matching failed... - */ - j = isc->ipsc_else; - ipsc_stat.iscs_else++; - } - - switch (j) - { - case ISC_A_CLOSE : - /* - * If as a result of a successful match we are to - * close a connection, change the "keep state" info. - * to block packets and generate TCP RST's. - */ - is->is_pass &= ~FR_RETICMP; - is->is_pass |= FR_RETRST; - break; - default : - break; - } - - return i; -} - - -/* - * check if a packet matches what we're scanning for - */ -int ipsc_packet(fin, is) -fr_info_t *fin; -ipstate_t *is; -{ - int i, j, rv, dlen, off, thoff; - u_32_t seq, s0; - tcphdr_t *tcp; - - rv = !IP6_EQ(&fin->fin_fi.fi_src, &is->is_src); - tcp = fin->fin_dp; - seq = ntohl(tcp->th_seq); - - if (!is->is_s0[rv]) - return 1; - - /* - * check if this packet has more data that falls within the first - * 16 bytes sent in either direction. - */ - s0 = is->is_s0[rv]; - off = seq - s0; - if ((off > 15) || (off < 0)) - return 1; - thoff = TCP_OFF(tcp) << 2; - dlen = fin->fin_dlen - thoff; - if (dlen <= 0) - return 1; - if (dlen > 16) - dlen = 16; - if (off + dlen > 16) - dlen = 16 - off; - - j = 0xffff >> (16 - dlen); - i = (0xffff & j) << off; -#ifdef _KERNEL - COPYDATA(*(mb_t **)fin->fin_mp, fin->fin_hlen + thoff, dlen, - (caddr_t)is->is_sbuf[rv] + off); -#endif - is->is_smsk[rv] |= i; - for (j = 0, i = is->is_smsk[rv]; i & 1; i >>= 1) - j++; - if (j == 0) - return 1; - - (void) ipsc_match(is); -#if 0 - /* - * There is the potential here for plain text passwords to get - * buffered and stored for some time... - */ - if (!(is->is_flags & IS_SC_CLIENT)) - bzero(is->is_sbuf[0], sizeof(is->is_sbuf[0])); - if (!(is->is_flags & IS_SC_SERVER)) - bzero(is->is_sbuf[1], sizeof(is->is_sbuf[1])); -#endif - return 0; -} - - -int fr_scan_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - ipscanstat_t ipscs; - int err = 0; - - switch (cmd) - { - case SIOCADSCA : - err = ipsc_add(data); - break; - case SIOCRMSCA : - err = ipsc_delete(data); - break; - case SIOCGSCST : - bcopy((char *)&ipsc_stat, (char *)&ipscs, sizeof(ipscs)); - ipscs.iscs_list = ipsc_list; - BCOPYOUT(&ipscs, data, sizeof(ipscs)); - break; - default : - err = EINVAL; - break; - } - - return err; -} -#endif /* IPFILTER_SCAN */ diff --git a/contrib/ipfilter/ip_scan.h b/contrib/ipfilter/ip_scan.h deleted file mode 100644 index de98f9cd6b79..000000000000 --- a/contrib/ipfilter/ip_scan.h +++ /dev/null @@ -1,108 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_fil.h 1.35 6/5/96 - * Id: ip_scan.h,v 2.9 2003/07/25 22:05:01 darrenr Exp - */ - -#ifndef __IP_SCAN_H__ -#define __IP_SCAN_H__ 1 - -#ifdef sun -# include -#endif - -#define IPSCAN_NAME "/dev/ipscan" -#define IPL_SCAN IPSCAN_NAME -#define ISC_TLEN 16 - - -struct fr_info; -struct frentry; -struct ip; -struct ipstate; - - -#if defined(__STDC__) || defined(__GNUC__) -# define SIOCADSCA _IOWR('r', 60, struct ipscan *) -# define SIOCRMSCA _IOWR('r', 61, struct ipscan *) -# define SIOCGSCST _IOWR('r', 62, struct ipscan *) -#else -# define SIOCADSCA _IOWR(r, 60, struct ipscan *) -# define SIOCRMSCA _IOWR(r, 61, struct ipscan *) -# define SIOCGSCST _IOWR(r, 62, struct ipscan *) -#endif - -struct action { - int act_val; /* what to do */ - struct in_addr act_ip; /* redirect IP# */ - u_short act_port; /* redirect port number */ - int act_else; /* what to do */ - struct in_addr act_eip; /* redirect IP# */ - u_short act_eport; /* redirect port number */ -}; - - -typedef struct sinfo { - char s_txt[ISC_TLEN]; /* text to match */ - char s_msk[ISC_TLEN]; /* mask of the above to check */ - int s_len; /* length of server text */ -} sinfo_t; - - -typedef struct ipscan { - struct ipscan *ipsc_next; - struct ipscan **ipsc_pnext; - char ipsc_tag[ISC_TLEN]; /* table entry protocol tag */ - sinfo_t ipsc_si[2]; /* client/server side information */ - int ipsc_hits; /* times this has been matched */ - int ipsc_active; /* # of active matches */ - int ipsc_fref; /* # of references from filter rules */ - int ipsc_sref; /* # of references from state entries */ - struct action ipsc_act; -} ipscan_t; - - -#define ipsc_cl ipsc_si[0] -#define ipsc_sl ipsc_si[1] -#define ipsc_ctxt ipsc_cl.s_txt -#define ipsc_cmsk ipsc_cl.s_msk -#define ipsc_clen ipsc_cl.s_len -#define ipsc_stxt ipsc_sl.s_txt -#define ipsc_smsk ipsc_sl.s_msk -#define ipsc_slen ipsc_sl.s_len -#define ipsc_action ipsc_act.act_val -#define ipsc_ip ipsc_act.act_ip -#define ipsc_port ipsc_act.act_port -#define ipsc_else ipsc_act.act_else -#define ipsc_eip ipsc_act.act_eip -#define ipsc_eport ipsc_act.act_eport - -#define ISC_A_NONE 0 -#define ISC_A_TRACK 1 -#define ISC_A_CLOSE 2 -#define ISC_A_REDIRECT 3 - - -typedef struct ipscanstat { - struct ipscan *iscs_list; - u_long iscs_acted; - u_long iscs_else; - int iscs_entries; -} ipscanstat_t; - - -extern int fr_scan_ioctl __P((caddr_t, ioctlcmd_t, int)); -extern int ipsc_init __P((void)); -extern int ipsc_attachis __P((struct ipstate *)); -extern int ipsc_attachfr __P((struct frentry *)); -extern int ipsc_detachis __P((struct ipstate *)); -extern int ipsc_detachfr __P((struct frentry *)); -extern int ipsc_packet __P((struct fr_info *, struct ipstate *)); -extern void fr_scanunload __P((void)); - -#endif /* __IP_SCAN_H__ */ diff --git a/contrib/ipfilter/ip_sfil.c b/contrib/ipfilter/ip_sfil.c deleted file mode 100644 index 9e995d9b85c8..000000000000 --- a/contrib/ipfilter/ip_sfil.c +++ /dev/null @@ -1,991 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * I hate legaleese, don't you ? - */ -#if !defined(lint) -static const char sccsid[] = "%W% %G% (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_sfil.c,v 2.23.2.27 2003/06/12 16:03:14 darrenr Exp $"; -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#ifdef USE_INET6 -# include -#endif -#include "ip_fil.h" -#include "ip_state.h" -#include "ip_nat.h" -#include "ip_frag.h" -#include "ip_auth.h" -#include "ip_proxy.h" -#include -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - - -extern fr_flags, fr_active; - -int fr_running = 0; -int ipl_unreach = ICMP_UNREACH_HOST; -u_long ipl_frouteok[2] = {0, 0}; -static int frzerostats __P((caddr_t)); -#if SOLARIS2 >= 7 -static u_int *ip_ttl_ptr; -static u_int *ip_mtudisc; -#else -static u_long *ip_ttl_ptr; -static u_long *ip_mtudisc; -#endif - -static int frrequest __P((minor_t, int, caddr_t, int)); -static int send_ip __P((fr_info_t *fin, mblk_t *m)); -kmutex_t ipl_mutex, ipf_authmx, ipf_rw; -KRWLOCK_T ipf_mutex, ipfs_mutex, ipf_solaris; -KRWLOCK_T ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; -kcondvar_t iplwait, ipfauthwait; - - -int ipldetach() -{ - int i; - -#ifdef IPFDEBUG - cmn_err(CE_CONT, "ipldetach()\n"); -#endif -#ifdef IPFILTER_LOG - for (i = IPL_LOGMAX; i >= 0; i--) - ipflog_clear(i); -#endif - i = frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE|FR_INACTIVE); - i += frflush(IPL_LOGIPF, 0, FR_INQUE|FR_OUTQUE); - ipfr_unload(); - fr_stateunload(); - ip_natunload(); - cv_destroy(&iplwait); - cv_destroy(&ipfauthwait); - mutex_destroy(&ipf_authmx); - mutex_destroy(&ipl_mutex); - mutex_destroy(&ipf_rw); - RW_DESTROY(&ipf_mutex); - RW_DESTROY(&ipf_frag); - RW_DESTROY(&ipf_state); - RW_DESTROY(&ipf_natfrag); - RW_DESTROY(&ipf_nat); - RW_DESTROY(&ipf_auth); - RW_DESTROY(&ipfs_mutex); - /* NOTE: This lock is acquired in ipf_detach */ - RWLOCK_EXIT(&ipf_solaris); - RW_DESTROY(&ipf_solaris); - return 0; -} - - -int iplattach __P((void)) -{ - int i; - -#ifdef IPFDEBUG - cmn_err(CE_CONT, "iplattach()\n"); -#endif - bzero((char *)frcache, sizeof(frcache)); - mutex_init(&ipf_rw, "ipf rw mutex", MUTEX_DRIVER, NULL); - mutex_init(&ipl_mutex, "ipf log mutex", MUTEX_DRIVER, NULL); - mutex_init(&ipf_authmx, "ipf auth log mutex", MUTEX_DRIVER, NULL); - RWLOCK_INIT(&ipf_solaris, "ipf filter load/unload mutex", NULL); - RWLOCK_INIT(&ipf_mutex, "ipf filter rwlock", NULL); - RWLOCK_INIT(&ipfs_mutex, "ipf solaris mutex", NULL); - RWLOCK_INIT(&ipf_frag, "ipf fragment rwlock", NULL); - RWLOCK_INIT(&ipf_state, "ipf IP state rwlock", NULL); - RWLOCK_INIT(&ipf_nat, "ipf IP NAT rwlock", NULL); - RWLOCK_INIT(&ipf_natfrag, "ipf IP NAT-Frag rwlock", NULL); - RWLOCK_INIT(&ipf_auth, "ipf IP User-Auth rwlock", NULL); - cv_init(&iplwait, "ipl condvar", CV_DRIVER, NULL); - cv_init(&ipfauthwait, "ipf auth condvar", CV_DRIVER, NULL); -#ifdef IPFILTER_LOG - ipflog_init(); -#endif - if (nat_init() == -1) - return -1; - if (fr_stateinit() == -1) - return -1; - if (appr_init() == -1) - return -1; - - ip_ttl_ptr = NULL; - ip_mtudisc = NULL; - /* - * XXX - There is no terminator for this array, so it is not possible - * to tell if what we are looking for is missing and go off the end - * of the array. - */ - for (i = 0; ; i++) { - if (strcmp(ip_param_arr[i].ip_param_name, "ip_def_ttl") == 0) { - ip_ttl_ptr = &ip_param_arr[i].ip_param_value; - } else if (strcmp(ip_param_arr[i].ip_param_name, - "ip_path_mtu_discovery") == 0) { - ip_mtudisc = &ip_param_arr[i].ip_param_value; - } - - if (ip_mtudisc != NULL && ip_ttl_ptr != NULL) - break; - } - return 0; -} - - -static int frzerostats(data) -caddr_t data; -{ - friostat_t fio; - int error; - - fr_getstat(&fio); - error = IWCOPYPTR((caddr_t)&fio, data, sizeof(fio)); - if (error) - return error; - - bzero((char *)frstats, sizeof(*frstats) * 2); - - return 0; -} - - -/* - * Filter ioctl interface. - */ -int iplioctl(dev, cmd, data, mode, cp, rp) -dev_t dev; -int cmd; -#if SOLARIS2 >= 7 -intptr_t data; -#else -int *data; -#endif -int mode; -cred_t *cp; -int *rp; -{ - int error = 0, tmp; - minor_t unit; - -#ifdef IPFDEBUG - cmn_err(CE_CONT, "iplioctl(%x,%x,%x,%d,%x,%d)\n", - dev, cmd, data, mode, cp, rp); -#endif - unit = getminor(dev); - if (IPL_LOGMAX < unit) - return ENXIO; - - if (fr_running == 0 && (cmd != SIOCFRENB || unit != IPL_LOGIPF)) - return ENODEV; - - if (fr_running <= 0) - return 0; - - READ_ENTER(&ipf_solaris); - if (unit == IPL_LOGNAT) { - error = nat_ioctl((caddr_t)data, cmd, mode); - RWLOCK_EXIT(&ipf_solaris); - return error; - } - if (unit == IPL_LOGSTATE) { - error = fr_state_ioctl((caddr_t)data, cmd, mode); - RWLOCK_EXIT(&ipf_solaris); - return error; - } - if (unit == IPL_LOGAUTH) { - if ((cmd == SIOCADAFR) || (cmd == SIOCRMAFR)) { - if (!(mode & FWRITE)) { - error = EPERM; - } else { - error = frrequest(unit, cmd, (caddr_t)data, - fr_active); - } - } else { - error = fr_auth_ioctl((caddr_t)data, mode, cmd); - } - RWLOCK_EXIT(&ipf_solaris); - return error; - } - - switch (cmd) { - case SIOCFRENB : - { - u_int enable; - - if (!(mode & FWRITE)) - error = EPERM; - else - error = IRCOPY((caddr_t)data, (caddr_t)&enable, - sizeof(enable)); - break; - } - case SIOCSETFF : - if (!(mode & FWRITE)) - error = EPERM; - else { - WRITE_ENTER(&ipf_mutex); - error = IRCOPY((caddr_t)data, (caddr_t)&fr_flags, - sizeof(fr_flags)); - RWLOCK_EXIT(&ipf_mutex); - } - break; - case SIOCGETFF : - error = IWCOPY((caddr_t)&fr_flags, (caddr_t)data, - sizeof(fr_flags)); - if (error) - error = EFAULT; - break; - case SIOCINAFR : - case SIOCRMAFR : - case SIOCADAFR : - case SIOCZRLST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, (caddr_t)data, fr_active); - break; - case SIOCINIFR : - case SIOCRMIFR : - case SIOCADIFR : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frrequest(unit, cmd, (caddr_t)data, - 1 - fr_active); - break; - case SIOCSWAPA : - if (!(mode & FWRITE)) - error = EPERM; - else { - WRITE_ENTER(&ipf_mutex); - bzero((char *)frcache, sizeof(frcache[0]) * 2); - error = IWCOPY((caddr_t)&fr_active, (caddr_t)data, - sizeof(fr_active)); - if (error) - error = EFAULT; - fr_active = 1 - fr_active; - RWLOCK_EXIT(&ipf_mutex); - } - break; - case SIOCGETFS : - { - friostat_t fio; - - READ_ENTER(&ipf_mutex); - fr_getstat(&fio); - RWLOCK_EXIT(&ipf_mutex); - error = IWCOPYPTR((caddr_t)&fio, (caddr_t)data, sizeof(fio)); - if (error) - error = EFAULT; - break; - } - case SIOCFRZST : - if (!(mode & FWRITE)) - error = EPERM; - else - error = frzerostats((caddr_t)data); - break; - case SIOCIPFFL : - if (!(mode & FWRITE)) - error = EPERM; - else { - error = IRCOPY((caddr_t)data, (caddr_t)&tmp, - sizeof(tmp)); - if (!error) { - tmp = frflush(unit, 4, tmp); - error = IWCOPY((caddr_t)&tmp, (caddr_t)data, - sizeof(tmp)); - if (error) - error = EFAULT; - } - } - break; -#ifdef USE_INET6 - case SIOCIPFL6 : - if (!(mode & FWRITE)) - error = EPERM; - else { - error = IRCOPY((caddr_t)data, (caddr_t)&tmp, - sizeof(tmp)); - if (!error) { - tmp = frflush(unit, 6, tmp); - error = IWCOPY((caddr_t)&tmp, (caddr_t)data, - sizeof(tmp)); - if (error) - error = EFAULT; - } - } - break; -#endif - case SIOCSTLCK : - error = IRCOPY((caddr_t)data, (caddr_t)&tmp, sizeof(tmp)); - if (!error) { - fr_state_lock = tmp; - fr_nat_lock = tmp; - fr_frag_lock = tmp; - fr_auth_lock = tmp; - } else - error = EFAULT; - break; -#ifdef IPFILTER_LOG - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else { - tmp = ipflog_clear(unit); - error = IWCOPY((caddr_t)&tmp, (caddr_t)data, - sizeof(tmp)); - if (error) - error = EFAULT; - } - break; -#endif /* IPFILTER_LOG */ - case SIOCFRSYN : - if (!(mode & FWRITE)) - error = EPERM; - else - error = ipfsync(); - break; - case SIOCGFRST : - error = IWCOPYPTR((caddr_t)ipfr_fragstats(), (caddr_t)data, - sizeof(ipfrstat_t)); - break; - case FIONREAD : - { -#ifdef IPFILTER_LOG - int copy = (int)iplused[IPL_LOGIPF]; - - error = IWCOPY((caddr_t)©, (caddr_t)data, sizeof(copy)); - if (error) - error = EFAULT; -#endif - break; - } - default : - error = EINVAL; - break; - } - RWLOCK_EXIT(&ipf_solaris); - return error; -} - - -ill_t *get_unit(name, v) -char *name; -int v; -{ - size_t len = strlen(name) + 1; /* includes \0 */ - ill_t *il; -#if SOLARIS2 >= 10 - ill_walk_context_t ctx; -#endif - int sap; - - if (v == 4) - sap = 0x0800; - else if (v == 6) - sap = 0x86dd; - else - return NULL; -#if SOLARIS2 >= 10 - for (il = ILL_START_WALK_ALL(&ctx); il; il = ill_next(&ctx, il)) -#else - for (il = ill_g_head; il; il = il->ill_next) -#endif - if ((len == il->ill_name_length) && (il->ill_sap == sap) && - !strncmp(il->ill_name, name, len)) - return il; - return NULL; -} - - -static int frrequest(unit, req, data, set) -minor_t unit; -int req, set; -caddr_t data; -{ - register frentry_t *fp, *f, **fprev; - register frentry_t **ftail; - frgroup_t *fg = NULL; - int error = 0, in, i; - u_int *p, *pp; - frdest_t *fdp; - frentry_t fr; - u_32_t group; - ipif_t *ipif; - ill_t *ill; - ire_t *ire; - - fp = &fr; - error = IRCOPYPTR(data, (caddr_t)fp, sizeof(*fp)); - if (error) - return EFAULT; - fp->fr_ref = 0; -#if SOLARIS2 >= 8 - if (fp->fr_v == 4) - fp->fr_sap = IP_DL_SAP; - else if (fp->fr_v == 6) - fp->fr_sap = IP6_DL_SAP; - else - return EINVAL; -#else - fp->fr_sap = 0; -#endif - - WRITE_ENTER(&ipf_mutex); - /* - * Check that the group number does exist and that if a head group - * has been specified, doesn't exist. - */ - if ((req != SIOCZRLST) && ((req == SIOCINAFR) || (req == SIOCINIFR) || - (req == SIOCADAFR) || (req == SIOCADIFR)) && fp->fr_grhead && - fr_findgroup(fp->fr_grhead, fp->fr_flags, unit, set, NULL)) { - error = EEXIST; - goto out; - } - if ((req != SIOCZRLST) && fp->fr_group && - !fr_findgroup(fp->fr_group, fp->fr_flags, unit, set, NULL)) { - error = ESRCH; - goto out; - } - - in = (fp->fr_flags & FR_INQUE) ? 0 : 1; - - if (unit == IPL_LOGAUTH) - ftail = fprev = &ipauth; - else if ((fp->fr_flags & FR_ACCOUNT) && (fp->fr_v == 4)) - ftail = fprev = &ipacct[in][set]; - else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) && (fp->fr_v == 4)) - ftail = fprev = &ipfilter[in][set]; -#ifdef USE_INET6 - else if ((fp->fr_flags & FR_ACCOUNT) && (fp->fr_v == 6)) - ftail = fprev = &ipacct6[in][set]; - else if ((fp->fr_flags & (FR_OUTQUE|FR_INQUE)) && (fp->fr_v == 6)) - ftail = fprev = &ipfilter6[in][set]; -#endif - else { - error = ESRCH; - goto out; - } - - group = fp->fr_group; - if (group != 0) { - fg = fr_findgroup(group, fp->fr_flags, unit, set, NULL); - if (fg == NULL) { - error = ESRCH; - goto out; - } - ftail = fprev = fg->fg_start; - } - - bzero((char *)frcache, sizeof(frcache[0]) * 2); - - for (i = 0; i < 4; i++) { - if ((fp->fr_ifnames[i][1] == '\0') && - ((fp->fr_ifnames[i][0] == '-') || - (fp->fr_ifnames[i][0] == '*'))) { - fp->fr_ifas[i] = NULL; - } else if (*fp->fr_ifnames[i]) { - fp->fr_ifas[i] = GETUNIT(fp->fr_ifnames[i], fp->fr_v); - if (!fp->fr_ifas[i]) - fp->fr_ifas[i] = (void *)-1; - } - } - - fdp = &fp->fr_dif; - fdp->fd_mp = NULL; - fp->fr_flags &= ~FR_DUP; - if (*fdp->fd_ifname) { - ill = get_unit(fdp->fd_ifname, (int)fp->fr_v); - if (!ill) - ire = (ire_t *)-1; - else if ((ipif = ill->ill_ipif) && (fp->fr_v == 4)) { -#if SOLARIS2 > 5 - ire = ire_ctable_lookup(ipif->ipif_local_addr, 0, - IRE_LOCAL, NULL, NULL, - MATCH_IRE_TYPE); -#else - ire = ire_lookup_myaddr(ipif->ipif_local_addr); -#endif - if (!ire) - ire = (ire_t *)-1; - else - fp->fr_flags |= FR_DUP; - } -#ifdef USE_INET6 - else if ((ipif = ill->ill_ipif) && (fp->fr_v == 6)) { - ire = ire_ctable_lookup_v6(&ipif->ipif_v6lcl_addr, 0, - IRE_LOCAL, NULL, NULL, - MATCH_IRE_TYPE); - if (!ire) - ire = (ire_t *)-1; - else - fp->fr_flags |= FR_DUP; - } -#endif - fdp->fd_ifp = (struct ifnet *)ire; - } - - fdp = &fp->fr_tif; - fdp->fd_mp = NULL; - if (*fdp->fd_ifname) { - ill = get_unit(fdp->fd_ifname, (int)fp->fr_v); - if (!ill) - ire = (ire_t *)-1; - else if ((ipif = ill->ill_ipif) && (fp->fr_v == 4)) { -#if SOLARIS2 > 5 - ire = ire_ctable_lookup(ipif->ipif_local_addr, 0, - IRE_LOCAL, NULL, NULL, - MATCH_IRE_TYPE); -#else - ire = ire_lookup_myaddr(ipif->ipif_local_addr); -#endif - if (!ire) - ire = (ire_t *)-1; - } -#ifdef USE_INET6 - else if ((ipif = ill->ill_ipif) && (fp->fr_v == 6)) { - ire = ire_ctable_lookup_v6(&ipif->ipif_v6lcl_addr, 0, - IRE_LOCAL, NULL, NULL, - MATCH_IRE_TYPE); - if (!ire) - ire = (ire_t *)-1; - } -#endif - fdp->fd_ifp = (struct ifnet *)ire; - } - - /* - * Look for a matching filter rule, but don't include the next or - * interface pointer in the comparison (fr_next, fr_ifa). - */ - for (fp->fr_cksum = 0, p = (u_int *)&fp->fr_ip, pp = &fp->fr_cksum; - p < pp; p++) - fp->fr_cksum += *p; - - for (; (f = *ftail); ftail = &f->fr_next) - if ((fp->fr_cksum == f->fr_cksum) && - !bcmp((char *)&f->fr_ip, (char *)&fp->fr_ip, FR_CMPSIZ)) - break; - - /* - * If zero'ing statistics, copy current to caller and zero. - */ - if (req == SIOCZRLST) { - if (!f) { - error = ESRCH; - goto out; - } - MUTEX_DOWNGRADE(&ipf_mutex); - error = IWCOPYPTR((caddr_t)f, data, sizeof(*f)); - if (error) - goto out; - f->fr_hits = 0; - f->fr_bytes = 0; - goto out; - } - - if (!f) { - if (req != SIOCINAFR && req != SIOCINIFR) - while ((f = *ftail)) - ftail = &f->fr_next; - else { - ftail = fprev; - if (fp->fr_hits) { - while (--fp->fr_hits && (f = *ftail)) - ftail = &f->fr_next; - } - f = NULL; - } - } - - if (req == SIOCRMAFR || req == SIOCRMIFR) { - if (!f) - error = ESRCH; - else { - /* - * Only return EBUSY if there is a group list, else - * it's probably just state information referencing - * the rule. - */ - if ((f->fr_ref > 1) && f->fr_grp) { - error = EBUSY; - goto out; - } - if (fg && fg->fg_head) - fg->fg_head->fr_ref--; - if (unit == IPL_LOGAUTH) { - return fr_preauthcmd(req, f, ftail); - } - if (f->fr_grhead) - fr_delgroup(f->fr_grhead, fp->fr_flags, - unit, set); - fixskip(fprev, f, -1); - *ftail = f->fr_next; - f->fr_next = NULL; - f->fr_ref--; - if (f->fr_ref == 0) - KFREE(f); - } - } else { - if (f) { - error = EEXIST; - } else { - if (unit == IPL_LOGAUTH) { - return fr_preauthcmd(req, fp, ftail); - } - KMALLOC(f, frentry_t *); - if (f != NULL) { - if (fg && fg->fg_head) - fg->fg_head->fr_ref++; - bcopy((char *)fp, (char *)f, sizeof(*f)); - f->fr_ref = 1; - f->fr_hits = 0; - f->fr_next = *ftail; - *ftail = f; - if (req == SIOCINIFR || req == SIOCINAFR) - fixskip(fprev, f, 1); - f->fr_grp = NULL; - group = f->fr_grhead; - if (group != 0) - fg = fr_addgroup(group, f, unit, set); - } else - error = ENOMEM; - } - } -out: - RWLOCK_EXIT(&ipf_mutex); - return (error); -} - - -/* - * routines below for saving IP headers to buffer - */ -int iplopen(devp, flags, otype, cred) -dev_t *devp; -int flags, otype; -cred_t *cred; -{ - minor_t min = getminor(*devp); - -#ifdef IPFDEBUG - cmn_err(CE_CONT, "iplopen(%x,%x,%x,%x)\n", devp, flags, otype, cred); -#endif - if ((fr_running <= 0) || !(otype & OTYP_CHR)) - return ENXIO; - min = (IPL_LOGMAX < min) ? ENXIO : 0; - return min; -} - - -int iplclose(dev, flags, otype, cred) -dev_t dev; -int flags, otype; -cred_t *cred; -{ - minor_t min = getminor(dev); - -#ifdef IPFDEBUG - cmn_err(CE_CONT, "iplclose(%x,%x,%x,%x)\n", dev, flags, otype, cred); -#endif - min = (IPL_LOGMAX < min) ? ENXIO : 0; - return min; -} - -#ifdef IPFILTER_LOG -/* - * iplread/ipllog - * both of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -int iplread(dev, uio, cp) -dev_t dev; -register struct uio *uio; -cred_t *cp; -{ -#ifdef IPFDEBUG - cmn_err(CE_CONT, "iplread(%x,%x,%x)\n", dev, uio, cp); -#endif - return ipflog_read(getminor(dev), uio); -} -#endif /* IPFILTER_LOG */ - - -/* - * send_reset - this could conceivably be a call to tcp_respond(), but that - * requires a large amount of setting up and isn't any more efficient. - */ -int send_reset(oip, fin) -ip_t *oip; -fr_info_t *fin; -{ - tcphdr_t *tcp, *tcp2; - int tlen, hlen; - mblk_t *m; -#ifdef USE_INET6 - ip6_t *ip6, *oip6 = (ip6_t *)oip; -#endif - ip_t *ip; - - tcp = (struct tcphdr *)fin->fin_dp; - if (tcp->th_flags & TH_RST) - return -1; - tlen = (tcp->th_flags & (TH_SYN|TH_FIN)) ? 1 : 0; -#ifdef USE_INET6 - if (fin->fin_v == 6) - hlen = sizeof(ip6_t); - else -#endif - hlen = sizeof(ip_t); - hlen += sizeof(*tcp2); - if ((m = (mblk_t *)allocb(hlen + 16, BPRI_HI)) == NULL) - return -1; - - m->b_rptr += 16; - MTYPE(m) = M_DATA; - m->b_wptr = m->b_rptr + hlen; - bzero((char *)m->b_rptr, hlen); - tcp2 = (struct tcphdr *)(m->b_rptr + hlen - sizeof(*tcp2)); - tcp2->th_dport = tcp->th_sport; - tcp2->th_sport = tcp->th_dport; - if (tcp->th_flags & TH_ACK) { - tcp2->th_seq = tcp->th_ack; - tcp2->th_flags = TH_RST; - } else { - tcp2->th_ack = ntohl(tcp->th_seq); - tcp2->th_ack += tlen; - tcp2->th_ack = htonl(tcp2->th_ack); - tcp2->th_flags = TH_RST|TH_ACK; - } - tcp2->th_off = sizeof(struct tcphdr) >> 2; - - /* - * This is to get around a bug in the Solaris 2.4/2.5 TCP checksum - * computation that is done by their put routine. - */ - tcp2->th_sum = htons(0x14); -#ifdef USE_INET6 - if (fin->fin_v == 6) { - ip6 = (ip6_t *)m->b_rptr; - ip6->ip6_src = oip6->ip6_dst; - ip6->ip6_dst = oip6->ip6_src; - ip6->ip6_plen = htons(sizeof(*tcp)); - ip6->ip6_nxt = IPPROTO_TCP; - } else -#endif - { - ip = (ip_t *)m->b_rptr; - ip->ip_src.s_addr = oip->ip_dst.s_addr; - ip->ip_dst.s_addr = oip->ip_src.s_addr; - ip->ip_hl = sizeof(*ip) >> 2; - ip->ip_p = IPPROTO_TCP; - ip->ip_len = htons(sizeof(*ip) + sizeof(*tcp)); - ip->ip_tos = oip->ip_tos; - } - return send_ip(fin, m); -} - - -int static send_ip(fin, m) -fr_info_t *fin; -mblk_t *m; -{ - RWLOCK_EXIT(&ipfs_mutex); - RWLOCK_EXIT(&ipf_solaris); -#ifdef USE_INET6 - if (fin->fin_v == 6) { - extern void ip_wput_v6 __P((queue_t *, mblk_t *)); - ip6_t *ip6; - - ip6 = (ip6_t *)m->b_rptr; - ip6->ip6_flow = 0; - ip6->ip6_vfc = 0x60; - ip6->ip6_hlim = 127; - ip_wput_v6(((qif_t *)fin->fin_qif)->qf_ill->ill_wq, m); - } else -#endif - { - ip_t *ip; - - ip = (ip_t *)m->b_rptr; - ip->ip_v = IPVERSION; - ip->ip_ttl = (u_char)(*ip_ttl_ptr); - ip->ip_off = htons(*ip_mtudisc ? IP_DF : 0); - ip_wput(((qif_t *)fin->fin_qif)->qf_ill->ill_wq, m); - } - READ_ENTER(&ipf_solaris); - READ_ENTER(&ipfs_mutex); - return 0; -} - - -int send_icmp_err(oip, type, fin, dst) -ip_t *oip; -int type; -fr_info_t *fin; -int dst; -{ - struct in_addr dst4; - struct icmp *icmp; - mblk_t *m, *mb; - int hlen, code; - qif_t *qif; - u_short sz; - ill_t *il; -#ifdef USE_INET6 - ip6_t *ip6, *oip6; -#endif - ip_t *ip; - - if ((type < 0) || (type > ICMP_MAXTYPE)) - return -1; - - code = fin->fin_icode; -#ifdef USE_INET6 - if ((code < 0) || (code > sizeof(icmptoicmp6unreach)/sizeof(int))) - return -1; -#endif - - qif = fin->fin_qif; - m = fin->fin_qfm; - -#ifdef USE_INET6 - if (oip->ip_v == 6) { - oip6 = (ip6_t *)oip; - sz = sizeof(ip6_t); - sz += MIN(m->b_wptr - m->b_rptr, 512); - hlen = sizeof(ip6_t); - type = icmptoicmp6types[type]; - if (type == ICMP6_DST_UNREACH) - code = icmptoicmp6unreach[code]; - } else -#endif - { - if ((oip->ip_p == IPPROTO_ICMP) && - !(fin->fin_fi.fi_fl & FI_SHORT)) - switch (ntohs(fin->fin_data[0]) >> 8) - { - case ICMP_ECHO : - case ICMP_TSTAMP : - case ICMP_IREQ : - case ICMP_MASKREQ : - break; - default : - return 0; - } - - sz = sizeof(ip_t) * 2; - sz += 8; /* 64 bits of data */ - hlen = sz; - } - - sz += offsetof(struct icmp, icmp_ip); - if ((mb = (mblk_t *)allocb((size_t)sz + 16, BPRI_HI)) == NULL) - return -1; - MTYPE(mb) = M_DATA; - mb->b_rptr += 16; - mb->b_wptr = mb->b_rptr + sz; - bzero((char *)mb->b_rptr, (size_t)sz); - icmp = (struct icmp *)(mb->b_rptr + sizeof(*ip)); - icmp->icmp_type = type; - icmp->icmp_code = code; - icmp->icmp_cksum = 0; -#ifdef icmp_nextmtu - if (type == ICMP_UNREACH && (il = qif->qf_ill) && - fin->fin_icode == ICMP_UNREACH_NEEDFRAG) - icmp->icmp_nextmtu = htons(il->ill_max_frag); -#endif - -#ifdef USE_INET6 - if (oip->ip_v == 6) { - struct in6_addr dst6; - int csz; - - if (dst == 0) { - if (fr_ifpaddr(6, ((qif_t *)fin->fin_qif)->qf_ill, - (struct in_addr *)&dst6) == -1) - return -1; - } else - dst6 = oip6->ip6_dst; - - csz = sz; - sz -= sizeof(ip6_t); - ip6 = (ip6_t *)mb->b_rptr; - ip6->ip6_flow = 0; - ip6->ip6_vfc = 0x60; - ip6->ip6_hlim = 127; - ip6->ip6_plen = htons(sz); - ip6->ip6_nxt = IPPROTO_ICMPV6; - ip6->ip6_src = dst6; - ip6->ip6_dst = oip6->ip6_src; - sz -= offsetof(struct icmp, icmp_ip); - bcopy((char *)m->b_rptr, (char *)&icmp->icmp_ip, sz); - icmp->icmp_cksum = csz - sizeof(ip6_t); - } else -#endif - { - ip = (ip_t *)mb->b_rptr; - ip->ip_v = IPVERSION; - ip->ip_hl = (sizeof(*ip) >> 2); - ip->ip_p = IPPROTO_ICMP; - ip->ip_id = oip->ip_id; - ip->ip_sum = 0; - ip->ip_ttl = (u_char)(*ip_ttl_ptr); - ip->ip_tos = oip->ip_tos; - ip->ip_len = (u_short)htons(sz); - if (dst == 0) { - if (fr_ifpaddr(4, ((qif_t *)fin->fin_qif)->qf_ill, - &dst4) == -1) - return -1; - } else - dst4 = oip->ip_dst; - ip->ip_src = dst4; - ip->ip_dst = oip->ip_src; - bcopy((char *)oip, (char *)&icmp->icmp_ip, sizeof(*oip)); - bcopy((char *)oip + (oip->ip_hl << 2), - (char *)&icmp->icmp_ip + sizeof(*oip), 8); - icmp->icmp_cksum = ipf_cksum((u_short *)icmp, - sizeof(*icmp) + 8); - } - - /* - * Need to exit out of these so we don't recursively call rw_enter - * from fr_qout. - */ - return send_ip(fin, mb); -} diff --git a/contrib/ipfilter/ip_state.c b/contrib/ipfilter/ip_state.c deleted file mode 100644 index 4ced16d3460d..000000000000 --- a/contrib/ipfilter/ip_state.c +++ /dev/null @@ -1,3802 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1995-2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \ - defined(_KERNEL) -# include "opt_ipfilter_log.h" -#endif -#if defined(_KERNEL) && defined(__FreeBSD_version) && \ - (__FreeBSD_version >= 400000) && !defined(KLD_MODULE) -#include "opt_inet6.h" -#endif -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include -# include -# include -# define _KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include -# include -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#else -# include -#endif -#include -#if !defined(linux) -# include -#endif -#include -#if defined(_KERNEL) -# include -# if !defined(__SVR4) && !defined(__svr4__) -# include -# endif -#endif -#if defined(__SVR4) || defined(__svr4__) -# include -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif - -#include -#ifdef sun -# include -#endif -#include -#include -#include -#include -#include -#if !defined(linux) -# include -#endif -#if !defined(__hpux) && !defined(linux) -# include -#endif -#include -#include -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#ifdef IPFILTER_SYNC -#include "netinet/ip_sync.h" -#endif -#ifdef IPFILTER_SCAN -#include "netinet/ip_scan.h" -#endif -#ifdef USE_INET6 -#include -#endif -#if (__FreeBSD_version >= 300000) -# include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include -# include -# endif -#endif -/* END OF INCLUDES */ - - -#if !defined(lint) -static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)Id: ip_state.c,v 2.186.2.29 2005/03/28 10:47:54 darrenr Exp"; -#endif - -static ipstate_t **ips_table = NULL; -static u_long *ips_seed = NULL; -static int ips_num = 0; -static u_long ips_last_force_flush = 0; -ips_stat_t ips_stats; - -#ifdef USE_INET6 -static ipstate_t *fr_checkicmp6matchingstate __P((fr_info_t *)); -#endif -static ipstate_t *fr_matchsrcdst __P((fr_info_t *, ipstate_t *, i6addr_t *, - i6addr_t *, tcphdr_t *, u_32_t)); -static ipstate_t *fr_checkicmpmatchingstate __P((fr_info_t *)); -static int fr_state_flush __P((int, int)); -static ips_stat_t *fr_statetstats __P((void)); -static void fr_delstate __P((ipstate_t *, int)); -static int fr_state_remove __P((caddr_t)); -static void fr_ipsmove __P((ipstate_t *, u_int)); -static int fr_tcpstate __P((fr_info_t *, tcphdr_t *, ipstate_t *)); -static int fr_tcpoptions __P((fr_info_t *, tcphdr_t *, tcpdata_t *)); -static ipstate_t *fr_stclone __P((fr_info_t *, tcphdr_t *, ipstate_t *)); -static void fr_fixinisn __P((fr_info_t *, ipstate_t *)); -static void fr_fixoutisn __P((fr_info_t *, ipstate_t *)); -static void fr_checknewisn __P((fr_info_t *, ipstate_t *)); - -int fr_stputent __P((caddr_t)); -int fr_stgetent __P((caddr_t)); - -#define ONE_DAY IPF_TTLVAL(1 * 86400) /* 1 day */ -#define FIVE_DAYS (5 * ONE_DAY) -#define DOUBLE_HASH(x) (((x) + ips_seed[(x) % fr_statesize]) % fr_statesize) - -u_long fr_tcpidletimeout = FIVE_DAYS, - fr_tcpclosewait = IPF_TTLVAL(2 * TCP_MSL), - fr_tcplastack = IPF_TTLVAL(2 * TCP_MSL), - fr_tcptimeout = IPF_TTLVAL(2 * TCP_MSL), - fr_tcpclosed = IPF_TTLVAL(60), - fr_tcphalfclosed = IPF_TTLVAL(2 * 3600), /* 2 hours */ - fr_udptimeout = IPF_TTLVAL(120), - fr_udpacktimeout = IPF_TTLVAL(12), - fr_icmptimeout = IPF_TTLVAL(60), - fr_icmpacktimeout = IPF_TTLVAL(6), - fr_iptimeout = IPF_TTLVAL(60); -int fr_statemax = IPSTATE_MAX, - fr_statesize = IPSTATE_SIZE; -int fr_state_doflush = 0, - fr_state_lock = 0, - fr_state_maxbucket = 0, - fr_state_maxbucket_reset = 1, - fr_state_init = 0; -ipftq_t ips_tqtqb[IPF_TCP_NSTATES], - ips_udptq, - ips_udpacktq, - ips_iptq, - ips_icmptq, - ips_icmpacktq, - *ips_utqe = NULL; -#ifdef IPFILTER_LOG -int ipstate_logging = 1; -#else -int ipstate_logging = 0; -#endif -ipstate_t *ips_list = NULL; - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stateinit */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: Nil */ -/* */ -/* Initialise all the global variables used within the state code. */ -/* This action also includes initiailising locks. */ -/* ------------------------------------------------------------------------ */ -int fr_stateinit() -{ - int i; - - KMALLOCS(ips_table, ipstate_t **, fr_statesize * sizeof(ipstate_t *)); - if (ips_table == NULL) - return -1; - bzero((char *)ips_table, fr_statesize * sizeof(ipstate_t *)); - - KMALLOCS(ips_seed, u_long *, fr_statesize * sizeof(*ips_seed)); - if (ips_seed == NULL) - return -2; - for (i = 0; i < fr_statesize; i++) { - /* - * XXX - ips_seed[X] should be a random number of sorts. - */ -#if (__FreeBSD_version >= 400000) - ips_seed[i] = arc4random(); -#else - ips_seed[i] = ((u_long)ips_seed + i) * fr_statesize; - ips_seed[i] ^= 0xa5a55a5a; - ips_seed[i] *= (u_long)ips_seed; - ips_seed[i] ^= 0x5a5aa5a5; - ips_seed[i] *= fr_statemax; -#endif - } - - /* fill icmp reply type table */ - for (i = 0; i <= ICMP_MAXTYPE; i++) - icmpreplytype4[i] = -1; - icmpreplytype4[ICMP_ECHO] = ICMP_ECHOREPLY; - icmpreplytype4[ICMP_TSTAMP] = ICMP_TSTAMPREPLY; - icmpreplytype4[ICMP_IREQ] = ICMP_IREQREPLY; - icmpreplytype4[ICMP_MASKREQ] = ICMP_MASKREPLY; -#ifdef USE_INET6 - /* fill icmp reply type table */ - for (i = 0; i <= ICMP6_MAXTYPE; i++) - icmpreplytype6[i] = -1; - icmpreplytype6[ICMP6_ECHO_REQUEST] = ICMP6_ECHO_REPLY; - icmpreplytype6[ICMP6_MEMBERSHIP_QUERY] = ICMP6_MEMBERSHIP_REPORT; - icmpreplytype6[ICMP6_NI_QUERY] = ICMP6_NI_REPLY; - icmpreplytype6[ND_ROUTER_SOLICIT] = ND_ROUTER_ADVERT; - icmpreplytype6[ND_NEIGHBOR_SOLICIT] = ND_NEIGHBOR_ADVERT; -#endif - - KMALLOCS(ips_stats.iss_bucketlen, u_long *, - fr_statesize * sizeof(u_long)); - if (ips_stats.iss_bucketlen == NULL) - return -1; - bzero((char *)ips_stats.iss_bucketlen, fr_statesize * sizeof(u_long)); - - if (fr_state_maxbucket == 0) { - for (i = fr_statesize; i > 0; i >>= 1) - fr_state_maxbucket++; - fr_state_maxbucket *= 2; - } - - fr_sttab_init(ips_tqtqb); - ips_tqtqb[IPF_TCP_NSTATES - 1].ifq_next = &ips_udptq; - ips_udptq.ifq_ttl = (u_long)fr_udptimeout; - ips_udptq.ifq_ref = 1; - ips_udptq.ifq_head = NULL; - ips_udptq.ifq_tail = &ips_udptq.ifq_head; - MUTEX_INIT(&ips_udptq.ifq_lock, "ipftq udp tab"); - ips_udptq.ifq_next = &ips_udpacktq; - ips_udpacktq.ifq_ttl = (u_long)fr_udpacktimeout; - ips_udpacktq.ifq_ref = 1; - ips_udpacktq.ifq_head = NULL; - ips_udpacktq.ifq_tail = &ips_udpacktq.ifq_head; - MUTEX_INIT(&ips_udpacktq.ifq_lock, "ipftq udpack tab"); - ips_udpacktq.ifq_next = &ips_icmptq; - ips_icmptq.ifq_ttl = (u_long)fr_icmptimeout; - ips_icmptq.ifq_ref = 1; - ips_icmptq.ifq_head = NULL; - ips_icmptq.ifq_tail = &ips_icmptq.ifq_head; - MUTEX_INIT(&ips_icmptq.ifq_lock, "ipftq icmp tab"); - ips_icmptq.ifq_next = &ips_icmpacktq; - ips_icmpacktq.ifq_ttl = (u_long)fr_icmpacktimeout; - ips_icmpacktq.ifq_ref = 1; - ips_icmpacktq.ifq_head = NULL; - ips_icmpacktq.ifq_tail = &ips_icmpacktq.ifq_head; - MUTEX_INIT(&ips_icmpacktq.ifq_lock, "ipftq icmpack tab"); - ips_icmpacktq.ifq_next = &ips_iptq; - ips_iptq.ifq_ttl = (u_long)fr_iptimeout; - ips_iptq.ifq_ref = 1; - ips_iptq.ifq_head = NULL; - ips_iptq.ifq_tail = &ips_iptq.ifq_head; - MUTEX_INIT(&ips_iptq.ifq_lock, "ipftq ip tab"); - ips_iptq.ifq_next = NULL; - - RWLOCK_INIT(&ipf_state, "ipf IP state rwlock"); - MUTEX_INIT(&ipf_stinsert, "ipf state insert mutex"); - fr_state_init = 1; - - ips_last_force_flush = fr_ticks; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stateunload */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Release and destroy any resources acquired or initialised so that */ -/* IPFilter can be unloaded or re-initialised. */ -/* ------------------------------------------------------------------------ */ -void fr_stateunload() -{ - ipftq_t *ifq, *ifqnext; - ipstate_t *is; - - while ((is = ips_list) != NULL) - fr_delstate(is, 0); - - /* - * Proxy timeout queues are not cleaned here because although they - * exist on the state list, appr_unload is called after fr_stateunload - * and the proxies actually are responsible for them being created. - * Should the proxy timeouts have their own list? There's no real - * justification as this is the only complicationA - */ - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - if (((ifq->ifq_flags & IFQF_PROXY) == 0) && - (fr_deletetimeoutqueue(ifq) == 0)) - fr_freetimeoutqueue(ifq); - } - - ips_stats.iss_inuse = 0; - ips_num = 0; - - if (fr_state_init == 1) { - fr_sttab_destroy(ips_tqtqb); - MUTEX_DESTROY(&ips_udptq.ifq_lock); - MUTEX_DESTROY(&ips_icmptq.ifq_lock); - MUTEX_DESTROY(&ips_udpacktq.ifq_lock); - MUTEX_DESTROY(&ips_icmpacktq.ifq_lock); - MUTEX_DESTROY(&ips_iptq.ifq_lock); - } - - if (ips_table != NULL) { - KFREES(ips_table, fr_statesize * sizeof(*ips_table)); - ips_table = NULL; - } - - if (ips_seed != NULL) { - KFREES(ips_seed, fr_statesize * sizeof(*ips_seed)); - ips_seed = NULL; - } - - if (ips_stats.iss_bucketlen != NULL) { - KFREES(ips_stats.iss_bucketlen, fr_statesize * sizeof(u_long)); - ips_stats.iss_bucketlen = NULL; - } - - if (fr_state_maxbucket_reset == 1) - fr_state_maxbucket = 0; - - if (fr_state_init == 1) { - fr_state_init = 0; - RW_DESTROY(&ipf_state); - MUTEX_DESTROY(&ipf_stinsert); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_statetstats */ -/* Returns: ips_state_t* - pointer to state stats structure */ -/* Parameters: Nil */ -/* */ -/* Put all the current numbers and pointers into a single struct and return */ -/* a pointer to it. */ -/* ------------------------------------------------------------------------ */ -static ips_stat_t *fr_statetstats() -{ - ips_stats.iss_active = ips_num; - ips_stats.iss_statesize = fr_statesize; - ips_stats.iss_statemax = fr_statemax; - ips_stats.iss_table = ips_table; - ips_stats.iss_list = ips_list; - ips_stats.iss_ticks = fr_ticks; - return &ips_stats; -} - -/* ------------------------------------------------------------------------ */ -/* Function: fr_state_remove */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to state structure to delete from table */ -/* */ -/* Search for a state structure that matches the one passed, according to */ -/* the IP addresses and other protocol specific information. */ -/* ------------------------------------------------------------------------ */ -static int fr_state_remove(data) -caddr_t data; -{ - ipstate_t *sp, st; - int error; - - sp = &st; - error = fr_inobj(data, &st, IPFOBJ_IPSTATE); - if (error) - return EFAULT; - - WRITE_ENTER(&ipf_state); - for (sp = ips_list; sp; sp = sp->is_next) - if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) && - !bcmp((caddr_t)&sp->is_src, (caddr_t)&st.is_src, - sizeof(st.is_src)) && - !bcmp((caddr_t)&sp->is_dst, (caddr_t)&st.is_src, - sizeof(st.is_dst)) && - !bcmp((caddr_t)&sp->is_ps, (caddr_t)&st.is_ps, - sizeof(st.is_ps))) { - fr_delstate(sp, ISL_REMOVE); - RWLOCK_EXIT(&ipf_state); - return 0; - } - RWLOCK_EXIT(&ipf_state); - return ESRCH; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_state_ioctl */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* cmd(I) - ioctl command integer */ -/* mode(I) - file mode bits used with open */ -/* */ -/* Processes an ioctl call made to operate on the IP Filter state device. */ -/* ------------------------------------------------------------------------ */ -int fr_state_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - int arg, ret, error = 0; - - switch (cmd) - { - /* - * Delete an entry from the state table. - */ - case SIOCDELST : - error = fr_state_remove(data); - break; - /* - * Flush the state table - */ - case SIOCIPFFL : - BCOPYIN(data, (char *)&arg, sizeof(arg)); - if (arg == 0 || arg == 1) { - WRITE_ENTER(&ipf_state); - ret = fr_state_flush(arg, 4); - RWLOCK_EXIT(&ipf_state); - BCOPYOUT((char *)&ret, data, sizeof(ret)); - } else - error = EINVAL; - break; -#ifdef USE_INET6 - case SIOCIPFL6 : - BCOPYIN(data, (char *)&arg, sizeof(arg)); - if (arg == 0 || arg == 1) { - WRITE_ENTER(&ipf_state); - ret = fr_state_flush(arg, 6); - RWLOCK_EXIT(&ipf_state); - BCOPYOUT((char *)&ret, data, sizeof(ret)); - } else - error = EINVAL; - break; -#endif -#ifdef IPFILTER_LOG - /* - * Flush the state log. - */ - case SIOCIPFFB : - if (!(mode & FWRITE)) - error = EPERM; - else { - int tmp; - - tmp = ipflog_clear(IPL_LOGSTATE); - BCOPYOUT((char *)&tmp, data, sizeof(tmp)); - } - break; - /* - * Turn logging of state information on/off. - */ - case SIOCSETLG : - if (!(mode & FWRITE)) - error = EPERM; - else { - BCOPYIN((char *)data, (char *)&ipstate_logging, - sizeof(ipstate_logging)); - } - break; - /* - * Return the current state of logging. - */ - case SIOCGETLG : - BCOPYOUT((char *)&ipstate_logging, (char *)data, - sizeof(ipstate_logging)); - break; - /* - * Return the number of bytes currently waiting to be read. - */ - case FIONREAD : - arg = iplused[IPL_LOGSTATE]; /* returned in an int */ - BCOPYOUT((char *)&arg, data, sizeof(arg)); - break; -#endif - /* - * Get the current state statistics. - */ - case SIOCGETFS : - error = fr_outobj(data, fr_statetstats(), IPFOBJ_STATESTAT); - break; - /* - * Lock/Unlock the state table. (Locking prevents any changes, which - * means no packets match). - */ - case SIOCSTLCK : - fr_lock(data, &fr_state_lock); - break; - /* - * Add an entry to the current state table. - */ - case SIOCSTPUT : - if (!fr_state_lock) { - error = EACCES; - break; - } - error = fr_stputent(data); - break; - /* - * Get a state table entry. - */ - case SIOCSTGET : - if (!fr_state_lock) { - error = EACCES; - break; - } - error = fr_stgetent(data); - break; - default : - error = EINVAL; - break; - } - return error; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stgetent */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to state structure to retrieve from table */ -/* */ -/* Copy out state information from the kernel to a user space process. If */ -/* there is a filter rule associated with the state entry, copy that out */ -/* as well. The entry to copy out is taken from the value of "ips_next" in */ -/* the struct passed in and if not null and not found in the list of current*/ -/* state entries, the retrieval fails. */ -/* ------------------------------------------------------------------------ */ -int fr_stgetent(data) -caddr_t data; -{ - ipstate_t *is, *isn; - ipstate_save_t ips; - int error; - - error = fr_inobj(data, &ips, IPFOBJ_STATESAVE); - if (error) - return EFAULT; - - isn = ips.ips_next; - if (isn == NULL) { - isn = ips_list; - if (isn == NULL) { - if (ips.ips_next == NULL) - return ENOENT; - return 0; - } - } else { - /* - * Make sure the pointer we're copying from exists in the - * current list of entries. Security precaution to prevent - * copying of random kernel data. - */ - for (is = ips_list; is; is = is->is_next) - if (is == isn) - break; - if (!is) - return ESRCH; - } - ips.ips_next = isn->is_next; - bcopy((char *)isn, (char *)&ips.ips_is, sizeof(ips.ips_is)); - ips.ips_rule = isn->is_rule; - if (isn->is_rule != NULL) - bcopy((char *)isn->is_rule, (char *)&ips.ips_fr, - sizeof(ips.ips_fr)); - error = fr_outobj(data, &ips, IPFOBJ_STATESAVE); - if (error) - return EFAULT; - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stputent */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to state information struct */ -/* */ -/* This function implements the SIOCSTPUT ioctl: insert a state entry into */ -/* the state table. If the state info. includes a pointer to a filter rule */ -/* then also add in an orphaned rule (will not show up in any "ipfstat -io" */ -/* output. */ -/* ------------------------------------------------------------------------ */ -int fr_stputent(data) -caddr_t data; -{ - ipstate_t *is, *isn; - ipstate_save_t ips; - int error, out, i; - frentry_t *fr; - char *name; - - error = fr_inobj(data, &ips, IPFOBJ_STATESAVE); - if (error) - return EFAULT; - - KMALLOC(isn, ipstate_t *); - if (isn == NULL) - return ENOMEM; - - bcopy((char *)&ips.ips_is, (char *)isn, sizeof(*isn)); - bzero((char *)isn, offsetof(struct ipstate, is_pkts)); - isn->is_sti.tqe_pnext = NULL; - isn->is_sti.tqe_next = NULL; - isn->is_sti.tqe_ifq = NULL; - isn->is_sti.tqe_parent = isn; - isn->is_ifp[0] = NULL; - isn->is_ifp[1] = NULL; - isn->is_ifp[2] = NULL; - isn->is_ifp[3] = NULL; - isn->is_sync = NULL; - fr = ips.ips_rule; - - if (fr == NULL) { - READ_ENTER(&ipf_state); - fr_stinsert(isn, 0); - RWLOCK_EXIT(&ipf_state); - return 0; - } - - if (isn->is_flags & SI_NEWFR) { - KMALLOC(fr, frentry_t *); - if (fr == NULL) { - KFREE(isn); - return ENOMEM; - } - bcopy((char *)&ips.ips_fr, (char *)fr, sizeof(*fr)); - out = fr->fr_flags & FR_OUTQUE ? 1 : 0; - isn->is_rule = fr; - ips.ips_is.is_rule = fr; - MUTEX_NUKE(&fr->fr_lock); - MUTEX_INIT(&fr->fr_lock, "state filter rule lock"); - - /* - * Look up all the interface names in the rule. - */ - for (i = 0; i < 4; i++) { - name = fr->fr_ifnames[i]; - fr->fr_ifas[i] = fr_resolvenic(name, fr->fr_v); - name = isn->is_ifname[i]; - isn->is_ifp[i] = fr_resolvenic(name, isn->is_v); - } - - fr->fr_ref = 0; - fr->fr_dsize = 0; - fr->fr_data = NULL; - - fr_resolvedest(&fr->fr_tif, fr->fr_v); - fr_resolvedest(&fr->fr_dif, fr->fr_v); - - /* - * send a copy back to userland of what we ended up - * to allow for verification. - */ - error = fr_outobj(data, &ips, IPFOBJ_STATESAVE); - if (error) { - KFREE(isn); - MUTEX_DESTROY(&fr->fr_lock); - KFREE(fr); - return EFAULT; - } - READ_ENTER(&ipf_state); - fr_stinsert(isn, 0); - RWLOCK_EXIT(&ipf_state); - - } else { - READ_ENTER(&ipf_state); - for (is = ips_list; is; is = is->is_next) - if (is->is_rule == fr) { - fr_stinsert(isn, 0); - break; - } - - if (is == NULL) { - KFREE(isn); - isn = NULL; - } - RWLOCK_EXIT(&ipf_state); - - return (isn == NULL) ? ESRCH : 0; - } - - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stinsert */ -/* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure */ -/* rev(I) - flag indicating forward/reverse direction of packet */ -/* */ -/* Inserts a state structure into the hash table (for lookups) and the list */ -/* of state entries (for enumeration). Resolves all of the interface names */ -/* to pointers and adjusts running stats for the hash table as appropriate. */ -/* */ -/* Locking: it is assumed that some kind of lock on ipf_state is held. */ -/* ------------------------------------------------------------------------ */ -void fr_stinsert(is, rev) -ipstate_t *is; -int rev; -{ - frentry_t *fr; - u_int hv; - int i; - - MUTEX_INIT(&is->is_lock, "ipf state entry"); - - fr = is->is_rule; - if (fr != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - fr->fr_statecnt++; - MUTEX_EXIT(&fr->fr_lock); - } - - /* - * Look up all the interface names in the state entry. - */ - for (i = 0; i < 4; i++) { - if (is->is_ifp[i] != NULL) - continue; - is->is_ifp[i] = fr_resolvenic(is->is_ifname[i], is->is_v); - } - - /* - * If we could trust is_hv, then the modulous would not be needed, but - * when running with IPFILTER_SYNC, this stops bad values. - */ - hv = is->is_hv % fr_statesize; - is->is_hv = hv; - - /* - * We need to get both of these locks...the first because it is - * possible that once the insert is complete another packet might - * come along, match the entry and want to update it. - */ - MUTEX_ENTER(&is->is_lock); - MUTEX_ENTER(&ipf_stinsert); - - /* - * add into list table. - */ - if (ips_list != NULL) - ips_list->is_pnext = &is->is_next; - is->is_pnext = &ips_list; - is->is_next = ips_list; - ips_list = is; - - if (ips_table[hv] != NULL) - ips_table[hv]->is_phnext = &is->is_hnext; - else - ips_stats.iss_inuse++; - is->is_phnext = ips_table + hv; - is->is_hnext = ips_table[hv]; - ips_table[hv] = is; - ips_stats.iss_bucketlen[hv]++; - ips_num++; - MUTEX_EXIT(&ipf_stinsert); - - fr_setstatequeue(is, rev); - MUTEX_EXIT(&is->is_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_addstate */ -/* Returns: ipstate_t* - NULL == failure, else pointer to new state */ -/* Parameters: fin(I) - pointer to packet information */ -/* stsave(O) - pointer to place to save pointer to created */ -/* state structure. */ -/* flags(I) - flags to use when creating the structure */ -/* */ -/* Creates a new IP state structure from the packet information collected. */ -/* Inserts it into the state table and appends to the bottom of the active */ -/* list. If the capacity of the table has reached the maximum allowed then */ -/* the call will fail and a flush is scheduled for the next timeout call. */ -/* ------------------------------------------------------------------------ */ -ipstate_t *fr_addstate(fin, stsave, flags) -fr_info_t *fin; -ipstate_t **stsave; -u_int flags; -{ - ipstate_t *is, ips; - struct icmp *ic; - u_int pass, hv; - frentry_t *fr; - tcphdr_t *tcp; - grehdr_t *gre; - void *ifp; - int out; - - if (fr_state_lock || - (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD))) - return NULL; - - if ((fin->fin_flx & FI_OOW) && !(fin->fin_tcpf & TH_SYN)) - return NULL; - - fr = fin->fin_fr; - if ((fr->fr_statemax == 0) && (ips_num == fr_statemax)) { - ATOMIC_INCL(ips_stats.iss_max); - fr_state_doflush = 1; - return NULL; - } - - /* - * If a "keep state" rule has reached the maximum number of references - * to it, then schedule an automatic flush in case we can clear out - * some "dead old wood". - */ - if ((fr != NULL) && (fr->fr_statemax != 0) && - (fr->fr_statecnt >= fr->fr_statemax)) { - MUTEX_EXIT(&fr->fr_lock); - ATOMIC_INCL(ips_stats.iss_maxref); - fr_state_doflush = 1; - return NULL; - } - - pass = (fr == NULL) ? 0 : fr->fr_flags; - - ic = NULL; - tcp = NULL; - out = fin->fin_out; - is = &ips; - bzero((char *)is, sizeof(*is)); - is->is_die = 1 + fr_ticks; - - /* - * Copy and calculate... - */ - hv = (is->is_p = fin->fin_fi.fi_p); - is->is_src = fin->fin_fi.fi_src; - hv += is->is_saddr; - is->is_dst = fin->fin_fi.fi_dst; - hv += is->is_daddr; -#ifdef USE_INET6 - if (fin->fin_v == 6) { - /* - * For ICMPv6, we check to see if the destination address is - * a multicast address. If it is, do not include it in the - * calculation of the hash because the correct reply will come - * back from a real address, not a multicast address. - */ - if ((is->is_p == IPPROTO_ICMPV6) && - IN6_IS_ADDR_MULTICAST(&is->is_dst.in6)) { - /* - * So you can do keep state with neighbour discovery. - * - * Here we could use the address from the neighbour - * solicit message to put in the state structure and - * we could use that without a wildcard flag too... - */ - flags |= SI_W_DADDR; - hv -= is->is_daddr; - } else { - hv += is->is_dst.i6[1]; - hv += is->is_dst.i6[2]; - hv += is->is_dst.i6[3]; - } - hv += is->is_src.i6[1]; - hv += is->is_src.i6[2]; - hv += is->is_src.i6[3]; - } -#endif - - switch (is->is_p) - { -#ifdef USE_INET6 - case IPPROTO_ICMPV6 : - ic = fin->fin_dp; - - switch (ic->icmp_type) - { - case ICMP6_ECHO_REQUEST : - is->is_icmp.ici_type = ic->icmp_type; - hv += (is->is_icmp.ici_id = ic->icmp_id); - break; - case ICMP6_MEMBERSHIP_QUERY : - case ND_ROUTER_SOLICIT : - case ND_NEIGHBOR_SOLICIT : - case ICMP6_NI_QUERY : - is->is_icmp.ici_type = ic->icmp_type; - break; - default : - return NULL; - } - ATOMIC_INCL(ips_stats.iss_icmp); - break; -#endif - case IPPROTO_ICMP : - ic = fin->fin_dp; - - switch (ic->icmp_type) - { - case ICMP_ECHO : - case ICMP_TSTAMP : - case ICMP_IREQ : - case ICMP_MASKREQ : - is->is_icmp.ici_type = ic->icmp_type; - hv += (is->is_icmp.ici_id = ic->icmp_id); - break; - default : - return NULL; - } - ATOMIC_INCL(ips_stats.iss_icmp); - break; - - case IPPROTO_GRE : - gre = fin->fin_dp; - - is->is_gre.gs_flags = gre->gr_flags; - is->is_gre.gs_ptype = gre->gr_ptype; - if (GRE_REV(is->is_gre.gs_flags) == 1) { - is->is_call[0] = fin->fin_data[0]; - is->is_call[1] = fin->fin_data[1]; - } - break; - - case IPPROTO_TCP : - tcp = fin->fin_dp; - - if (tcp->th_flags & TH_RST) - return NULL; - /* - * The endian of the ports doesn't matter, but the ack and - * sequence numbers do as we do mathematics on them later. - */ - is->is_sport = htons(fin->fin_data[0]); - is->is_dport = htons(fin->fin_data[1]); - if ((flags & (SI_W_DPORT|SI_W_SPORT)) == 0) { - hv += is->is_sport; - hv += is->is_dport; - } - - /* - * If this is a real packet then initialise fields in the - * state information structure from the TCP header information. - */ - - is->is_maxdwin = 1; - is->is_maxswin = ntohs(tcp->th_win); - if (is->is_maxswin == 0) - is->is_maxswin = 1; - - if ((fin->fin_flx & FI_IGNORE) == 0) { - is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen - - (TCP_OFF(tcp) << 2) + - ((tcp->th_flags & TH_SYN) ? 1 : 0) + - ((tcp->th_flags & TH_FIN) ? 1 : 0); - is->is_maxsend = is->is_send; - - /* - * Window scale option is only present in - * SYN/SYN-ACK packet. - */ - if ((tcp->th_flags & ~(TH_FIN|TH_ACK|TH_ECNALL)) == - TH_SYN && - (TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) { - if (fr_tcpoptions(fin, tcp, - &is->is_tcp.ts_data[0])) - is->is_swinflags = TCP_WSCALE_SEEN| - TCP_WSCALE_FIRST; - } - - if ((fin->fin_out != 0) && (pass & FR_NEWISN) != 0) { - fr_checknewisn(fin, is); - fr_fixoutisn(fin, is); - } - - if ((tcp->th_flags & TH_OPENING) == TH_SYN) - flags |= IS_TCPFSM; - else { - is->is_maxdwin = is->is_maxswin * 2; - is->is_dend = ntohl(tcp->th_ack); - is->is_maxdend = ntohl(tcp->th_ack); - is->is_maxdwin *= 2; - } - } - - /* - * If we're creating state for a starting connection, start the - * timer on it as we'll never see an error if it fails to - * connect. - */ - ATOMIC_INCL(ips_stats.iss_tcp); - break; - - case IPPROTO_UDP : - tcp = fin->fin_dp; - - is->is_sport = htons(fin->fin_data[0]); - is->is_dport = htons(fin->fin_data[1]); - if ((flags & (SI_W_DPORT|SI_W_SPORT)) == 0) { - hv += tcp->th_dport; - hv += tcp->th_sport; - } - ATOMIC_INCL(ips_stats.iss_udp); - break; - - default : - break; - } - hv = DOUBLE_HASH(hv); - is->is_hv = hv; - is->is_rule = fr; - is->is_flags = flags & IS_INHERITED; - - /* - * Look for identical state. - */ - for (is = ips_table[is->is_hv % fr_statesize]; is != NULL; - is = is->is_hnext) { - if (bcmp(&ips.is_src, &is->is_src, - offsetof(struct ipstate, is_ps) - - offsetof(struct ipstate, is_src)) == 0) - break; - } - if (is != NULL) - return NULL; - - if (ips_stats.iss_bucketlen[hv] >= fr_state_maxbucket) { - ATOMIC_INCL(ips_stats.iss_bucketfull); - return NULL; - } - KMALLOC(is, ipstate_t *); - if (is == NULL) { - ATOMIC_INCL(ips_stats.iss_nomem); - return NULL; - } - bcopy((char *)&ips, (char *)is, sizeof(*is)); - /* - * Do not do the modulous here, it is done in fr_stinsert(). - */ - if (fr != NULL) { - (void) strncpy(is->is_group, fr->fr_group, FR_GROUPLEN); - if (fr->fr_age[0] != 0) { - is->is_tqehead[0] = fr_addtimeoutqueue(&ips_utqe, - fr->fr_age[0]); - is->is_sti.tqe_flags |= TQE_RULEBASED; - } - if (fr->fr_age[1] != 0) { - is->is_tqehead[1] = fr_addtimeoutqueue(&ips_utqe, - fr->fr_age[1]); - is->is_sti.tqe_flags |= TQE_RULEBASED; - } - - is->is_tag = fr->fr_logtag; - - is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1]; - is->is_ifp[(1 - out) << 1] = fr->fr_ifas[2]; - is->is_ifp[((1 - out) << 1) + 1] = fr->fr_ifas[3]; - - if (((ifp = fr->fr_ifas[1]) != NULL) && - (ifp != (void *)-1)) { - COPYIFNAME(ifp, is->is_ifname[(out << 1) + 1]); - } - if (((ifp = fr->fr_ifas[2]) != NULL) && - (ifp != (void *)-1)) { - COPYIFNAME(ifp, is->is_ifname[(1 - out) << 1]); - } - if (((ifp = fr->fr_ifas[3]) != NULL) && - (ifp != (void *)-1)) { - COPYIFNAME(ifp, is->is_ifname[((1 - out) << 1) + 1]); - } - } else { - pass = fr_flags; - is->is_tag = FR_NOLOGTAG; - } - - is->is_ifp[out << 1] = fin->fin_ifp; - if (fin->fin_ifp != NULL) { - COPYIFNAME(fin->fin_ifp, is->is_ifname[out << 1]); - } - - /* - * It may seem strange to set is_ref to 2, but fr_check() will call - * fr_statederef() after calling fr_addstate() and the idea is to - * have it exist at the end of fr_check() with is_ref == 1. - */ - is->is_ref = 2; - is->is_pass = pass; - is->is_pkts[0] = 0, is->is_bytes[0] = 0; - is->is_pkts[1] = 0, is->is_bytes[1] = 0; - is->is_pkts[2] = 0, is->is_bytes[2] = 0; - is->is_pkts[3] = 0, is->is_bytes[3] = 0; - if ((fin->fin_flx & FI_IGNORE) == 0) { - is->is_pkts[out] = 1; - is->is_bytes[out] = fin->fin_plen; - is->is_flx[out][0] = fin->fin_flx & FI_CMP; - is->is_flx[out][0] &= ~FI_OOW; - } - - if (pass & FR_STSTRICT) - is->is_flags |= IS_STRICT; - - if (pass & FR_STATESYNC) - is->is_flags |= IS_STATESYNC; - - /* - * We want to check everything that is a property of this packet, - * but we don't (automatically) care about it's fragment status as - * this may change. - */ - is->is_v = fin->fin_v; - is->is_opt = fin->fin_optmsk; - is->is_optmsk = 0xffffffff; - is->is_sec = fin->fin_secmsk; - is->is_secmsk = 0xffff; - is->is_auth = fin->fin_auth; - is->is_authmsk = 0xffff; - if (flags & (SI_WILDP|SI_WILDA)) { - ATOMIC_INCL(ips_stats.iss_wild); - } - is->is_rulen = fin->fin_rule; - - - if (pass & FR_LOGFIRST) - is->is_pass &= ~(FR_LOGFIRST|FR_LOG); - - READ_ENTER(&ipf_state); - is->is_me = stsave; - - fr_stinsert(is, fin->fin_rev); - - if (fin->fin_p == IPPROTO_TCP) { - /* - * If we're creating state for a starting connection, start the - * timer on it as we'll never see an error if it fails to - * connect. - */ - MUTEX_ENTER(&is->is_lock); - (void) fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags); - MUTEX_EXIT(&is->is_lock); -#ifdef IPFILTER_SCAN - if ((is->is_flags & SI_CLONE) == 0) - (void) ipsc_attachis(is); -#endif - } -#ifdef IPFILTER_SYNC - if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0)) - is->is_sync = ipfsync_new(SMC_STATE, fin, is); -#endif - if (ipstate_logging) - ipstate_log(is, ISL_NEW); - - RWLOCK_EXIT(&ipf_state); - fin->fin_state = is; - fin->fin_rev = IP6_NEQ(&is->is_dst, &fin->fin_daddr); - fin->fin_flx |= FI_STATE; - if (fin->fin_flx & FI_FRAG) - (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE); - - return is; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_tcpoptions */ -/* Returns: int - 1 == packet matches state entry, 0 == it does not */ -/* Parameters: fin(I) - pointer to packet information */ -/* tcp(I) - pointer to TCP packet header */ -/* td(I) - pointer to TCP data held as part of the state */ -/* */ -/* Look after the TCP header for any options and deal with those that are */ -/* present. Record details about those that we recogise. */ -/* ------------------------------------------------------------------------ */ -static int fr_tcpoptions(fin, tcp, td) -fr_info_t *fin; -tcphdr_t *tcp; -tcpdata_t *td; -{ - int off, mlen, ol, i, len, retval; - char buf[64], *s, opt; - mb_t *m = NULL; - - off = fin->fin_hlen + sizeof(*tcp); - len = (TCP_OFF(tcp) << 2) - sizeof(*tcp); - if (fin->fin_plen < off + len) - return 0; - - m = fin->fin_m; - off += fin->fin_ipoff; - mlen = MSGDSIZE(m) - off; - if (len > mlen) { - len = mlen; - retval = 0; - } else { - retval = 1; - } - - COPYDATA(m, off, len, buf); - - for (s = buf; len > 0; ) { - opt = *s; - if (opt == TCPOPT_EOL) - break; - else if (opt == TCPOPT_NOP) - ol = 1; - else { - if (len < 2) - break; - ol = (int)*(s + 1); - if (ol < 2 || ol > len) - break; - - /* - * Extract the TCP options we are interested in out of - * the header and store them in the the tcpdata struct. - */ - switch (opt) - { - case TCPOPT_WINDOW : - if (ol == TCPOLEN_WINDOW) { - i = (int)*(s + 2); - if (i > TCP_WSCALE_MAX) - i = TCP_WSCALE_MAX; - else if (i < 0) - i = 0; - td->td_winscale = i; - } - break; - case TCPOPT_MAXSEG : - /* - * So, if we wanted to set the TCP MAXSEG, - * it should be done here... - */ - if (ol == TCPOLEN_MAXSEG) { - i = (int)*(s + 2); - i <<= 8; - i += (int)*(s + 3); - td->td_maxseg = i; - } - break; - } - } - len -= ol; - s += ol; - } - return retval; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_tcpstate */ -/* Returns: int - 1 == packet matches state entry, 0 == it does not */ -/* Parameters: fin(I) - pointer to packet information */ -/* tcp(I) - pointer to TCP packet header */ -/* is(I) - pointer to master state structure */ -/* */ -/* Check to see if a packet with TCP headers fits within the TCP window. */ -/* Change timeout depending on whether new packet is a SYN-ACK returning */ -/* for a SYN or a RST or FIN which indicate time to close up shop. */ -/* ------------------------------------------------------------------------ */ -static int fr_tcpstate(fin, tcp, is) -fr_info_t *fin; -tcphdr_t *tcp; -ipstate_t *is; -{ - int source, ret = 0, flags; - tcpdata_t *fdata, *tdata; - - source = !fin->fin_rev; - if (((is->is_flags & IS_TCPFSM) != 0) && (source == 1) && - (ntohs(is->is_sport) != fin->fin_data[0])) - source = 0; - fdata = &is->is_tcp.ts_data[!source]; - tdata = &is->is_tcp.ts_data[source]; - - MUTEX_ENTER(&is->is_lock); - if (fr_tcpinwindow(fin, fdata, tdata, tcp, is->is_flags)) { -#ifdef IPFILTER_SCAN - if (is->is_flags & (IS_SC_CLIENT|IS_SC_SERVER)) { - ipsc_packet(fin, is); - if (FR_ISBLOCK(is->is_pass)) { - MUTEX_EXIT(&is->is_lock); - return 1; - } - } -#endif - - /* - * Nearing end of connection, start timeout. - */ - ret = fr_tcp_age(&is->is_sti, fin, ips_tqtqb, is->is_flags); - if (ret == 0) { - MUTEX_EXIT(&is->is_lock); - return 0; - } - - /* - * set s0's as appropriate. Use syn-ack packet as it - * contains both pieces of required information. - */ - /* - * Window scale option is only present in SYN/SYN-ACK packet. - * Compare with ~TH_FIN to mask out T/TCP setups. - */ - flags = tcp->th_flags & ~(TH_FIN|TH_ECNALL); - if (flags == (TH_SYN|TH_ACK)) { - is->is_s0[source] = ntohl(tcp->th_ack); - is->is_s0[!source] = ntohl(tcp->th_seq) + 1; - if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2)) && - tdata->td_winscale) { - if (fr_tcpoptions(fin, tcp, fdata)) { - fdata->td_winflags = TCP_WSCALE_SEEN| - TCP_WSCALE_FIRST; - } else { - if (!fdata->td_winscale) - tdata->td_winscale = 0; - } - } - if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN)) - fr_checknewisn(fin, is); - } else if (flags == TH_SYN) { - is->is_s0[source] = ntohl(tcp->th_seq) + 1; - if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2))) - if (fr_tcpoptions(fin, tcp, tdata)) { - tdata->td_winflags = TCP_WSCALE_SEEN| - TCP_WSCALE_FIRST; - } - - if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN)) - fr_checknewisn(fin, is); - - } - ret = 1; - } else - fin->fin_flx |= FI_OOW; - MUTEX_EXIT(&is->is_lock); - return ret; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checknewisn */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to master state structure */ -/* */ -/* Check to see if this TCP connection is expecting and needs a new */ -/* sequence number for a particular direction of the connection. */ -/* */ -/* NOTE: This does not actually change the sequence numbers, only gets new */ -/* one ready. */ -/* ------------------------------------------------------------------------ */ -static void fr_checknewisn(fin, is) -fr_info_t *fin; -ipstate_t *is; -{ - u_32_t sumd, old, new; - tcphdr_t *tcp; - int i; - - i = fin->fin_rev; - tcp = fin->fin_dp; - - if (((i == 0) && !(is->is_flags & IS_ISNSYN)) || - ((i == 1) && !(is->is_flags & IS_ISNACK))) { - old = ntohl(tcp->th_seq); - new = fr_newisn(fin); - is->is_isninc[i] = new - old; - CALC_SUMD(old, new, sumd); - is->is_sumd[i] = (sumd & 0xffff) + (sumd >> 16); - - is->is_flags |= ((i == 0) ? IS_ISNSYN : IS_ISNACK); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_tcpinwindow */ -/* Returns: int - 1 == packet inside TCP "window", 0 == not inside. */ -/* Parameters: fin(I) - pointer to packet information */ -/* fdata(I) - pointer to tcp state informatio (forward) */ -/* tdata(I) - pointer to tcp state informatio (reverse) */ -/* tcp(I) - pointer to TCP packet header */ -/* */ -/* Given a packet has matched addresses and ports, check to see if it is */ -/* within the TCP data window. In a show of generosity, allow packets that */ -/* are within the window space behind the current sequence # as well. */ -/* ------------------------------------------------------------------------ */ -int fr_tcpinwindow(fin, fdata, tdata, tcp, flags) -fr_info_t *fin; -tcpdata_t *fdata, *tdata; -tcphdr_t *tcp; -int flags; -{ - tcp_seq seq, ack, end; - int ackskew, tcpflags; - u_32_t win, maxwin; - - /* - * Find difference between last checked packet and this packet. - */ - tcpflags = tcp->th_flags; - seq = ntohl(tcp->th_seq); - ack = ntohl(tcp->th_ack); - if (tcpflags & TH_SYN) - win = ntohs(tcp->th_win); - else - win = ntohs(tcp->th_win) << fdata->td_winscale; - if (win == 0) - win = 1; - - /* - * if window scaling is present, the scaling is only allowed - * for windows not in the first SYN packet. In that packet the - * window is 65535 to specify the largest window possible - * for receivers not implementing the window scale option. - * Currently, we do not assume TTCP here. That means that - * if we see a second packet from a host (after the initial - * SYN), we can assume that the receiver of the SYN did - * already send back the SYN/ACK (and thus that we know if - * the receiver also does window scaling) - */ - if (!(tcpflags & TH_SYN) && (fdata->td_winflags & TCP_WSCALE_FIRST)) { - if (tdata->td_winflags & TCP_WSCALE_SEEN) { - fdata->td_winflags &= ~TCP_WSCALE_FIRST; - fdata->td_maxwin = win; - } else { - fdata->td_winscale = 0; - fdata->td_winflags = 0; - tdata->td_winscale = 0; - tdata->td_winflags = 0; - } - } - - end = seq + fin->fin_dlen - (TCP_OFF(tcp) << 2) + - ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0); - - if ((fdata->td_end == 0) && - (!(flags & IS_TCPFSM) || - ((tcpflags & TH_OPENING) == TH_OPENING))) { - /* - * Must be a (outgoing) SYN-ACK in reply to a SYN. - */ - fdata->td_end = end; - fdata->td_maxwin = 1; - fdata->td_maxend = end + win; - } - - if (!(tcpflags & TH_ACK)) { /* Pretend an ack was sent */ - ack = tdata->td_end; - } else if (((tcpflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) && - (ack == 0)) { - /* gross hack to get around certain broken tcp stacks */ - ack = tdata->td_end; - } - - if (seq == end) - seq = end = fdata->td_end; - - maxwin = tdata->td_maxwin; - ackskew = tdata->td_end - ack; - - /* - * Strict sequencing only allows in-order delivery. - */ - if ((flags & IS_STRICT) != 0) { - if (seq != fdata->td_end) { - return 0; - } - } - -#define SEQ_GE(a,b) ((int)((a) - (b)) >= 0) -#define SEQ_GT(a,b) ((int)((a) - (b)) > 0) - if ( -#if defined(_KERNEL) - (SEQ_GE(fdata->td_maxend, end)) && - (SEQ_GE(seq, fdata->td_end - maxwin)) && -#endif -/* XXX what about big packets */ -#define MAXACKWINDOW 66000 - (-ackskew <= (MAXACKWINDOW << fdata->td_winscale)) && - ( ackskew <= (MAXACKWINDOW << fdata->td_winscale))) { - - /* if ackskew < 0 then this should be due to fragmented - * packets. There is no way to know the length of the - * total packet in advance. - * We do know the total length from the fragment cache though. - * Note however that there might be more sessions with - * exactly the same source and destination parameters in the - * state cache (and source and destination is the only stuff - * that is saved in the fragment cache). Note further that - * some TCP connections in the state cache are hashed with - * sport and dport as well which makes it not worthwhile to - * look for them. - * Thus, when ackskew is negative but still seems to belong - * to this session, we bump up the destinations end value. - */ - if (ackskew < 0) - tdata->td_end = ack; - - /* update max window seen */ - if (fdata->td_maxwin < win) - fdata->td_maxwin = win; - if (SEQ_GT(end, fdata->td_end)) - fdata->td_end = end; - if (SEQ_GE(ack + win, tdata->td_maxend)) - tdata->td_maxend = ack + win; - return 1; - } - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stclone */ -/* Returns: ipstate_t* - NULL == cloning failed, */ -/* else pointer to new state structure */ -/* Parameters: fin(I) - pointer to packet information */ -/* tcp(I) - pointer to TCP/UDP header */ -/* is(I) - pointer to master state structure */ -/* */ -/* Create a "duplcate" state table entry from the master. */ -/* ------------------------------------------------------------------------ */ -static ipstate_t *fr_stclone(fin, tcp, is) -fr_info_t *fin; -tcphdr_t *tcp; -ipstate_t *is; -{ - ipstate_t *clone; - u_32_t send; - - if (ips_num == fr_statemax) { - ATOMIC_INCL(ips_stats.iss_max); - fr_state_doflush = 1; - return NULL; - } - KMALLOC(clone, ipstate_t *); - if (clone == NULL) - return NULL; - bcopy((char *)is, (char *)clone, sizeof(*clone)); - - MUTEX_NUKE(&clone->is_lock); - - clone->is_die = ONE_DAY + fr_ticks; - clone->is_state[0] = 0; - clone->is_state[1] = 0; - send = ntohl(tcp->th_seq) + fin->fin_dlen - (TCP_OFF(tcp) << 2) + - ((tcp->th_flags & TH_SYN) ? 1 : 0) + - ((tcp->th_flags & TH_FIN) ? 1 : 0); - - if (fin->fin_rev == 1) { - clone->is_dend = send; - clone->is_maxdend = send; - clone->is_send = 0; - clone->is_maxswin = 1; - clone->is_maxdwin = ntohs(tcp->th_win); - if (clone->is_maxdwin == 0) - clone->is_maxdwin = 1; - } else { - clone->is_send = send; - clone->is_maxsend = send; - clone->is_dend = 0; - clone->is_maxdwin = 1; - clone->is_maxswin = ntohs(tcp->th_win); - if (clone->is_maxswin == 0) - clone->is_maxswin = 1; - } - - clone->is_flags &= ~SI_CLONE; - clone->is_flags |= SI_CLONED; - fr_stinsert(clone, fin->fin_rev); - MUTEX_ENTER(&clone->is_lock); - clone->is_ref = 1; - if (clone->is_p == IPPROTO_TCP) { - (void) fr_tcp_age(&clone->is_sti, fin, ips_tqtqb, - clone->is_flags); - } - MUTEX_EXIT(&clone->is_lock); -#ifdef IPFILTER_SCAN - (void) ipsc_attachis(is); -#endif -#ifdef IPFILTER_SYNC - if (is->is_flags & IS_STATESYNC) - clone->is_sync = ipfsync_new(SMC_STATE, fin, clone); -#endif - return clone; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_matchsrcdst */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to state structure */ -/* src(I) - pointer to source address */ -/* dst(I) - pointer to destination address */ -/* tcp(I) - pointer to TCP/UDP header */ -/* */ -/* Match a state table entry against an IP packet. The logic below is that */ -/* ret gets set to one if the match succeeds, else remains 0. If it is */ -/* still 0 after the test. no match. */ -/* ------------------------------------------------------------------------ */ -static ipstate_t *fr_matchsrcdst(fin, is, src, dst, tcp, cmask) -fr_info_t *fin; -ipstate_t *is; -i6addr_t *src, *dst; -tcphdr_t *tcp; -u_32_t cmask; -{ - int ret = 0, rev, out, flags, flx = 0, idx; - u_short sp, dp; - u_32_t cflx; - void *ifp; - - rev = IP6_NEQ(&is->is_dst, dst); - ifp = fin->fin_ifp; - out = fin->fin_out; - flags = is->is_flags; - sp = 0; - dp = 0; - - if (tcp != NULL) { - sp = htons(fin->fin_sport); - dp = ntohs(fin->fin_dport); - } - if (!rev) { - if (tcp != NULL) { - if (!(flags & SI_W_SPORT) && (sp != is->is_sport)) - rev = 1; - else if (!(flags & SI_W_DPORT) && (dp != is->is_dport)) - rev = 1; - } - } - - idx = (out << 1) + rev; - - /* - * If the interface for this 'direction' is set, make sure it matches. - * An interface name that is not set matches any, as does a name of *. - */ - if ((is->is_ifp[idx] == NULL && - (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) || - is->is_ifp[idx] == ifp) - ret = 1; - - if (ret == 0) - return NULL; - ret = 0; - - /* - * Match addresses and ports. - */ - if (rev == 0) { - if ((IP6_EQ(&is->is_dst, dst) || (flags & SI_W_DADDR)) && - (IP6_EQ(&is->is_src, src) || (flags & SI_W_SADDR))) { - if (tcp) { - if ((sp == is->is_sport || flags & SI_W_SPORT)&& - (dp == is->is_dport || flags & SI_W_DPORT)) - ret = 1; - } else { - ret = 1; - } - } - } else { - if ((IP6_EQ(&is->is_dst, src) || (flags & SI_W_DADDR)) && - (IP6_EQ(&is->is_src, dst) || (flags & SI_W_SADDR))) { - if (tcp) { - if ((dp == is->is_sport || flags & SI_W_SPORT)&& - (sp == is->is_dport || flags & SI_W_DPORT)) - ret = 1; - } else { - ret = 1; - } - } - } - - if (ret == 0) - return NULL; - - /* - * Whether or not this should be here, is questionable, but the aim - * is to get this out of the main line. - */ - if (tcp == NULL) - flags = is->is_flags & ~(SI_WILDP|SI_NEWFR|SI_CLONE|SI_CLONED); - - /* - * Only one of the source or destination address can be flaged as a - * wildcard. Fill in the missing address, if set. - * For IPv6, if the address being copied in is multicast, then - * don't reset the wild flag - multicast causes it to be set in the - * first place! - */ - if ((flags & (SI_W_SADDR|SI_W_DADDR))) { - fr_ip_t *fi = &fin->fin_fi; - - if ((flags & SI_W_SADDR) != 0) { - if (rev == 0) { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_src.in6)) - /*EMPTY*/; - else -#endif - { - is->is_src = fi->fi_src; - is->is_flags &= ~SI_W_SADDR; - } - } else { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_dst.in6)) - /*EMPTY*/; - else -#endif - { - is->is_src = fi->fi_dst; - is->is_flags &= ~SI_W_SADDR; - } - } - } else if ((flags & SI_W_DADDR) != 0) { - if (rev == 0) { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_dst.in6)) - /*EMPTY*/; - else -#endif - { - is->is_dst = fi->fi_dst; - is->is_flags &= ~SI_W_DADDR; - } - } else { -#ifdef USE_INET6 - if (is->is_v == 6 && - IN6_IS_ADDR_MULTICAST(&fi->fi_src.in6)) - /*EMPTY*/; - else -#endif - { - is->is_dst = fi->fi_src; - is->is_flags &= ~SI_W_DADDR; - } - } - } - if ((is->is_flags & (SI_WILDA|SI_WILDP)) == 0) { - ATOMIC_DECL(ips_stats.iss_wild); - } - } - - flx = fin->fin_flx & cmask; - cflx = is->is_flx[out][rev]; - - /* - * Match up any flags set from IP options. - */ - if ((cflx && (flx != (cflx & cmask))) || - ((fin->fin_optmsk & is->is_optmsk) != is->is_opt) || - ((fin->fin_secmsk & is->is_secmsk) != is->is_sec) || - ((fin->fin_auth & is->is_authmsk) != is->is_auth)) - return NULL; - - /* - * Only one of the source or destination port can be flagged as a - * wildcard. When filling it in, fill in a copy of the matched entry - * if it has the cloning flag set. - */ - if ((fin->fin_flx & FI_IGNORE) != 0) { - fin->fin_rev = rev; - return is; - } - - if ((flags & (SI_W_SPORT|SI_W_DPORT))) { - if ((flags & SI_CLONE) != 0) { - is = fr_stclone(fin, tcp, is); - if (is == NULL) - return NULL; - } else { - ATOMIC_DECL(ips_stats.iss_wild); - } - - if ((flags & SI_W_SPORT) != 0) { - if (rev == 0) { - is->is_sport = sp; - is->is_send = ntohl(tcp->th_seq); - } else { - is->is_sport = dp; - is->is_send = ntohl(tcp->th_ack); - } - is->is_maxsend = is->is_send + 1; - } else if ((flags & SI_W_DPORT) != 0) { - if (rev == 0) { - is->is_dport = dp; - is->is_dend = ntohl(tcp->th_ack); - } else { - is->is_dport = sp; - is->is_dend = ntohl(tcp->th_seq); - } - is->is_maxdend = is->is_dend + 1; - } - is->is_flags &= ~(SI_W_SPORT|SI_W_DPORT); - if ((flags & SI_CLONED) && ipstate_logging) - ipstate_log(is, ISL_CLONE); - } - - ret = -1; - - if (is->is_flx[out][rev] == 0) - is->is_flx[out][rev] = flx; - - /* - * Check if the interface name for this "direction" is set and if not, - * fill it in. - */ - if (is->is_ifp[idx] == NULL && - (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) { - is->is_ifp[idx] = ifp; - COPYIFNAME(ifp, is->is_ifname[idx]); - } - fin->fin_rev = rev; - return is; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checkicmpmatchingstate */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* */ -/* If we've got an ICMP error message, using the information stored in the */ -/* ICMP packet, look for a matching state table entry. */ -/* */ -/* If we return NULL then no lock on ipf_state is held. */ -/* If we return non-null then a read-lock on ipf_state is held. */ -/* ------------------------------------------------------------------------ */ -static ipstate_t *fr_checkicmpmatchingstate(fin) -fr_info_t *fin; -{ - ipstate_t *is, **isp; - u_short sport, dport; - u_char pr; - int backward, i, oi; - i6addr_t dst, src; - struct icmp *ic; - u_short savelen; - icmphdr_t *icmp; - fr_info_t ofin; - tcphdr_t *tcp; - int type, len; - ip_t *oip; - u_int hv; - - /* - * Does it at least have the return (basic) IP header ? - * Only a basic IP header (no options) should be with - * an ICMP error header. - */ - if ((fin->fin_v != 4) || (fin->fin_hlen != sizeof(ip_t)) || - (fin->fin_plen < ICMPERR_MINPKTLEN)) - return NULL; - ic = fin->fin_dp; - type = ic->icmp_type; - /* - * If it's not an error type, then return - */ - if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) && - (type != ICMP_REDIRECT) && (type != ICMP_TIMXCEED) && - (type != ICMP_PARAMPROB)) - return NULL; - - oip = (ip_t *)((char *)ic + ICMPERR_ICMPHLEN); - /* - * Check if the at least the old IP header (with options) and - * 8 bytes of payload is present. - */ - if (fin->fin_plen < ICMPERR_MAXPKTLEN + ((IP_HL(oip) - 5) << 2)) - return NULL; - - /* - * Sanity Checks. - */ - len = fin->fin_dlen - ICMPERR_ICMPHLEN; - if ((len <= 0) || ((IP_HL(oip) << 2) > len)) - return NULL; - - /* - * Is the buffer big enough for all of it ? It's the size of the IP - * header claimed in the encapsulated part which is of concern. It - * may be too big to be in this buffer but not so big that it's - * outside the ICMP packet, leading to TCP deref's causing problems. - * This is possible because we don't know how big oip_hl is when we - * do the pullup early in fr_check() and thus can't guarantee it is - * all here now. - */ -#ifdef _KERNEL - { - mb_t *m; - - m = fin->fin_m; -# if defined(MENTAT) - if ((char *)oip + len > (char *)m->b_wptr) - return NULL; -# else - if ((char *)oip + len > (char *)fin->fin_ip + m->m_len) - return NULL; -# endif - } -#endif - bcopy((char *)fin, (char *)&ofin, sizeof(fin)); - - /* - * in the IPv4 case we must zero the i6addr union otherwise - * the IP6_EQ and IP6_NEQ macros produce the wrong results because - * of the 'junk' in the unused part of the union - */ - bzero((char *)&src, sizeof(src)); - bzero((char *)&dst, sizeof(dst)); - - /* - * we make an fin entry to be able to feed it to - * matchsrcdst note that not all fields are encessary - * but this is the cleanest way. Note further we fill - * in fin_mp such that if someone uses it we'll get - * a kernel panic. fr_matchsrcdst does not use this. - * - * watch out here, as ip is in host order and oip in network - * order. Any change we make must be undone afterwards, like - * oip->ip_off - it is still in network byte order so fix it. - */ - savelen = oip->ip_len; - oip->ip_len = len; - oip->ip_off = htons(oip->ip_off); - - ofin.fin_flx = FI_NOCKSUM; - ofin.fin_v = 4; - ofin.fin_ip = oip; - ofin.fin_m = NULL; /* if dereferenced, panic XXX */ - ofin.fin_mp = NULL; /* if dereferenced, panic XXX */ - ofin.fin_plen = fin->fin_dlen - ICMPERR_ICMPHLEN; - (void) fr_makefrip(IP_HL(oip) << 2, oip, &ofin); - ofin.fin_ifp = fin->fin_ifp; - ofin.fin_out = !fin->fin_out; - /* - * Reset the short and bad flag here because in fr_matchsrcdst() - * the flags for the current packet (fin_flx) are compared against - * those for the existing session. - */ - ofin.fin_flx &= ~(FI_BAD|FI_SHORT); - - /* - * Put old values of ip_len and ip_off back as we don't know - * if we have to forward the packet (or process it again. - */ - oip->ip_len = savelen; - oip->ip_off = htons(oip->ip_off); - - switch (oip->ip_p) - { - case IPPROTO_ICMP : - icmp = (icmphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - - /* - * an ICMP error can only be generated as a result of an - * ICMP query, not as the response on an ICMP error - * - * XXX theoretically ICMP_ECHOREP and the other reply's are - * ICMP query's as well, but adding them here seems strange XXX - */ - if ((icmp->icmp_type != ICMP_ECHO) && - (icmp->icmp_type != ICMP_TSTAMP) && - (icmp->icmp_type != ICMP_IREQ) && - (icmp->icmp_type != ICMP_MASKREQ)) - return NULL; - - /* - * perform a lookup of the ICMP packet in the state table - */ - hv = (pr = oip->ip_p); - src.in4 = oip->ip_src; - hv += src.in4.s_addr; - dst.in4 = oip->ip_dst; - hv += dst.in4.s_addr; - hv += icmp->icmp_id; - hv = DOUBLE_HASH(hv); - - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - if ((is->is_p != pr) || (is->is_v != 4)) - continue; - if (is->is_pass & FR_NOICMPERR) - continue; - is = fr_matchsrcdst(&ofin, is, &src, &dst, - NULL, FI_ICMPCMP); - if (is != NULL) { - if ((is->is_pass & FR_NOICMPERR) != 0) { - RWLOCK_EXIT(&ipf_state); - return NULL; - } - /* - * i : the index of this packet (the icmp - * unreachable) - * oi : the index of the original packet found - * in the icmp header (i.e. the packet - * causing this icmp) - * backward : original packet was backward - * compared to the state - */ - backward = IP6_NEQ(&is->is_src, &src); - fin->fin_rev = !backward; - i = (!backward << 1) + fin->fin_out; - oi = (backward << 1) + ofin.fin_out; - if (is->is_icmppkts[i] > is->is_pkts[oi]) - continue; - ips_stats.iss_hits++; - is->is_icmppkts[i]++; - return is; - } - } - RWLOCK_EXIT(&ipf_state); - return NULL; - case IPPROTO_TCP : - case IPPROTO_UDP : - break; - default : - return NULL; - } - - tcp = (tcphdr_t *)((char *)oip + (IP_HL(oip) << 2)); - dport = tcp->th_dport; - sport = tcp->th_sport; - - hv = (pr = oip->ip_p); - src.in4 = oip->ip_src; - hv += src.in4.s_addr; - dst.in4 = oip->ip_dst; - hv += dst.in4.s_addr; - hv += dport; - hv += sport; - hv = DOUBLE_HASH(hv); - - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - /* - * Only allow this icmp though if the - * encapsulated packet was allowed through the - * other way around. Note that the minimal amount - * of info present does not allow for checking against - * tcp internals such as seq and ack numbers. Only the - * ports are known to be present and can be even if the - * short flag is set. - */ - if ((is->is_p == pr) && (is->is_v == 4) && - (is = fr_matchsrcdst(&ofin, is, &src, &dst, - tcp, FI_ICMPCMP))) { - /* - * i : the index of this packet (the icmp unreachable) - * oi : the index of the original packet found in the - * icmp header (i.e. the packet causing this icmp) - * backward : original packet was backward compared to - * the state - */ - backward = IP6_NEQ(&is->is_src, &src); - fin->fin_rev = !backward; - i = (!backward << 1) + fin->fin_out; - oi = (backward << 1) + ofin.fin_out; - - if (((is->is_pass & FR_NOICMPERR) != 0) || - (is->is_icmppkts[i] > is->is_pkts[oi])) - break; - ips_stats.iss_hits++; - is->is_icmppkts[i]++; - /* - * we deliberately do not touch the timeouts - * for the accompanying state table entry. - * It remains to be seen if that is correct. XXX - */ - return is; - } - } - RWLOCK_EXIT(&ipf_state); - return NULL; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_ipsmove */ -/* Returns: Nil */ -/* Parameters: is(I) - pointer to state table entry */ -/* hv(I) - new hash value for state table entry */ -/* Write Locks: ipf_state */ -/* */ -/* Move a state entry from one position in the hash table to another. */ -/* ------------------------------------------------------------------------ */ -static void fr_ipsmove(is, hv) -ipstate_t *is; -u_int hv; -{ - ipstate_t **isp; - u_int hvm; - - ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0); - - hvm = is->is_hv; - /* - * Remove the hash from the old location... - */ - isp = is->is_phnext; - if (is->is_hnext) - is->is_hnext->is_phnext = isp; - *isp = is->is_hnext; - if (ips_table[hvm] == NULL) - ips_stats.iss_inuse--; - ips_stats.iss_bucketlen[hvm]--; - - /* - * ...and put the hash in the new one. - */ - hvm = DOUBLE_HASH(hv); - is->is_hv = hvm; - isp = &ips_table[hvm]; - if (*isp) - (*isp)->is_phnext = &is->is_hnext; - else - ips_stats.iss_inuse++; - ips_stats.iss_bucketlen[hvm]++; - is->is_phnext = isp; - is->is_hnext = *isp; - *isp = is; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_stlookup */ -/* Returns: ipstate_t* - NULL == no matching state found, */ -/* else pointer to state information is returned */ -/* Parameters: fin(I) - pointer to packet information */ -/* tcp(I) - pointer to TCP/UDP header. */ -/* */ -/* Search the state table for a matching entry to the packet described by */ -/* the contents of *fin. */ -/* */ -/* If we return NULL then no lock on ipf_state is held. */ -/* If we return non-null then a read-lock on ipf_state is held. */ -/* ------------------------------------------------------------------------ */ -ipstate_t *fr_stlookup(fin, tcp, ifqp) -fr_info_t *fin; -tcphdr_t *tcp; -ipftq_t **ifqp; -{ - u_int hv, hvm, pr, v, tryagain; - ipstate_t *is, **isp; - u_short dport, sport; - i6addr_t src, dst; - struct icmp *ic; - ipftq_t *ifq; - int oow; - - is = NULL; - ifq = NULL; - tcp = fin->fin_dp; - ic = (struct icmp *)tcp; - hv = (pr = fin->fin_fi.fi_p); - src = fin->fin_fi.fi_src; - dst = fin->fin_fi.fi_dst; - hv += src.in4.s_addr; - hv += dst.in4.s_addr; - - v = fin->fin_fi.fi_v; -#ifdef USE_INET6 - if (v == 6) { - hv += fin->fin_fi.fi_src.i6[1]; - hv += fin->fin_fi.fi_src.i6[2]; - hv += fin->fin_fi.fi_src.i6[3]; - - if ((fin->fin_p == IPPROTO_ICMPV6) && - IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_dst.in6)) { - hv -= dst.in4.s_addr; - } else { - hv += fin->fin_fi.fi_dst.i6[1]; - hv += fin->fin_fi.fi_dst.i6[2]; - hv += fin->fin_fi.fi_dst.i6[3]; - } - } -#endif - - /* - * Search the hash table for matching packet header info. - */ - switch (pr) - { -#ifdef USE_INET6 - case IPPROTO_ICMPV6 : - tryagain = 0; - if (v == 6) { - if ((ic->icmp_type == ICMP6_ECHO_REQUEST) || - (ic->icmp_type == ICMP6_ECHO_REPLY)) { - hv += ic->icmp_id; - } - } - READ_ENTER(&ipf_state); -icmp6again: - hvm = DOUBLE_HASH(hv); - for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - if ((is->is_p != pr) || (is->is_v != v)) - continue; - is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); - if (is != NULL && - fr_matchicmpqueryreply(v, &is->is_icmp, - ic, fin->fin_rev)) { - if (fin->fin_rev) - ifq = &ips_icmpacktq; - else - ifq = &ips_icmptq; - break; - } - } - - if (is != NULL) { - if ((tryagain != 0) && !(is->is_flags & SI_W_DADDR)) { - hv += fin->fin_fi.fi_src.i6[0]; - hv += fin->fin_fi.fi_src.i6[1]; - hv += fin->fin_fi.fi_src.i6[2]; - hv += fin->fin_fi.fi_src.i6[3]; - fr_ipsmove(is, hv); - MUTEX_DOWNGRADE(&ipf_state); - } - break; - } - RWLOCK_EXIT(&ipf_state); - - /* - * No matching icmp state entry. Perhaps this is a - * response to another state entry. - * - * XXX With some ICMP6 packets, the "other" address is already - * in the packet, after the ICMP6 header, and this could be - * used in place of the multicast address. However, taking - * advantage of this requires some significant code changes - * to handle the specific types where that is the case. - */ - if ((ips_stats.iss_wild != 0) && (v == 6) && (tryagain == 0) && - !IN6_IS_ADDR_MULTICAST(&fin->fin_fi.fi_src.in6)) { - hv -= fin->fin_fi.fi_src.i6[0]; - hv -= fin->fin_fi.fi_src.i6[1]; - hv -= fin->fin_fi.fi_src.i6[2]; - hv -= fin->fin_fi.fi_src.i6[3]; - tryagain = 1; - WRITE_ENTER(&ipf_state); - goto icmp6again; - } - - is = fr_checkicmp6matchingstate(fin); - if (is != NULL) - return is; - break; -#endif - - case IPPROTO_ICMP : - if (v == 4) { - hv += ic->icmp_id; - } - hv = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - if ((is->is_p != pr) || (is->is_v != v)) - continue; - is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); - if (is != NULL && - fr_matchicmpqueryreply(v, &is->is_icmp, - ic, fin->fin_rev)) { - if (fin->fin_rev) - ifq = &ips_icmpacktq; - else - ifq = &ips_icmptq; - break; - } - } - if (is == NULL) { - RWLOCK_EXIT(&ipf_state); - } - break; - - case IPPROTO_TCP : - case IPPROTO_UDP : - ifqp = NULL; - sport = htons(fin->fin_data[0]); - hv += sport; - dport = htons(fin->fin_data[1]); - hv += dport; - oow = 0; - tryagain = 0; - READ_ENTER(&ipf_state); -retry_tcpudp: - hvm = DOUBLE_HASH(hv); - for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - if ((is->is_p != pr) || (is->is_v != v)) - continue; - fin->fin_flx &= ~FI_OOW; - is = fr_matchsrcdst(fin, is, &src, &dst, tcp, FI_CMP); - if (is != NULL) { - if (pr == IPPROTO_TCP) { - if (!fr_tcpstate(fin, tcp, is)) { - oow |= fin->fin_flx & FI_OOW; - continue; - } - } - break; - } - } - if (is != NULL) { - if (tryagain && - !(is->is_flags & (SI_CLONE|SI_WILDP|SI_WILDA))) { - hv += dport; - hv += sport; - fr_ipsmove(is, hv); - MUTEX_DOWNGRADE(&ipf_state); - } - break; - } - RWLOCK_EXIT(&ipf_state); - - if (!tryagain && ips_stats.iss_wild) { - hv -= dport; - hv -= sport; - tryagain = 1; - WRITE_ENTER(&ipf_state); - goto retry_tcpudp; - } - fin->fin_flx |= oow; - break; - -#if 0 - case IPPROTO_GRE : - gre = fin->fin_dp; - if (GRE_REV(gre->gr_flags) == 1) { - hv += gre->gr_call; - } - /* FALLTHROUGH */ -#endif - default : - ifqp = NULL; - hvm = DOUBLE_HASH(hv); - READ_ENTER(&ipf_state); - for (isp = &ips_table[hvm]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - if ((is->is_p != pr) || (is->is_v != v)) - continue; - is = fr_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP); - if (is != NULL) { - ifq = &ips_iptq; - break; - } - } - if (is == NULL) { - RWLOCK_EXIT(&ipf_state); - } - break; - } - - if ((is != NULL) && ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) && - (is->is_tqehead[fin->fin_rev] != NULL)) - ifq = is->is_tqehead[fin->fin_rev]; - if (ifq != NULL && ifqp != NULL) - *ifqp = ifq; - return is; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_updatestate */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to state table entry */ -/* Read Locks: ipf_state */ -/* */ -/* Updates packet and byte counters for a newly received packet. Seeds the */ -/* fragment cache with a new entry as required. */ -/* ------------------------------------------------------------------------ */ -void fr_updatestate(fin, is, ifq) -fr_info_t *fin; -ipstate_t *is; -ipftq_t *ifq; -{ - ipftqent_t *tqe; - int i, pass; - - i = (fin->fin_rev << 1) + fin->fin_out; - - /* - * For TCP packets, ifq == NULL. For all others, check if this new - * queue is different to the last one it was on and move it if so. - */ - tqe = &is->is_sti; - MUTEX_ENTER(&is->is_lock); - if ((tqe->tqe_flags & TQE_RULEBASED) != 0) - ifq = is->is_tqehead[fin->fin_rev]; - - if (ifq != NULL) - fr_movequeue(tqe, tqe->tqe_ifq, ifq); - - is->is_pkts[i]++; - is->is_bytes[i] += fin->fin_plen; - MUTEX_EXIT(&is->is_lock); - -#ifdef IPFILTER_SYNC - if (is->is_flags & IS_STATESYNC) - ipfsync_update(SMC_STATE, fin, is->is_sync); -#endif - - ATOMIC_INCL(ips_stats.iss_hits); - - fin->fin_fr = is->is_rule; - - /* - * If this packet is a fragment and the rule says to track fragments, - * then create a new fragment cache entry. - */ - pass = is->is_pass; - if ((fin->fin_flx & FI_FRAG) && FR_ISPASS(pass)) - (void) fr_newfrag(fin, pass ^ FR_KEEPSTATE); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_checkstate */ -/* Returns: frentry_t* - NULL == search failed, */ -/* else pointer to rule for matching state */ -/* Parameters: ifp(I) - pointer to interface */ -/* passp(I) - pointer to filtering result flags */ -/* */ -/* Check if a packet is associated with an entry in the state table. */ -/* ------------------------------------------------------------------------ */ -frentry_t *fr_checkstate(fin, passp) -fr_info_t *fin; -u_32_t *passp; -{ - ipstate_t *is; - frentry_t *fr; - tcphdr_t *tcp; - ipftq_t *ifq; - u_int pass; - - if (fr_state_lock || (ips_list == NULL) || - (fin->fin_flx & (FI_SHORT|FI_STATE|FI_FRAGBODY|FI_BAD))) - return NULL; - - is = NULL; - if ((fin->fin_flx & FI_TCPUDP) || - (fin->fin_fi.fi_p == IPPROTO_ICMP) -#ifdef USE_INET6 - || (fin->fin_fi.fi_p == IPPROTO_ICMPV6) -#endif - ) - tcp = fin->fin_dp; - else - tcp = NULL; - - /* - * Search the hash table for matching packet header info. - */ - ifq = NULL; - is = fin->fin_state; - if (is == NULL) - is = fr_stlookup(fin, tcp, &ifq); - switch (fin->fin_p) - { -#ifdef USE_INET6 - case IPPROTO_ICMPV6 : - if (is != NULL) - break; - if (fin->fin_v == 6) { - is = fr_checkicmp6matchingstate(fin); - if (is != NULL) - goto matched; - } - break; -#endif - case IPPROTO_ICMP : - if (is != NULL) - break; - /* - * No matching icmp state entry. Perhaps this is a - * response to another state entry. - */ - is = fr_checkicmpmatchingstate(fin); - if (is != NULL) - goto matched; - break; - case IPPROTO_TCP : - if (is == NULL) - break; - - if (is->is_pass & FR_NEWISN) { - if (fin->fin_out == 0) - fr_fixinisn(fin, is); - else if (fin->fin_out == 1) - fr_fixoutisn(fin, is); - } - break; - default : - if (fin->fin_rev) - ifq = &ips_udpacktq; - else - ifq = &ips_udptq; - break; - } - if (is == NULL) { - ATOMIC_INCL(ips_stats.iss_miss); - return NULL; - } - -matched: - fr = is->is_rule; - if (fr != NULL) { - if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) { - if (fin->fin_nattag == NULL) - return NULL; - if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) != 0) - return NULL; - } - (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN); - fin->fin_icode = fr->fr_icode; - } - - fin->fin_rule = is->is_rulen; - pass = is->is_pass; - fr_updatestate(fin, is, ifq); - if (fin->fin_out == 1) - fin->fin_nat = is->is_nat[fin->fin_rev]; - - fin->fin_state = is; - is->is_touched = fr_ticks; - MUTEX_ENTER(&is->is_lock); - is->is_ref++; - MUTEX_EXIT(&is->is_lock); - RWLOCK_EXIT(&ipf_state); - fin->fin_flx |= FI_STATE; - if ((pass & FR_LOGFIRST) != 0) - pass &= ~(FR_LOGFIRST|FR_LOG); - *passp = pass; - return fr; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fixoutisn */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to master state structure */ -/* */ -/* Called only for outbound packets, adjusts the sequence number and the */ -/* TCP checksum to match that change. */ -/* ------------------------------------------------------------------------ */ -static void fr_fixoutisn(fin, is) -fr_info_t *fin; -ipstate_t *is; -{ - tcphdr_t *tcp; - int rev; - u_32_t seq; - - tcp = fin->fin_dp; - rev = fin->fin_rev; - if ((is->is_flags & IS_ISNSYN) != 0) { - if (rev == 0) { - seq = ntohl(tcp->th_seq); - seq += is->is_isninc[0]; - tcp->th_seq = htonl(seq); - fix_outcksum(fin, &tcp->th_sum, is->is_sumd[0]); - } - } - if ((is->is_flags & IS_ISNACK) != 0) { - if (rev == 1) { - seq = ntohl(tcp->th_seq); - seq += is->is_isninc[1]; - tcp->th_seq = htonl(seq); - fix_outcksum(fin, &tcp->th_sum, is->is_sumd[1]); - } - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_fixinisn */ -/* Returns: Nil */ -/* Parameters: fin(I) - pointer to packet information */ -/* is(I) - pointer to master state structure */ -/* */ -/* Called only for inbound packets, adjusts the acknowledge number and the */ -/* TCP checksum to match that change. */ -/* ------------------------------------------------------------------------ */ -static void fr_fixinisn(fin, is) -fr_info_t *fin; -ipstate_t *is; -{ - tcphdr_t *tcp; - int rev; - u_32_t ack; - - tcp = fin->fin_dp; - rev = fin->fin_rev; - if ((is->is_flags & IS_ISNSYN) != 0) { - if (rev == 1) { - ack = ntohl(tcp->th_ack); - ack -= is->is_isninc[0]; - tcp->th_ack = htonl(ack); - fix_incksum(fin, &tcp->th_sum, is->is_sumd[0]); - } - } - if ((is->is_flags & IS_ISNACK) != 0) { - if (rev == 0) { - ack = ntohl(tcp->th_ack); - ack -= is->is_isninc[1]; - tcp->th_ack = htonl(ack); - fix_incksum(fin, &tcp->th_sum, is->is_sumd[1]); - } - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_statesync */ -/* Returns: Nil */ -/* Parameters: ifp(I) - pointer to interface */ -/* */ -/* Walk through all state entries and if an interface pointer match is */ -/* found then look it up again, based on its name in case the pointer has */ -/* changed since last time. */ -/* */ -/* If ifp is passed in as being non-null then we are only doing updates for */ -/* existing, matching, uses of it. */ -/* ------------------------------------------------------------------------ */ -void fr_statesync(ifp) -void *ifp; -{ - ipstate_t *is; - int i; - - if (fr_running <= 0) - return; - - WRITE_ENTER(&ipf_state); - - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_state); - return; - } - - for (is = ips_list; is; is = is->is_next) { - /* - * Look up all the interface names in the state entry. - */ - for (i = 0; i < 4; i++) { - if (ifp == NULL || ifp == is->is_ifp[i]) - is->is_ifp[i] = fr_resolvenic(is->is_ifname[i], - is->is_v); - } - } - RWLOCK_EXIT(&ipf_state); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_delstate */ -/* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure to delete */ -/* why(I) - if not 0, log reason why it was deleted */ -/* Write Locks: ipf_state */ -/* */ -/* Deletes a state entry from the enumerated list as well as the hash table */ -/* and timeout queue lists. Make adjustments to hash table statistics and */ -/* global counters as required. */ -/* ------------------------------------------------------------------------ */ -static void fr_delstate(is, why) -ipstate_t *is; -int why; -{ - - ASSERT(rw_read_locked(&ipf_state.ipf_lk) == 0); - - /* - * Since we want to delete this, remove it from the state table, - * where it can be found & used, first. - */ - if (is->is_pnext != NULL) { - *is->is_pnext = is->is_next; - - if (is->is_next != NULL) - is->is_next->is_pnext = is->is_pnext; - - is->is_pnext = NULL; - is->is_next = NULL; - } - - if (is->is_phnext != NULL) { - *is->is_phnext = is->is_hnext; - if (is->is_hnext != NULL) - is->is_hnext->is_phnext = is->is_phnext; - if (ips_table[is->is_hv] == NULL) - ips_stats.iss_inuse--; - ips_stats.iss_bucketlen[is->is_hv]--; - - is->is_phnext = NULL; - is->is_hnext = NULL; - } - - /* - * Because ips_stats.iss_wild is a count of entries in the state - * table that have wildcard flags set, only decerement it once - * and do it here. - */ - if (is->is_flags & (SI_WILDP|SI_WILDA)) { - if (!(is->is_flags & SI_CLONED)) { - ATOMIC_DECL(ips_stats.iss_wild); - } - is->is_flags &= ~(SI_WILDP|SI_WILDA); - } - - /* - * Next, remove it from the timeout queue it is in. - */ - fr_deletequeueentry(&is->is_sti); - - if (is->is_me != NULL) { - *is->is_me = NULL; - is->is_me = NULL; - } - - /* - * If it is still in use by something else, do not go any further, - * but note that at this point it is now an orphan. - */ - is->is_ref--; - if (is->is_ref > 0) - return; - - if (is->is_tqehead[0] != NULL) { - if (fr_deletetimeoutqueue(is->is_tqehead[0]) == 0) - fr_freetimeoutqueue(is->is_tqehead[0]); - } - if (is->is_tqehead[1] != NULL) { - if (fr_deletetimeoutqueue(is->is_tqehead[1]) == 0) - fr_freetimeoutqueue(is->is_tqehead[1]); - } - -#ifdef IPFILTER_SYNC - if (is->is_sync) - ipfsync_del(is->is_sync); -#endif -#ifdef IPFILTER_SCAN - (void) ipsc_detachis(is); -#endif - - if (ipstate_logging != 0 && why != 0) - ipstate_log(is, why); - - if (is->is_rule != NULL) { - is->is_rule->fr_statecnt--; - (void)fr_derefrule(&is->is_rule); - } - - MUTEX_DESTROY(&is->is_lock); - KFREE(is); - ips_num--; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_timeoutstate */ -/* Returns: Nil */ -/* Parameters: Nil */ -/* */ -/* Slowly expire held state for thingslike UDP and ICMP. The algorithm */ -/* used here is to keep the queue sorted with the oldest things at the top */ -/* and the youngest at the bottom. So if the top one doesn't need to be */ -/* expired then neither will any under it. */ -/* ------------------------------------------------------------------------ */ -void fr_timeoutstate() -{ - ipftq_t *ifq, *ifqnext; - ipftqent_t *tqe, *tqn; - ipstate_t *is; -#if defined(USE_SPL) && defined(_KERNEL) - int s; -#endif - - SPL_NET(s); - WRITE_ENTER(&ipf_state); - for (ifq = ips_tqtqb; ifq != NULL; ifq = ifq->ifq_next) - for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { - if (tqe->tqe_die > fr_ticks) - break; - tqn = tqe->tqe_next; - is = tqe->tqe_parent; - fr_delstate(is, ISL_EXPIRE); - } - - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - - for (tqn = ifq->ifq_head; ((tqe = tqn) != NULL); ) { - if (tqe->tqe_die > fr_ticks) - break; - tqn = tqe->tqe_next; - is = tqe->tqe_parent; - fr_delstate(is, ISL_EXPIRE); - } - } - - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - - if (((ifq->ifq_flags & IFQF_DELETE) != 0) && - (ifq->ifq_ref == 0)) { - fr_freetimeoutqueue(ifq); - } - } - - if (fr_state_doflush) { - (void) fr_state_flush(2, 0); - fr_state_doflush = 0; - } - - RWLOCK_EXIT(&ipf_state); - SPL_X(s); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_state_flush */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: Nil */ -/* Write Locks: ipf_state */ -/* */ -/* Flush state tables. Three actions currently defined: */ -/* which == 0 : flush all state table entries */ -/* which == 1 : flush TCP connections which have started to close but are */ -/* stuck for some reason. */ -/* which == 2 : flush TCP connections which have been idle for a long time, */ -/* starting at > 4 days idle and working back in successive half-*/ -/* days to at most 12 hours old. If this fails to free enough */ -/* slots then work backwards in half hour slots to 30 minutes. */ -/* If that too fails, then work backwards in 30 second intervals */ -/* for the last 30 minutes to at worst 30 seconds idle. */ -/* ------------------------------------------------------------------------ */ -static int fr_state_flush(which, proto) -int which, proto; -{ - ipftq_t *ifq, *ifqnext; - ipftqent_t *tqe, *tqn; - ipstate_t *is, **isp; - int delete, removed; - long try, maxtick; - u_long interval; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif - - removed = 0; - - SPL_NET(s); - for (isp = &ips_list; ((is = *isp) != NULL); ) { - delete = 0; - - if ((proto != 0) && (is->is_v != proto)) { - isp = &is->is_next; - continue; - } - - switch (which) - { - case 0 : - delete = 1; - break; - case 1 : - case 2 : - if (is->is_p != IPPROTO_TCP) - break; - if ((is->is_state[0] != IPF_TCPS_ESTABLISHED) || - (is->is_state[1] != IPF_TCPS_ESTABLISHED)) - delete = 1; - break; - } - - if (delete) { - if (is->is_p == IPPROTO_TCP) - ips_stats.iss_fin++; - else - ips_stats.iss_expire++; - fr_delstate(is, ISL_FLUSH); - removed++; - } else - isp = &is->is_next; - } - - if (which != 2) { - SPL_X(s); - return removed; - } - - /* - * Asked to remove inactive entries because the table is full, try - * again, 3 times, if first attempt failed with a different criteria - * each time. The order tried in must be in decreasing age. - * Another alternative is to implement random drop and drop N entries - * at random until N have been freed up. - */ - if (fr_ticks - ips_last_force_flush < IPF_TTLVAL(5)) - goto force_flush_skipped; - ips_last_force_flush = fr_ticks; - - if (fr_ticks > IPF_TTLVAL(43200)) - interval = IPF_TTLVAL(43200); - else if (fr_ticks > IPF_TTLVAL(1800)) - interval = IPF_TTLVAL(1800); - else if (fr_ticks > IPF_TTLVAL(30)) - interval = IPF_TTLVAL(30); - else - interval = IPF_TTLVAL(10); - try = fr_ticks - (fr_ticks - interval); - if (try < 0) - goto force_flush_skipped; - - while (removed == 0) { - maxtick = fr_ticks - interval; - if (maxtick < 0) - break; - - while (try < maxtick) { - for (ifq = ips_tqtqb; ifq != NULL; - ifq = ifq->ifq_next) { - for (tqn = ifq->ifq_head; - ((tqe = tqn) != NULL); ) { - if (tqe->tqe_die > try) - break; - tqn = tqe->tqe_next; - is = tqe->tqe_parent; - fr_delstate(is, ISL_EXPIRE); - removed++; - } - } - - for (ifq = ips_utqe; ifq != NULL; ifq = ifqnext) { - ifqnext = ifq->ifq_next; - - for (tqn = ifq->ifq_head; - ((tqe = tqn) != NULL); ) { - if (tqe->tqe_die > try) - break; - tqn = tqe->tqe_next; - is = tqe->tqe_parent; - fr_delstate(is, ISL_EXPIRE); - removed++; - } - } - if (try + interval > maxtick) - break; - try += interval; - } - - if (removed == 0) { - if (interval == IPF_TTLVAL(43200)) { - interval = IPF_TTLVAL(1800); - } else if (interval == IPF_TTLVAL(1800)) { - interval = IPF_TTLVAL(30); - } else if (interval == IPF_TTLVAL(30)) { - interval = IPF_TTLVAL(10); - } else { - break; - } - } - } -force_flush_skipped: - SPL_X(s); - return removed; -} - - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_tcp_age */ -/* Returns: int - 1 == state transition made, 0 == no change (rejected) */ -/* Parameters: tq(I) - pointer to timeout queue information */ -/* fin(I) - pointer to packet information */ -/* tqtab(I) - TCP timeout queue table this is in */ -/* flags(I) - flags from state/NAT entry */ -/* */ -/* Rewritten by Arjan de Vet , 2000-07-29: */ -/* */ -/* - (try to) base state transitions on real evidence only, */ -/* i.e. packets that are sent and have been received by ipfilter; */ -/* diagram 18.12 of TCP/IP volume 1 by W. Richard Stevens was used. */ -/* */ -/* - deal with half-closed connections correctly; */ -/* */ -/* - store the state of the source in state[0] such that ipfstat */ -/* displays the state as source/dest instead of dest/source; the calls */ -/* to fr_tcp_age have been changed accordingly. */ -/* */ -/* Internal Parameters: */ -/* */ -/* state[0] = state of source (host that initiated connection) */ -/* state[1] = state of dest (host that accepted the connection) */ -/* */ -/* dir == 0 : a packet from source to dest */ -/* dir == 1 : a packet from dest to source */ -/* */ -/* Locking: it is assumed that the parent of the tqe structure is locked. */ -/* ------------------------------------------------------------------------ */ -int fr_tcp_age(tqe, fin, tqtab, flags) -ipftqent_t *tqe; -fr_info_t *fin; -ipftq_t *tqtab; -int flags; -{ - int dlen, ostate, nstate, rval, dir; - u_char tcpflags; - tcphdr_t *tcp; - - tcp = fin->fin_dp; - - rval = 0; - dir = fin->fin_rev; - tcpflags = tcp->th_flags; - dlen = fin->fin_plen - fin->fin_hlen - (TCP_OFF(tcp) << 2); - - if (tcpflags & TH_RST) { - if (!(tcpflags & TH_PUSH) && !dlen) - nstate = IPF_TCPS_CLOSED; - else - nstate = IPF_TCPS_CLOSE_WAIT; - rval = 1; - } else { - ostate = tqe->tqe_state[1 - dir]; - nstate = tqe->tqe_state[dir]; - - switch (nstate) - { - case IPF_TCPS_CLOSED: /* 0 */ - if ((tcpflags & TH_OPENING) == TH_OPENING) { - /* - * 'dir' received an S and sends SA in - * response, CLOSED -> SYN_RECEIVED - */ - nstate = IPF_TCPS_SYN_RECEIVED; - rval = 1; - } else if ((tcpflags & TH_OPENING) == TH_SYN) { - /* 'dir' sent S, CLOSED -> SYN_SENT */ - nstate = IPF_TCPS_SYN_SENT; - rval = 1; - } - /* - * the next piece of code makes it possible to get - * already established connections into the state table - * after a restart or reload of the filter rules; this - * does not work when a strict 'flags S keep state' is - * used for tcp connections of course - */ - if (((flags & IS_TCPFSM) == 0) && - ((tcpflags & TH_ACKMASK) == TH_ACK)) { - /* - * we saw an A, guess 'dir' is in ESTABLISHED - * mode - */ - switch (ostate) - { - case IPF_TCPS_CLOSED : - case IPF_TCPS_SYN_RECEIVED : - nstate = IPF_TCPS_HALF_ESTAB; - rval = 1; - break; - case IPF_TCPS_HALF_ESTAB : - case IPF_TCPS_ESTABLISHED : - nstate = IPF_TCPS_ESTABLISHED; - rval = 1; - break; - default : - break; - } - } - /* - * TODO: besides regular ACK packets we can have other - * packets as well; it is yet to be determined how we - * should initialize the states in those cases - */ - break; - - case IPF_TCPS_LISTEN: /* 1 */ - /* NOT USED */ - break; - - case IPF_TCPS_SYN_SENT: /* 2 */ - if ((tcpflags & ~(TH_ECN|TH_CWR)) == TH_SYN) { - /* - * A retransmitted SYN packet. We do not reset - * the timeout here to fr_tcptimeout because a - * connection connect timeout does not renew - * after every packet that is sent. We need to - * set rval so as to indicate the packet has - * passed the check for its flags being valid - * in the TCP FSM. Setting rval to 2 has the - * result of not resetting the timeout. - */ - rval = 2; - } else if ((tcpflags & (TH_SYN|TH_FIN|TH_ACK)) == - TH_ACK) { - /* - * we see an A from 'dir' which is in SYN_SENT - * state: 'dir' sent an A in response to an SA - * which it received, SYN_SENT -> ESTABLISHED - */ - nstate = IPF_TCPS_ESTABLISHED; - rval = 1; - } else if (tcpflags & TH_FIN) { - /* - * we see an F from 'dir' which is in SYN_SENT - * state and wants to close its side of the - * connection; SYN_SENT -> FIN_WAIT_1 - */ - nstate = IPF_TCPS_FIN_WAIT_1; - rval = 1; - } else if ((tcpflags & TH_OPENING) == TH_OPENING) { - /* - * we see an SA from 'dir' which is already in - * SYN_SENT state, this means we have a - * simultaneous open; SYN_SENT -> SYN_RECEIVED - */ - nstate = IPF_TCPS_SYN_RECEIVED; - rval = 1; - } - break; - - case IPF_TCPS_SYN_RECEIVED: /* 3 */ - if ((tcpflags & (TH_SYN|TH_FIN|TH_ACK)) == TH_ACK) { - /* - * we see an A from 'dir' which was in - * SYN_RECEIVED state so it must now be in - * established state, SYN_RECEIVED -> - * ESTABLISHED - */ - nstate = IPF_TCPS_ESTABLISHED; - rval = 1; - } else if ((tcpflags & ~(TH_ECN|TH_CWR)) == - TH_OPENING) { - /* - * We see an SA from 'dir' which is already in - * SYN_RECEIVED state. - */ - rval = 2; - } else if (tcpflags & TH_FIN) { - /* - * we see an F from 'dir' which is in - * SYN_RECEIVED state and wants to close its - * side of the connection; SYN_RECEIVED -> - * FIN_WAIT_1 - */ - nstate = IPF_TCPS_FIN_WAIT_1; - rval = 1; - } - break; - - case IPF_TCPS_HALF_ESTAB: /* 4 */ - if (ostate >= IPF_TCPS_HALF_ESTAB) { - if ((tcpflags & TH_ACKMASK) == TH_ACK) { - nstate = IPF_TCPS_ESTABLISHED; - rval = 1; - } - } - - break; - - case IPF_TCPS_ESTABLISHED: /* 5 */ - rval = 1; - if (tcpflags & TH_FIN) { - /* - * 'dir' closed its side of the connection; - * this gives us a half-closed connection; - * ESTABLISHED -> FIN_WAIT_1 - */ - nstate = IPF_TCPS_FIN_WAIT_1; - } else if (tcpflags & TH_ACK) { - /* - * an ACK, should we exclude other flags here? - */ - if (ostate == IPF_TCPS_FIN_WAIT_1) { - /* - * We know the other side did an active - * close, so we are ACKing the recvd - * FIN packet (does the window matching - * code guarantee this?) and go into - * CLOSE_WAIT state; this gives us a - * half-closed connection - */ - nstate = IPF_TCPS_CLOSE_WAIT; - } else if (ostate < IPF_TCPS_CLOSE_WAIT) { - /* - * still a fully established - * connection reset timeout - */ - nstate = IPF_TCPS_ESTABLISHED; - } - } - break; - - case IPF_TCPS_CLOSE_WAIT: /* 6 */ - rval = 1; - if (tcpflags & TH_FIN) { - /* - * application closed and 'dir' sent a FIN, - * we're now going into LAST_ACK state - */ - nstate = IPF_TCPS_LAST_ACK; - } else { - /* - * we remain in CLOSE_WAIT because the other - * side has closed already and we did not - * close our side yet; reset timeout - */ - nstate = IPF_TCPS_CLOSE_WAIT; - } - break; - - case IPF_TCPS_FIN_WAIT_1: /* 7 */ - rval = 1; - if ((tcpflags & TH_ACK) && - ostate > IPF_TCPS_CLOSE_WAIT) { - /* - * if the other side is not active anymore - * it has sent us a FIN packet that we are - * ack'ing now with an ACK; this means both - * sides have now closed the connection and - * we go into TIME_WAIT - */ - /* - * XXX: how do we know we really are ACKing - * the FIN packet here? does the window code - * guarantee that? - */ - nstate = IPF_TCPS_TIME_WAIT; - } else { - /* - * we closed our side of the connection - * already but the other side is still active - * (ESTABLISHED/CLOSE_WAIT); continue with - * this half-closed connection - */ - nstate = IPF_TCPS_FIN_WAIT_1; - } - break; - - case IPF_TCPS_CLOSING: /* 8 */ - /* NOT USED */ - break; - - case IPF_TCPS_LAST_ACK: /* 9 */ - if (tcpflags & TH_ACK) { - if ((tcpflags & TH_PUSH) || dlen) - /* - * there is still data to be delivered, - * reset timeout - */ - rval = 1; - else - rval = 2; - } - /* - * we cannot detect when we go out of LAST_ACK state to - * CLOSED because that is based on the reception of ACK - * packets; ipfilter can only detect that a packet - * has been sent by a host - */ - break; - - case IPF_TCPS_FIN_WAIT_2: /* 10 */ - rval = 1; - if ((tcpflags & TH_OPENING) == TH_OPENING) - nstate = IPF_TCPS_SYN_RECEIVED; - else if (tcpflags & TH_SYN) - nstate = IPF_TCPS_SYN_SENT; - break; - - case IPF_TCPS_TIME_WAIT: /* 11 */ - /* we're in 2MSL timeout now */ - rval = 1; - break; - - default : -#if defined(_KERNEL) -# if SOLARIS - cmn_err(CE_NOTE, - "tcp %lx flags %x si %lx nstate %d ostate %d\n", - (u_long)tcp, tcpflags, (u_long)tqe, - nstate, ostate); -# else - printf("tcp %lx flags %x si %lx nstate %d ostate %d\n", - (u_long)tcp, tcpflags, (u_long)tqe, - nstate, ostate); -# endif -# ifdef DIAGNOSTIC - panic("invalid TCP state"); -# endif -#else - abort(); -#endif - break; - } - } - - /* - * If rval == 2 then do not update the queue position, but treat the - * packet as being ok. - */ - if (rval == 2) - rval = 1; - else if (rval == 1) { - tqe->tqe_state[dir] = nstate; - if ((tqe->tqe_flags & TQE_RULEBASED) == 0) - fr_movequeue(tqe, tqe->tqe_ifq, tqtab + nstate); - } - - return rval; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipstate_log */ -/* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure */ -/* type(I) - type of log entry to create */ -/* */ -/* Creates a state table log entry using the state structure and type info. */ -/* passed in. Log packet/byte counts, source/destination address and other */ -/* protocol specific information. */ -/* ------------------------------------------------------------------------ */ -void ipstate_log(is, type) -struct ipstate *is; -u_int type; -{ -#ifdef IPFILTER_LOG - struct ipslog ipsl; - size_t sizes[1]; - void *items[1]; - int types[1]; - - /* - * Copy information out of the ipstate_t structure and into the - * structure used for logging. - */ - ipsl.isl_type = type; - ipsl.isl_pkts[0] = is->is_pkts[0] + is->is_icmppkts[0]; - ipsl.isl_bytes[0] = is->is_bytes[0]; - ipsl.isl_pkts[1] = is->is_pkts[1] + is->is_icmppkts[1]; - ipsl.isl_bytes[1] = is->is_bytes[1]; - ipsl.isl_pkts[2] = is->is_pkts[2] + is->is_icmppkts[2]; - ipsl.isl_bytes[2] = is->is_bytes[2]; - ipsl.isl_pkts[3] = is->is_pkts[3] + is->is_icmppkts[3]; - ipsl.isl_bytes[3] = is->is_bytes[3]; - ipsl.isl_src = is->is_src; - ipsl.isl_dst = is->is_dst; - ipsl.isl_p = is->is_p; - ipsl.isl_v = is->is_v; - ipsl.isl_flags = is->is_flags; - ipsl.isl_tag = is->is_tag; - ipsl.isl_rulen = is->is_rulen; - (void) strncpy(ipsl.isl_group, is->is_group, FR_GROUPLEN); - - if (ipsl.isl_p == IPPROTO_TCP || ipsl.isl_p == IPPROTO_UDP) { - ipsl.isl_sport = is->is_sport; - ipsl.isl_dport = is->is_dport; - if (ipsl.isl_p == IPPROTO_TCP) { - ipsl.isl_state[0] = is->is_state[0]; - ipsl.isl_state[1] = is->is_state[1]; - } - } else if (ipsl.isl_p == IPPROTO_ICMP) { - ipsl.isl_itype = is->is_icmp.ici_type; - } else if (ipsl.isl_p == IPPROTO_ICMPV6) { - ipsl.isl_itype = is->is_icmp.ici_type; - } else { - ipsl.isl_ps.isl_filler[0] = 0; - ipsl.isl_ps.isl_filler[1] = 0; - } - - items[0] = &ipsl; - sizes[0] = sizeof(ipsl); - types[0] = 0; - - if (ipllog(IPL_LOGSTATE, NULL, items, sizes, types, 1)) { - ATOMIC_INCL(ips_stats.iss_logged); - } else { - ATOMIC_INCL(ips_stats.iss_logfail); - } -#endif -} - - -#ifdef USE_INET6 -/* ------------------------------------------------------------------------ */ -/* Function: fr_checkicmp6matchingstate */ -/* Returns: ipstate_t* - NULL == no match found, */ -/* else pointer to matching state entry */ -/* Parameters: fin(I) - pointer to packet information */ -/* Locks: NULL == no locks, else Read Lock on ipf_state */ -/* */ -/* If we've got an ICMPv6 error message, using the information stored in */ -/* the ICMPv6 packet, look for a matching state table entry. */ -/* ------------------------------------------------------------------------ */ -static ipstate_t *fr_checkicmp6matchingstate(fin) -fr_info_t *fin; -{ - struct icmp6_hdr *ic6, *oic; - int type, backward, i; - ipstate_t *is, **isp; - u_short sport, dport; - i6addr_t dst, src; - u_short savelen; - icmpinfo_t *ic; - fr_info_t ofin; - tcphdr_t *tcp; - ip6_t *oip6; - u_char pr; - u_int hv; - - /* - * Does it at least have the return (basic) IP header ? - * Only a basic IP header (no options) should be with - * an ICMP error header. - */ - if ((fin->fin_v != 6) || (fin->fin_plen < ICMP6ERR_MINPKTLEN)) - return NULL; - - ic6 = fin->fin_dp; - type = ic6->icmp6_type; - /* - * If it's not an error type, then return - */ - if ((type != ICMP6_DST_UNREACH) && (type != ICMP6_PACKET_TOO_BIG) && - (type != ICMP6_TIME_EXCEEDED) && (type != ICMP6_PARAM_PROB)) - return NULL; - - oip6 = (ip6_t *)((char *)ic6 + ICMPERR_ICMPHLEN); - if (fin->fin_plen < sizeof(*oip6)) - return NULL; - - bcopy((char *)fin, (char *)&ofin, sizeof(fin)); - ofin.fin_v = 6; - ofin.fin_ifp = fin->fin_ifp; - ofin.fin_out = !fin->fin_out; - ofin.fin_m = NULL; /* if dereferenced, panic XXX */ - ofin.fin_mp = NULL; /* if dereferenced, panic XXX */ - - /* - * We make a fin entry to be able to feed it to - * matchsrcdst. Note that not all fields are necessary - * but this is the cleanest way. Note further we fill - * in fin_mp such that if someone uses it we'll get - * a kernel panic. fr_matchsrcdst does not use this. - * - * watch out here, as ip is in host order and oip6 in network - * order. Any change we make must be undone afterwards. - */ - savelen = oip6->ip6_plen; - oip6->ip6_plen = fin->fin_dlen - ICMPERR_ICMPHLEN; - ofin.fin_flx = FI_NOCKSUM; - ofin.fin_ip = (ip_t *)oip6; - ofin.fin_plen = oip6->ip6_plen; - (void) fr_makefrip(sizeof(*oip6), (ip_t *)oip6, &ofin); - ofin.fin_flx &= ~(FI_BAD|FI_SHORT); - oip6->ip6_plen = savelen; - - if (oip6->ip6_nxt == IPPROTO_ICMPV6) { - oic = (struct icmp6_hdr *)(oip6 + 1); - /* - * an ICMP error can only be generated as a result of an - * ICMP query, not as the response on an ICMP error - * - * XXX theoretically ICMP_ECHOREP and the other reply's are - * ICMP query's as well, but adding them here seems strange XXX - */ - if (!(oic->icmp6_type & ICMP6_INFOMSG_MASK)) - return NULL; - - /* - * perform a lookup of the ICMP packet in the state table - */ - hv = (pr = oip6->ip6_nxt); - src.in6 = oip6->ip6_src; - hv += src.in4.s_addr; - dst.in6 = oip6->ip6_dst; - hv += dst.in4.s_addr; - hv += oic->icmp6_id; - hv += oic->icmp6_seq; - hv = DOUBLE_HASH(hv); - - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { - ic = &is->is_icmp; - isp = &is->is_hnext; - if ((is->is_p == pr) && - !(is->is_pass & FR_NOICMPERR) && - (oic->icmp6_id == ic->ici_id) && - (oic->icmp6_seq == ic->ici_seq) && - (is = fr_matchsrcdst(&ofin, is, &src, - &dst, NULL, FI_ICMPCMP))) { - /* - * in the state table ICMP query's are stored - * with the type of the corresponding ICMP - * response. Correct here - */ - if (((ic->ici_type == ICMP6_ECHO_REPLY) && - (oic->icmp6_type == ICMP6_ECHO_REQUEST)) || - (ic->ici_type - 1 == oic->icmp6_type )) { - ips_stats.iss_hits++; - backward = IP6_NEQ(&is->is_dst, &src); - fin->fin_rev = !backward; - i = (backward << 1) + fin->fin_out; - is->is_icmppkts[i]++; - return is; - } - } - } - RWLOCK_EXIT(&ipf_state); - return NULL; - } - - hv = (pr = oip6->ip6_nxt); - src.in6 = oip6->ip6_src; - hv += src.i6[0]; - hv += src.i6[1]; - hv += src.i6[2]; - hv += src.i6[3]; - dst.in6 = oip6->ip6_dst; - hv += dst.i6[0]; - hv += dst.i6[1]; - hv += dst.i6[2]; - hv += dst.i6[3]; - - if ((oip6->ip6_nxt == IPPROTO_TCP) || (oip6->ip6_nxt == IPPROTO_UDP)) { - tcp = (tcphdr_t *)(oip6 + 1); - dport = tcp->th_dport; - sport = tcp->th_sport; - hv += dport; - hv += sport; - } else - tcp = NULL; - hv = DOUBLE_HASH(hv); - - READ_ENTER(&ipf_state); - for (isp = &ips_table[hv]; ((is = *isp) != NULL); ) { - isp = &is->is_hnext; - /* - * Only allow this icmp though if the - * encapsulated packet was allowed through the - * other way around. Note that the minimal amount - * of info present does not allow for checking against - * tcp internals such as seq and ack numbers. - */ - if ((is->is_p != pr) || (is->is_v != 6) || - (is->is_pass & FR_NOICMPERR)) - continue; - is = fr_matchsrcdst(&ofin, is, &src, &dst, tcp, FI_ICMPCMP); - if (is != NULL) { - ips_stats.iss_hits++; - backward = IP6_NEQ(&is->is_dst, &src); - fin->fin_rev = !backward; - i = (backward << 1) + fin->fin_out; - is->is_icmppkts[i]++; - /* - * we deliberately do not touch the timeouts - * for the accompanying state table entry. - * It remains to be seen if that is correct. XXX - */ - return is; - } - } - RWLOCK_EXIT(&ipf_state); - return NULL; -} -#endif - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_sttab_init */ -/* Returns: Nil */ -/* Parameters: tqp(I) - pointer to an array of timeout queues for TCP */ -/* */ -/* Initialise the array of timeout queues for TCP. */ -/* ------------------------------------------------------------------------ */ -void fr_sttab_init(tqp) -ipftq_t *tqp; -{ - int i; - - for (i = IPF_TCP_NSTATES - 1; i >= 0; i--) { - tqp[i].ifq_ttl = 0; - tqp[i].ifq_ref = 1; - tqp[i].ifq_head = NULL; - tqp[i].ifq_tail = &tqp[i].ifq_head; - tqp[i].ifq_next = tqp + i + 1; - MUTEX_INIT(&tqp[i].ifq_lock, "ipftq tcp tab"); - } - tqp[IPF_TCP_NSTATES - 1].ifq_next = NULL; - tqp[IPF_TCPS_CLOSED].ifq_ttl = fr_tcpclosed; - tqp[IPF_TCPS_LISTEN].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_SYN_SENT].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_SYN_RECEIVED].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_ESTABLISHED].ifq_ttl = fr_tcpidletimeout; - tqp[IPF_TCPS_CLOSE_WAIT].ifq_ttl = fr_tcphalfclosed; - tqp[IPF_TCPS_FIN_WAIT_1].ifq_ttl = fr_tcphalfclosed; - tqp[IPF_TCPS_CLOSING].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_LAST_ACK].ifq_ttl = fr_tcplastack; - tqp[IPF_TCPS_FIN_WAIT_2].ifq_ttl = fr_tcpclosewait; - tqp[IPF_TCPS_TIME_WAIT].ifq_ttl = fr_tcptimeout; - tqp[IPF_TCPS_HALF_ESTAB].ifq_ttl = fr_tcptimeout; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_sttab_destroy */ -/* Returns: Nil */ -/* Parameters: tqp(I) - pointer to an array of timeout queues for TCP */ -/* */ -/* Do whatever is necessary to "destroy" each of the entries in the array */ -/* of timeout queues for TCP. */ -/* ------------------------------------------------------------------------ */ -void fr_sttab_destroy(tqp) -ipftq_t *tqp; -{ - int i; - - for (i = IPF_TCP_NSTATES - 1; i >= 0; i--) - MUTEX_DESTROY(&tqp[i].ifq_lock); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_statederef */ -/* Returns: Nil */ -/* Parameters: isp(I) - pointer to pointer to state table entry */ -/* */ -/* Decrement the reference counter for this state table entry and free it */ -/* if there are no more things using it. */ -/* */ -/* When operating in userland (ipftest), we have no timers to clear a state */ -/* entry. Therefore, we make a few simple tests before deleting an entry */ -/* outright. We compare states on each side looking for a combination of */ -/* TIME_WAIT (should really be FIN_WAIT_2?) and LAST_ACK. Then we factor */ -/* in packet direction with the interface list to make sure we don't */ -/* prematurely delete an entry on a final inbound packet that's we're also */ -/* supposed to route elsewhere. */ -/* */ -/* Internal parameters: */ -/* state[0] = state of source (host that initiated connection) */ -/* state[1] = state of dest (host that accepted the connection) */ -/* */ -/* dir == 0 : a packet from source to dest */ -/* dir == 1 : a packet from dest to source */ -/* ------------------------------------------------------------------------ */ -void fr_statederef(fin, isp) -fr_info_t *fin; -ipstate_t **isp; -{ - ipstate_t *is = *isp; -#if 0 - int nstate, ostate, dir, eol; - - eol = 0; /* End-of-the-line flag. */ - dir = fin->fin_rev; - ostate = is->is_state[1 - dir]; - nstate = is->is_state[dir]; - /* - * Determine whether this packet is local or routed. State entries - * with us as the destination will have an interface list of - * int1,-,-,int1. Entries with us as the origin run as -,int1,int1,-. - */ - if ((fin->fin_p == IPPROTO_TCP) && (fin->fin_out == 0)) { - if ((strcmp(is->is_ifname[0], is->is_ifname[3]) == 0) && - (strcmp(is->is_ifname[1], is->is_ifname[2]) == 0)) { - if ((dir == 0) && - (strcmp(is->is_ifname[1], "-") == 0) && - (strcmp(is->is_ifname[0], "-") != 0)) { - eol = 1; - } else if ((dir == 1) && - (strcmp(is->is_ifname[0], "-") == 0) && - (strcmp(is->is_ifname[1], "-") != 0)) { - eol = 1; - } - } - } -#endif - - fin = fin; /* LINT */ - is = *isp; - *isp = NULL; - WRITE_ENTER(&ipf_state); - is->is_ref--; - if (is->is_ref == 0) { - is->is_ref++; /* To counter ref-- in fr_delstate() */ - fr_delstate(is, ISL_EXPIRE); -#ifndef _KERNEL -#if 0 - } else if (((fin->fin_out == 1) || (eol == 1)) && - ((ostate == IPF_TCPS_LAST_ACK) && - (nstate == IPF_TCPS_TIME_WAIT))) { - ; -#else - } else if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) || - (is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) { -#endif - fr_delstate(is, ISL_ORPHAN); -#endif - } - RWLOCK_EXIT(&ipf_state); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_setstatequeue */ -/* Returns: Nil */ -/* Parameters: is(I) - pointer to state structure */ -/* rev(I) - forward(0) or reverse(1) direction */ -/* Locks: ipf_state (read or write) */ -/* */ -/* Put the state entry on its default queue entry, using rev as a helped in */ -/* determining which queue it should be placed on. */ -/* ------------------------------------------------------------------------ */ -void fr_setstatequeue(is, rev) -ipstate_t *is; -int rev; -{ - ipftq_t *oifq, *nifq; - - - if ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) - nifq = is->is_tqehead[rev]; - else - nifq = NULL; - - if (nifq == NULL) { - switch (is->is_p) - { -#ifdef USE_INET6 - case IPPROTO_ICMPV6 : - if (rev == 1) - nifq = &ips_icmpacktq; - else - nifq = &ips_icmptq; - break; -#endif - case IPPROTO_ICMP : - if (rev == 1) - nifq = &ips_icmpacktq; - else - nifq = &ips_icmptq; - break; - case IPPROTO_TCP : - nifq = ips_tqtqb + is->is_state[rev]; - break; - - case IPPROTO_UDP : - if (rev == 1) - nifq = &ips_udpacktq; - else - nifq = &ips_udptq; - break; - - default : - nifq = &ips_iptq; - break; - } - } - - oifq = is->is_sti.tqe_ifq; - /* - * If it's currently on a timeout queue, move it from one queue to - * another, else put it on the end of the newly determined queue. - */ - if (oifq != NULL) - fr_movequeue(&is->is_sti, oifq, nifq); - else - fr_queueappend(&is->is_sti, nifq, is); - return; -} diff --git a/contrib/ipfilter/ip_state.h b/contrib/ipfilter/ip_state.h deleted file mode 100644 index 2f5f7f11dcc3..000000000000 --- a/contrib/ipfilter/ip_state.h +++ /dev/null @@ -1,261 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1995-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_state.h 1.3 1/12/96 (C) 1995 Darren Reed - * Id: ip_state.h,v 2.68.2.3 2005/03/03 14:24:11 darrenr Exp - */ -#ifndef __IP_STATE_H__ -#define __IP_STATE_H__ - -#if defined(__STDC__) || defined(__GNUC__) -# define SIOCDELST _IOW('r', 61, struct ipfobj) -#else -# define SIOCDELST _IOW(r, 61, struct ipfobj) -#endif - -struct ipscan; - -#ifndef IPSTATE_SIZE -# define IPSTATE_SIZE 5737 -#endif -#ifndef IPSTATE_MAX -# define IPSTATE_MAX 4013 /* Maximum number of states held */ -#endif - -#define PAIRS(s1,d1,s2,d2) ((((s1) == (s2)) && ((d1) == (d2))) ||\ - (((s1) == (d2)) && ((d1) == (s2)))) -#define IPPAIR(s1,d1,s2,d2) PAIRS((s1).s_addr, (d1).s_addr, \ - (s2).s_addr, (d2).s_addr) - - -typedef struct ipstate { - ipfmutex_t is_lock; - struct ipstate *is_next; - struct ipstate **is_pnext; - struct ipstate *is_hnext; - struct ipstate **is_phnext; - struct ipstate **is_me; - void *is_ifp[4]; - void *is_sync; - struct nat *is_nat[2]; - frentry_t *is_rule; - struct ipftq *is_tqehead[2]; - struct ipscan *is_isc; - U_QUAD_T is_pkts[4]; - U_QUAD_T is_bytes[4]; - U_QUAD_T is_icmppkts[4]; - struct ipftqent is_sti; - u_int is_frage[2]; - int is_ref; /* reference count */ - int is_isninc[2]; - u_short is_sumd[2]; - i6addr_t is_src; - i6addr_t is_dst; - u_int is_pass; - u_char is_p; /* Protocol */ - u_char is_v; - u_32_t is_hv; - u_32_t is_tag; - u_32_t is_opt; /* packet options set */ - u_32_t is_optmsk; /* " " mask */ - u_short is_sec; /* security options set */ - u_short is_secmsk; /* " " mask */ - u_short is_auth; /* authentication options set */ - u_short is_authmsk; /* " " mask */ - union { - icmpinfo_t is_ics; - tcpinfo_t is_ts; - udpinfo_t is_us; - greinfo_t is_ug; - } is_ps; - u_32_t is_flags; - int is_flx[2][2]; - u_32_t is_rulen; /* rule number when created */ - u_32_t is_s0[2]; - u_short is_smsk[2]; - char is_group[FR_GROUPLEN]; - char is_sbuf[2][16]; - char is_ifname[4][LIFNAMSIZ]; -} ipstate_t; - -#define is_die is_sti.tqe_die -#define is_state is_sti.tqe_state -#define is_touched is_sti.tqe_touched -#define is_saddr is_src.in4.s_addr -#define is_daddr is_dst.in4.s_addr -#define is_icmp is_ps.is_ics -#define is_type is_icmp.ici_type -#define is_code is_icmp.ici_code -#define is_tcp is_ps.is_ts -#define is_udp is_ps.is_us -#define is_send is_tcp.ts_data[0].td_end -#define is_dend is_tcp.ts_data[1].td_end -#define is_maxswin is_tcp.ts_data[0].td_maxwin -#define is_maxdwin is_tcp.ts_data[1].td_maxwin -#define is_maxsend is_tcp.ts_data[0].td_maxend -#define is_maxdend is_tcp.ts_data[1].td_maxend -#define is_swinscale is_tcp.ts_data[0].td_winscale -#define is_dwinscale is_tcp.ts_data[1].td_winscale -#define is_swinflags is_tcp.ts_data[0].td_winflags -#define is_dwinflags is_tcp.ts_data[1].td_winflags -#define is_sport is_tcp.ts_sport -#define is_dport is_tcp.ts_dport -#define is_ifpin is_ifp[0] -#define is_ifpout is_ifp[2] -#define is_gre is_ps.is_ug -#define is_call is_gre.gs_call - -#define IS_WSPORT SI_W_SPORT /* 0x00100 */ -#define IS_WDPORT SI_W_DPORT /* 0x00200 */ -#define IS_WSADDR SI_W_SADDR /* 0x00400 */ -#define IS_WDADDR SI_W_DADDR /* 0x00800 */ -#define IS_NEWFR SI_NEWFR /* 0x01000 */ -#define IS_CLONE SI_CLONE /* 0x02000 */ -#define IS_CLONED SI_CLONED /* 0x04000 */ -#define IS_TCPFSM 0x10000 -#define IS_STRICT 0x20000 -#define IS_ISNSYN 0x40000 -#define IS_ISNACK 0x80000 -#define IS_STATESYNC 0x100000 -/* - * IS_SC flags are for scan-operations that need to be recognised in state. - */ -#define IS_SC_CLIENT 0x10000000 -#define IS_SC_SERVER 0x20000000 -#define IS_SC_MATCHC 0x40000000 -#define IS_SC_MATCHS 0x80000000 -#define IS_SC_MATCHALL (IS_SC_MATCHC|IS_SC_MATCHC) -#define IS_SC_ALL (IS_SC_MATCHC|IS_SC_MATCHC|IS_SC_CLIENT|IS_SC_SERVER) - -/* - * Flags that can be passed into fr_addstate - */ -#define IS_INHERITED 0x0fffff00 - -#define TH_OPENING (TH_SYN|TH_ACK) -/* - * is_flags: - * Bits 0 - 3 are use as a mask with the current packet's bits to check for - * whether it is short, tcp/udp, a fragment or the presence of IP options. - * Bits 4 - 7 are set from the initial packet and contain what the packet - * anded with bits 0-3 must match. - * Bits 8,9 are used to indicate wildcard source/destination port matching. - * Bits 10,11 are reserved for other wildcard flag compatibility. - * Bits 12,13 are for scaning. - */ - -typedef struct ipstate_save { - void *ips_next; - struct ipstate ips_is; - struct frentry ips_fr; -} ipstate_save_t; - -#define ips_rule ips_is.is_rule - - -typedef struct ipslog { - U_QUAD_T isl_pkts[4]; - U_QUAD_T isl_bytes[4]; - i6addr_t isl_src; - i6addr_t isl_dst; - u_32_t isl_tag; - u_short isl_type; - union { - u_short isl_filler[2]; - u_short isl_ports[2]; - u_short isl_icmp; - } isl_ps; - u_char isl_v; - u_char isl_p; - u_char isl_flags; - u_char isl_state[2]; - u_32_t isl_rulen; - char isl_group[FR_GROUPLEN]; -} ipslog_t; - -#define isl_sport isl_ps.isl_ports[0] -#define isl_dport isl_ps.isl_ports[1] -#define isl_itype isl_ps.isl_icmp - -#define ISL_NEW 0 -#define ISL_CLONE 1 -#define ISL_EXPIRE 0xffff -#define ISL_FLUSH 0xfffe -#define ISL_REMOVE 0xfffd -#define ISL_INTERMEDIATE 0xfffc -#define ISL_KILLED 0xfffb -#define ISL_ORPHAN 0xfffa - - -typedef struct ips_stat { - u_long iss_hits; - u_long iss_miss; - u_long iss_max; - u_long iss_maxref; - u_long iss_tcp; - u_long iss_udp; - u_long iss_icmp; - u_long iss_nomem; - u_long iss_expire; - u_long iss_fin; - u_long iss_active; - u_long iss_logged; - u_long iss_logfail; - u_long iss_inuse; - u_long iss_wild; - u_long iss_killed; - u_long iss_ticks; - u_long iss_bucketfull; - int iss_statesize; - int iss_statemax; - ipstate_t **iss_table; - ipstate_t *iss_list; - u_long *iss_bucketlen; -} ips_stat_t; - - -extern u_long fr_tcpidletimeout; -extern u_long fr_tcpclosewait; -extern u_long fr_tcplastack; -extern u_long fr_tcptimeout; -extern u_long fr_tcpclosed; -extern u_long fr_tcphalfclosed; -extern u_long fr_udptimeout; -extern u_long fr_udpacktimeout; -extern u_long fr_icmptimeout; -extern u_long fr_icmpacktimeout; -extern u_long fr_iptimeout; -extern int fr_statemax; -extern int fr_statesize; -extern int fr_state_lock; -extern int fr_state_maxbucket; -extern int fr_state_maxbucket_reset; -extern ipstate_t *ips_list; -extern ipftq_t *ips_utqe; -extern ipftq_t ips_tqtqb[IPF_TCP_NSTATES]; - -extern int fr_stateinit __P((void)); -extern ipstate_t *fr_addstate __P((fr_info_t *, ipstate_t **, u_int)); -extern frentry_t *fr_checkstate __P((struct fr_info *, u_32_t *)); -extern ipstate_t *fr_stlookup __P((fr_info_t *, tcphdr_t *, ipftq_t **)); -extern void fr_statesync __P((void *)); -extern void fr_timeoutstate __P((void)); -extern int fr_tcp_age __P((struct ipftqent *, struct fr_info *, - struct ipftq *, int)); -extern int fr_tcpinwindow __P((struct fr_info *, struct tcpdata *, - struct tcpdata *, tcphdr_t *, int)); -extern void fr_stateunload __P((void)); -extern void ipstate_log __P((struct ipstate *, u_int)); -extern int fr_state_ioctl __P((caddr_t, ioctlcmd_t, int)); -extern void fr_stinsert __P((struct ipstate *, int)); -extern void fr_sttab_init __P((struct ipftq *)); -extern void fr_sttab_destroy __P((struct ipftq *)); -extern void fr_updatestate __P((fr_info_t *, ipstate_t *, ipftq_t *)); -extern void fr_statederef __P((fr_info_t *, ipstate_t **)); -extern void fr_setstatequeue __P((ipstate_t *, int)); - -#endif /* __IP_STATE_H__ */ diff --git a/contrib/ipfilter/ip_sync.c b/contrib/ipfilter/ip_sync.c deleted file mode 100644 index 396bae791196..000000000000 --- a/contrib/ipfilter/ip_sync.c +++ /dev/null @@ -1,1001 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1995-1998 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(KERNEL) || defined(_KERNEL) -# undef KERNEL -# undef _KERNEL -# define KERNEL 1 -# define _KERNEL 1 -#endif -#include -#include -#include -#include -#if !defined(_KERNEL) && !defined(__KERNEL__) -# include -# include -# include -# define _KERNEL -# define KERNEL -# ifdef __OpenBSD__ -struct file; -# endif -# include -# undef _KERNEL -# undef KERNEL -#else -# include -# if !defined(__SVR4) && !defined(__svr4__) -# include -# endif -#endif -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000) -# include -#endif -#if defined(_KERNEL) && (__FreeBSD_version >= 220000) -# include -# include -# if (__FreeBSD_version >= 300000) && !defined(IPFILTER_LKM) -# include "opt_ipfilter.h" -# endif -#else -# include -#endif -#include -#if !defined(linux) -# include -#endif -#include -#if defined(__SVR4) || defined(__svr4__) -# include -# include -# ifdef _KERNEL -# include -# endif -# include -# include -#endif - -#include -#ifdef sun -# include -#endif -#include -#include -#include -#include -#include -#if !defined(linux) -# include -#endif -#if !defined(__hpux) && !defined(linux) -# include -#endif -#include -#include -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_frag.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "netinet/ip_sync.h" -#ifdef USE_INET6 -#include -#endif -#if (__FreeBSD_version >= 300000) -# include -# if defined(_KERNEL) && !defined(IPFILTER_LKM) -# include -# include -# endif -#endif -/* END OF INCLUDES */ - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ip_sync.c,v 2.40.2.3 2005/02/18 13:06:29 darrenr Exp"; -#endif - -#define SYNC_STATETABSZ 256 -#define SYNC_NATTABSZ 256 - -#ifdef IPFILTER_SYNC -ipfmutex_t ipf_syncadd, ipsl_mutex; -ipfrwlock_t ipf_syncstate, ipf_syncnat; -#if SOLARIS && defined(_KERNEL) -kcondvar_t ipslwait; -#endif -synclist_t *syncstatetab[SYNC_STATETABSZ]; -synclist_t *syncnattab[SYNC_NATTABSZ]; -synclogent_t synclog[SYNCLOG_SZ]; -syncupdent_t syncupd[SYNCLOG_SZ]; -u_int ipf_syncnum = 1; -u_int ipf_syncwrap = 0; -u_int sl_idx = 0, /* next available sync log entry */ - su_idx = 0, /* next available sync update entry */ - sl_tail = 0, /* next sync log entry to read */ - su_tail = 0; /* next sync update entry to read */ -int ipf_sync_debug = 0; - - -# if !defined(sparc) && !defined(__hppa) -void ipfsync_tcporder __P((int, struct tcpdata *)); -void ipfsync_natorder __P((int, struct nat *)); -void ipfsync_storder __P((int, struct ipstate *)); -# endif - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_init */ -/* Returns: int - 0 == success, -1 == failure */ -/* Parameters: Nil */ -/* */ -/* Initialise all of the locks required for the sync code and initialise */ -/* any data structures, as required. */ -/* ------------------------------------------------------------------------ */ -int ipfsync_init() -{ - RWLOCK_INIT(&ipf_syncstate, "add things to state sync table"); - RWLOCK_INIT(&ipf_syncnat, "add things to nat sync table"); - MUTEX_INIT(&ipf_syncadd, "add things to sync table"); - MUTEX_INIT(&ipsl_mutex, "add things to sync table"); -# if SOLARIS && defined(_KERNEL) - cv_init(&ipslwait, "ipsl condvar", CV_DRIVER, NULL); -# endif - - bzero((char *)syncnattab, sizeof(syncnattab)); - bzero((char *)syncstatetab, sizeof(syncstatetab)); - - return 0; -} - - -# if !defined(sparc) && !defined(__hppa) -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_tcporder */ -/* Returns: Nil */ -/* Parameters: way(I) - direction of byte order conversion. */ -/* td(IO) - pointer to data to be converted. */ -/* */ -/* Do byte swapping on values in the TCP state information structure that */ -/* need to be used at both ends by the host in their native byte order. */ -/* ------------------------------------------------------------------------ */ -void ipfsync_tcporder(way, td) -int way; -tcpdata_t *td; -{ - if (way) { - td->td_maxwin = htons(td->td_maxwin); - td->td_end = htonl(td->td_end); - td->td_maxend = htonl(td->td_maxend); - } else { - td->td_maxwin = ntohs(td->td_maxwin); - td->td_end = ntohl(td->td_end); - td->td_maxend = ntohl(td->td_maxend); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_natorder */ -/* Returns: Nil */ -/* Parameters: way(I) - direction of byte order conversion. */ -/* nat(IO) - pointer to data to be converted. */ -/* */ -/* Do byte swapping on values in the NAT data structure that need to be */ -/* used at both ends by the host in their native byte order. */ -/* ------------------------------------------------------------------------ */ -void ipfsync_natorder(way, n) -int way; -nat_t *n; -{ - if (way) { - n->nat_age = htonl(n->nat_age); - n->nat_flags = htonl(n->nat_flags); - n->nat_ipsumd = htonl(n->nat_ipsumd); - n->nat_use = htonl(n->nat_use); - n->nat_dir = htonl(n->nat_dir); - } else { - n->nat_age = ntohl(n->nat_age); - n->nat_flags = ntohl(n->nat_flags); - n->nat_ipsumd = ntohl(n->nat_ipsumd); - n->nat_use = ntohl(n->nat_use); - n->nat_dir = ntohl(n->nat_dir); - } -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_storder */ -/* Returns: Nil */ -/* Parameters: way(I) - direction of byte order conversion. */ -/* ips(IO) - pointer to data to be converted. */ -/* */ -/* Do byte swapping on values in the IP state data structure that need to */ -/* be used at both ends by the host in their native byte order. */ -/* ------------------------------------------------------------------------ */ -void ipfsync_storder(way, ips) -int way; -ipstate_t *ips; -{ - ipfsync_tcporder(way, &ips->is_tcp.ts_data[0]); - ipfsync_tcporder(way, &ips->is_tcp.ts_data[1]); - - if (way) { - ips->is_hv = htonl(ips->is_hv); - ips->is_die = htonl(ips->is_die); - ips->is_pass = htonl(ips->is_pass); - ips->is_flags = htonl(ips->is_flags); - ips->is_opt = htonl(ips->is_opt); - ips->is_optmsk = htonl(ips->is_optmsk); - ips->is_sec = htons(ips->is_sec); - ips->is_secmsk = htons(ips->is_secmsk); - ips->is_auth = htons(ips->is_auth); - ips->is_authmsk = htons(ips->is_authmsk); - ips->is_s0[0] = htonl(ips->is_s0[0]); - ips->is_s0[1] = htonl(ips->is_s0[1]); - ips->is_smsk[0] = htons(ips->is_smsk[0]); - ips->is_smsk[1] = htons(ips->is_smsk[1]); - } else { - ips->is_hv = ntohl(ips->is_hv); - ips->is_die = ntohl(ips->is_die); - ips->is_pass = ntohl(ips->is_pass); - ips->is_flags = ntohl(ips->is_flags); - ips->is_opt = ntohl(ips->is_opt); - ips->is_optmsk = ntohl(ips->is_optmsk); - ips->is_sec = ntohs(ips->is_sec); - ips->is_secmsk = ntohs(ips->is_secmsk); - ips->is_auth = ntohs(ips->is_auth); - ips->is_authmsk = ntohs(ips->is_authmsk); - ips->is_s0[0] = ntohl(ips->is_s0[0]); - ips->is_s0[1] = ntohl(ips->is_s0[1]); - ips->is_smsk[0] = ntohl(ips->is_smsk[0]); - ips->is_smsk[1] = ntohl(ips->is_smsk[1]); - } -} -# else /* !defined(sparc) && !defined(__hppa) */ -# define ipfsync_tcporder(x,y) -# define ipfsync_natorder(x,y) -# define ipfsync_storder(x,y) -# endif /* !defined(sparc) && !defined(__hppa) */ - -/* enable this for debugging */ - -# ifdef _KERNEL -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_write */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: uio(I) - pointer to information about data to write */ -/* */ -/* Moves data from user space into the kernel and uses it for updating data */ -/* structures in the state/NAT tables. */ -/* ------------------------------------------------------------------------ */ -int ipfsync_write(uio) -struct uio *uio; -{ - synchdr_t sh; - - /* - * THIS MUST BE SUFFICIENT LARGE TO STORE - * ANY POSSIBLE DATA TYPE - */ - char data[2048]; - - int err = 0; - -# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) - uio->uio_rw = UIO_WRITE; -# endif - - /* Try to get bytes */ - while (uio->uio_resid > 0) { - - if (uio->uio_resid >= sizeof(sh)) { - - err = UIOMOVE((caddr_t)&sh, sizeof(sh), UIO_WRITE, uio); - - if (err) { - if (ipf_sync_debug > 2) - printf("uiomove(header) failed: %d\n", - err); - return err; - } - - /* convert to host order */ - sh.sm_magic = ntohl(sh.sm_magic); - sh.sm_len = ntohl(sh.sm_len); - sh.sm_num = ntohl(sh.sm_num); - - if (ipf_sync_debug > 8) - printf("[%d] Read v:%d p:%d cmd:%d table:%d rev:%d len:%d magic:%x\n", - sh.sm_num, sh.sm_v, sh.sm_p, sh.sm_cmd, - sh.sm_table, sh.sm_rev, sh.sm_len, - sh.sm_magic); - - if (sh.sm_magic != SYNHDRMAGIC) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalud %s\n", - "magic"); - return EINVAL; - } - - if (sh.sm_v != 4 && sh.sm_v != 6) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalid %s\n", - "protocol"); - return EINVAL; - } - - if (sh.sm_cmd > SMC_MAXCMD) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalid %s\n", - "command"); - return EINVAL; - } - - - if (sh.sm_table > SMC_MAXTBL) { - if (ipf_sync_debug > 2) - printf("uiomove(header) invalid %s\n", - "table"); - return EINVAL; - } - - } else { - /* unsufficient data, wait until next call */ - if (ipf_sync_debug > 2) - printf("uiomove(header) insufficient data"); - return EAGAIN; - } - - - /* - * We have a header, so try to read the amount of data - * needed for the request - */ - - /* not supported */ - if (sh.sm_len == 0) { - if (ipf_sync_debug > 2) - printf("uiomove(data zero length %s\n", - "not supported"); - return EINVAL; - } - - if (uio->uio_resid >= sh.sm_len) { - - err = UIOMOVE((caddr_t)data, sh.sm_len, UIO_WRITE, uio); - - if (err) { - if (ipf_sync_debug > 2) - printf("uiomove(data) failed: %d\n", - err); - return err; - } - - if (ipf_sync_debug > 7) - printf("uiomove(data) %d bytes read\n", - sh.sm_len); - - if (sh.sm_table == SMC_STATE) - err = ipfsync_state(&sh, data); - else if (sh.sm_table == SMC_NAT) - err = ipfsync_nat(&sh, data); - if (ipf_sync_debug > 7) - printf("[%d] Finished with error %d\n", - sh.sm_num, err); - - } else { - /* insufficient data, wait until next call */ - if (ipf_sync_debug > 2) - printf("uiomove(data) %s %d bytes, got %d\n", - "insufficient data, need", - sh.sm_len, uio->uio_resid); - return EAGAIN; - } - } - - /* no more data */ - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_read */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: uio(O) - pointer to information about where to store data */ -/* */ -/* This function is called when a user program wants to read some data */ -/* for pending state/NAT updates. If no data is available, the caller is */ -/* put to sleep, pending a wakeup from the "lower half" of this code. */ -/* ------------------------------------------------------------------------ */ -int ipfsync_read(uio) -struct uio *uio; -{ - syncupdent_t *su; - synclogent_t *sl; - int err = 0; - - if ((uio->uio_resid & 3) || (uio->uio_resid < 8)) - return EINVAL; - -# if (BSD >= 199306) || defined(__FreeBSD__) || defined(__osf__) - uio->uio_rw = UIO_READ; -# endif - - MUTEX_ENTER(&ipsl_mutex); - while ((sl_tail == sl_idx) && (su_tail == su_idx)) { -# if SOLARIS && defined(_KERNEL) - if (!cv_wait_sig(&ipslwait, &ipsl_mutex)) { - MUTEX_EXIT(&ipsl_mutex); - return EINTR; - } -# else -# ifdef __hpux - { - lock_t *l; - - l = get_sleep_lock(&sl_tail); - err = sleep(&sl_tail, PZERO+1); - spinunlock(l); - } -# else /* __hpux */ -# ifdef __osf__ - err = mpsleep(&sl_tail, PSUSP|PCATCH, "ipl sleep", 0, - &ipsl_mutex, MS_LOCK_SIMPLE); -# else - MUTEX_EXIT(&ipsl_mutex); - err = SLEEP(&sl_tail, "ipl sleep"); -# endif /* __osf__ */ -# endif /* __hpux */ - if (err) { - MUTEX_EXIT(&ipsl_mutex); - return err; - } -# endif /* SOLARIS */ - } - MUTEX_EXIT(&ipsl_mutex); - - READ_ENTER(&ipf_syncstate); - while ((sl_tail < sl_idx) && (uio->uio_resid > sizeof(*sl))) { - sl = synclog + sl_tail++; - err = UIOMOVE((caddr_t)sl, sizeof(*sl), UIO_READ, uio); - if (err != 0) - break; - } - - while ((su_tail < su_idx) && (uio->uio_resid > sizeof(*su))) { - su = syncupd + su_tail; - su_tail++; - err = UIOMOVE((caddr_t)su, sizeof(*su), UIO_READ, uio); - if (err != 0) - break; - if (su->sup_hdr.sm_sl != NULL) - su->sup_hdr.sm_sl->sl_idx = -1; - } - - MUTEX_ENTER(&ipf_syncadd); - if (su_tail == su_idx) - su_tail = su_idx = 0; - if (sl_tail == sl_idx) - sl_tail = sl_idx = 0; - MUTEX_EXIT(&ipf_syncadd); - RWLOCK_EXIT(&ipf_syncstate); - return err; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_state */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: sp(I) - pointer to sync packet data header */ -/* uio(I) - pointer to user data for further information */ -/* */ -/* Updates the state table according to information passed in the sync */ -/* header. As required, more data is fetched from the uio structure but */ -/* varies depending on the contents of the sync header. This function can */ -/* create a new state entry or update one. Deletion is left to the state */ -/* structures being timed out correctly. */ -/* ------------------------------------------------------------------------ */ -int ipfsync_state(sp, data) -synchdr_t *sp; -void *data; -{ - synctcp_update_t su; - ipstate_t *is, sn; - synclist_t *sl; - frentry_t *fr; - u_int hv; - int err = 0; - - hv = sp->sm_num & (SYNC_STATETABSZ - 1); - - switch (sp->sm_cmd) - { - case SMC_CREATE : - - bcopy(data, &sn, sizeof(sn)); - KMALLOC(is, ipstate_t *); - if (is == NULL) { - err = ENOMEM; - break; - } - - KMALLOC(sl, synclist_t *); - if (sl == NULL) { - err = ENOMEM; - KFREE(is); - break; - } - - bzero((char *)is, offsetof(ipstate_t, is_die)); - bcopy((char *)&sn.is_die, (char *)&is->is_die, - sizeof(*is) - offsetof(ipstate_t, is_die)); - ipfsync_storder(0, is); - - /* - * We need to find the same rule on the slave as was used on - * the master to create this state entry. - */ - READ_ENTER(&ipf_mutex); - fr = fr_getrulen(IPL_LOGIPF, sn.is_group, sn.is_rulen); - if (fr != NULL) { - MUTEX_ENTER(&fr->fr_lock); - fr->fr_ref++; - fr->fr_statecnt++; - MUTEX_EXIT(&fr->fr_lock); - } - RWLOCK_EXIT(&ipf_mutex); - - if (ipf_sync_debug > 4) - printf("[%d] Filter rules = %p\n", sp->sm_num, fr); - - is->is_rule = fr; - is->is_sync = sl; - - sl->sl_idx = -1; - sl->sl_ips = is; - bcopy(sp, &sl->sl_hdr, sizeof(struct synchdr)); - - WRITE_ENTER(&ipf_syncstate); - WRITE_ENTER(&ipf_state); - - sl->sl_pnext = syncstatetab + hv; - sl->sl_next = syncstatetab[hv]; - if (syncstatetab[hv] != NULL) - syncstatetab[hv]->sl_pnext = &sl->sl_next; - syncstatetab[hv] = sl; - MUTEX_DOWNGRADE(&ipf_syncstate); - fr_stinsert(is, sp->sm_rev); - /* - * Do not initialise the interface pointers for the state - * entry as the full complement of interface names may not - * be present. - * - * Put this state entry on its timeout queue. - */ - /*fr_setstatequeue(is, sp->sm_rev);*/ - break; - - case SMC_UPDATE : - bcopy(data, &su, sizeof(su)); - - if (ipf_sync_debug > 4) - printf("[%d] Update age %lu state %d/%d \n", - sp->sm_num, su.stu_age, su.stu_state[0], - su.stu_state[1]); - - READ_ENTER(&ipf_syncstate); - for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) - if (sl->sl_hdr.sm_num == sp->sm_num) - break; - if (sl == NULL) { - if (ipf_sync_debug > 1) - printf("[%d] State not found - can't update\n", - sp->sm_num); - RWLOCK_EXIT(&ipf_syncstate); - err = ENOENT; - break; - } - - READ_ENTER(&ipf_state); - - if (ipf_sync_debug > 6) - printf("[%d] Data from state v:%d p:%d cmd:%d table:%d rev:%d\n", - sp->sm_num, sl->sl_hdr.sm_v, sl->sl_hdr.sm_p, - sl->sl_hdr.sm_cmd, sl->sl_hdr.sm_table, - sl->sl_hdr.sm_rev); - - is = sl->sl_ips; - - MUTEX_ENTER(&is->is_lock); - switch (sp->sm_p) - { - case IPPROTO_TCP : - /* XXX FV --- shouldn't we do ntohl/htonl???? XXX */ - is->is_send = su.stu_data[0].td_end; - is->is_maxsend = su.stu_data[0].td_maxend; - is->is_maxswin = su.stu_data[0].td_maxwin; - is->is_state[0] = su.stu_state[0]; - is->is_dend = su.stu_data[1].td_end; - is->is_maxdend = su.stu_data[1].td_maxend; - is->is_maxdwin = su.stu_data[1].td_maxwin; - is->is_state[1] = su.stu_state[1]; - break; - default : - break; - } - - if (ipf_sync_debug > 6) - printf("[%d] Setting timers for state\n", sp->sm_num); - - fr_setstatequeue(is, sp->sm_rev); - - MUTEX_EXIT(&is->is_lock); - break; - - default : - err = EINVAL; - break; - } - - if (err == 0) { - RWLOCK_EXIT(&ipf_state); - RWLOCK_EXIT(&ipf_syncstate); - } - - if (ipf_sync_debug > 6) - printf("[%d] Update completed with error %d\n", - sp->sm_num, err); - - return err; -} -# endif /* _KERNEL */ - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_del */ -/* Returns: Nil */ -/* Parameters: sl(I) - pointer to synclist object to delete */ -/* */ -/* Deletes an object from the synclist table and free's its memory. */ -/* ------------------------------------------------------------------------ */ -void ipfsync_del(sl) -synclist_t *sl; -{ - WRITE_ENTER(&ipf_syncstate); - *sl->sl_pnext = sl->sl_next; - if (sl->sl_next != NULL) - sl->sl_next->sl_pnext = sl->sl_pnext; - if (sl->sl_idx != -1) - syncupd[sl->sl_idx].sup_hdr.sm_sl = NULL; - RWLOCK_EXIT(&ipf_syncstate); - KFREE(sl); -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_nat */ -/* Returns: int - 0 == success, else error value. */ -/* Parameters: sp(I) - pointer to sync packet data header */ -/* uio(I) - pointer to user data for further information */ -/* */ -/* Updates the NAT table according to information passed in the sync */ -/* header. As required, more data is fetched from the uio structure but */ -/* varies depending on the contents of the sync header. This function can */ -/* create a new NAT entry or update one. Deletion is left to the NAT */ -/* structures being timed out correctly. */ -/* ------------------------------------------------------------------------ */ -int ipfsync_nat(sp, data) -synchdr_t *sp; -void *data; -{ - synclogent_t sle; - syncupdent_t su; - nat_t *n, *nat; - synclist_t *sl; - u_int hv = 0; - int err; - - READ_ENTER(&ipf_syncstate); - - switch (sp->sm_cmd) - { - case SMC_CREATE : - bcopy(data, &sle, sizeof(sle)); - - KMALLOC(n, nat_t *); - if (n == NULL) { - err = ENOMEM; - break; - } - - KMALLOC(sl, synclist_t *); - if (sl == NULL) { - err = ENOMEM; - KFREE(n); - break; - } - - WRITE_ENTER(&ipf_nat); - - nat = &sle.sle_un.sleu_ipn; - bzero((char *)n, offsetof(nat_t, nat_age)); - bcopy((char *)&nat->nat_age, (char *)&n->nat_age, - sizeof(*n) - offsetof(nat_t, nat_age)); - ipfsync_natorder(0, n); - n->nat_sync = sl; - - sl->sl_idx = -1; - sl->sl_ipn = n; - sl->sl_num = ntohl(sp->sm_num); - sl->sl_pnext = syncstatetab + hv; - sl->sl_next = syncstatetab[hv]; - if (syncstatetab[hv] != NULL) - syncstatetab[hv]->sl_pnext = &sl->sl_next; - syncstatetab[hv] = sl; - nat_insert(n, sl->sl_rev); - RWLOCK_EXIT(&ipf_nat); - break; - - case SMC_UPDATE : - bcopy(data, &su, sizeof(su)); - - READ_ENTER(&ipf_syncstate); - for (sl = syncstatetab[hv]; (sl != NULL); sl = sl->sl_next) - if (sl->sl_hdr.sm_num == sp->sm_num) - break; - if (sl == NULL) { - err = ENOENT; - break; - } - - READ_ENTER(&ipf_nat); - - nat = sl->sl_ipn; - - MUTEX_ENTER(&nat->nat_lock); - fr_setnatqueue(nat, sl->sl_rev); - MUTEX_EXIT(&nat->nat_lock); - - RWLOCK_EXIT(&ipf_nat); - - break; - - default : - err = EINVAL; - break; - } - - RWLOCK_EXIT(&ipf_syncstate); - return 0; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_new */ -/* Returns: synclist_t* - NULL == failure, else pointer to new synclist */ -/* data structure. */ -/* Parameters: tab(I) - type of synclist_t to create */ -/* fin(I) - pointer to packet information */ -/* ptr(I) - pointer to owning object */ -/* */ -/* Creates a new sync table entry and notifies any sleepers that it's there */ -/* waiting to be processed. */ -/* ------------------------------------------------------------------------ */ -synclist_t *ipfsync_new(tab, fin, ptr) -int tab; -fr_info_t *fin; -void *ptr; -{ - synclist_t *sl, *ss; - synclogent_t *sle; - u_int hv, sz; - - if (sl_idx == SYNCLOG_SZ) - return NULL; - KMALLOC(sl, synclist_t *); - if (sl == NULL) - return NULL; - - MUTEX_ENTER(&ipf_syncadd); - /* - * Get a unique number for this synclist_t. The number is only meant - * to be unique for the lifetime of the structure and may be reused - * later. - */ - ipf_syncnum++; - if (ipf_syncnum == 0) { - ipf_syncnum = 1; - ipf_syncwrap = 1; - } - - hv = ipf_syncnum & (SYNC_STATETABSZ - 1); - while (ipf_syncwrap != 0) { - for (ss = syncstatetab[hv]; ss; ss = ss->sl_next) - if (ss->sl_hdr.sm_num == ipf_syncnum) - break; - if (ss == NULL) - break; - ipf_syncnum++; - hv = ipf_syncnum & (SYNC_STATETABSZ - 1); - } - /* - * Use the synch number of the object as the hash key. Should end up - * with relatively even distribution over time. - * XXX - an attacker could lunch an DoS attack, of sorts, if they are - * the only one causing new table entries by only keeping open every - * nth connection they make, where n is a value in the interval - * [0, SYNC_STATETABSZ-1]. - */ - sl->sl_pnext = syncstatetab + hv; - sl->sl_next = syncstatetab[hv]; - syncstatetab[hv] = sl; - sl->sl_num = ipf_syncnum; - MUTEX_EXIT(&ipf_syncadd); - - sl->sl_magic = htonl(SYNHDRMAGIC); - sl->sl_v = fin->fin_v; - sl->sl_p = fin->fin_p; - sl->sl_cmd = SMC_CREATE; - sl->sl_idx = -1; - sl->sl_table = tab; - sl->sl_rev = fin->fin_rev; - if (tab == SMC_STATE) { - sl->sl_ips = ptr; - sz = sizeof(*sl->sl_ips); - } else if (tab == SMC_NAT) { - sl->sl_ipn = ptr; - sz = sizeof(*sl->sl_ipn); - } else { - ptr = NULL; - sz = 0; - } - sl->sl_len = sz; - - /* - * Create the log entry to be read by a user daemon. When it has been - * finished and put on the queue, send a signal to wakeup any waiters. - */ - MUTEX_ENTER(&ipf_syncadd); - sle = synclog + sl_idx++; - bcopy((char *)&sl->sl_hdr, (char *)&sle->sle_hdr, - sizeof(sle->sle_hdr)); - sle->sle_hdr.sm_num = htonl(sle->sle_hdr.sm_num); - sle->sle_hdr.sm_len = htonl(sle->sle_hdr.sm_len); - if (ptr != NULL) { - bcopy((char *)ptr, (char *)&sle->sle_un, sz); - if (tab == SMC_STATE) { - ipfsync_storder(1, &sle->sle_un.sleu_ips); - } else if (tab == SMC_NAT) { - ipfsync_natorder(1, &sle->sle_un.sleu_ipn); - } - } - MUTEX_EXIT(&ipf_syncadd); - - MUTEX_ENTER(&ipsl_mutex); -# if SOLARIS -# ifdef _KERNEL - cv_signal(&ipslwait); -# endif - MUTEX_EXIT(&ipsl_mutex); -# else - MUTEX_EXIT(&ipsl_mutex); -# ifdef _KERNEL - wakeup(&sl_tail); -# endif -# endif - return sl; -} - - -/* ------------------------------------------------------------------------ */ -/* Function: ipfsync_update */ -/* Returns: Nil */ -/* Parameters: tab(I) - type of synclist_t to create */ -/* fin(I) - pointer to packet information */ -/* sl(I) - pointer to synchronisation object */ -/* */ -/* For outbound packets, only, create an sync update record for the user */ -/* process to read. */ -/* ------------------------------------------------------------------------ */ -void ipfsync_update(tab, fin, sl) -int tab; -fr_info_t *fin; -synclist_t *sl; -{ - synctcp_update_t *st; - syncupdent_t *slu; - ipstate_t *ips; - nat_t *nat; - - if (fin->fin_out == 0 || sl == NULL) - return; - - WRITE_ENTER(&ipf_syncstate); - MUTEX_ENTER(&ipf_syncadd); - if (sl->sl_idx == -1) { - slu = syncupd + su_idx; - sl->sl_idx = su_idx++; - bcopy((char *)&sl->sl_hdr, (char *)&slu->sup_hdr, - sizeof(slu->sup_hdr)); - slu->sup_hdr.sm_magic = htonl(SYNHDRMAGIC); - slu->sup_hdr.sm_sl = sl; - slu->sup_hdr.sm_cmd = SMC_UPDATE; - slu->sup_hdr.sm_table = tab; - slu->sup_hdr.sm_num = htonl(sl->sl_num); - slu->sup_hdr.sm_len = htonl(sizeof(struct synctcp_update)); - slu->sup_hdr.sm_rev = fin->fin_rev; -# if 0 - if (fin->fin_p == IPPROTO_TCP) { - st->stu_len[0] = 0; - st->stu_len[1] = 0; - } -# endif - } else - slu = syncupd + sl->sl_idx; - MUTEX_EXIT(&ipf_syncadd); - MUTEX_DOWNGRADE(&ipf_syncstate); - - /* - * Only TCP has complex timeouts, others just use default timeouts. - * For TCP, we only need to track the connection state and window. - */ - if (fin->fin_p == IPPROTO_TCP) { - st = &slu->sup_tcp; - if (tab == SMC_STATE) { - ips = sl->sl_ips; - st->stu_age = htonl(ips->is_die); - st->stu_data[0].td_end = ips->is_send; - st->stu_data[0].td_maxend = ips->is_maxsend; - st->stu_data[0].td_maxwin = ips->is_maxswin; - st->stu_state[0] = ips->is_state[0]; - st->stu_data[1].td_end = ips->is_dend; - st->stu_data[1].td_maxend = ips->is_maxdend; - st->stu_data[1].td_maxwin = ips->is_maxdwin; - st->stu_state[1] = ips->is_state[1]; - } else if (tab == SMC_NAT) { - nat = sl->sl_ipn; - st->stu_age = htonl(nat->nat_age); - } - } - RWLOCK_EXIT(&ipf_syncstate); - - MUTEX_ENTER(&ipsl_mutex); -# if SOLARIS -# ifdef _KERNEL - cv_signal(&ipslwait); -# endif - MUTEX_EXIT(&ipsl_mutex); -# else - MUTEX_EXIT(&ipsl_mutex); -# ifdef _KERNEL - wakeup(&sl_tail); -# endif -# endif -} - - -/* ------------------------------------------------------------------------ */ -/* Function: fr_sync_ioctl */ -/* Returns: int - 0 == success, != 0 == failure */ -/* Parameters: data(I) - pointer to ioctl data */ -/* cmd(I) - ioctl command integer */ -/* mode(I) - file mode bits used with open */ -/* */ -/* This function currently does not handle any ioctls and so just returns */ -/* EINVAL on all occasions. */ -/* ------------------------------------------------------------------------ */ -int fr_sync_ioctl(data, cmd, mode) -caddr_t data; -ioctlcmd_t cmd; -int mode; -{ - return EINVAL; -} -#endif /* IPFILTER_SYNC */ diff --git a/contrib/ipfilter/ip_sync.h b/contrib/ipfilter/ip_sync.h deleted file mode 100644 index e319a95dfcdb..000000000000 --- a/contrib/ipfilter/ip_sync.h +++ /dev/null @@ -1,117 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ip_fil.h 1.35 6/5/96 - * Id: ip_sync.h,v 2.11.2.2 2004/11/04 19:29:07 darrenr Exp - */ - -#ifndef __IP_SYNC_H__ -#define __IP_SYNC_H__ - -typedef struct synchdr { - u_32_t sm_magic; /* magic */ - u_char sm_v; /* version: 4,6 */ - u_char sm_p; /* protocol */ - u_char sm_cmd; /* command */ - u_char sm_table; /* NAT, STATE, etc */ - u_int sm_num; /* table entry number */ - int sm_rev; /* forward/reverse */ - int sm_len; /* length of the data section */ - struct synclist *sm_sl; /* back pointer to parent */ -} synchdr_t; - - -#define SYNHDRMAGIC 0x0FF51DE5 - -/* - * Commands - * No delete required as expirey will take care of that! - */ -#define SMC_CREATE 0 /* pass ipstate_t after synchdr_t */ -#define SMC_UPDATE 1 -#define SMC_MAXCMD 1 - -/* - * Tables - */ -#define SMC_NAT 0 -#define SMC_STATE 1 -#define SMC_MAXTBL 1 - - -/* - * Only TCP requires "more" information than just a reference to the entry - * for which an update is being made. - */ -typedef struct synctcp_update { - u_long stu_age; - tcpdata_t stu_data[2]; - int stu_state[2]; -} synctcp_update_t; - - -typedef struct synclist { - struct synclist *sl_next; - struct synclist **sl_pnext; - int sl_idx; /* update index */ - struct synchdr sl_hdr; - union { - struct ipstate *slu_ips; - struct nat *slu_ipn; - void *slu_ptr; - } sl_un; -} synclist_t; - -#define sl_ptr sl_un.slu_ptr -#define sl_ips sl_un.slu_ips -#define sl_ipn sl_un.slu_ipn -#define sl_magic sl_hdr.sm_magic -#define sl_v sl_hdr.sm_v -#define sl_p sl_hdr.sm_p -#define sl_cmd sl_hdr.sm_cmd -#define sl_rev sl_hdr.sm_rev -#define sl_table sl_hdr.sm_table -#define sl_num sl_hdr.sm_num -#define sl_len sl_hdr.sm_len - -/* - * NOTE: SYNCLOG_SZ is defined *low*. It should be the next power of two - * up for whatever number of packets per second you expect to see. Be - * warned: this index's a table of large elements (upto 272 bytes in size - * each), and thus a size of 8192, for example, results in a 2MB table. - * The lesson here is not to use small machines for running fast firewalls - * (100BaseT) in sync, where you might have upwards of 10k pps. - */ -#define SYNCLOG_SZ 256 - -typedef struct synclogent { - struct synchdr sle_hdr; - union { - struct ipstate sleu_ips; - struct nat sleu_ipn; - } sle_un; -} synclogent_t; - -typedef struct syncupdent { /* 28 or 32 bytes */ - struct synchdr sup_hdr; - struct synctcp_update sup_tcp; -} syncupdent_t; - -extern synclogent_t synclog[SYNCLOG_SZ]; - - -extern int fr_sync_ioctl __P((caddr_t, ioctlcmd_t, int)); -extern synclist_t *ipfsync_new __P((int, fr_info_t *, void *)); -extern void ipfsync_del __P((synclist_t *)); -extern void ipfsync_update __P((int, fr_info_t *, synclist_t *)); -extern int ipfsync_init __P((void)); -extern int ipfsync_nat __P((synchdr_t *sp, void *data)); -extern int ipfsync_state __P((synchdr_t *sp, void *data)); -extern int ipfsync_read __P((struct uio *uio)); -extern int ipfsync_write __P((struct uio *uio)); - -#endif /* IP_SYNC */ diff --git a/contrib/ipfilter/ipf.c b/contrib/ipfilter/ipf.c deleted file mode 100644 index cf8528046897..000000000000 --- a/contrib/ipfilter/ipf.c +++ /dev/null @@ -1,764 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#ifdef __FreeBSD__ -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -#endif -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include "ip_compat.h" -#include "ip_fil.h" -#include "ip_nat.h" -#include "ip_state.h" -#include "ipf.h" -#include "ipl.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.23 2003/06/27 14:39:13 darrenr Exp $"; -#endif - -#if SOLARIS -static void blockunknown __P((void)); -#endif -#if !defined(__SVR4) && defined(__GNUC__) -extern char *index __P((const char *, int)); -#endif - -extern char *optarg; -extern int optind; - -void frsync __P((void)); -void zerostats __P((void)); -int main __P((int, char *[])); - -int opts = 0; -int use_inet6 = 0; - -static int fd = -1; - -static void procfile __P((char *, char *)), flushfilter __P((char *)); -static int set_state __P((u_int)); -static void showstats __P((friostat_t *)); -static void packetlogon __P((char *)), swapactive __P((void)); -static int opendevice __P((char *)); -static void closedevice __P((void)); -static char *getline __P((char *, size_t, FILE *, int *)); -static char *ipfname = IPL_NAME; -static void usage __P((char *)); -static int showversion __P((void)); -static int get_flags __P((int *)); - - -#if SOLARIS -# define OPTS "6AdDEf:F:Il:noPrsUvVyzZ" -#else -# define OPTS "6AdDEf:F:Il:noPrsvVyzZ" -#endif - -static void usage(name) -char *name; -{ - fprintf(stderr, "usage: %s [-%s] %s %s %s\n", name, OPTS, - "[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]"); - exit(1); -} - - -int main(argc,argv) -int argc; -char *argv[]; -{ - int c; - - if (argc < 2) - usage(argv[0]); - - while ((c = getopt(argc, argv, OPTS)) != -1) { - switch (c) - { - case '6' : - use_inet6 = 1; - break; - case 'A' : - opts &= ~OPT_INACTIVE; - break; - case 'E' : - if (set_state((u_int)1)) - exit(1); - break; - case 'D' : - if (set_state((u_int)0)) - exit(1); - break; - case 'd' : - opts |= OPT_DEBUG; - break; - case 'f' : - procfile(argv[0], optarg); - break; - case 'F' : - flushfilter(optarg); - break; - case 'I' : - opts |= OPT_INACTIVE; - break; - case 'l' : - packetlogon(optarg); - break; - case 'n' : - opts |= OPT_DONOTHING; - break; - case 'o' : - break; - case 'P' : - ipfname = IPL_AUTH; - break; - case 'r' : - opts |= OPT_REMOVE; - break; - case 's' : - swapactive(); - break; -#if SOLARIS - case 'U' : - blockunknown(); - break; -#endif - case 'v' : - opts += OPT_VERBOSE; - break; - case 'V' : - if (showversion()) - exit(1); - break; - case 'y' : - frsync(); - break; - case 'z' : - opts |= OPT_ZERORULEST; - break; - case 'Z' : - zerostats(); - break; - case '?' : - default : - usage(argv[0]); - break; - } - } - - if (optind < 2) - usage(argv[0]); - - if (fd != -1) - (void) close(fd); - - exit(0); - /* NOTREACHED */ -} - - -static int opendevice(ipfdev) -char *ipfdev; -{ - if (opts & OPT_DONOTHING) - return 0; - - if (!ipfdev) - ipfdev = ipfname; - - /* - * shouldn't we really be testing for fd < 0 here and below? - */ - - if (fd != -1) - return 0; - - if ((fd = open(ipfdev, O_RDWR)) == -1) { - if ((fd = open(ipfdev, O_RDONLY)) == -1) { - perror("open device"); - if (errno == ENODEV) - fprintf(stderr, "IPFilter enabled?\n"); - return -1; - } - } - - return 0; -} - - -static void closedevice() -{ - if (fd != -1) - close(fd); - fd = -1; -} - - -/* - * Return codes: - * 0 Success - * !0 Failure (and an error message has already been printed) - */ -static int get_flags(i) -int *i; -{ - - if (opts & OPT_DONOTHING) - return 0; - - if (opendevice(ipfname) < 0) - return -1; - - if (ioctl(fd, SIOCGETFF, i) == -1) { - perror("SIOCGETFF"); - return -1; - } - return 0; -} - - -static int set_state(enable) -u_int enable; -{ - if (opts & OPT_DONOTHING) - return 0; - - if (opendevice(ipfname)) - return -1; - - if (ioctl(fd, SIOCFRENB, &enable) == -1) { - if (errno == EBUSY) - /* Not really an error */ - fprintf(stderr, - "IP Filter: already initialized\n"); - else { - perror("SIOCFRENB"); - return -1; - } - } - return 0; -} - -static void procfile(name, file) -char *name, *file; -{ - FILE *fp; - char line[513], *s; - struct frentry *fr; - u_int add, del; - int linenum = 0; - int parsestatus; - - if (opendevice(ipfname) == -1) - exit(1); - - if (opts & OPT_INACTIVE) { - add = SIOCADIFR; - del = SIOCRMIFR; - } else { - add = SIOCADAFR; - del = SIOCRMAFR; - } - if (opts & OPT_DEBUG) - printf("add %x del %x\n", add, del); - - initparse(); - - if (!strcmp(file, "-")) - fp = stdin; - else if (!(fp = fopen(file, "r"))) { - fprintf(stderr, "%s: fopen(%s) failed: %s\n", name, file, - STRERROR(errno)); - exit(1); - } - - while (getline(line, sizeof(line), fp, &linenum)) { - /* - * treat CR as EOL. LF is converted to NUL by getline(). - */ - if ((s = index(line, '\r'))) - *s = '\0'; - /* - * # is comment marker, everything after is a ignored - */ - if ((s = index(line, '#'))) - *s = '\0'; - - if (!*line) - continue; - - if (opts & OPT_VERBOSE) - (void)fprintf(stderr, "[%s]\n", line); - - parsestatus = 1; - fr = parse(line, linenum, &parsestatus); - (void)fflush(stdout); - - if (parsestatus != 0) { - fprintf(stderr, "%s: %s: %s error (%d), quitting\n", - name, file, - ((parsestatus < 0)? "parse": "internal"), - parsestatus); - exit(1); - } - - if (fr) { - if (opts & OPT_ZERORULEST) - add = SIOCZRLST; - else if (opts & OPT_INACTIVE) - add = (u_int)fr->fr_hits ? SIOCINIFR : - SIOCADIFR; - else - add = (u_int)fr->fr_hits ? SIOCINAFR : - SIOCADAFR; - if (fr->fr_hits) - fr->fr_hits--; - if (fr && (opts & OPT_VERBOSE)) - printfr(fr); - if (fr && (opts & OPT_OUTQUE)) - fr->fr_flags |= FR_OUTQUE; - - if (opts & OPT_DEBUG) - binprint(fr); - - if ((opts & OPT_ZERORULEST) && - !(opts & OPT_DONOTHING)) { - if (ioctl(fd, add, &fr) == -1) { - fprintf(stderr, "%d:", linenum); - perror("ioctl(SIOCZRLST)"); - exit(1); - } else { -#ifdef USE_QUAD_T - printf("hits %qd bytes %qd ", - (long long)fr->fr_hits, - (long long)fr->fr_bytes); -#else - printf("hits %ld bytes %ld ", - fr->fr_hits, fr->fr_bytes); -#endif - printfr(fr); - } - } else if ((opts & OPT_REMOVE) && - !(opts & OPT_DONOTHING)) { - if (ioctl(fd, del, &fr) == -1) { - fprintf(stderr, "%d:", linenum); - perror("ioctl(delete rule)"); - exit(1); - } - } else if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, add, &fr) == -1) { - fprintf(stderr, "%d:", linenum); - perror("ioctl(add/insert rule)"); - exit(1); - } - } - } - } - if (ferror(fp) || !feof(fp)) { - fprintf(stderr, "%s: %s: file error or line too long\n", - name, file); - exit(1); - } - (void)fclose(fp); -} - -/* - * Similar to fgets(3) but can handle '\\' and NL is converted to NUL. - * Returns NULL if error occurred, EOF encounterd or input line is too long. - */ -static char *getline(str, size, file, linenum) -register char *str; -size_t size; -FILE *file; -int *linenum; -{ - char *p; - int s, len; - - do { - for (p = str, s = size;; p += (len - 1), s -= (len - 1)) { - /* - * if an error occurred, EOF was encounterd, or there - * was no room to put NUL, return NULL. - */ - if (fgets(p, s, file) == NULL) - return (NULL); - len = strlen(p); - if (p[len - 1] != '\n') { - p[len] = '\0'; - break; - } - (*linenum)++; - p[len - 1] = '\0'; - if (len < 2 || p[len - 2] != '\\') - break; - else - /* - * Convert '\\' to a space so words don't - * run together - */ - p[len - 2] = ' '; - } - } while (*str == '\0'); - return (str); -} - - -static void packetlogon(opt) -char *opt; -{ - int flag; - - if (get_flags(&flag)) - exit(1); - - if (flag != 0) { - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) - printf("log flag is currently %#x\n", flag); - } - - flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK); - - if (index(opt, 'p')) { - flag |= FF_LOGPASS; - if (opts & OPT_VERBOSE) - printf("set log flag: pass\n"); - } - if (index(opt, 'm') && (*opt == 'n' || *opt == 'N')) { - flag |= FF_LOGNOMATCH; - if (opts & OPT_VERBOSE) - printf("set log flag: nomatch\n"); - } - if (index(opt, 'b') || index(opt, 'd')) { - flag |= FF_LOGBLOCK; - if (opts & OPT_VERBOSE) - printf("set log flag: block\n"); - } - - if (opendevice(ipfname) == -1) { - exit(1); - } - - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCSETFF, &flag) != 0) { - perror("ioctl(SIOCSETFF)"); - exit(1); - } - } - - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - /* - * Even though the ioctls above succeeded, it - * is possible that a calling script/program - * relies on the following verbose mode string. - * Thus, we still take an error exit if get_flags - * fails here. - */ - if (get_flags(&flag)) - exit(1); - printf("log flag is now %#x\n", flag); - } -} - - -static void flushfilter(arg) -char *arg; -{ - int fl = 0, rem; - - if (!arg || !*arg) { - fprintf(stderr, "-F: no filter specified\n"); - exit(1); - } - - if (!strcmp(arg, "s") || !strcmp(arg, "S")) { - if (*arg == 'S') - fl = 0; - else - fl = 1; - rem = fl; - - closedevice(); - - if (opendevice(IPL_STATE) == -1) { - exit(1); - } - - if (!(opts & OPT_DONOTHING)) { - if (use_inet6) { - if (ioctl(fd, SIOCIPFL6, &fl) == -1) { - perror("ioctl(SIOCIPFL6)"); - exit(1); - } - } else { - if (ioctl(fd, SIOCIPFFL, &fl) == -1) { - perror("ioctl(SIOCIPFFL)"); - exit(1); - } - } - } - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - printf("remove flags %s (%d)\n", arg, rem); - printf("removed %d filter rules\n", fl); - } - closedevice(); - return; - } - if (strchr(arg, 'i') || strchr(arg, 'I')) - fl = FR_INQUE; - if (strchr(arg, 'o') || strchr(arg, 'O')) - fl = FR_OUTQUE; - if (strchr(arg, 'a') || strchr(arg, 'A')) - fl = FR_OUTQUE|FR_INQUE; - fl |= (opts & FR_INACTIVE); - rem = fl; - - if (opendevice(ipfname) == -1) { - exit(1); - } - - if (!(opts & OPT_DONOTHING)) { - if (use_inet6) { - if (ioctl(fd, SIOCIPFL6, &fl) == -1) { - perror("ioctl(SIOCIPFL6)"); - exit(1); - } - } else { - if (ioctl(fd, SIOCIPFFL, &fl) == -1) { - perror("ioctl(SIOCIPFFL)"); - exit(1); - } - } - } - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "", - (rem & FR_OUTQUE) ? "O" : "", rem); - printf("removed %d filter rules\n", fl); - } - return; -} - - -static void swapactive() -{ - int in = 2; - - if (opendevice(ipfname) == -1) { - exit(1); - } - - - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCSWAPA, &in) == -1) { - perror("ioctl(SIOCSWAPA)"); - exit(1); - } - } - printf("Set %d now inactive\n", in); -} - - -void frsync() -{ - int frsyn = 0; - - if (opendevice(ipfname) == -1) - exit(1); - - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCFRSYN, &frsyn) == -1) { - perror("SIOCFRSYN"); - exit(1); - } - } - printf("filter sync'd\n"); -} - - -void zerostats() -{ - friostat_t fio; - friostat_t *fiop = &fio; - - if (opendevice(ipfname) == -1) - exit(1); - - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCFRZST, &fiop) == -1) { - perror("ioctl(SIOCFRZST)"); - exit(-1); - } - showstats(fiop); - } - -} - - -/* - * Read the kernel stats for packets blocked and passed - */ -static void showstats(fp) -friostat_t *fp; -{ -#if SOLARIS - printf("dropped packets:\tin %lu\tout %lu\n", - fp->f_st[0].fr_drop, fp->f_st[1].fr_drop); - printf("non-ip packets:\t\tin %lu\tout %lu\n", - fp->f_st[0].fr_notip, fp->f_st[1].fr_notip); - printf(" bad packets:\t\tin %lu\tout %lu\n", - fp->f_st[0].fr_bad, fp->f_st[1].fr_bad); -#endif - printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu", - fp->f_st[0].fr_block, fp->f_st[0].fr_pass, - fp->f_st[0].fr_nom); - printf(" counted %lu\n", fp->f_st[0].fr_acct); - printf("output packets:\t\tblocked %lu passed %lu nomatch %lu", - fp->f_st[1].fr_block, fp->f_st[1].fr_pass, - fp->f_st[1].fr_nom); - printf(" counted %lu\n", fp->f_st[0].fr_acct); - printf(" input packets logged:\tblocked %lu passed %lu\n", - fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl); - printf("output packets logged:\tblocked %lu passed %lu\n", - fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl); - printf(" packets logged:\tinput %lu-%lu output %lu-%lu\n", - fp->f_st[0].fr_pkl, fp->f_st[0].fr_skip, - fp->f_st[1].fr_pkl, fp->f_st[1].fr_skip); -} - - -#if SOLARIS -static void blockunknown() -{ - int flag; - - if (opendevice(ipfname) == -1) - exit(1); - - if (get_flags(&flag)) - exit(1); - - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) - printf("log flag is currently %#x\n", flag); - - flag ^= FF_BLOCKNONIP; - - if (opendevice(ipfname) == -1) - exit(1); - - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCSETFF, &flag)) - perror("ioctl(SIOCSETFF)"); - } - - if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) { - if (ioctl(fd, SIOCGETFF, &flag)) - perror("ioctl(SIOCGETFF)"); - - printf("log flag is now %#x\n", flag); - } -} -#endif - - -/* - * nonzero return value means caller should exit with error - */ -static int showversion() -{ - struct friostat fio; - struct friostat *fiop=&fio; - int flags, vfd; - char *s; - - printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t)); - - if ((vfd = open(ipfname, O_RDONLY)) == -1) { - perror("open device"); - return 1; - } - - if (ioctl(vfd, SIOCGETFS, &fiop)) { - perror("ioctl(SIOCGETFS)"); - close(vfd); - return 1; - } - close(vfd); - - printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version), - (int)sizeof(fio.f_version), fio.f_version); - printf("Running: %s\n", fio.f_running ? "yes" : "no"); - - if (get_flags(&flags)) { - return 1; - } - printf("Log Flags: %#x = ", flags); - s = ""; - if (flags & FF_LOGPASS) { - printf("pass"); - s = ", "; - } - if (flags & FF_LOGBLOCK) { - printf("%sblock", s); - s = ", "; - } - if (flags & FF_LOGNOMATCH) { - printf("%snomatch", s); - s = ", "; - } - if (flags & FF_BLOCKNONIP) { - printf("%snonip", s); - s = ", "; - } - if (!*s) - printf("none set"); - putchar('\n'); - - printf("Default: "); - if (fio.f_defpass & FR_PASS) - s = "pass"; - else if (fio.f_defpass & FR_BLOCK) - s = "block"; - else - s = "nomatch -> block"; - printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un"); - printf("Active list: %d\n", fio.f_active); - - return 0; -} diff --git a/contrib/ipfilter/ipfs.c b/contrib/ipfilter/ipfs.c deleted file mode 100644 index ffbd71bd6488..000000000000 --- a/contrib/ipfilter/ipfs.c +++ /dev/null @@ -1,859 +0,0 @@ -/* - * Copyright (C) 1999-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#ifdef __FreeBSD__ -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include "ip_compat.h" -#include "ip_fil.h" -#include "ip_nat.h" -#include "ip_state.h" -#include "ipf.h" - -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: ipfs.c,v 2.6.2.15 2003/05/31 02:12:21 darrenr Exp $"; -#endif - -#ifndef IPF_SAVEDIR -# define IPF_SAVEDIR "/var/db/ipf" -#endif -#ifndef IPF_NATFILE -# define IPF_NATFILE "ipnat.ipf" -#endif -#ifndef IPF_STATEFILE -# define IPF_STATEFILE "ipstate.ipf" -#endif - -#if !defined(__SVR4) && defined(__GNUC__) -extern char *index __P((const char *, int)); -#endif - -extern char *optarg; -extern int optind; - -int main __P((int, char *[])); -void usage __P((void)); -int changestateif __P((char *, char *)); -int changenatif __P((char *, char *)); -int readstate __P((int, char *)); -int readnat __P((int, char *)); -int writestate __P((int, char *)); -int opendevice __P((char *)); -void closedevice __P((int)); -int setlock __P((int, int)); -int writeall __P((char *)); -int readall __P((char *)); -int writenat __P((int, char *)); -char *concat __P((char *, char *)); - -int opts = 0; -char *progname; - - -void usage() -{ - fprintf(stderr, "\ -usage: %s [-nv] -l\n\ -usage: %s [-nv] -u\n\ -usage: %s [-nv] [-d ] -R\n\ -usage: %s [-nv] [-d ] -W\n\ -usage: %s [-nv] -N [-f | -d ] -r\n\ -usage: %s [-nv] -S [-f | -d ] -r\n\ -usage: %s [-nv] -N [-f | -d ] -w\n\ -usage: %s [-nv] -S [-f | -d ] -w\n\ -usage: %s [-nv] -N [-f | -d ] -i ,\n\ -usage: %s [-nv] -S [-f | -d ] -i ,\n\ -", progname, progname, progname, progname, progname, progname, - progname, progname, progname, progname); - exit(1); -} - - -/* - * Change interface names in state information saved out to disk. - */ -int changestateif(ifs, fname) -char *ifs, *fname; -{ - int fd, olen, nlen, rw; - ipstate_save_t ips; - off_t pos; - char *s; - - s = strchr(ifs, ','); - if (!s) - usage(); - *s++ = '\0'; - nlen = strlen(s); - olen = strlen(ifs); - if (nlen >= sizeof(ips.ips_is.is_ifname) || - olen >= sizeof(ips.ips_is.is_ifname)) - usage(); - - fd = open(fname, O_RDWR); - if (fd == -1) { - perror("open"); - exit(1); - } - - for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) { - rw = 0; - if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) { - strcpy(ips.ips_is.is_ifname[0], s); - rw = 1; - } - if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) { - strcpy(ips.ips_is.is_ifname[1], s); - rw = 1; - } - if (rw == 1) { - if (lseek(fd, pos, SEEK_SET) != pos) { - perror("lseek"); - exit(1); - } - if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) { - perror("write"); - exit(1); - } - } - pos = lseek(fd, 0, SEEK_CUR); - } - close(fd); - - return 0; -} - - -/* - * Change interface names in NAT information saved out to disk. - */ -int changenatif(ifs, fname) -char *ifs, *fname; -{ - int fd, olen, nlen, rw; - nat_save_t ipn; - nat_t *nat; - off_t pos; - char *s; - - s = strchr(ifs, ','); - if (!s) - usage(); - *s++ = '\0'; - nlen = strlen(s); - olen = strlen(ifs); - nat = &ipn.ipn_nat; - if (nlen >= sizeof(nat->nat_ifname) || olen >= sizeof(nat->nat_ifname)) - usage(); - - fd = open(fname, O_RDWR); - if (fd == -1) { - perror("open"); - exit(1); - } - - for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) { - rw = 0; - if (!strncmp(nat->nat_ifname, ifs, olen + 1)) { - strcpy(nat->nat_ifname, s); - rw = 1; - } - if (rw == 1) { - if (lseek(fd, pos, SEEK_SET) != pos) { - perror("lseek"); - exit(1); - } - if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) { - perror("write"); - exit(1); - } - } - pos = lseek(fd, 0, SEEK_CUR); - } - close(fd); - - return 0; -} - - -int main(argc,argv) -int argc; -char *argv[]; -{ - int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; - char *dirname = NULL, *filename = NULL, *ifs = NULL; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "d:f:i:lNnSRruvWw")) != -1) - switch (c) - { - case 'd' : - if ((set == 0) && !dirname && !filename) - dirname = optarg; - else - usage(); - break; - case 'f' : - if ((set == 1) && !dirname && !filename && !(rw & 2)) - filename = optarg; - else - usage(); - break; - case 'i' : - ifs = optarg; - set = 1; - break; - case 'l' : - if (filename || dirname || set) - usage(); - lock = 1; - set = 1; - break; - case 'n' : - opts |= OPT_DONOTHING; - break; - case 'N' : - if ((ns >= 0) || dirname || (rw != -1) || set) - usage(); - ns = 0; - set = 1; - break; - case 'r' : - if (dirname || (rw != -1) || (ns == -1)) - usage(); - rw = 0; - set = 1; - break; - case 'R' : - if (filename || (ns != -1)) - usage(); - rw = 2; - set = 1; - break; - case 'S' : - if ((ns >= 0) || dirname || (rw != -1) || set) - usage(); - ns = 1; - set = 1; - break; - case 'u' : - if (filename || dirname || set) - usage(); - lock = 0; - set = 1; - break; - case 'v' : - opts |= OPT_VERBOSE; - break; - case 'w' : - if (dirname || (rw != -1) || (ns == -1)) - usage(); - rw = 1; - set = 1; - break; - case 'W' : - if (filename || (ns != -1)) - usage(); - rw = 3; - set = 1; - break; - case '?' : - default : - usage(); - } - - if (optind < 2) - usage(); - - if (filename == NULL) { - if (ns == 0) { - if (dirname == NULL) - dirname = IPF_SAVEDIR; - if (dirname[strlen(dirname) - 1] != '/') - dirname = concat(dirname, "/"); - filename = concat(dirname, IPF_NATFILE); - } else if (ns == 1) { - if (dirname == NULL) - dirname = IPF_SAVEDIR; - if (dirname[strlen(dirname) - 1] != '/') - dirname = concat(dirname, "/"); - filename = concat(dirname, IPF_STATEFILE); - } - } - - if (ifs) { - if (!filename || ns < 0) - usage(); - if (ns == 0) - return changenatif(ifs, filename); - else - return changestateif(ifs, filename); - } - - if ((ns >= 0) || (lock >= 0)) { - if (lock >= 0) - devfd = opendevice(NULL); - else if (ns >= 0) { - if (ns == 1) - devfd = opendevice(IPL_STATE); - else if (ns == 0) - devfd = opendevice(IPL_NAT); - } - if (devfd == -1) - exit(1); - } - - if (lock >= 0) - err = setlock(devfd, lock); - else if (rw >= 0) { - if (rw & 1) { /* WRITE */ - if (rw & 2) - err = writeall(dirname); - else { - if (ns == 0) - err = writenat(devfd, filename); - else if (ns == 1) - err = writestate(devfd, filename); - } - } else { - if (rw & 2) - err = readall(dirname); - else { - if (ns == 0) - err = readnat(devfd, filename); - else if (ns == 1) - err = readstate(devfd, filename); - } - } - } - return err; -} - - -char *concat(base, append) -char *base, *append; -{ - char *str; - - str = malloc(strlen(base) + strlen(append) + 1); - if (str != NULL) { - strcpy(str, base); - strcat(str, append); - } - return str; -} - - -int opendevice(ipfdev) -char *ipfdev; -{ - int fd = -1; - - if (opts & OPT_DONOTHING) - return -2; - - if (!ipfdev) - ipfdev = IPL_NAME; - - if ((fd = open(ipfdev, O_RDWR)) == -1) - if ((fd = open(ipfdev, O_RDONLY)) == -1) - perror("open device"); - return fd; -} - - -void closedevice(fd) -int fd; -{ - close(fd); -} - - -int setlock(fd, lock) -int fd, lock; -{ - if (opts & OPT_VERBOSE) - printf("Turn lock %s\n", lock ? "on" : "off"); - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCSTLCK, &lock) == -1) { - perror("SIOCSTLCK"); - return 1; - } - if (opts & OPT_VERBOSE) - printf("Lock now %s\n", lock ? "on" : "off"); - } - return 0; -} - - -int writestate(fd, file) -int fd; -char *file; -{ - ipstate_save_t ips, *ipsp; - int wfd = -1; - - if (!file) - file = IPF_STATEFILE; - - wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); - if (wfd == -1) { - fprintf(stderr, "%s ", file); - perror("state:open"); - return 1; - } - - ipsp = &ips; - bzero((char *)ipsp, sizeof(ips)); - - do { - if (opts & OPT_VERBOSE) - printf("Getting state from addr %p\n", ips.ips_next); - if (ioctl(fd, SIOCSTGET, &ipsp)) { - if (errno == ENOENT) - break; - perror("state:SIOCSTGET"); - close(wfd); - return 1; - } - if (opts & OPT_VERBOSE) - printf("Got state next %p\n", ips.ips_next); - if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) { - perror("state:write"); - close(wfd); - return 1; - } - } while (ips.ips_next != NULL); - close(wfd); - - return 0; -} - - -int readstate(fd, file) -int fd; -char *file; -{ - ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; - int sfd = -1, i; - - if (!file) - file = IPF_STATEFILE; - - sfd = open(file, O_RDONLY, 0600); - if (sfd == -1) { - fprintf(stderr, "%s ", file); - perror("open"); - return 1; - } - - bzero((char *)&ips, sizeof(ips)); - - /* - * 1. Read all state information in. - */ - do { - i = read(sfd, &ips, sizeof(ips)); - if (i == -1) { - perror("read"); - close(sfd); - return 1; - } - if (i == 0) - break; - if (i != sizeof(ips)) { - fprintf(stderr, "incomplete read: %d != %d\n", i, - (int)sizeof(ips)); - close(sfd); - return 1; - } - is = (ipstate_save_t *)malloc(sizeof(*is)); - if(!is) { - fprintf(stderr, "malloc failed\n"); - return 1; - } - - bcopy((char *)&ips, (char *)is, sizeof(ips)); - - /* - * Check to see if this is the first state entry that will - * reference a particular rule and if so, flag it as such - * else just adjust the rule pointer to become a pointer to - * the other. We do this so we have a means later for tracking - * who is referencing us when we get back the real pointer - * in is_rule after doing the ioctl. - */ - for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next) - if (is1->ips_rule == is->ips_rule) - break; - if (is1 == NULL) - is->ips_is.is_flags |= FI_NEWFR; - else - is->ips_rule = (void *)&is1->ips_rule; - - /* - * Use a tail-queue type list (add things to the end).. - */ - is->ips_next = NULL; - if (!ipshead) - ipshead = is; - if (ipstail) - ipstail->ips_next = is; - ipstail = is; - } while (1); - - close(sfd); - - for (is = ipshead; is; is = is->ips_next) { - if (opts & OPT_VERBOSE) - printf("Loading new state table entry\n"); - if (is->ips_is.is_flags & FI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Loading new filter rule\n"); - } - if (!(opts & OPT_DONOTHING)) - if (ioctl(fd, SIOCSTPUT, &is)) { - perror("SIOCSTPUT"); - return 1; - } - - if (is->ips_is.is_flags & FI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Real rule addr %p\n", is->ips_rule); - for (is1 = is->ips_next; is1; is1 = is1->ips_next) - if (is1->ips_rule == (frentry_t *)&is->ips_rule) - is1->ips_rule = is->ips_rule; - } - } - - return 0; -} - - -int readnat(fd, file) -int fd; -char *file; -{ - nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL; - int nfd = -1, i; - nat_t *nat; - char *s; - int n; - - if (!file) - file = IPF_NATFILE; - - nfd = open(file, O_RDONLY); - if (nfd == -1) { - fprintf(stderr, "%s ", file); - perror("nat:open"); - return 1; - } - - bzero((char *)&ipn, sizeof(ipn)); - - /* - * 1. Read all state information in. - */ - do { - i = read(nfd, &ipn, sizeof(ipn)); - if (i == -1) { - perror("read"); - close(nfd); - return 1; - } - if (i == 0) - break; - if (i != sizeof(ipn)) { - fprintf(stderr, "incomplete read: %d != %d\n", i, - (int)sizeof(ipn)); - close(nfd); - return 1; - } - - if (ipn.ipn_dsize > 0) { - n = ipn.ipn_dsize; - - if (n > sizeof(ipn.ipn_data)) - n -= sizeof(ipn.ipn_data); - else - n = 0; - in = malloc(sizeof(*in) + n); - if (!in) - break; - - if (n > 0) { - s = in->ipn_data + sizeof(in->ipn_data); - i = read(nfd, s, n); - if (i == 0) - break; - if (i != n) { - fprintf(stderr, - "incomplete read: %d != %d\n", - i, n); - close(nfd); - return 1; - } - } - } else - in = (nat_save_t *)malloc(sizeof(*in)); - bcopy((char *)&ipn, (char *)in, sizeof(ipn)); - - /* - * Check to see if this is the first NAT entry that will - * reference a particular rule and if so, flag it as such - * else just adjust the rule pointer to become a pointer to - * the other. We do this so we have a means later for tracking - * who is referencing us when we get back the real pointer - * in is_rule after doing the ioctl. - */ - nat = &in->ipn_nat; - if (nat->nat_fr != NULL) { - for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next) - if (in1->ipn_rule == nat->nat_fr) - break; - if (in1 == NULL) - nat->nat_flags |= FI_NEWFR; - else - nat->nat_fr = &in1->ipn_fr; - } - - /* - * Use a tail-queue type list (add things to the end).. - */ - in->ipn_next = NULL; - if (!ipnhead) - ipnhead = in; - if (ipntail) - ipntail->ipn_next = in; - ipntail = in; - } while (1); - - close(nfd); - nfd = -1; - - for (in = ipnhead; in; in = in->ipn_next) { - if (opts & OPT_VERBOSE) - printf("Loading new NAT table entry\n"); - nat = &in->ipn_nat; - if (nat->nat_flags & FI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Loading new filter rule\n"); - } - if (!(opts & OPT_DONOTHING)) - if (ioctl(fd, SIOCSTPUT, &in)) { - perror("SIOCSTPUT"); - return 1; - } - - if (nat->nat_flags & FI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Real rule addr %p\n", nat->nat_fr); - for (in1 = in->ipn_next; in1; in1 = in1->ipn_next) - if (in1->ipn_rule == &in->ipn_fr) - in1->ipn_rule = nat->nat_fr; - } - } - - return 0; -} - - -int writenat(fd, file) -int fd; -char *file; -{ - nat_save_t *ipnp = NULL, *next = NULL; - int nfd = -1; - natget_t ng; - - if (!file) - file = IPF_NATFILE; - - nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); - if (nfd == -1) { - fprintf(stderr, "%s ", file); - perror("nat:open"); - return 1; - } - - - do { - if (opts & OPT_VERBOSE) - printf("Getting nat from addr %p\n", ipnp); - ng.ng_ptr = next; - ng.ng_sz = 0; - if (ioctl(fd, SIOCSTGSZ, &ng)) { - perror("nat:SIOCSTGSZ"); - close(nfd); - return 1; - } - - if (opts & OPT_VERBOSE) - printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr); - - if (ng.ng_sz == 0) - break; - - if (!ipnp) - ipnp = malloc(ng.ng_sz); - else - ipnp = realloc((char *)ipnp, ng.ng_sz); - if (!ipnp) { - fprintf(stderr, - "malloc for %d bytes failed\n", ng.ng_sz); - break; - } - - bzero((char *)ipnp, ng.ng_sz); - ipnp->ipn_next = next; - if (ioctl(fd, SIOCSTGET, &ipnp)) { - if (errno == ENOENT) - break; - perror("nat:SIOCSTGET"); - close(nfd); - return 1; - } - - if (opts & OPT_VERBOSE) - printf("Got nat next %p\n", ipnp->ipn_next); - if (write(nfd, ipnp, ng.ng_sz) != ng.ng_sz) { - perror("nat:write"); - close(nfd); - return 1; - } - next = ipnp->ipn_next; - } while (ipnp && next); - close(nfd); - - return 0; -} - - -int writeall(dirname) -char *dirname; -{ - int fd, devfd; - - if (!dirname) - dirname = IPF_SAVEDIR; - - if (chdir(dirname)) { - fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname); - perror("chdir(IPF_SAVEDIR)"); - return 1; - } - - fd = opendevice(NULL); - if (fd == -1) - return 1; - if (setlock(fd, 1)) { - close(fd); - return 1; - } - - devfd = opendevice(IPL_STATE); - if (devfd == -1) - goto bad; - if (writestate(devfd, NULL)) - goto bad; - close(devfd); - - devfd = opendevice(IPL_NAT); - if (devfd == -1) - goto bad; - if (writenat(devfd, NULL)) - goto bad; - close(devfd); - - if (setlock(fd, 0)) { - close(fd); - return 1; - } - - return 0; - -bad: - setlock(fd, 0); - close(fd); - return 1; -} - - -int readall(dirname) -char *dirname; -{ - int fd, devfd; - - if (!dirname) - dirname = IPF_SAVEDIR; - - if (chdir(dirname)) { - perror("chdir(IPF_SAVEDIR)"); - return 1; - } - - fd = opendevice(NULL); - if (fd == -1) - return 1; - if (setlock(fd, 1)) { - close(fd); - return 1; - } - - devfd = opendevice(IPL_STATE); - if (devfd == -1) - return 1; - if (readstate(devfd, NULL)) - return 1; - close(devfd); - - devfd = opendevice(IPL_NAT); - if (devfd == -1) - return 1; - if (readnat(devfd, NULL)) - return 1; - close(devfd); - - if (setlock(fd, 0)) { - close(fd); - return 1; - } - - return 0; -} diff --git a/contrib/ipfilter/ipft_ef.c b/contrib/ipfilter/ipft_ef.c deleted file mode 100644 index c8ae3f2a5934..000000000000 --- a/contrib/ipfilter/ipft_ef.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ - -/* - icmp type - lnth proto source destination src port dst port - -etherfind -n - - 60 tcp 128.250.20.20 128.250.133.13 2419 telnet - -etherfind -n -t - - 0.32 91 04 131.170.1.10 128.250.133.13 - 0.33 566 udp 128.250.37.155 128.250.133.3 901 901 -*/ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include -#include "ipf.h" -#include "ipt.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipft_ef.c 1.6 2/4/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.5 2003/05/19 12:02:35 darrenr Exp $"; -#endif - -static int etherf_open __P((char *)); -static int etherf_close __P((void)); -static int etherf_readip __P((char *, int, char **, int *)); - -struct ipread etherf = { etherf_open, etherf_close, etherf_readip }; - -static FILE *efp = NULL; -static int efd = -1; - - -static int etherf_open(fname) -char *fname; -{ - if (efd != -1) - return efd; - - if (!strcmp(fname, "-")) { - efd = 0; - efp = stdin; - } else { - efd = open(fname, O_RDONLY); - efp = fdopen(efd, "r"); - } - return efd; -} - - -static int etherf_close() -{ - return close(efd); -} - - -static int etherf_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - struct tcpiphdr pkt; - ip_t *ip = (ip_t *)&pkt; - struct protoent *p = NULL; - char src[16], dst[16], sprt[16], dprt[16]; - char lbuf[128], len[8], prot[8], time[8], *s; - int slen, extra = 0, i; - - if (!fgets(lbuf, sizeof(lbuf) - 1, efp)) - return 0; - - if ((s = strchr(lbuf, '\n'))) - *s = '\0'; - lbuf[sizeof(lbuf)-1] = '\0'; - - bzero(&pkt, sizeof(pkt)); - - if (sscanf(lbuf, "%7s %7s %15s %15s %15s %15s", len, prot, src, dst, - sprt, dprt) != 6) - if (sscanf(lbuf, "%7s %7s %7s %15s %15s %15s %15s", time, - len, prot, src, dst, sprt, dprt) != 7) - return -1; - - ip->ip_p = atoi(prot); - if (ip->ip_p == 0) { - if (!(p = getprotobyname(prot))) - return -1; - ip->ip_p = p->p_proto; - } - - switch (ip->ip_p) { - case IPPROTO_TCP : - case IPPROTO_UDP : - s = strtok(NULL, " :"); - ip->ip_len += atoi(s); - if (p->p_proto == IPPROTO_TCP) - extra = sizeof(struct tcphdr); - else if (p->p_proto == IPPROTO_UDP) - extra = sizeof(struct udphdr); - break; -#ifdef IGMP - case IPPROTO_IGMP : - extra = sizeof(struct igmp); - break; -#endif - case IPPROTO_ICMP : - extra = sizeof(struct icmp); - break; - default : - break; - } - - (void) inet_aton(src, &ip->ip_src); - (void) inet_aton(dst, &ip->ip_dst); - ip->ip_len = atoi(len); - ip->ip_hl = sizeof(ip_t); - - slen = ip->ip_hl + extra; - i = MIN(cnt, slen); - bcopy((char *)&pkt, buf, i); - return i; -} diff --git a/contrib/ipfilter/ipft_hx.c b/contrib/ipfilter/ipft_hx.c deleted file mode 100644 index b26bd93e02aa..000000000000 --- a/contrib/ipfilter/ipft_hx.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 1995-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include -#include "ipf.h" -#include "ipt.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipft_hx.c 1.1 3/9/96 (C) 1996 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_hx.c,v 2.2.2.6 2002/12/06 11:40:25 darrenr Exp $"; -#endif - -extern int opts; - -static int hex_open __P((char *)); -static int hex_close __P((void)); -static int hex_readip __P((char *, int, char **, int *)); -static char *readhex __P((char *, char *)); - -struct ipread iphex = { hex_open, hex_close, hex_readip }; -static FILE *tfp = NULL; -static int tfd = -1; - -static int hex_open(fname) -char *fname; -{ - if (tfp && tfd != -1) { - rewind(tfp); - return tfd; - } - - if (!strcmp(fname, "-")) { - tfd = 0; - tfp = stdin; - } else { - tfd = open(fname, O_RDONLY); - if (tfd != -1) - tfp = fdopen(tfd, "r"); - } - return tfd; -} - - -static int hex_close() -{ - int cfd = tfd; - - tfd = -1; - return close(cfd); -} - - -static int hex_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - register char *s, *t, *u; - char line[513]; - ip_t *ip; - - /* - * interpret start of line as possibly "[ifname]" or - * "[in/out,ifname]". - */ - if (ifn) - *ifn = NULL; - if (dir) - *dir = 0; - ip = (ip_t *)buf; - while (fgets(line, sizeof(line)-1, tfp)) { - if ((s = index(line, '\n'))) { - if (s == line) - return (char *)ip - buf; - *s = '\0'; - } - if ((s = index(line, '#'))) - *s = '\0'; - if (!*line) - continue; - if (!(opts & OPT_BRIEF)) { - printf("input: %s\n", line); - fflush(stdout); - } - - if ((*line == '[') && (s = index(line, ']'))) { - t = line + 1; - if (s - t > 0) { - *s++ = '\0'; - if ((u = index(t, ',')) && (u < s)) { - u++; - if (ifn) - *ifn = strdup(u); - if (dir) { - if (*t == 'i') - *dir = 0; - else if (*t == 'o') - *dir = 1; - } - } else if (ifn) - *ifn = t; - } - } else - s = line; - ip = (ip_t *)readhex(s, (char *)ip); - } - return -1; -} - - -static char *readhex(src, dst) -register char *src, *dst; -{ - int state = 0; - char c; - - while ((c = *src++)) { - if (isspace(c)) { - if (state) { - dst++; - state = 0; - } - continue; - } else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || - (c >= 'A' && c <= 'F')) { - c = isdigit(c) ? (c - '0') : (toupper(c) - 55); - if (state == 0) { - *dst = (c << 4); - state++; - } else { - *dst++ |= c; - state = 0; - } - } else - break; - } - return dst; -} diff --git a/contrib/ipfilter/ipft_pc.c b/contrib/ipfilter/ipft_pc.c deleted file mode 100644 index b6060de2297d..000000000000 --- a/contrib/ipfilter/ipft_pc.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include "ip_compat.h" -#include -#include "ipf.h" -#include "pcap.h" -#include "bpf.h" -#include "ipt.h" - -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: ipft_pc.c,v 2.2.2.5 2002/12/06 11:40:25 darrenr Exp $"; -#endif - -struct llc { - int lc_type; - int lc_sz; /* LLC header length */ - int lc_to; /* LLC Type offset */ - int lc_tl; /* LLC Type length */ -}; - -/* - * While many of these maybe the same, some do have different header formats - * which make this useful. - */ - -static struct llc llcs[] = { - { DLT_NULL, 0, 0, 0 }, - { DLT_EN10MB, 14, 12, 2 }, - { DLT_EN3MB, 0, 0, 0 }, - { DLT_AX25, 0, 0, 0 }, - { DLT_PRONET, 0, 0, 0 }, - { DLT_CHAOS, 0, 0, 0 }, - { DLT_IEEE802, 0, 0, 0 }, - { DLT_ARCNET, 0, 0, 0 }, - { DLT_SLIP, 0, 0, 0 }, - { DLT_PPP, 0, 0, 0 }, - { DLT_FDDI, 0, 0, 0 }, -#ifdef DLT_ATMRFC1483 - { DLT_ATMRFC1483, 0, 0, 0 }, -#endif - { DLT_RAW, 0, 0, 0 }, -#ifdef DLT_ENC - { DLT_ENC, 0, 0, 0 }, -#endif -#ifdef DLT_SLIP_BSDOS - { DLT_SLIP_BSDOS, 0, 0, 0 }, -#endif -#ifdef DLT_PPP_BSDOS - { DLT_PPP_BSDOS, 0, 0, 0 }, -#endif -#ifdef DLT_HIPPI - { DLT_HIPPI, 0, 0, 0 }, -#endif -#ifdef DLT_HDLC - { DLT_HDLC, 0, 0, 0 }, -#endif -#ifdef DLT_PPP_SERIAL - { DLT_PPP_SERIAL, 4, 4, 0 }, -#endif -#ifdef DLT_PPP_ETHER - { DLT_PPP_ETHER, 8, 8, 0 }, -#endif -#ifdef DLT_ECONET - { DLT_ECONET, 0, 0, 0 }, -#endif - { -1, -1, -1, -1 } -}; - -static int pcap_open __P((char *)); -static int pcap_close __P((void)); -static int pcap_readip __P((char *, int, char **, int *)); -static void swap_hdr __P((pcaphdr_t *)); -static int pcap_read_rec __P((struct pcap_pkthdr *)); - -static int pfd = -1, s_type = -1, swapped = 0; -static struct llc *llcp = NULL; - -struct ipread pcap = { pcap_open, pcap_close, pcap_readip }; - -#define SWAPLONG(y) \ - ((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff)) -#define SWAPSHORT(y) \ - ( (((y)&0xff)<<8) | (((y)&0xff00)>>8) ) - -static void swap_hdr(p) -pcaphdr_t *p; -{ - p->pc_v_maj = SWAPSHORT(p->pc_v_maj); - p->pc_v_min = SWAPSHORT(p->pc_v_min); - p->pc_zone = SWAPLONG(p->pc_zone); - p->pc_sigfigs = SWAPLONG(p->pc_sigfigs); - p->pc_slen = SWAPLONG(p->pc_slen); - p->pc_type = SWAPLONG(p->pc_type); -} - -static int pcap_open(fname) -char *fname; -{ - pcaphdr_t ph; - int fd, i; - - if (pfd != -1) - return pfd; - - if (!strcmp(fname, "-")) - fd = 0; - else if ((fd = open(fname, O_RDONLY)) == -1) - return -1; - - if (read(fd, (char *)&ph, sizeof(ph)) != sizeof(ph)) - return -2; - - if (ph.pc_id != TCPDUMP_MAGIC) { - if (SWAPLONG(ph.pc_id) != TCPDUMP_MAGIC) { - (void) close(fd); - return -2; - } - swapped = 1; - swap_hdr(&ph); - } - - if (ph.pc_v_maj != PCAP_VERSION_MAJ) { - (void) close(fd); - return -2; - } - - for (i = 0; llcs[i].lc_type != -1; i++) - if (llcs[i].lc_type == ph.pc_type) { - llcp = llcs + i; - break; - } - - if (llcp == NULL) { - (void) close(fd); - return -2; - } - - pfd = fd; - s_type = ph.pc_type; - printf("opened pcap file %s:\n", fname); - printf("\tid: %08x version: %d.%d type: %d snap %d\n", - ph.pc_id, ph.pc_v_maj, ph.pc_v_min, ph.pc_type, ph.pc_slen); - - return fd; -} - - -static int pcap_close() -{ - return close(pfd); -} - - -/* - * read in the header (and validate) which should be the first record - * in a pcap file. - */ -static int pcap_read_rec(rec) -struct pcap_pkthdr *rec; -{ - int n, p; - - if (read(pfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) - return -2; - - if (swapped) { - rec->ph_clen = SWAPLONG(rec->ph_clen); - rec->ph_len = SWAPLONG(rec->ph_len); - rec->ph_ts.tv_sec = SWAPLONG(rec->ph_ts.tv_sec); - rec->ph_ts.tv_usec = SWAPLONG(rec->ph_ts.tv_usec); - } - p = rec->ph_clen; - n = MIN(p, rec->ph_len); - if (!n || n < 0) - return -3; - - return p; -} - - -#ifdef notyet -/* - * read an entire pcap packet record. only the data part is copied into - * the available buffer, with the number of bytes copied returned. - */ -static int pcap_read(buf, cnt) -char *buf; -int cnt; -{ - struct pcap_pkthdr rec; - static char *bufp = NULL; - int i, n; - - if ((i = pcap_read_rec(&rec)) <= 0) - return i; - - if (!bufp) - bufp = malloc(i); - else - bufp = realloc(bufp, i); - - if (read(pfd, bufp, i) != i) - return -2; - - n = MIN(i, cnt); - bcopy(bufp, buf, n); - return n; -} -#endif - - -/* - * return only an IP packet read into buf - */ -static int pcap_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - static char *bufp = NULL; - struct pcap_pkthdr rec; - struct llc *l; - char *s, ty[4]; - int i, n; - - l = llcp; - - /* do { */ - if ((i = pcap_read_rec(&rec)) <= 0) - return i; - - if (!bufp) - bufp = malloc(i); - else - bufp = realloc(bufp, i); - s = bufp; - - if (read(pfd, s, i) != i) - return -2; - - i -= l->lc_sz; - s += l->lc_to; - bcopy(s, ty, l->lc_tl); - s += l->lc_tl; - /* } while (ty[0] != 0x8 && ty[1] != 0); */ - n = MIN(i, cnt); - bcopy(s, buf, n); - return n; -} diff --git a/contrib/ipfilter/ipft_sn.c b/contrib/ipfilter/ipft_sn.c deleted file mode 100644 index 859bf5ed9df7..000000000000 --- a/contrib/ipfilter/ipft_sn.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ - -/* - * Written to comply with the recent RFC 1761 from Sun. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include "ip_compat.h" -#include -#include "ipf.h" -#include "snoop.h" -#include "ipt.h" - -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: ipft_sn.c,v 2.2.2.4 2002/12/06 11:40:26 darrenr Exp $"; -#endif - -struct llc { - int lc_sz; /* LLC header length */ - int lc_to; /* LLC Type offset */ - int lc_tl; /* LLC Type length */ -}; - -/* - * While many of these maybe the same, some do have different header formats - * which make this useful. - */ -static struct llc llcs[SDL_MAX+1] = { - { 0, 0, 0 }, /* SDL_8023 */ - { 0, 0, 0 }, /* SDL_8024 */ - { 0, 0, 0 }, /* SDL_8025 */ - { 0, 0, 0 }, /* SDL_8026 */ - { 14, 12, 2 }, /* SDL_ETHER */ - { 0, 0, 0 }, /* SDL_HDLC */ - { 0, 0, 0 }, /* SDL_CHSYNC */ - { 0, 0, 0 }, /* SDL_IBMCC */ - { 0, 0, 0 }, /* SDL_FDDI */ - { 0, 0, 0 }, /* SDL_OTHER */ -}; - -static int snoop_open __P((char *)); -static int snoop_close __P((void)); -static int snoop_readip __P((char *, int, char **, int *)); - -static int sfd = -1, s_type = -1; -static int snoop_read_rec __P((struct snooppkt *)); - -struct ipread snoop = { snoop_open, snoop_close, snoop_readip }; - - -static int snoop_open(fname) -char *fname; -{ - struct snoophdr sh; - int fd; - int s_v; - - if (sfd != -1) - return sfd; - - if (!strcmp(fname, "-")) - fd = 0; - else if ((fd = open(fname, O_RDONLY)) == -1) - return -1; - - if (read(fd, (char *)&sh, sizeof(sh)) != sizeof(sh)) - return -2; - - s_v = (int)ntohl(sh.s_v); - s_type = (int)ntohl(sh.s_type); - - if (s_v != SNOOP_VERSION || - s_type < 0 || s_type > SDL_MAX) { - (void) close(fd); - return -2; - } - - sfd = fd; - printf("opened snoop file %s:\n", fname); - printf("\tid: %8.8s version: %d type: %d\n", sh.s_id, s_v, s_type); - - return fd; -} - - -static int snoop_close() -{ - return close(sfd); -} - - -/* - * read in the header (and validate) which should be the first record - * in a snoop file. - */ -static int snoop_read_rec(rec) -struct snooppkt *rec; -{ - int n, plen, ilen; - - if (read(sfd, (char *)rec, sizeof(*rec)) != sizeof(*rec)) - return -2; - - ilen = (int)ntohl(rec->sp_ilen); - plen = (int)ntohl(rec->sp_plen); - if (ilen > plen || plen < sizeof(*rec)) - return -2; - - plen -= sizeof(*rec); - n = MIN(plen, ilen); - if (!n || n < 0) - return -3; - - return plen; -} - - -#ifdef notyet -/* - * read an entire snoop packet record. only the data part is copied into - * the available buffer, with the number of bytes copied returned. - */ -static int snoop_read(buf, cnt) -char *buf; -int cnt; -{ - struct snooppkt rec; - static char *bufp = NULL; - int i, n; - - if ((i = snoop_read_rec(&rec)) <= 0) - return i; - - if (!bufp) - bufp = malloc(i); - else - bufp = realloc(bufp, i); - - if (read(sfd, bufp, i) != i) - return -2; - - n = MIN(i, cnt); - bcopy(bufp, buf, n); - return n; -} -#endif - - -/* - * return only an IP packet read into buf - */ -static int snoop_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - static char *bufp = NULL; - struct snooppkt rec; - struct llc *l; - char ty[4], *s; - int i, n; - - do { - if ((i = snoop_read_rec(&rec)) <= 0) - return i; - - if (!bufp) - bufp = malloc(i); - else - bufp = realloc(bufp, i); - s = bufp; - - if (read(sfd, s, i) != i) - return -2; - - l = &llcs[s_type]; - i -= l->lc_to; - s += l->lc_to; - /* - * XXX - bogus assumption here on the part of the time field - * that it won't be greater than 4 bytes and the 1st two will - * have the values 8 and 0 for IP. Should be a table of - * these too somewhere. Really only works for SDL_ETHER. - */ - bcopy(s, ty, l->lc_tl); - } while (ty[0] != 0x8 && ty[1] != 0); - - i -= l->lc_tl; - s += l->lc_tl; - n = MIN(i, cnt); - bcopy(s, buf, n); - - return n; -} diff --git a/contrib/ipfilter/ipft_td.c b/contrib/ipfilter/ipft_td.c deleted file mode 100644 index 99beab5b6a44..000000000000 --- a/contrib/ipfilter/ipft_td.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ - -/* -tcpdump -n - -00:05:47.816843 128.231.76.76.3291 > 224.2.252.231.36573: udp 36 (encap) - -tcpdump -nq - -00:33:48.410771 192.73.213.11.1463 > 224.2.248.153.59360: udp 31 (encap) - -tcpdump -nqt - -128.250.133.13.23 > 128.250.20.20.2419: tcp 27 - -tcpdump -nqtt - -123456789.1234567 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 - -tcpdump -nqte - -8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 - -*/ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include -#include "ipf.h" -#include "ipt.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_td.c,v 2.2.2.6 2003/05/31 02:13:04 darrenr Exp $"; -#endif - -static int tcpd_open __P((char *)); -static int tcpd_close __P((void)); -static int tcpd_readip __P((char *, int, char **, int *)); -static int count_dots __P((char *)); - -struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip }; - -static FILE *tfp = NULL; -static int tfd = -1; - - -static int tcpd_open(fname) -char *fname; -{ - if (tfd != -1) - return tfd; - - if (!strcmp(fname, "-")) { - tfd = 0; - tfp = stdin; - } else { - tfd = open(fname, O_RDONLY); - tfp = fdopen(tfd, "r"); - } - return tfd; -} - - -static int tcpd_close() -{ - (void) fclose(tfp); - return close(tfd); -} - - -static int count_dots(str) -char *str; -{ - int i = 0; - - while (*str) - if (*str++ == '.') - i++; - return i; -} - - -static int tcpd_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - struct tcpiphdr pkt; - ip_t *ip = (ip_t *)&pkt; - struct protoent *p; - char src[32], dst[32], misc[256], time[32], link1[32], link2[32]; - char lbuf[160], *s; - int n, slen, extra = 0; - - if (!fgets(lbuf, sizeof(lbuf) - 1, tfp)) - return 0; - - if ((s = strchr(lbuf, '\n'))) - *s = '\0'; - lbuf[sizeof(lbuf)-1] = '\0'; - - bzero(&pkt, sizeof(pkt)); - - if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3) - if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s", - time, src, dst, misc)) != 4) - if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s", - link1, link2, src, dst, misc)) != 5) { - n = sscanf(lbuf, - "%31s %31s %31s: %31s > %31s: %255s", - time, link1, link2, src, dst, misc); - if (n != 6) - return -1; - } - - if (count_dots(dst) == 4) { - s = strrchr(src, '.'); - *s++ = '\0'; - (void) inet_aton(src, &ip->ip_src); - pkt.ti_sport = htons(atoi(s)); - *--s = '.'; - s = strrchr(dst, '.'); - - *s++ = '\0'; - (void) inet_aton(src, &ip->ip_dst); - pkt.ti_dport = htons(atoi(s)); - *--s = '.'; - - } else { - (void) inet_aton(src, &ip->ip_src); - (void) inet_aton(src, &ip->ip_dst); - } - ip->ip_len = ip->ip_hl = sizeof(ip_t); - - s = strtok(misc, " :"); - if ((p = getprotobyname(s))) { - ip->ip_p = p->p_proto; - - switch (p->p_proto) { - case IPPROTO_TCP : - case IPPROTO_UDP : - s = strtok(NULL, " :"); - ip->ip_len += atoi(s); - if (p->p_proto == IPPROTO_TCP) - extra = sizeof(struct tcphdr); - else if (p->p_proto == IPPROTO_UDP) - extra = sizeof(struct udphdr); - break; -#ifdef IGMP - case IPPROTO_IGMP : - extra = sizeof(struct igmp); - break; -#endif - case IPPROTO_ICMP : - extra = sizeof(struct icmp); - break; - default : - break; - } - } - slen = ip->ip_hl + extra + ip->ip_len; - return slen; -} diff --git a/contrib/ipfilter/ipft_tx.c b/contrib/ipfilter/ipft_tx.c deleted file mode 100644 index 7ea87e334c86..000000000000 --- a/contrib/ipfilter/ipft_tx.c +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 1995-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include -#include "ipf.h" -#include "ipt.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipft_tx.c 1.7 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipft_tx.c,v 2.3.2.8 2002/12/06 11:40:26 darrenr Exp $"; -#endif - -extern int opts; - -static char *tx_proto = ""; - -static int text_open __P((char *)), text_close __P((void)); -static int text_readip __P((char *, int, char **, int *)); -static int parseline __P((char *, ip_t *, char **, int *)); - -static char _tcp_flagset[] = "FSRPAUEC"; -static u_char _tcp_flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, - TH_ACK, TH_URG, TH_ECN, TH_CWR }; - -struct ipread iptext = { text_open, text_close, text_readip }; -static FILE *tfp = NULL; -static int tfd = -1; - -static u_32_t tx_hostnum __P((char *, int *)); -static u_short tx_portnum __P((char *)); - - -/* - * returns an ip address as a long var as a result of either a DNS lookup or - * straight inet_addr() call - */ -static u_32_t tx_hostnum(host, resolved) -char *host; -int *resolved; -{ - struct hostent *hp; - struct netent *np; - - *resolved = 0; - if (!strcasecmp("any",host)) - return 0L; - if (isdigit(*host)) - return inet_addr(host); - - if (!(hp = gethostbyname(host))) { - if (!(np = getnetbyname(host))) { - *resolved = -1; - fprintf(stderr, "can't resolve hostname: %s\n", host); - return 0; - } - return htonl(np->n_net); - } - return *(u_32_t *)hp->h_addr; -} - - -/* - * find the port number given by the name, either from getservbyname() or - * straight atoi() - */ -static u_short tx_portnum(name) -char *name; -{ - struct servent *sp, *sp2; - u_short p1 = 0; - - if (isdigit(*name)) - return (u_short)atoi(name); - if (!tx_proto) - tx_proto = "tcp/udp"; - if (strcasecmp(tx_proto, "tcp/udp")) { - sp = getservbyname(name, tx_proto); - if (sp) - return ntohs(sp->s_port); - (void) fprintf(stderr, "unknown service \"%s\".\n", name); - return 0; - } - sp = getservbyname(name, "tcp"); - if (sp) - p1 = sp->s_port; - sp2 = getservbyname(name, "udp"); - if (!sp || !sp2) { - (void) fprintf(stderr, "unknown tcp/udp service \"%s\".\n", - name); - return 0; - } - if (p1 != sp2->s_port) { - (void) fprintf(stderr, "%s %d/tcp is a different port to ", - name, p1); - (void) fprintf(stderr, "%s %d/udp\n", name, sp->s_port); - return 0; - } - return ntohs(p1); -} - - -char *tx_icmptypes[] = { - "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", - "redir", (char *)NULL, (char *)NULL, "echo", "routerad", - "routersol", "timex", "paramprob", "timest", "timestrep", - "inforeq", "inforep", "maskreq", "maskrep", "END" -}; - -static int text_open(fname) -char *fname; -{ - if (tfp && tfd != -1) { - rewind(tfp); - return tfd; - } - - if (!strcmp(fname, "-")) { - tfd = 0; - tfp = stdin; - } else { - tfd = open(fname, O_RDONLY); - if (tfd != -1) - tfp = fdopen(tfd, "r"); - } - return tfd; -} - - -static int text_close() -{ - int cfd = tfd; - - tfd = -1; - return close(cfd); -} - - -static int text_readip(buf, cnt, ifn, dir) -char *buf, **ifn; -int cnt, *dir; -{ - register char *s; - char line[513]; - - *ifn = NULL; - while (fgets(line, sizeof(line)-1, tfp)) { - if ((s = index(line, '\n'))) - *s = '\0'; - if ((s = index(line, '\r'))) - *s = '\0'; - if ((s = index(line, '#'))) - *s = '\0'; - if (!*line) - continue; - if (!(opts & OPT_BRIEF)) - printf("input: %s\n", line); - *ifn = NULL; - *dir = 0; - if (!parseline(line, (ip_t *)buf, ifn, dir)) -#if 0 - return sizeof(ip_t) + sizeof(tcphdr_t); -#else - return sizeof(ip_t); -#endif - } - return -1; -} - -static int parseline(line, ip, ifn, out) -char *line; -ip_t *ip; -char **ifn; -int *out; -{ - tcphdr_t th, *tcp = &th; - struct icmp icmp, *ic = &icmp; - char *cps[20], **cpp, c, ipopts[68]; - int i, r; - - if (*ifn) - free(*ifn); - bzero((char *)ip, MAX(sizeof(*tcp), sizeof(*ic)) + sizeof(*ip)); - bzero((char *)tcp, sizeof(*tcp)); - bzero((char *)ic, sizeof(*ic)); - bzero(ipopts, sizeof(ipopts)); - ip->ip_hl = sizeof(*ip) >> 2; - ip->ip_v = IPVERSION; - for (i = 0, cps[0] = strtok(line, " \b\t\r\n"); cps[i] && (i < 19); ) - cps[++i] = strtok(NULL, " \b\t\r\n"); - - cpp = cps; - if (!*cpp) - return 1; - - c = **cpp; - if (!isalpha(c) || (tolower(c) != 'o' && tolower(c) != 'i')) { - fprintf(stderr, "bad direction \"%s\"\n", *cpp); - return 1; - } - *out = (tolower(c) == 'o') ? 1 : 0; - cpp++; - if (!*cpp) - return 1; - - if (!strcasecmp(*cpp, "on")) { - cpp++; - if (!*cpp) - return 1; - *ifn = strdup(*cpp++); - if (!*cpp) - return 1; - } - - c = **cpp; - ip->ip_len = sizeof(ip_t); - if (!strcasecmp(*cpp, "tcp") || !strcasecmp(*cpp, "udp") || - !strcasecmp(*cpp, "icmp")) { - if (c == 't') { - ip->ip_p = IPPROTO_TCP; - ip->ip_len += sizeof(struct tcphdr); - tx_proto = "tcp"; - } else if (c == 'u') { - ip->ip_p = IPPROTO_UDP; - ip->ip_len += sizeof(struct udphdr); - tx_proto = "udp"; - } else { - ip->ip_p = IPPROTO_ICMP; - ip->ip_len += ICMPERR_IPICMPHLEN; - tx_proto = "icmp"; - } - cpp++; - } else if (isdigit(**cpp) && !index(*cpp, '.')) { - ip->ip_p = atoi(*cpp); - cpp++; - } else - ip->ip_p = IPPROTO_IP; - - if (!*cpp) - return 1; - if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { - char *last; - - last = index(*cpp, ','); - if (!last) { - fprintf(stderr, "tcp/udp with no source port\n"); - return 1; - } - *last++ = '\0'; - tcp->th_sport = htons(tx_portnum(last)); - } - ip->ip_src.s_addr = tx_hostnum(*cpp, &r); - cpp++; - if (!*cpp) - return 1; - - if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) { - char *last; - - last = index(*cpp, ','); - if (!last) { - fprintf(stderr, "tcp/udp with no destination port\n"); - return 1; - } - *last++ = '\0'; - tcp->th_dport = htons(tx_portnum(last)); - } - ip->ip_dst.s_addr = tx_hostnum(*cpp, &r); - cpp++; - if (*cpp && ip->ip_p == IPPROTO_TCP) { - extern char _tcp_flagset[]; - extern u_char _tcp_flags[]; - char *s, *t; - - for (s = *cpp; *s; s++) - if ((t = index(_tcp_flagset, *s))) - tcp->th_flags |= _tcp_flags[t - _tcp_flagset]; - if (tcp->th_flags) - cpp++; - assert(tcp->th_flags != 0); - tcp->th_win = htons(4096); - tcp->th_off = sizeof(*tcp) >> 2; - } else if (*cpp && ip->ip_p == IPPROTO_ICMP) { - extern char *tx_icmptypes[]; - char **s, *t; - int i; - - for (s = tx_icmptypes, i = 0; !*s || strcmp(*s, "END"); - s++, i++) - if (*s && !strncasecmp(*cpp, *s, strlen(*s))) { - ic->icmp_type = i; - if ((t = index(*cpp, ','))) - ic->icmp_code = atoi(t+1); - cpp++; - break; - } - } - - if (*cpp && !strcasecmp(*cpp, "opt")) { - u_long olen; - - cpp++; - olen = buildopts(*cpp, ipopts, (ip->ip_hl - 5) << 2); - if (olen) { - bcopy(ipopts, (char *)(ip + 1), olen); - ip->ip_hl += olen >> 2; - } - } - if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) - bcopy((char *)tcp, ((char *)ip) + (ip->ip_hl << 2), - sizeof(*tcp)); - else if (ip->ip_p == IPPROTO_ICMP) - bcopy((char *)ic, ((char *)ip) + (ip->ip_hl << 2), - sizeof(*ic)); - ip->ip_len = htons(ip->ip_len); - return 0; -} diff --git a/contrib/ipfilter/ipl.h b/contrib/ipfilter/ipl.h deleted file mode 100644 index 7e90820c85d9..000000000000 --- a/contrib/ipfilter/ipl.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-2001, 2003 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * @(#)ipl.h 1.21 6/5/96 - * Id: ipl.h,v 2.52.2.9 2005/03/30 14:14:05 darrenr Exp - */ - -#ifndef __IPL_H__ -#define __IPL_H__ - -#define IPL_VERSION "IP Filter: v4.1.8" - -#define IPFILTER_VERSION 4010800 - -#endif diff --git a/contrib/ipfilter/ipl_ldev.c b/contrib/ipfilter/ipl_ldev.c deleted file mode 100644 index a2893257e72e..000000000000 --- a/contrib/ipfilter/ipl_ldev.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * (C)opyright 1993,1994,1995 by Darren Reed. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and due credit is given - * to the original author and the contributors. - */ - -/* - * routines below for saving IP headers to buffer - */ -int iplopen(struct inode * inode, struct file * filp) -{ - u_int min = MINOR(inode->i_rdev); - - if (flags & FWRITE) - return ENXIO; - if (min) - return ENXIO; - iplbusy++; - return 0; -} - - -int iplclose(struct inode * inode, struct file * filp) -{ - u_int min = MINOR(inode->i_rdev); - - if (min) - return ENXIO; - iplbusy--; - return 0; -} - - -/* - * iplread/ipllog - * all three of these must operate with at least splnet() lest they be - * called during packet processing and cause an inconsistancy to appear in - * the filter lists. - */ -int iplread(struct inode *inode, struct file *file, char *buf, int count) -{ - register int ret, s; - register size_t sz, sx; - int error; - - if (!uio->uio_resid) - return 0; - while (!iplused) { - error = SLEEP(iplbuf, "ipl sleep"); - if (error) - return error; - } - - SPLNET(s); - - ret = sx = sz = MIN(count, iplused); - if (iplh < iplt) - sz = MIN(sz, LOGSIZE - (iplt - iplbuf)); - sx -= sz; - - memcpy_tofs(buf, iplt, sz); - buf += sz; - iplt += sz; - iplused -= sz; - if ((iplh < iplt) && (iplt == iplbuf + LOGSIZE)) - iplt = iplbuf; - - if (sx) { - memcpy_tofs(buf, iplt, sx); - ret += sx; - iplt += sx; - iplused -= sx; - if ((iplh < iplt) && (iplt == iplbuf + LOGSIZE)) - iplt = iplbuf; - } - if (!iplused) /* minimise wrapping around the end */ - iplh = iplt = iplbuf; - - SPLX(s); - return ret; -} diff --git a/contrib/ipfilter/iplang/.cvsignore b/contrib/ipfilter/iplang/.cvsignore deleted file mode 100644 index 68b5b4e4e985..000000000000 --- a/contrib/ipfilter/iplang/.cvsignore +++ /dev/null @@ -1,9 +0,0 @@ -y.tab.h -y.output -lex.yy.c -y.tab.c -y.tab.o -lex.yy.o -iplang_y.output -iplang_y.tab.c -iplang_y.tab.h diff --git a/contrib/ipfilter/ipmon.c b/contrib/ipfilter/ipmon.c deleted file mode 100644 index 2e4b2b546275..000000000000 --- a/contrib/ipfilter/ipmon.c +++ /dev/null @@ -1,1493 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#ifndef SOLARIS -#define SOLARIS (defined(__SVR4) || defined(__svr4__)) && defined(sun) -#endif - -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -# if (__FreeBSD_version >= 300000) -# include -# else -# include -# endif -#else -# include -# include -#endif -#if !defined(__SVR4) && !defined(__GNUC__) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef linux -# include -# include -#endif - -#include -#include - -#include -#include - -#include "netinet/ip_compat.h" -#include -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_state.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipmon.c 1.21 6/5/96 (C)1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipmon.c,v 2.12.2.40 2004/05/12 23:21:55 darrenr Exp $"; -#endif - - -#if defined(sun) && !defined(SOLARIS2) -#define STRERROR(x) sys_errlist[x] -extern char *sys_errlist[]; -#else -#define STRERROR(x) strerror(x) -#endif - - -struct flags { - int value; - char flag; -}; - - -typedef struct icmp_subtype { - int ist_val; - char *ist_name; -} icmp_subtype_t; - -typedef struct icmp_type { - int it_val; - struct icmp_subtype *it_subtable; - size_t it_stsize; - char *it_name; -} icmp_type_t; - - -#define IST_SZ(x) (sizeof(x)/sizeof(icmp_subtype_t)) - - -struct flags tcpfl[] = { - { TH_ACK, 'A' }, - { TH_RST, 'R' }, - { TH_SYN, 'S' }, - { TH_FIN, 'F' }, - { TH_URG, 'U' }, - { TH_PUSH,'P' }, - { TH_ECN, 'E' }, - { TH_CWR, 'C' }, - { 0, '\0' } -}; - -#if SOLARIS -static char *pidfile = "/etc/opt/ipf/ipmon.pid"; -#else -# if BSD >= 199306 -static char *pidfile = "/var/run/ipmon.pid"; -# else -static char *pidfile = "/etc/ipmon.pid"; -# endif -#endif - -static char line[2048]; -static int opts = 0; -static FILE *newlog = NULL; -static char *logfile = NULL; -static int donehup = 0; -static void usage __P((char *)); -static void handlehup __P((int)); -static void flushlogs __P((char *, FILE *)); -static void print_log __P((int, FILE *, char *, int)); -static void print_ipflog __P((FILE *, char *, int)); -static void print_natlog __P((FILE *, char *, int)); -static void print_statelog __P((FILE *, char *, int)); -static void dumphex __P((FILE *, u_char *, int)); -static int read_log __P((int, int *, char *, int)); -static void write_pid __P((char *)); -static char *icmpname __P((u_int, u_int)); -static char *icmpname6 __P((u_int, u_int)); -static icmp_type_t *find_icmptype __P((int, icmp_type_t *, size_t)); -static icmp_subtype_t *find_icmpsubtype __P((int, icmp_subtype_t *, size_t)); - -char *hostname __P((int, int, u_32_t *)); -char *portname __P((int, char *, u_int)); -int main __P((int, char *[])); - -static void logopts __P((int, char *)); -static void init_tabs __P((void)); -static char *getproto __P((u_int)); - -static char **protocols = NULL; -static char **udp_ports = NULL; -static char **tcp_ports = NULL; - -#define OPT_SYSLOG 0x001 -#define OPT_RESOLVE 0x002 -#define OPT_HEXBODY 0x004 -#define OPT_VERBOSE 0x008 -#define OPT_HEXHDR 0x010 -#define OPT_TAIL 0x020 -#define OPT_NAT 0x080 -#define OPT_STATE 0x100 -#define OPT_FILTER 0x200 -#define OPT_PORTNUM 0x400 -#define OPT_LOGALL (OPT_NAT|OPT_STATE|OPT_FILTER) -#define OPT_LOGBODY 0x800 - -#define HOSTNAME_V4(a,b) hostname((a), 4, (u_32_t *)&(b)) - -#ifndef LOGFAC -#define LOGFAC LOG_LOCAL0 -#endif - - -static icmp_subtype_t icmpunreachnames[] = { - { ICMP_UNREACH_NET, "net" }, - { ICMP_UNREACH_HOST, "host" }, - { ICMP_UNREACH_PROTOCOL, "protocol" }, - { ICMP_UNREACH_PORT, "port" }, - { ICMP_UNREACH_NEEDFRAG, "needfrag" }, - { ICMP_UNREACH_SRCFAIL, "srcfail" }, - { ICMP_UNREACH_NET_UNKNOWN, "net_unknown" }, - { ICMP_UNREACH_HOST_UNKNOWN, "host_unknown" }, - { ICMP_UNREACH_NET, "isolated" }, - { ICMP_UNREACH_NET_PROHIB, "net_prohib" }, - { ICMP_UNREACH_NET_PROHIB, "host_prohib" }, - { ICMP_UNREACH_TOSNET, "tosnet" }, - { ICMP_UNREACH_TOSHOST, "toshost" }, - { ICMP_UNREACH_ADMIN_PROHIBIT, "admin_prohibit" }, - { -2, NULL } -}; - -static icmp_subtype_t redirectnames[] = { - { ICMP_REDIRECT_NET, "net" }, - { ICMP_REDIRECT_HOST, "host" }, - { ICMP_REDIRECT_TOSNET, "tosnet" }, - { ICMP_REDIRECT_TOSHOST, "toshost" }, - { -2, NULL } -}; - -static icmp_subtype_t timxceednames[] = { - { ICMP_TIMXCEED_INTRANS, "transit" }, - { ICMP_TIMXCEED_REASS, "reassem" }, - { -2, NULL } -}; - -static icmp_subtype_t paramnames[] = { - { ICMP_PARAMPROB_ERRATPTR, "errata_pointer" }, - { ICMP_PARAMPROB_OPTABSENT, "optmissing" }, - { ICMP_PARAMPROB_LENGTH, "length" }, - { -2, NULL } -}; - -static icmp_type_t icmptypes[] = { - { ICMP_ECHOREPLY, NULL, 0, "echoreply" }, - { -1, NULL, 0, NULL }, - { -1, NULL, 0, NULL }, - { ICMP_UNREACH, icmpunreachnames, - IST_SZ(icmpunreachnames),"unreach" }, - { ICMP_SOURCEQUENCH, NULL, 0, "sourcequench" }, - { ICMP_REDIRECT, redirectnames, - IST_SZ(redirectnames), "redirect" }, - { -1, NULL, 0, NULL }, - { -1, NULL, 0, NULL }, - { ICMP_ECHO, NULL, 0, "echo" }, - { ICMP_ROUTERADVERT, NULL, 0, "routeradvert" }, - { ICMP_ROUTERSOLICIT, NULL, 0, "routersolicit" }, - { ICMP_TIMXCEED, timxceednames, - IST_SZ(timxceednames), "timxceed" }, - { ICMP_PARAMPROB, paramnames, - IST_SZ(paramnames), "paramprob" }, - { ICMP_TSTAMP, NULL, 0, "timestamp" }, - { ICMP_TSTAMPREPLY, NULL, 0, "timestampreply" }, - { ICMP_IREQ, NULL, 0, "inforeq" }, - { ICMP_IREQREPLY, NULL, 0, "inforeply" }, - { ICMP_MASKREQ, NULL, 0, "maskreq" }, - { ICMP_MASKREPLY, NULL, 0, "maskreply" }, - { -2, NULL, 0, NULL } -}; - -static icmp_subtype_t icmpredirect6[] = { - { ICMP6_DST_UNREACH_NOROUTE, "noroute" }, - { ICMP6_DST_UNREACH_ADMIN, "admin" }, - { ICMP6_DST_UNREACH_NOTNEIGHBOR, "neighbour" }, - { ICMP6_DST_UNREACH_ADDR, "address" }, - { ICMP6_DST_UNREACH_NOPORT, "noport" }, - { -2, NULL } -}; - -static icmp_subtype_t icmptimexceed6[] = { - { ICMP6_TIME_EXCEED_TRANSIT, "intransit" }, - { ICMP6_TIME_EXCEED_REASSEMBLY, "reassem" }, - { -2, NULL } -}; - -static icmp_subtype_t icmpparamprob6[] = { - { ICMP6_PARAMPROB_HEADER, "header" }, - { ICMP6_PARAMPROB_NEXTHEADER, "nextheader" }, - { ICMP6_PARAMPROB_OPTION, "option" }, - { -2, NULL } -}; - -static icmp_subtype_t icmpquerysubject6[] = { - { ICMP6_NI_SUBJ_IPV6, "ipv6" }, - { ICMP6_NI_SUBJ_FQDN, "fqdn" }, - { ICMP6_NI_SUBJ_IPV4, "ipv4" }, - { -2, NULL }, -}; - -static icmp_subtype_t icmpnodeinfo6[] = { - { ICMP6_NI_SUCCESS, "success" }, - { ICMP6_NI_REFUSED, "refused" }, - { ICMP6_NI_UNKNOWN, "unknown" }, - { -2, NULL } -}; - -static icmp_subtype_t icmprenumber6[] = { - { ICMP6_ROUTER_RENUMBERING_COMMAND, "command" }, - { ICMP6_ROUTER_RENUMBERING_RESULT, "result" }, - { ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET, "seqnum_reset" }, - { -2, NULL } -}; - -static icmp_type_t icmptypes6[] = { - { 0, NULL, 0, NULL }, - { ICMP6_DST_UNREACH, icmpredirect6, - IST_SZ(icmpredirect6), "unreach" }, - { ICMP6_PACKET_TOO_BIG, NULL, 0, "toobig" }, - { ICMP6_TIME_EXCEEDED, icmptimexceed6, - IST_SZ(icmptimexceed6), "timxceed" }, - { ICMP6_PARAM_PROB, icmpparamprob6, - IST_SZ(icmpparamprob6), "paramprob" }, - { ICMP6_ECHO_REQUEST, NULL, 0, "echo" }, - { ICMP6_ECHO_REPLY, NULL, 0, "echoreply" }, - { ICMP6_MEMBERSHIP_QUERY, icmpquerysubject6, - IST_SZ(icmpquerysubject6), "groupmemberquery" }, - { ICMP6_MEMBERSHIP_REPORT,NULL, 0, "groupmemberreport" }, - { ICMP6_MEMBERSHIP_REDUCTION,NULL, 0, "groupmemberterm" }, - { ND_ROUTER_SOLICIT, NULL, 0, "routersolicit" }, - { ND_ROUTER_ADVERT, NULL, 0, "routeradvert" }, - { ND_NEIGHBOR_SOLICIT, NULL, 0, "neighborsolicit" }, - { ND_NEIGHBOR_ADVERT, NULL, 0, "neighboradvert" }, - { ND_REDIRECT, NULL, 0, "redirect" }, - { ICMP6_ROUTER_RENUMBERING, icmprenumber6, - IST_SZ(icmprenumber6), "routerrenumber" }, - { ICMP6_WRUREQUEST, NULL, 0, "whoareyourequest" }, - { ICMP6_WRUREPLY, NULL, 0, "whoareyoureply" }, - { ICMP6_FQDN_QUERY, NULL, 0, "fqdnquery" }, - { ICMP6_FQDN_REPLY, NULL, 0, "fqdnreply" }, - { ICMP6_NI_QUERY, icmpnodeinfo6, - IST_SZ(icmpnodeinfo6), "nodeinforequest" }, - { ICMP6_NI_REPLY, NULL, 0, "nodeinforeply" }, - { MLD6_MTRACE_RESP, NULL, 0, "mtraceresponse" }, - { MLD6_MTRACE, NULL, 0, "mtracerequest" }, - { -2, NULL, 0, NULL } -}; - -static icmp_subtype_t *find_icmpsubtype(type, table, tablesz) -int type; -icmp_subtype_t *table; -size_t tablesz; -{ - icmp_subtype_t *ist; - int i; - - if (tablesz < 2) - return NULL; - - if ((type < 0) || (type > table[tablesz - 2].ist_val)) - return NULL; - - i = type; - if (table[type].ist_val == type) - return table + type; - - for (i = 0, ist = table; ist->ist_val != -2; i++, ist++) - if (ist->ist_val == type) - return ist; - return NULL; -} - - -static icmp_type_t *find_icmptype(type, table, tablesz) -int type; -icmp_type_t *table; -size_t tablesz; -{ - icmp_type_t *it; - int i; - - if (tablesz < 2) - return NULL; - - if ((type < 0) || (type > table[tablesz - 2].it_val)) - return NULL; - - i = type; - if (table[type].it_val == type) - return table + type; - - for (i = 0, it = table; it->it_val != -2; i++, it++) - if (it->it_val == type) - return it; - return NULL; -} - - -static void handlehup(sig) -int sig; -{ - FILE *fp; - - signal(SIGHUP, handlehup); - if (logfile && (fp = fopen(logfile, "a"))) - newlog = fp; - init_tabs(); - donehup = 1; -} - - -static void init_tabs() -{ - struct protoent *p; - struct servent *s; - char *name, **tab; - int port; - - if (protocols != NULL) { - free(protocols); - protocols = NULL; - } - protocols = (char **)malloc(256 * sizeof(*protocols)); - if (protocols != NULL) { - bzero((char *)protocols, 256 * sizeof(*protocols)); - - setprotoent(1); - while ((p = getprotoent()) != NULL) - if (p->p_proto >= 0 && p->p_proto <= 255 && - p->p_name != NULL && protocols[p->p_proto] == NULL) - protocols[p->p_proto] = strdup(p->p_name); - endprotoent(); - } - - if (udp_ports != NULL) { - free(udp_ports); - udp_ports = NULL; - } - udp_ports = (char **)malloc(65536 * sizeof(*udp_ports)); - if (udp_ports != NULL) - bzero((char *)udp_ports, 65536 * sizeof(*udp_ports)); - - if (tcp_ports != NULL) { - free(tcp_ports); - tcp_ports = NULL; - } - tcp_ports = (char **)malloc(65536 * sizeof(*tcp_ports)); - if (tcp_ports != NULL) - bzero((char *)tcp_ports, 65536 * sizeof(*tcp_ports)); - - setservent(1); - while ((s = getservent()) != NULL) { - if (s->s_proto == NULL) - continue; - else if (!strcmp(s->s_proto, "tcp")) { - port = ntohs(s->s_port); - name = s->s_name; - tab = tcp_ports; - } else if (!strcmp(s->s_proto, "udp")) { - port = ntohs(s->s_port); - name = s->s_name; - tab = udp_ports; - } else - continue; - if ((port < 0 || port > 65535) || (name == NULL)) - continue; - tab[port] = strdup(name); - } - endservent(); -} - - -static char *getproto(p) -u_int p; -{ - static char pnum[4]; - char *s; - - p &= 0xff; - s = protocols ? protocols[p] : NULL; - if (s == NULL) { - sprintf(pnum, "%u", p); - s = pnum; - } - return s; -} - - -static int read_log(fd, lenp, buf, bufsize) -int fd, bufsize, *lenp; -char *buf; -{ - int nr; - - nr = read(fd, buf, bufsize); - if (!nr) - return 2; - if ((nr < 0) && (errno != EINTR)) - return -1; - *lenp = nr; - return 0; -} - - -char *hostname(res, v, ip) -int res, v; -u_32_t *ip; -{ -# define MAX_INETA 16 - static char hname[MAXHOSTNAMELEN + MAX_INETA + 3]; -#ifdef USE_INET6 - static char hostbuf[MAXHOSTNAMELEN+1]; -#endif - struct hostent *hp; - struct in_addr ipa; - - if (v == 4) { - ipa.s_addr = *ip; - if (!res) - return inet_ntoa(ipa); - hp = gethostbyaddr((char *)ip, sizeof(*ip), AF_INET); - if (!hp) - return inet_ntoa(ipa); - sprintf(hname, "%.*s[%s]", MAXHOSTNAMELEN, hp->h_name, - inet_ntoa(ipa)); - return hname; - } -#ifdef USE_INET6 - (void) inet_ntop(AF_INET6, ip, hostbuf, sizeof(hostbuf) - 1); - hostbuf[MAXHOSTNAMELEN] = '\0'; - return hostbuf; -#else - return "IPv6"; -#endif -} - - -char *portname(res, proto, port) -int res; -char *proto; -u_int port; -{ - static char pname[8]; - char *s; - - port = ntohs(port); - port &= 0xffff; - (void) sprintf(pname, "%u", port); - if (!res || (opts & OPT_PORTNUM)) - return pname; - s = NULL; - if (!strcmp(proto, "tcp")) - s = tcp_ports[port]; - else if (!strcmp(proto, "udp")) - s = udp_ports[port]; - if (s == NULL) - s = pname; - return s; -} - - -static char *icmpname(type, code) -u_int type; -u_int code; -{ - static char name[80]; - icmp_subtype_t *ist; - icmp_type_t *it; - char *s; - - s = NULL; - it = find_icmptype(type, icmptypes, sizeof(icmptypes) / sizeof(*it)); - if (it != NULL) - s = it->it_name; - - if (s == NULL) - sprintf(name, "icmptype(%d)/", type); - else - sprintf(name, "%s/", s); - - ist = NULL; - if (it != NULL && it->it_subtable != NULL) - ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); - - if (ist != NULL && ist->ist_name != NULL) - strcat(name, ist->ist_name); - else - sprintf(name + strlen(name), "%d", code); - - return name; -} - -static char *icmpname6(type, code) -u_int type; -u_int code; -{ - static char name[80]; - icmp_subtype_t *ist; - icmp_type_t *it; - char *s; - - s = NULL; - it = find_icmptype(type, icmptypes6, sizeof(icmptypes6) / sizeof(*it)); - if (it != NULL) - s = it->it_name; - - if (s == NULL) - sprintf(name, "icmpv6type(%d)/", type); - else - sprintf(name, "%s/", s); - - ist = NULL; - if (it != NULL && it->it_subtable != NULL) - ist = find_icmpsubtype(code, it->it_subtable, it->it_stsize); - - if (ist != NULL && ist->ist_name != NULL) - strcat(name, ist->ist_name); - else - sprintf(name + strlen(name), "%d", code); - - return name; -} - - -static void dumphex(log, buf, len) -FILE *log; -u_char *buf; -int len; -{ - char line[80]; - int i, j, k; - u_char *s = buf, *t = (u_char *)line; - - if (len == 0 || buf == 0) - return; - *line = '\0'; - - for (i = len, j = 0; i; i--, j++, s++) { - if (j && !(j & 0xf)) { - *t++ = '\n'; - *t = '\0'; - if (!(opts & OPT_SYSLOG)) - fputs(line, log); - else - syslog(LOG_INFO, "%s", line); - t = (u_char *)line; - *t = '\0'; - } - sprintf((char *)t, "%02x", *s & 0xff); - t += 2; - if (!((j + 1) & 0xf)) { - s -= 15; - sprintf((char *)t, " "); - t += 8; - for (k = 16; k; k--, s++) - *t++ = (isprint(*s) ? *s : '.'); - s--; - } - - if ((j + 1) & 0xf) - *t++ = ' ';; - } - - if (j & 0xf) { - for (k = 16 - (j & 0xf); k; k--) { - *t++ = ' '; - *t++ = ' '; - *t++ = ' '; - } - sprintf((char *)t, " "); - t += 7; - s -= j & 0xf; - for (k = j & 0xf; k; k--, s++) - *t++ = (isprint(*s) ? *s : '.'); - *t++ = '\n'; - *t = '\0'; - } - if (!(opts & OPT_SYSLOG)) { - fputs(line, log); - fflush(log); - } else - syslog(LOG_INFO, "%s", line); -} - -static void print_natlog(log, buf, blen) -FILE *log; -char *buf; -int blen; -{ - struct natlog *nl; - iplog_t *ipl = (iplog_t *)buf; - char *t = line; - struct tm *tm; - int res, i, len; - char *proto; - - nl = (struct natlog *)((char *)ipl + IPLOG_SIZE); - res = (opts & OPT_RESOLVE) ? 1 : 0; - tm = localtime((time_t *)&ipl->ipl_sec); - len = sizeof(line); - if (!(opts & OPT_SYSLOG)) { - (void) strftime(t, len, "%d/%m/%Y ", tm); - i = strlen(t); - len -= i; - t += i; - } - (void) strftime(t, len, "%T", tm); - t += strlen(t); - (void) sprintf(t, ".%-.6ld @%hd ", ipl->ipl_usec, nl->nl_rule + 1); - t += strlen(t); - - if (nl->nl_type == NL_NEWMAP) - strcpy(t, "NAT:MAP "); - else if (nl->nl_type == NL_NEWRDR) - strcpy(t, "NAT:RDR "); - else if (nl->nl_type == NL_EXPIRE) - strcpy(t, "NAT:EXPIRE "); - else if (nl->nl_type == NL_FLUSH) - strcpy(t, "NAT:FLUSH "); - else if (nl->nl_type == NL_NEWBIMAP) - strcpy(t, "NAT:BIMAP "); - else if (nl->nl_type == NL_NEWBLOCK) - strcpy(t, "NAT:MAPBLOCK "); - else - sprintf(t, "Type: %d ", nl->nl_type); - t += strlen(t); - - proto = getproto(nl->nl_p); - - (void) sprintf(t, "%s,%s <- -> ", HOSTNAME_V4(res, nl->nl_inip), - portname(res, proto, (u_int)nl->nl_inport)); - t += strlen(t); - (void) sprintf(t, "%s,%s ", HOSTNAME_V4(res, nl->nl_outip), - portname(res, proto, (u_int)nl->nl_outport)); - t += strlen(t); - (void) sprintf(t, "[%s,%s]", HOSTNAME_V4(res, nl->nl_origip), - portname(res, proto, (u_int)nl->nl_origport)); - t += strlen(t); - if (nl->nl_type == NL_EXPIRE) { -#ifdef USE_QUAD_T - (void) sprintf(t, " Pkts %qd Bytes %qd", - (long long)nl->nl_pkts, - (long long)nl->nl_bytes); -#else - (void) sprintf(t, " Pkts %ld Bytes %ld", - nl->nl_pkts, nl->nl_bytes); -#endif - t += strlen(t); - } - - *t++ = '\n'; - *t++ = '\0'; - if (opts & OPT_SYSLOG) - syslog(LOG_INFO, "%s", line); - else - (void) fprintf(log, "%s", line); -} - - -static void print_statelog(log, buf, blen) -FILE *log; -char *buf; -int blen; -{ - struct ipslog *sl; - iplog_t *ipl = (iplog_t *)buf; - char *t = line, *proto; - struct tm *tm; - int res, i, len; - - sl = (struct ipslog *)((char *)ipl + IPLOG_SIZE); - res = (opts & OPT_RESOLVE) ? 1 : 0; - tm = localtime((time_t *)&ipl->ipl_sec); - len = sizeof(line); - if (!(opts & OPT_SYSLOG)) { - (void) strftime(t, len, "%d/%m/%Y ", tm); - i = strlen(t); - len -= i; - t += i; - } - (void) strftime(t, len, "%T", tm); - t += strlen(t); - (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); - t += strlen(t); - - if (sl->isl_type == ISL_NEW) - strcpy(t, "STATE:NEW "); - else if (sl->isl_type == ISL_EXPIRE) { - if ((sl->isl_p == IPPROTO_TCP) && - (sl->isl_state[0] > TCPS_ESTABLISHED || - sl->isl_state[1] > TCPS_ESTABLISHED)) - strcpy(t, "STATE:CLOSE "); - else - strcpy(t, "STATE:EXPIRE "); - } else if (sl->isl_type == ISL_FLUSH) - strcpy(t, "STATE:FLUSH "); - else if (sl->isl_type == ISL_REMOVE) - strcpy(t, "STATE:REMOVE "); - else - sprintf(t, "Type: %d ", sl->isl_type); - t += strlen(t); - - proto = getproto(sl->isl_p); - - if (sl->isl_p == IPPROTO_TCP || sl->isl_p == IPPROTO_UDP) { - (void) sprintf(t, "%s,%s -> ", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_src), - portname(res, proto, (u_int)sl->isl_sport)); - t += strlen(t); - (void) sprintf(t, "%s,%s PR %s", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), - portname(res, proto, (u_int)sl->isl_dport), proto); - } else if (sl->isl_p == IPPROTO_ICMP) { - (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, - (u_32_t *)&sl->isl_src)); - t += strlen(t); - (void) sprintf(t, "%s PR icmp %d", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), - sl->isl_itype); - } else if (sl->isl_p == IPPROTO_ICMPV6) { - (void) sprintf(t, "%s -> ", hostname(res, sl->isl_v, - (u_32_t *)&sl->isl_src)); - t += strlen(t); - (void) sprintf(t, "%s PR icmpv6 %d", - hostname(res, sl->isl_v, (u_32_t *)&sl->isl_dst), - sl->isl_itype); - } - t += strlen(t); - if (sl->isl_type != ISL_NEW) { -#ifdef USE_QUAD_T - (void) sprintf(t, " Pkts %qd Bytes %qd", - (long long)sl->isl_pkts, - (long long)sl->isl_bytes); -#else - (void) sprintf(t, " Pkts %ld Bytes %ld", - sl->isl_pkts, sl->isl_bytes); -#endif - t += strlen(t); - } - - *t++ = '\n'; - *t++ = '\0'; - if (opts & OPT_SYSLOG) - syslog(LOG_INFO, "%s", line); - else - (void) fprintf(log, "%s", line); -} - - -static void print_log(logtype, log, buf, blen) -FILE *log; -char *buf; -int logtype, blen; -{ - iplog_t *ipl; - char *bp = NULL, *bpo = NULL; - int psize; - - while (blen > 0) { - ipl = (iplog_t *)buf; - if ((u_long)ipl & (sizeof(long)-1)) { - if (bp) - bpo = bp; - bp = (char *)malloc(blen); - bcopy((char *)ipl, bp, blen); - if (bpo) { - free(bpo); - bpo = NULL; - } - buf = bp; - continue; - } - if (ipl->ipl_magic != IPL_MAGIC) { - /* invalid data or out of sync */ - break; - } - psize = ipl->ipl_dsize; - switch (logtype) - { - case IPL_LOGIPF : - print_ipflog(log, buf, psize); - break; - case IPL_LOGNAT : - print_natlog(log, buf, psize); - break; - case IPL_LOGSTATE : - print_statelog(log, buf, psize); - break; - } - - blen -= psize; - buf += psize; - } - if (bp) - free(bp); - return; -} - - -static void print_ipflog(log, buf, blen) -FILE *log; -char *buf; -int blen; -{ - tcphdr_t *tp; - struct icmp *ic; - struct icmp *icmp; - struct tm *tm; - char *t, *proto; - int i, v, lvl, res, len, off, plen, ipoff; - ip_t *ipc, *ip; - u_short hl, p; - ipflog_t *ipf; - iplog_t *ipl; - u_32_t *s, *d; -#ifdef USE_INET6 - ip6_t *ip6; -#endif - - ipl = (iplog_t *)buf; - ipf = (ipflog_t *)((char *)buf + IPLOG_SIZE); - ip = (ip_t *)((char *)ipf + sizeof(*ipf)); - v = ip->ip_v; - res = (opts & OPT_RESOLVE) ? 1 : 0; - t = line; - *t = '\0'; - tm = localtime((time_t *)&ipl->ipl_sec); -#ifdef linux - if (v == 4) - ip->ip_len = ntohs(ip->ip_len); -#endif - - len = sizeof(line); - if (!(opts & OPT_SYSLOG)) { - (void) strftime(t, len, "%d/%m/%Y ", tm); - i = strlen(t); - len -= i; - t += i; - } - (void) strftime(t, len, "%T", tm); - t += strlen(t); - (void) sprintf(t, ".%-.6ld ", ipl->ipl_usec); - t += strlen(t); - if (ipl->ipl_count > 1) { - (void) sprintf(t, "%dx ", ipl->ipl_count); - t += strlen(t); - } -#if (SOLARIS || \ - (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199603)) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) || \ - (defined(OpenBSD) && (OpenBSD >= 199603))) || defined(linux) - { - char ifname[sizeof(ipf->fl_ifname) + 1]; - - strncpy(ifname, (char *)ipf->fl_ifname, sizeof(ipf->fl_ifname)); - ifname[sizeof(ipf->fl_ifname)] = '\0'; - (void) sprintf(t, "%s", ifname); - t += strlen(t); -# if SOLARIS - if (isalpha(*(t - 1))) { - sprintf(t, "%d", ipf->fl_unit); - t += strlen(t); - } -# endif - } -#else - for (len = 0; len < 3; len++) - if (ipf->fl_ifname[len] == '\0') - break; - if (ipf->fl_ifname[len]) - len++; - (void) sprintf(t, "%*.*s%u", len, len, ipf->fl_ifname, ipf->fl_unit); - t += strlen(t); -#endif - if (ipf->fl_group == 0xffffffff) - strcat(t, " @-1:"); - else - (void) sprintf(t, " @%u:", ipf->fl_group); - t += strlen(t); - if (ipf->fl_rule == 0xffffffff) - strcat(t, "-1 "); - else - (void) sprintf(t, "%u ", ipf->fl_rule + 1); - t += strlen(t); - - if (ipf->fl_flags & FF_SHORT) { - *t++ = 'S'; - lvl = LOG_ERR; - } else if (ipf->fl_flags & FR_PASS) { - if (ipf->fl_flags & FR_LOG) - *t++ = 'p'; - else - *t++ = 'P'; - lvl = LOG_NOTICE; - } else if (ipf->fl_flags & FR_BLOCK) { - if (ipf->fl_flags & FR_LOG) - *t++ = 'b'; - else - *t++ = 'B'; - lvl = LOG_WARNING; - } else if (ipf->fl_flags & FF_LOGNOMATCH) { - *t++ = 'n'; - lvl = LOG_NOTICE; - } else { - *t++ = 'L'; - lvl = LOG_INFO; - } - if (ipf->fl_loglevel != 0xffff) - lvl = ipf->fl_loglevel; - *t++ = ' '; - *t = '\0'; - - if (v == 6) { -#ifdef USE_INET6 - off = 0; - ipoff = 0; - hl = sizeof(ip6_t); - ip6 = (ip6_t *)ip; - p = (u_short)ip6->ip6_nxt; - s = (u_32_t *)&ip6->ip6_src; - d = (u_32_t *)&ip6->ip6_dst; - plen = hl + ntohs(ip6->ip6_plen); -#else - sprintf(t, "ipv6"); - goto printipflog; -#endif - } else if (v == 4) { - hl = (ip->ip_hl << 2); - ipoff = ip->ip_off; - off = ipoff & IP_OFFMASK; - p = (u_short)ip->ip_p; - s = (u_32_t *)&ip->ip_src; - d = (u_32_t *)&ip->ip_dst; - plen = ip->ip_len; - } else { - goto printipflog; - } - proto = getproto(p); - - if ((p == IPPROTO_TCP || p == IPPROTO_UDP) && !off) { - tp = (tcphdr_t *)((char *)ip + hl); - if (!(ipf->fl_flags & FF_SHORT)) { - (void) sprintf(t, "%s,%s -> ", hostname(res, v, s), - portname(res, proto, (u_int)tp->th_sport)); - t += strlen(t); - (void) sprintf(t, "%s,%s PR %s len %hu %hu", - hostname(res, v, d), - portname(res, proto, (u_int)tp->th_dport), - proto, hl, plen); - t += strlen(t); - - if (p == IPPROTO_TCP) { - *t++ = ' '; - *t++ = '-'; - for (i = 0; tcpfl[i].value; i++) - if (tp->th_flags & tcpfl[i].value) - *t++ = tcpfl[i].flag; - if (opts & OPT_VERBOSE) { - (void) sprintf(t, " %lu %lu %hu", - (u_long)(ntohl(tp->th_seq)), - (u_long)(ntohl(tp->th_ack)), - ntohs(tp->th_win)); - t += strlen(t); - } - } - *t = '\0'; - } else { - (void) sprintf(t, "%s -> ", hostname(res, v, s)); - t += strlen(t); - (void) sprintf(t, "%s PR %s len %hu %hu", - hostname(res, v, d), proto, hl, plen); - } - } else if ((p == IPPROTO_ICMPV6) && !off && (v == 6)) { - ic = (struct icmp *)((char *)ip + hl); - (void) sprintf(t, "%s -> ", hostname(res, v, s)); - t += strlen(t); - (void) sprintf(t, "%s PR icmpv6 len %hu %hu icmpv6 %s", - hostname(res, v, d), hl, plen, - icmpname6(ic->icmp_type, ic->icmp_code)); - } else if ((p == IPPROTO_ICMP) && !off && (v == 4)) { - ic = (struct icmp *)((char *)ip + hl); - (void) sprintf(t, "%s -> ", hostname(res, v, s)); - t += strlen(t); - (void) sprintf(t, "%s PR icmp len %hu %hu icmp %s", - hostname(res, v, d), hl, plen, - icmpname(ic->icmp_type, ic->icmp_code)); - if (ic->icmp_type == ICMP_UNREACH || - ic->icmp_type == ICMP_SOURCEQUENCH || - ic->icmp_type == ICMP_PARAMPROB || - ic->icmp_type == ICMP_REDIRECT || - ic->icmp_type == ICMP_TIMXCEED) { - ipc = &ic->icmp_ip; - i = ntohs(ipc->ip_len); - ipoff = ntohs(ipc->ip_off); - proto = getproto(ipc->ip_p); - - if (!(ipoff & IP_OFFMASK) && - ((ipc->ip_p == IPPROTO_TCP) || - (ipc->ip_p == IPPROTO_UDP))) { - tp = (tcphdr_t *)((char *)ipc + hl); - t += strlen(t); - (void) sprintf(t, " for %s,%s -", - HOSTNAME_V4(res, ipc->ip_src), - portname(res, proto, - (u_int)tp->th_sport)); - t += strlen(t); - (void) sprintf(t, " %s,%s PR %s len %hu %hu", - HOSTNAME_V4(res, ipc->ip_dst), - portname(res, proto, - (u_int)tp->th_dport), - proto, ipc->ip_hl << 2, i); - } else if (!(ipoff & IP_OFFMASK) && - (ipc->ip_p == IPPROTO_ICMP)) { - icmp = (icmphdr_t *)((char *)ipc + hl); - - t += strlen(t); - (void) sprintf(t, " for %s -", - HOSTNAME_V4(res, ipc->ip_src)); - t += strlen(t); - (void) sprintf(t, - " %s PR icmp len %hu %hu icmp %d/%d", - HOSTNAME_V4(res, ipc->ip_dst), - ipc->ip_hl << 2, i, - icmp->icmp_type, icmp->icmp_code); - - } else { - t += strlen(t); - (void) sprintf(t, " for %s -", - HOSTNAME_V4(res, ipc->ip_src)); - t += strlen(t); - (void) sprintf(t, " %s PR %s len %hu (%hu)", - HOSTNAME_V4(res, ipc->ip_dst), proto, - ipc->ip_hl << 2, i); - t += strlen(t); - if (ipoff & IP_OFFMASK) { - (void) sprintf(t, " (frag %d:%hu@%hu%s%s)", - ntohs(ipc->ip_id), - i - (ipc->ip_hl<<2), - (ipoff & IP_OFFMASK) << 3, - ipoff & IP_MF ? "+" : "", - ipoff & IP_DF ? "-" : ""); - } - } - } - } else { - (void) sprintf(t, "%s -> ", hostname(res, v, s)); - t += strlen(t); - (void) sprintf(t, "%s PR %s len %hu (%hu)", - hostname(res, v, d), proto, hl, plen); - t += strlen(t); - if (off & IP_OFFMASK) - (void) sprintf(t, " (frag %d:%hu@%hu%s%s)", - ntohs(ip->ip_id), - plen - hl, (off & IP_OFFMASK) << 3, - ipoff & IP_MF ? "+" : "", - ipoff & IP_DF ? "-" : ""); - } - t += strlen(t); - - if (ipf->fl_flags & FR_KEEPSTATE) { - (void) strcpy(t, " K-S"); - t += strlen(t); - } - - if (ipf->fl_flags & FR_KEEPFRAG) { - (void) strcpy(t, " K-F"); - t += strlen(t); - } - - if (ipf->fl_dir == 0) - strcpy(t, " IN"); - else if (ipf->fl_dir == 1) - strcpy(t, " OUT"); - t += strlen(t); -printipflog: - *t++ = '\n'; - *t++ = '\0'; - if (opts & OPT_SYSLOG) - syslog(lvl, "%s", line); - else - (void) fprintf(log, "%s", line); - if (opts & OPT_HEXHDR) - dumphex(log, (u_char *)buf, sizeof(iplog_t) + sizeof(*ipf)); - if (opts & OPT_HEXBODY) - dumphex(log, (u_char *)ip, ipf->fl_plen + ipf->fl_hlen); - else if ((opts & OPT_LOGBODY) && (ipf->fl_flags & FR_LOGBODY)) - dumphex(log, (u_char *)ip + ipf->fl_hlen, ipf->fl_plen); -} - - -static void usage(prog) -char *prog; -{ - fprintf(stderr, "%s: [-NFhstvxX] [-f ]\n", prog); - exit(1); -} - - -static void write_pid(file) -char *file; -{ - FILE *fp = NULL; - int fd; - - if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0644)) >= 0) - fp = fdopen(fd, "w"); - if (!fp) { - close(fd); - fprintf(stderr, "unable to open/create pid file: %s\n", file); - return; - } - fprintf(fp, "%d", getpid()); - fclose(fp); - close(fd); -} - - -static void flushlogs(file, log) -char *file; -FILE *log; -{ - int fd, flushed = 0; - - if ((fd = open(file, O_RDWR)) == -1) { - (void) fprintf(stderr, "%s: open: %s\n", - file, STRERROR(errno)); - exit(1); - } - - if (ioctl(fd, SIOCIPFFB, &flushed) == 0) { - printf("%d bytes flushed from log buffer\n", - flushed); - fflush(stdout); - } else - perror("SIOCIPFFB"); - (void) close(fd); - - if (flushed) { - if (opts & OPT_SYSLOG) - syslog(LOG_INFO, "%d bytes flushed from log\n", - flushed); - else if (log != stdout) - fprintf(log, "%d bytes flushed from log\n", flushed); - } -} - - -static void logopts(turnon, options) -int turnon; -char *options; -{ - int flags = 0; - char *s; - - for (s = options; *s; s++) - { - switch (*s) - { - case 'N' : - flags |= OPT_NAT; - break; - case 'S' : - flags |= OPT_STATE; - break; - case 'I' : - flags |= OPT_FILTER; - break; - default : - fprintf(stderr, "Unknown log option %c\n", *s); - exit(1); - } - } - - if (turnon) - opts |= flags; - else - opts &= ~(flags); -} - - -int main(argc, argv) -int argc; -char *argv[]; -{ - int fdt[3], devices = 0, make_daemon = 0; - char buf[IPLLOGSIZE], *iplfile[3], *s; - int fd[3], doread, n, i; - extern char *optarg; - extern int optind; - int regular[3], c; - FILE *log = stdout; - struct stat sb; - size_t nr, tr; - - fd[0] = fd[1] = fd[2] = -1; - fdt[0] = fdt[1] = fdt[2] = -1; - iplfile[0] = IPL_NAME; - iplfile[1] = IPNAT_NAME; - iplfile[2] = IPSTATE_NAME; - - while ((c = getopt(argc, argv, "?abDf:FhnN:o:O:pP:sS:tvxX")) != -1) - switch (c) - { - case 'a' : - opts |= OPT_LOGALL; - fdt[0] = IPL_LOGIPF; - fdt[1] = IPL_LOGNAT; - fdt[2] = IPL_LOGSTATE; - break; - case 'b' : - opts |= OPT_LOGBODY; - break; - case 'D' : - make_daemon = 1; - break; - case 'f' : case 'I' : - opts |= OPT_FILTER; - fdt[0] = IPL_LOGIPF; - iplfile[0] = optarg; - break; - case 'F' : - flushlogs(iplfile[0], log); - flushlogs(iplfile[1], log); - flushlogs(iplfile[2], log); - break; - case 'n' : - opts |= OPT_RESOLVE; - break; - case 'N' : - opts |= OPT_NAT; - fdt[1] = IPL_LOGNAT; - iplfile[1] = optarg; - break; - case 'o' : case 'O' : - logopts(c == 'o', optarg); - fdt[0] = fdt[1] = fdt[2] = -1; - if (opts & OPT_FILTER) - fdt[0] = IPL_LOGIPF; - if (opts & OPT_NAT) - fdt[1] = IPL_LOGNAT; - if (opts & OPT_STATE) - fdt[2] = IPL_LOGSTATE; - break; - case 'p' : - opts |= OPT_PORTNUM; - break; - case 'P' : - pidfile = optarg; - break; - case 's' : - s = strrchr(argv[0], '/'); - if (s == NULL) - s = argv[0]; - else - s++; - openlog(s, LOG_NDELAY|LOG_PID, LOGFAC); - opts |= OPT_SYSLOG; - log = NULL; - break; - case 'S' : - opts |= OPT_STATE; - fdt[2] = IPL_LOGSTATE; - iplfile[2] = optarg; - break; - case 't' : - opts |= OPT_TAIL; - break; - case 'v' : - opts |= OPT_VERBOSE; - break; - case 'x' : - opts |= OPT_HEXBODY; - break; - case 'X' : - opts |= OPT_HEXHDR; - break; - default : - case 'h' : - case '?' : - usage(argv[0]); - } - - init_tabs(); - - /* - * Default action is to only open the filter log file. - */ - if ((fdt[0] == -1) && (fdt[1] == -1) && (fdt[2] == -1)) - fdt[0] = IPL_LOGIPF; - - for (i = 0; i < 3; i++) { - if (fdt[i] == -1) - continue; - if (!strcmp(iplfile[i], "-")) - fd[i] = 0; - else { - if ((fd[i] = open(iplfile[i], O_RDONLY)) == -1) { - (void) fprintf(stderr, - "%s: open: %s\n", iplfile[i], - STRERROR(errno)); - exit(1); - /* NOTREACHED */ - } - if (fstat(fd[i], &sb) == -1) { - (void) fprintf(stderr, "%d: fstat: %s\n", - fd[i], STRERROR(errno)); - exit(1); - /* NOTREACHED */ - } - if (!(regular[i] = !S_ISCHR(sb.st_mode))) - devices++; - } - } - - if (!(opts & OPT_SYSLOG)) { - logfile = argv[optind]; - log = logfile ? fopen(logfile, "a") : stdout; - if (log == NULL) { - (void) fprintf(stderr, "%s: fopen: %s\n", - argv[optind], STRERROR(errno)); - exit(1); - /* NOTREACHED */ - } - setvbuf(log, NULL, _IONBF, 0); - } else - log = NULL; - - if (make_daemon && ((log != stdout) || (opts & OPT_SYSLOG))) { -#if BSD - daemon(0, !(opts & OPT_SYSLOG)); -#else - int pid; - if ((pid = fork()) > 0) - exit(0); - if (pid < 0) { - (void) fprintf(stderr, "%s: fork() failed: %s\n", - argv[0], STRERROR(errno)); - exit(1); - /* NOTREACHED */ - } - setsid(); - if ((opts & OPT_SYSLOG)) - close(2); -#endif /* !BSD */ - close(0); - close(1); - } - write_pid(pidfile); - - signal(SIGHUP, handlehup); - - for (doread = 1; doread; ) { - nr = 0; - - for (i = 0; i < 3; i++) { - tr = 0; - if (fdt[i] == -1) - continue; - if (!regular[i]) { - if (ioctl(fd[i], FIONREAD, &tr) == -1) { - if (opts & OPT_SYSLOG) - syslog(LOG_CRIT, - "ioctl(FIONREAD): %m"); - else - perror("ioctl(FIONREAD)"); - exit(1); - /* NOTREACHED */ - } - } else { - tr = (lseek(fd[i], 0, SEEK_CUR) < sb.st_size); - if (!tr && !(opts & OPT_TAIL)) - doread = 0; - } - if (!tr) - continue; - nr += tr; - - tr = read_log(fd[i], &n, buf, sizeof(buf)); - if (donehup) { - donehup = 0; - if (newlog) { - fclose(log); - log = newlog; - newlog = NULL; - } - } - - switch (tr) - { - case -1 : - if (opts & OPT_SYSLOG) - syslog(LOG_CRIT, "read: %m\n"); - else - perror("read"); - doread = 0; - break; - case 1 : - if (opts & OPT_SYSLOG) - syslog(LOG_CRIT, "aborting logging\n"); - else - fprintf(log, "aborting logging\n"); - doread = 0; - break; - case 2 : - break; - case 0 : - if (n > 0) { - print_log(fdt[i], log, buf, n); - if (!(opts & OPT_SYSLOG)) - fflush(log); - } - break; - } - } - if (!nr && ((opts & OPT_TAIL) || devices)) - sleep(1); - } - exit(0); - /* NOTREACHED */ -} diff --git a/contrib/ipfilter/ipnat.c b/contrib/ipfilter/ipnat.c deleted file mode 100644 index 69e7959260e7..000000000000 --- a/contrib/ipfilter/ipnat.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) -# include -# include -#endif -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include -#include -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "ipf.h" -#include "kmem.h" - -#if defined(sun) && !SOLARIS2 -# define STRERROR(x) sys_errlist[x] -extern char *sys_errlist[]; -#else -# define STRERROR(x) strerror(x) -#endif - -#if !defined(lint) -static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipnat.c,v 2.16.2.25 2003/06/05 14:00:28 darrenr Exp $"; -#endif - - -#if SOLARIS -#define bzero(a,b) memset(a,0,b) -#endif -int use_inet6 = 0; -char thishost[MAXHOSTNAMELEN]; - -extern char *optarg; -extern int optind; -#if 0 -extern ipnat_t *natparse __P((char *, int)); -#endif -extern void natparsefile __P((int, char *, int)); -extern void printnat __P((ipnat_t *, int)); -extern void printactivenat __P((nat_t *, int)); -extern void printhostmap __P((hostmap_t *, u_int)); -extern char *getsumd __P((u_32_t)); - -static int dostats __P((natstat_t *, int)); -static int flushtable __P((int, int)); -void usage __P((char *)); -int countbits __P((u_32_t)); -char *getnattype __P((ipnat_t *)); -int main __P((int, char*[])); -void printaps __P((ap_session_t *, int)); -static int showhostmap __P((natstat_t *nsp)); -static int natstat_dead __P((natstat_t *, char *)); - - -void usage(name) -char *name; -{ - fprintf(stderr, "Usage: %s [-CFhlnrsv] [-f filename]\n", name); - exit(1); -} - - -int main(argc, argv) -int argc; -char *argv[]; -{ - natstat_t ns, *nsp = &ns; - char *file, *core, *kernel; - int fd, opts, c, mode; - - fd = -1; - opts = 0; - file = NULL; - core = NULL; - kernel = NULL; - mode = O_RDWR; - - while ((c = getopt(argc, argv, "CdFf:hlM:N:nrsv")) != -1) - switch (c) - { - case 'C' : - opts |= OPT_CLEAR; - break; - case 'd' : - opts |= OPT_DEBUG; - break; - case 'f' : - file = optarg; - break; - case 'F' : - opts |= OPT_FLUSH; - break; - case 'h' : - opts |=OPT_HITS; - break; - case 'l' : - opts |= OPT_LIST; - mode = O_RDONLY; - break; - case 'M' : - core = optarg; - break; - case 'N' : - kernel = optarg; - break; - case 'n' : - opts |= OPT_NODO; - mode = O_RDONLY; - break; - case 'r' : - opts |= OPT_REMOVE; - break; - case 's' : - opts |= OPT_STAT; - mode = O_RDONLY; - break; - case 'v' : - opts |= OPT_VERBOSE; - break; - case '?' : - default : - usage(argv[0]); - } - - if (optind < 2) - usage(argv[0]); - - if ((kernel != NULL) || (core != NULL)) { - (void) setgid(getgid()); - (void) setuid(getuid()); - } - - bzero((char *)&ns, sizeof(ns)); - - gethostname(thishost, sizeof(thishost)); - thishost[sizeof(thishost) - 1] = '\0'; - - if (!(opts & OPT_NODO) && (kernel == NULL) && (core == NULL)) { - if (openkmem(kernel, core) == -1) - exit(1); - - if (((fd = open(IPL_NAT, mode)) == -1) && - ((fd = open(IPL_NAT, O_RDONLY)) == -1)) { - (void) fprintf(stderr, "%s: open: %s\n", IPL_NAT, - STRERROR(errno)); - if (errno == ENODEV) - fprintf(stderr, "IPFilter enabled?\n"); - exit(1); - } - if (ioctl(fd, SIOCGNATS, &nsp) == -1) { - perror("ioctl(SIOCGNATS)"); - exit(1); - } - (void) setgid(getgid()); - (void) setuid(getuid()); - } else if ((kernel != NULL) || (core != NULL)) { - if (openkmem(kernel, core) == -1) - exit(1); - - if (natstat_dead(nsp, kernel)) - exit(1); - if (opts & (OPT_LIST|OPT_STAT)) { - if (dostats(nsp, opts)) - exit(1); - } - exit(0); - } - - if (opts & (OPT_FLUSH|OPT_CLEAR)) - if (flushtable(fd, opts)) - exit(1); - if (file) { - /* NB natparsefile exits with nonzero in case of error */ - natparsefile(fd, file, opts); - } - if (opts & (OPT_LIST|OPT_STAT)) - if (dostats(nsp, opts)) - exit(1); - - /* TBD why not exit(0)? */ - return 0; -} - - -/* - * Read NAT statistic information in using a symbol table and memory file - * rather than doing ioctl's. - */ -static int natstat_dead(nsp, kernel) -natstat_t *nsp; -char *kernel; -{ - struct nlist nat_nlist[10] = { - { "nat_table" }, /* 0 */ - { "nat_list" }, - { "maptable" }, - { "ipf_nattable_sz" }, - { "ipf_natrules_sz" }, - { "ipf_rdrrules_sz" }, /* 5 */ - { "ipf_hostmap_sz" }, - { "nat_instances" }, - { "ap_sess_list" }, - { NULL } - }; - void *tables[2]; - - if (nlist(kernel, nat_nlist) == -1) { - fprintf(stderr, "nlist error\n"); - return -1; - } - - /* - * Normally the ioctl copies all of these values into the structure - * for us, before returning it to userland, so here we must copy each - * one in individually. - */ - kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); - nsp->ns_table[0] = tables[0]; - nsp->ns_table[1] = tables[1]; - - kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, - sizeof(nsp->ns_list)); - kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value, - sizeof(nsp->ns_maptable)); - kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value, - sizeof(nsp->ns_nattab_sz)); - kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value, - sizeof(nsp->ns_rultab_sz)); - kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value, - sizeof(nsp->ns_rdrtab_sz)); - kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value, - sizeof(nsp->ns_hostmap_sz)); - kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, - sizeof(nsp->ns_instances)); - kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value, - sizeof(nsp->ns_apslist)); - - return 0; -} - - -/* - * Display NAT statistics. - */ -static int dostats(nsp, opts) -natstat_t *nsp; -int opts; -{ - nat_t **nt[2], *np, nat; - ipnat_t ipn; - int rc = 0; - - /* - * Show statistics ? - */ - if (opts & OPT_STAT) { - printf("mapped\tin\t%lu\tout\t%lu\n", - nsp->ns_mapped[0], nsp->ns_mapped[1]); - printf("added\t%lu\texpired\t%lu\n", - nsp->ns_added, nsp->ns_expire); - printf("no memory\t%lu\tbad nat\t%lu\n", - nsp->ns_memfail, nsp->ns_badnat); - printf("inuse\t%lu\nrules\t%lu\n", - nsp->ns_inuse, nsp->ns_rules); - printf("wilds\t%u\n", nsp->ns_wilds); - if (opts & OPT_VERBOSE) - printf("table %p list %p\n", - nsp->ns_table, nsp->ns_list); - } - - /* - * Show list of NAT rules and NAT sessions ? - */ - if (opts & OPT_LIST) { - printf("List of active MAP/Redirect filters:\n"); - while (nsp->ns_list) { - if (kmemcpy((char *)&ipn, (long)nsp->ns_list, - sizeof(ipn))) { - perror("kmemcpy"); - rc = -1; - break; - } - if (opts & OPT_HITS) - printf("%d ", ipn.in_hits); - printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); - nsp->ns_list = ipn.in_next; - } - - nt[0] = (nat_t **)malloc(sizeof(*nt) * NAT_SIZE); - if (kmemcpy((char *)nt[0], (long)nsp->ns_table[0], - sizeof(**nt) * NAT_SIZE)) { - perror("kmemcpy"); - rc = -1; - } - if (rc) { - free(nt[0]); - return rc; - } - - printf("\nList of active sessions:\n"); - - for (np = nsp->ns_instances; np; np = nat.nat_next) { - if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) { - /* TBD Is this an error? If so, return -1 */ - break; - } - printactivenat(&nat, opts); - } - - if (opts & OPT_VERBOSE) { - if (showhostmap(nsp)) { - free(nt[0]); - return -1; - } - } - - free(nt[0]); - } - return 0; -} - - -/* - * Display the active host mapping table. - */ -static int showhostmap(nsp) -natstat_t *nsp; -{ - hostmap_t hm, *hmp, **maptable; - u_int hv; - - printf("\nList of active host mappings:\n"); - - maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) * - nsp->ns_hostmap_sz); - if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable, - sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) { - perror("kmemcpy (maptable)"); - free(maptable); - return -1; - } - - for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) { - hmp = maptable[hv]; - - while (hmp) { - if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) { - perror("kmemcpy (hostmap)"); - free(maptable); - return -1; - } - - printhostmap(&hm, hv); - hmp = hm.hm_next; - } - } - free(maptable); - return 0; -} - - -/* - * Issue an ioctl to flush either the NAT rules table or the active mapping - * table or both. - */ -static int flushtable(fd, opts) -int fd, opts; -{ - int n = 0; - int rc = 0; - - if (opts & OPT_FLUSH) { - n = 0; - if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1) { - perror("ioctl(SIOCFLNAT)"); - rc = -1; - } else { - printf("%d entries flushed from NAT table\n", n); - } - } - - if (opts & OPT_CLEAR) { - n = 1; - if (!(opts & OPT_NODO) && ioctl(fd, SIOCIPFFL, &n) == -1) { - perror("ioctl(SIOCCNATL)"); - rc = -1; - } else { - printf("%d entries flushed from NAT list\n", n); - } - } - - return rc; -} diff --git a/contrib/ipfilter/ipsd/ip_compat.h b/contrib/ipfilter/ipsd/ip_compat.h deleted file mode 100644 index a911fd83c3f3..000000000000 --- a/contrib/ipfilter/ipsd/ip_compat.h +++ /dev/null @@ -1,201 +0,0 @@ -/* - * (C)opyright 1995 by Darren Reed. - * - * This code may be freely distributed as long as it retains this notice - * and is not changed in any way. The author accepts no responsibility - * for the use of this software. I hate legaleese, don't you ? - * - * @(#)ip_compat.h 1.1 9/14/95 - */ - -/* - * These #ifdef's are here mainly for linux, but who knows, they may - * not be in other places or maybe one day linux will grow up and some - * of these will turn up there too. - */ -#ifndef ICMP_UNREACH -# define ICMP_UNREACH ICMP_DEST_UNREACH -#endif -#ifndef ICMP_SOURCEQUENCH -# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH -#endif -#ifndef ICMP_TIMXCEED -# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED -#endif -#ifndef ICMP_PARAMPROB -# define ICMP_PARAMPROB ICMP_PARAMETERPROB -#endif -#ifndef IPVERSION -# define IPVERSION 4 -#endif -#ifndef IPOPT_MINOFF -# define IPOPT_MINOFF 4 -#endif -#ifndef IPOPT_COPIED -# define IPOPT_COPIED(x) ((x)&0x80) -#endif -#ifndef IPOPT_EOL -# define IPOPT_EOL 0 -#endif -#ifndef IPOPT_NOP -# define IPOPT_NOP 1 -#endif -#ifndef IP_MF -# define IP_MF ((u_short)0x2000) -#endif -#ifndef ETHERTYPE_IP -# define ETHERTYPE_IP ((u_short)0x0800) -#endif -#ifndef TH_FIN -# define TH_FIN 0x01 -#endif -#ifndef TH_SYN -# define TH_SYN 0x02 -#endif -#ifndef TH_RST -# define TH_RST 0x04 -#endif -#ifndef TH_PUSH -# define TH_PUSH 0x08 -#endif -#ifndef TH_ACK -# define TH_ACK 0x10 -#endif -#ifndef TH_URG -# define TH_URG 0x20 -#endif -#ifndef IPOPT_EOL -# define IPOPT_EOL 0 -#endif -#ifndef IPOPT_NOP -# define IPOPT_NOP 1 -#endif -#ifndef IPOPT_RR -# define IPOPT_RR 7 -#endif -#ifndef IPOPT_TS -# define IPOPT_TS 68 -#endif -#ifndef IPOPT_SECURITY -# define IPOPT_SECURITY 130 -#endif -#ifndef IPOPT_LSRR -# define IPOPT_LSRR 131 -#endif -#ifndef IPOPT_SATID -# define IPOPT_SATID 136 -#endif -#ifndef IPOPT_SSRR -# define IPOPT_SSRR 137 -#endif -#ifndef IPOPT_SECUR_UNCLASS -# define IPOPT_SECUR_UNCLASS ((u_short)0x0000) -#endif -#ifndef IPOPT_SECUR_CONFID -# define IPOPT_SECUR_CONFID ((u_short)0xf135) -#endif -#ifndef IPOPT_SECUR_EFTO -# define IPOPT_SECUR_EFTO ((u_short)0x789a) -#endif -#ifndef IPOPT_SECUR_MMMM -# define IPOPT_SECUR_MMMM ((u_short)0xbc4d) -#endif -#ifndef IPOPT_SECUR_RESTR -# define IPOPT_SECUR_RESTR ((u_short)0xaf13) -#endif -#ifndef IPOPT_SECUR_SECRET -# define IPOPT_SECUR_SECRET ((u_short)0xd788) -#endif -#ifndef IPOPT_SECUR_TOPSECRET -# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5) -#endif - -#ifdef linux -# define icmp icmphdr -# define icmp_type type -# define icmp_code code - -/* - * From /usr/include/netinet/ip_var.h - * !%@#!$@# linux... - */ -struct ipovly { - caddr_t ih_next, ih_prev; /* for protocol sequence q's */ - u_char ih_x1; /* (unused) */ - u_char ih_pr; /* protocol */ - short ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -}; - -typedef struct { - __u16 th_sport; - __u16 th_dport; - __u32 th_seq; - __u32 th_ack; -# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\ - defined(vax) - __u8 th_res:4; - __u8 th_off:4; -#else - __u8 th_off:4; - __u8 th_res:4; -#endif - __u8 th_flags; - __u16 th_win; - __u16 th_sum; - __u16 th_urp; -} tcphdr_t; - -typedef struct { - __u16 uh_sport; - __u16 uh_dport; - __s16 uh_ulen; - __u16 uh_sum; -} udphdr_t; - -typedef struct { -# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\ - defined(vax) - __u8 ip_hl:4; - __u8 ip_v:4; -# else - __u8 ip_hl:4; - __u8 ip_v:4; -# endif - __u8 ip_tos; - __u16 ip_len; - __u16 ip_id; - __u16 ip_off; - __u8 ip_ttl; - __u8 ip_p; - __u16 ip_sum; - struct in_addr ip_src; - struct in_addr ip_dst; -} ip_t; - -typedef struct { - __u8 ether_dhost[6]; - __u8 ether_shost[6]; - __u16 ether_type; -} ether_header_t; - -# define bcopy(a,b,c) memmove(b,a,c) -# define bcmp(a,b,c) memcmp(a,b,c) - -# define ifnet device - -#else - -typedef struct udphdr udphdr_t; -typedef struct tcphdr tcphdr_t; -typedef struct ip ip_t; -typedef struct ether_header ether_header_t; - -#endif - -#ifdef solaris -# define bcopy(a,b,c) memmove(b,a,c) -# define bcmp(a,b,c) memcmp(a,b,c) -# define bzero(a,b) memset(a,0,b) -#endif diff --git a/contrib/ipfilter/ipsd/ipsd.sed b/contrib/ipfilter/ipsd/ipsd.sed deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/ipfilter/ipsend/.cvsignore b/contrib/ipfilter/ipsend/.cvsignore deleted file mode 100644 index b7aea24eb881..000000000000 --- a/contrib/ipfilter/ipsend/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -ipsend -ipresend -iptest diff --git a/contrib/ipfilter/ipsend/ip_compat.h b/contrib/ipfilter/ipsend/ip_compat.h deleted file mode 100644 index c38fa59ed3c7..000000000000 --- a/contrib/ipfilter/ipsend/ip_compat.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * (C)opyright 1995 by Darren Reed. - * - * This code may be freely distributed as long as it retains this notice - * and is not changed in any way. The author accepts no responsibility - * for the use of this software. I hate legaleese, don't you ? - * - * @(#)ip_compat.h 1.2 12/7/95 - */ - -/* - * These #ifdef's are here mainly for linux, but who knows, they may - * not be in other places or maybe one day linux will grow up and some - * of these will turn up there too. - */ -#ifndef ICMP_UNREACH -# define ICMP_UNREACH ICMP_DEST_UNREACH -#endif -#ifndef ICMP_SOURCEQUENCH -# define ICMP_SOURCEQUENCH ICMP_SOURCE_QUENCH -#endif -#ifndef ICMP_TIMXCEED -# define ICMP_TIMXCEED ICMP_TIME_EXCEEDED -#endif -#ifndef ICMP_PARAMPROB -# define ICMP_PARAMPROB ICMP_PARAMETERPROB -#endif -#ifndef IPVERSION -# define IPVERSION 4 -#endif -#ifndef IPOPT_MINOFF -# define IPOPT_MINOFF 4 -#endif -#ifndef IPOPT_COPIED -# define IPOPT_COPIED(x) ((x)&0x80) -#endif -#ifndef IPOPT_EOL -# define IPOPT_EOL 0 -#endif -#ifndef IPOPT_NOP -# define IPOPT_NOP 1 -#endif -#ifndef IP_MF -# define IP_MF ((u_short)0x2000) -#endif -#ifndef ETHERTYPE_IP -# define ETHERTYPE_IP ((u_short)0x0800) -#endif -#ifndef TH_FIN -# define TH_FIN 0x01 -#endif -#ifndef TH_SYN -# define TH_SYN 0x02 -#endif -#ifndef TH_RST -# define TH_RST 0x04 -#endif -#ifndef TH_PUSH -# define TH_PUSH 0x08 -#endif -#ifndef TH_ACK -# define TH_ACK 0x10 -#endif -#ifndef TH_URG -# define TH_URG 0x20 -#endif -#ifndef IPOPT_EOL -# define IPOPT_EOL 0 -#endif -#ifndef IPOPT_NOP -# define IPOPT_NOP 1 -#endif -#ifndef IPOPT_RR -# define IPOPT_RR 7 -#endif -#ifndef IPOPT_TS -# define IPOPT_TS 68 -#endif -#ifndef IPOPT_SECURITY -# define IPOPT_SECURITY 130 -#endif -#ifndef IPOPT_LSRR -# define IPOPT_LSRR 131 -#endif -#ifndef IPOPT_SATID -# define IPOPT_SATID 136 -#endif -#ifndef IPOPT_SSRR -# define IPOPT_SSRR 137 -#endif -#ifndef IPOPT_SECUR_UNCLASS -# define IPOPT_SECUR_UNCLASS ((u_short)0x0000) -#endif -#ifndef IPOPT_SECUR_CONFID -# define IPOPT_SECUR_CONFID ((u_short)0xf135) -#endif -#ifndef IPOPT_SECUR_EFTO -# define IPOPT_SECUR_EFTO ((u_short)0x789a) -#endif -#ifndef IPOPT_SECUR_MMMM -# define IPOPT_SECUR_MMMM ((u_short)0xbc4d) -#endif -#ifndef IPOPT_SECUR_RESTR -# define IPOPT_SECUR_RESTR ((u_short)0xaf13) -#endif -#ifndef IPOPT_SECUR_SECRET -# define IPOPT_SECUR_SECRET ((u_short)0xd788) -#endif -#ifndef IPOPT_SECUR_TOPSECRET -# define IPOPT_SECUR_TOPSECRET ((u_short)0x6bc5) -#endif - -#ifdef linux -# if LINUX < 0200 -# define icmp icmphdr -# define icmp_type type -# define icmp_code code -# endif - -/* - * From /usr/include/netinet/ip_var.h - * !%@#!$@# linux... - */ -struct ipovly { - caddr_t ih_next, ih_prev; /* for protocol sequence q's */ - u_char ih_x1; /* (unused) */ - u_char ih_pr; /* protocol */ - short ih_len; /* protocol length */ - struct in_addr ih_src; /* source internet address */ - struct in_addr ih_dst; /* destination internet address */ -}; - -typedef struct { - __u16 th_sport; - __u16 th_dport; - __u32 th_seq; - __u32 th_ack; -# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\ - defined(vax) - __u8 th_res:4; - __u8 th_off:4; -#else - __u8 th_off:4; - __u8 th_res:4; -#endif - __u8 th_flags; - __u16 th_win; - __u16 th_sum; - __u16 th_urp; -} tcphdr_t; - -typedef struct { - __u16 uh_sport; - __u16 uh_dport; - __s16 uh_ulen; - __u16 uh_sum; -} udphdr_t; - -typedef struct { -# if defined(__i386__) || defined(__MIPSEL__) || defined(__alpha__) ||\ - defined(vax) - __u8 ip_hl:4; - __u8 ip_v:4; -# else - __u8 ip_hl:4; - __u8 ip_v:4; -# endif - __u8 ip_tos; - __u16 ip_len; - __u16 ip_id; - __u16 ip_off; - __u8 ip_ttl; - __u8 ip_p; - __u16 ip_sum; - struct in_addr ip_src; - struct in_addr ip_dst; -} ip_t; - -typedef struct { - __u8 ether_dhost[6]; - __u8 ether_shost[6]; - __u16 ether_type; -} ether_header_t; - -typedef struct icmp { - u_char icmp_type; /* type of message, see below */ - u_char icmp_code; /* type sub code */ - u_short icmp_cksum; /* ones complement cksum of struct */ - union { - u_char ih_pptr; /* ICMP_PARAMPROB */ - struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ - struct ih_idseq { - n_short icd_id; - n_short icd_seq; - } ih_idseq; - int ih_void; - } icmp_hun; -#define icmp_pptr icmp_hun.ih_pptr -#define icmp_gwaddr icmp_hun.ih_gwaddr -#define icmp_id icmp_hun.ih_idseq.icd_id -#define icmp_seq icmp_hun.ih_idseq.icd_seq -#define icmp_void icmp_hun.ih_void - union { - struct id_ts { - n_time its_otime; - n_time its_rtime; - n_time its_ttime; - } id_ts; - struct id_ip { - ip_t idi_ip; - /* options and then 64 bits of data */ - } id_ip; - u_long id_mask; - char id_data[1]; - } icmp_dun; -#define icmp_otime icmp_dun.id_ts.its_otime -#define icmp_rtime icmp_dun.id_ts.its_rtime -#define icmp_ttime icmp_dun.id_ts.its_ttime -#define icmp_ip icmp_dun.id_ip.idi_ip -#define icmp_mask icmp_dun.id_mask -#define icmp_data icmp_dun.id_data -} icmphdr_t; - -# define bcopy(a,b,c) memmove(b,a,c) -# define bcmp(a,b,c) memcmp(a,b,c) - -# define ifnet device - -#else - -typedef struct udphdr udphdr_t; -typedef struct tcphdr tcphdr_t; -typedef struct ip ip_t; -typedef struct ether_header ether_header_t; - -#endif - -#if defined(__SVR4) || defined(__svr4__) -# define bcopy(a,b,c) memmove(b,a,c) -# define bcmp(a,b,c) memcmp(a,b,c) -# define bzero(a,b) memset(a,0,b) -#endif diff --git a/contrib/ipfilter/ipsend/ipsend.sed b/contrib/ipfilter/ipsend/ipsend.sed deleted file mode 100644 index 774c0e24e3df..000000000000 --- a/contrib/ipfilter/ipsend/ipsend.sed +++ /dev/null @@ -1,3 +0,0 @@ -0Æ . Ä,..+ CVS0Í -.cvsignore0Î44arp.c0Ï Crashable0ÐMakefile0Ñarp.c0Ò -dlcommon.c0Ódltest.h0Ôin_var.h0Õip.c0Ö ip_compat.h0×ip_var.h0Ø diff --git a/contrib/ipfilter/ipsend/ultrix.c b/contrib/ipfilter/ipsend/ultrix.c deleted file mode 100644 index f41a8a9a7481..000000000000 --- a/contrib/ipfilter/ipsend/ultrix.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * (C)opyright 1998 Darren Reed. (from tcplog) - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -static struct dli_devid dli_devid; - - -int initdevice(device, sport, tout) -char *device; -int sport, tout; -{ - u_char *s; - int fd; - - fd = socket(AF_DLI, SOCK_DGRAM, 0); - if (fd == -1) - perror("socket(AF_DLI,SOCK_DGRAM)"); - else { - strncpy(dli_devid.dli_devname, device, DLI_DEVSIZE); - dli_devid.dli_devname[DLI_DEVSIZE] ='\0'; - for (s = dli_devid.dli_devname; *s && isalpha((char)*s); s++) - ; - if (*s && isdigit((char)*s)) { - dli_devid.dli_devnumber = atoi(s); - } - } - return fd; -} - - -/* - * output an IP packet onto a fd opened for /dev/bpf - */ -int sendip(fd, pkt, len) -int fd, len; -char *pkt; -{ - struct sockaddr_dl dl; - struct sockaddr_edl *edl = &dl.choose_addr.dli_eaddr; - - dl.dli_family = AF_DLI; - dl.dli_substructype = DLI_ETHERNET; - bcopy((char *)&dli_devid, (char *)&dl.dli_device, sizeof(dli_devid)); - bcopy(pkt, edl->dli_target, DLI_EADDRSIZE); - bcopy(pkt, edl->dli_dest, DLI_EADDRSIZE); - bcopy(pkt + DLI_EADDRSIZE * 2, (char *)&edl->dli_protype, 2); - edl->dli_ioctlflg = 0; - - if (sendto(fd, pkt, len, 0, (struct sockaddr *)&dl, sizeof(dl)) == -1) - { - perror("send"); - return -1; - } - - return len; -} - - -char *strdup(str) -char *str; -{ - char *s; - - if ((s = (char *)malloc(strlen(str) + 1))) - return strcpy(s, str); - return NULL; -} diff --git a/contrib/ipfilter/ipt.c b/contrib/ipfilter/ipt.c deleted file mode 100644 index 5a20f240aa9d..000000000000 --- a/contrib/ipfilter/ipt.c +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#ifdef __FreeBSD__ -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -#endif -#if defined(__sgi) && (IRIX > 602) -# define _KMEMUSER -# include -#endif -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) && !defined(__sgi) -#include -#else -#if !defined(__sgi) -#include -#endif -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include -#include "ip_fil.h" -#include "ip_nat.h" -#include "ip_state.h" -#include "ip_frag.h" -#include "ipf.h" -#include "ipt.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)ipt.c 1.19 6/3/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ipt.c,v 2.6.2.26 2003/11/09 17:22:21 darrenr Exp $"; -#endif - -extern char *optarg; -extern struct frentry *ipfilter[2][2]; -extern struct ipread snoop, etherf, tcpd, pcap, iptext, iphex; -extern struct ifnet *get_unit __P((char *, int)); -extern void init_ifp __P((void)); -extern ipnat_t *natparse __P((char *, int, int *)); -extern int fr_running; - -int opts = 0; -int rremove = 0; -int use_inet6 = 0; -int main __P((int, char *[])); -int loadrules __P((char *)); -int kmemcpy __P((char *, long, int)); -void dumpnat __P((void)); -void dumpstate __P((void)); -char *getifname __P((void *)); -void drain_log __P((char *)); - -int main(argc,argv) -int argc; -char *argv[]; -{ - char *datain, *iface, *ifname, *packet, *logout; - int fd, i, dir, c, loaded, dump, hlen; - struct in_addr src; - struct ifnet *ifp; - struct ipread *r; - u_long buf[2048]; - ip_t *ip; - - dir = 0; - dump = 0; - loaded = 0; - r = &iptext; - iface = NULL; - logout = NULL; - src.s_addr = 0; - ifname = "anon0"; - datain = NULL; - - nat_init(); - fr_stateinit(); - initparse(); - ipflog_init(); - fr_running = 1; - - while ((c = getopt(argc, argv, "6bdDEHi:I:l:NoPr:Rs:STvxX")) != -1) - switch (c) - { - case '6' : -#ifdef USE_INET6 - use_inet6 = 1; - break; -#else - fprintf(stderr, "IPv6 not supported\n"); - exit(1); -#endif - case 'b' : - opts |= OPT_BRIEF; - break; - case 'd' : - opts |= OPT_DEBUG; - break; - case 'D' : - dump = 1; - break; - case 'i' : - datain = optarg; - break; - case 'I' : - ifname = optarg; - break; - case 'l' : - logout = optarg; - break; - case 'o' : - opts |= OPT_SAVEOUT; - break; - case 'r' : - if (loadrules(optarg) == -1) - return -1; - loaded = 1; - break; - case 's' : - src.s_addr = inet_addr(optarg); - break; - case 'v' : - opts |= OPT_VERBOSE; - break; - case 'E' : - r = ðerf; - break; - case 'H' : - r = &iphex; - break; - case 'N' : - opts |= OPT_NAT; - break; - case 'P' : - r = &pcap; - break; - case 'R' : - rremove = 1; - break; - case 'S' : - r = &snoop; - break; - case 'T' : - r = &tcpd; - break; - case 'x' : - opts |= OPT_HEX; - break; - case 'X' : - r = &iptext; - break; - } - - if (loaded == 0) { - (void)fprintf(stderr,"no rules loaded\n"); - exit(-1); - } - - if (opts & OPT_SAVEOUT) - init_ifp(); - - if (datain) - fd = (*r->r_open)(datain); - else - fd = (*r->r_open)("-"); - - if (fd < 0) - exit(-1); - - ip = (ip_t *)buf; - while ((i = (*r->r_readip)((char *)buf, sizeof(buf), - &iface, &dir)) > 0) { - if (iface == NULL || *iface == '\0') - iface = ifname; - ifp = get_unit(iface, ip->ip_v); - hlen = 0; - if (!use_inet6) { - ip->ip_off = ntohs(ip->ip_off); - ip->ip_len = ntohs(ip->ip_len); - hlen = ip->ip_hl << 2; - if (src.s_addr != 0) { - if (src.s_addr == ip->ip_src.s_addr) - dir = 1; - else if (src.s_addr == ip->ip_dst.s_addr) - dir = 0; - } - } -#ifdef USE_INET6 - else - hlen = sizeof(ip6_t); -#endif - if (opts & OPT_VERBOSE) { - printf("%s on [%s]: ", dir ? "out" : "in", - (iface && *iface) ? iface : "??"); - } - packet = (char *)buf; - /* ipfr_slowtimer(); */ - i = fr_check(ip, hlen, ifp, dir, (mb_t **)&packet); - if ((opts & OPT_NAT) == 0) - switch (i) - { - case -5 : - (void)printf("block return-icmp-as-dest"); - break; - case -4 : - (void)printf("block return-icmp"); - break; - case -3 : - (void)printf("block return-rst"); - break; - case -2 : - (void)printf("auth"); - break; - case -1 : - (void)printf("block"); - break; - case 0 : - (void)printf("pass"); - break; - case 1 : - (void)printf("nomatch"); - break; - } - if (!use_inet6) { - ip->ip_off = htons(ip->ip_off); - ip->ip_len = htons(ip->ip_len); - } - - if (!(opts & OPT_BRIEF)) { - putchar(' '); - printpacket((ip_t *)buf); - printf("--------------"); - } else if ((opts & (OPT_BRIEF|OPT_NAT)) == (OPT_NAT|OPT_BRIEF)) - printpacket((ip_t *)buf); -#ifndef linux - if (dir && (ifp != NULL) && ip->ip_v && (packet != NULL)) -# if defined(__sgi) && (IRIX < 605) - (*ifp->if_output)(ifp, (void *)packet, NULL); -# else - (*ifp->if_output)(ifp, (void *)packet, NULL, 0); -# endif -#endif - if ((opts & (OPT_BRIEF|OPT_NAT)) != (OPT_NAT|OPT_BRIEF)) - putchar('\n'); - dir = 0; - if (iface != ifname) { - free(iface); - iface = ifname; - } - } - (*r->r_close)(); - - if (logout != NULL) { - drain_log(logout); - } - - if (dump == 1) { - dumpnat(); - dumpstate(); - } - - return 0; -} - - -/* - * Load in either NAT or ipf rules from a file, which is treated as stdin - * if the name is "-". NOTE, stdin can only be used once as the file is - * closed after use. - */ -int loadrules(file) -char *file; -{ - char line[513], *s; - int linenum, i; - void *fr; - FILE *fp; - int parsestatus; - - if (!strcmp(file, "-")) - fp = stdin; - else if (!(fp = fopen(file, "r"))) { - (void)fprintf(stderr, "couldn't open %s\n", file); - return (-1); - } - - if (!(opts & OPT_BRIEF)) - (void)printf("opening rule file \"%s\"\n", file); - - linenum = 0; - - while (fgets(line, sizeof(line) - 1, fp)) { - linenum++; - - /* - * treat both CR and LF as EOL - */ - if ((s = index(line, '\n'))) - *s = '\0'; - if ((s = index(line, '\r'))) - *s = '\0'; - - /* - * # is comment marker, everything after is a ignored - */ - if ((s = index(line, '#'))) - *s = '\0'; - - if (!*line) - continue; - - /* fake an `ioctl' call :) */ - - if ((opts & OPT_NAT) != 0) { - parsestatus = 1; - fr = natparse(line, linenum, &parsestatus); - if (parsestatus != 0) { - if (*line) { - fprintf(stderr, - "%d: syntax error in \"%s\"\n", - linenum, line); - } - fprintf(stderr, "%s: %s error (%d), quitting\n", - file, - ((parsestatus < 0)? "parse": "internal"), - parsestatus); - exit(1); - } - if (!fr) - continue; - - if (rremove == 0) { - i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCADNAT, - (caddr_t)&fr, - FWRITE|FREAD); - if (opts & OPT_DEBUG) - fprintf(stderr, - "iplioctl(ADNAT,%p,1) = %d\n", - fr, i); - } else { - i = IPL_EXTERN(ioctl)(IPL_LOGNAT, SIOCRMNAT, - (caddr_t)&fr, - FWRITE|FREAD); - if (opts & OPT_DEBUG) - fprintf(stderr, - "iplioctl(RMNAT,%p,1) = %d\n", - fr, i); - } - } else { - fr = parse(line, linenum, &parsestatus); - - if (parsestatus != 0) { - fprintf(stderr, "%s: %s error (%d), quitting\n", - file, - ((parsestatus < 0)? "parse": "internal"), - parsestatus); - exit(1); - } - - if (!fr) { - continue; - } - - if (rremove == 0) { - i = IPL_EXTERN(ioctl)(0, SIOCADAFR, - (caddr_t)&fr, - FWRITE|FREAD); - if (opts & OPT_DEBUG) - fprintf(stderr, - "iplioctl(ADAFR,%p,1) = %d\n", - fr, i); - } else { - i = IPL_EXTERN(ioctl)(0, SIOCRMAFR, - (caddr_t)&fr, - FWRITE|FREAD); - if (opts & OPT_DEBUG) - fprintf(stderr, - "iplioctl(RMAFR,%p,1) = %d\n", - fr, i); - } - } - } - (void)fclose(fp); - - return 0; -} - - -int kmemcpy(addr, offset, size) -char *addr; -long offset; -int size; -{ - bcopy((char *)offset, addr, size); - return 0; -} - - -/* - * Display the built up NAT table rules and mapping entries. - */ -void dumpnat() -{ - ipnat_t *ipn; - nat_t *nat; - - printf("List of active MAP/Redirect filters:\n"); - for (ipn = nat_list; ipn != NULL; ipn = ipn->in_next) - printnat(ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); - printf("\nList of active sessions:\n"); - for (nat = nat_instances; nat; nat = nat->nat_next) - printactivenat(nat, opts); -} - - -/* - * Display the built up state table rules and mapping entries. - */ -void dumpstate() -{ - ipstate_t *ips; - - printf("List of active state sessions:\n"); - for (ips = ips_list; ips != NULL; ) - ips = printstate(ips, opts & (OPT_DEBUG|OPT_VERBOSE)); -} - - -/* - * Given a pointer to an interface in the kernel, return a pointer to a - * string which is the interface name. - */ -char *getifname(ptr) -void *ptr; -{ -#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ - defined(__OpenBSD__) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) -#else - char buf[32], *s; - int len; -#endif - struct ifnet netif; - - if (ptr == (void *)-1) - return "!"; - if (ptr == NULL) - return "-"; - - if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1) - return "X"; -#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ - defined(__OpenBSD__) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) - return strdup(netif.if_xname); -#else - if (kmemcpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1) - return "X"; - if (netif.if_unit < 10) - len = 2; - else if (netif.if_unit < 1000) - len = 3; - else if (netif.if_unit < 10000) - len = 4; - else - len = 5; - buf[sizeof(buf) - len] = '\0'; - for (s = buf; *s && !isdigit(*s); s++) - ; - if (isdigit(*s)) - *s = '\0'; - sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000); - return strdup(buf); -#endif -} - - -void drain_log(filename) -char *filename; -{ - char buffer[IPLLOGSIZE]; - struct iovec iov; - struct uio uio; - size_t resid; - int fd; - - fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, 0644); - if (fd == -1) { - perror("drain_log:open"); - return; - } - - while (1) { - bzero((char *)&iov, sizeof(iov)); - iov.iov_base = buffer; - iov.iov_len = sizeof(buffer); - - bzero((char *)&uio, sizeof(uio)); - uio.uio_iov = &iov; - uio.uio_iovcnt = 1; - uio.uio_resid = iov.iov_len; - resid = uio.uio_resid; - - if (ipflog_read(0, &uio) == 0) { - /* - * If nothing was read then break out. - */ - if (uio.uio_resid == resid) - break; - write(fd, buffer, resid - uio.uio_resid); - } else - break; - } - - close(fd); -} diff --git a/contrib/ipfilter/kmem.c b/contrib/ipfilter/kmem.c deleted file mode 100644 index 5723ba3806c6..000000000000 --- a/contrib/ipfilter/kmem.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* - * kmemcpy() - copies n bytes from kernel memory into user buffer. - * returns 0 on success, -1 on error. - */ - -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef __sgi -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif - -#include "kmem.h" -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "ipf.h" - - -#ifndef __STDC__ -# define const -#endif - -#if !defined(lint) -static const char sccsid[] = "@(#)kmem.c 1.4 1/12/96 (C) 1992 Darren Reed"; -static const char rcsid[] = "@(#)$Id: kmem.c,v 2.2.2.18 2003/11/09 17:22:22 darrenr Exp $"; -#endif - -#ifdef __sgi -typedef int kvm_t; - -static int kvm_fd = -1; -static char *kvm_errstr = NULL; - -kvm_t *kvm_open(kernel, core, swap, mode, errstr) -char *kernel, *core, *swap; -int mode; -char *errstr; -{ - kvm_errstr = errstr; - - if (core == NULL) - core = "/dev/kmem"; - kvm_fd = open(core, mode); - return (kvm_fd >= 0) ? (kvm_t *)&kvm_fd : NULL; -} - -int kvm_read(kvm, pos, buffer, size) -kvm_t *kvm; -u_long pos; -char *buffer; -size_t size; -{ - size_t left; - char *bufp; - int r; - - if (lseek(*kvm, pos, 0) == -1) { - if (kvm_errstr != NULL) { - fprintf(stderr, "%s:", kvm_errstr); - perror("lseek"); - } - return -1; - } - - for (bufp = buffer, left = size; left > 0; bufp += r, left -= r) { - r = read(*kvm, bufp, 1); - if (r <= 0) - return -1; - } - return size; -} -#endif - -static kvm_t *kvm_f = NULL; - -int openkmem(kern, core) -char *kern, *core; -{ - union { - int ui; - kvm_t *uk; - } k; - - kvm_f = kvm_open(kern, core, NULL, O_RDONLY, NULL); - if (kvm_f == NULL) - { - perror("openkmem:open"); - return -1; - } - k.uk = kvm_f; - return k.ui; -} - -int kmemcpy(buf, pos, n) -register char *buf; -long pos; -register int n; -{ - register int r; - - if (!n) - return 0; - - if (kvm_f == NULL) - if (openkmem(NULL, NULL) == -1) - return -1; - - while ((r = kvm_read(kvm_f, pos, buf, (size_t)n)) < n) - if (r <= 0) - { - fprintf(stderr, "pos=0x%x ", (u_int)pos); - perror("kmemcpy:read"); - return -1; - } - else - { - buf += r; - pos += r; - n -= r; - } - return 0; -} - -int kstrncpy(buf, pos, n) -register char *buf; -long pos; -register int n; -{ - register int r; - - if (!n) - return 0; - - if (kvm_f == NULL) - if (openkmem(NULL, NULL) == -1) - return -1; - - while (n > 0) - { - r = kvm_read(kvm_f, pos, buf, (size_t)1); - if (r <= 0) - { - fprintf(stderr, "pos=0x%x ", (u_int)pos); - perror("kstrncpy:read"); - return -1; - } - else - { - if (*buf == '\0') - break; - buf++; - pos++; - n--; - } - } - return 0; -} - - -/* - * Given a pointer to an interface in the kernel, return a pointer to a - * string which is the interface name. - */ -char *getifname(ptr) -void *ptr; -{ -#if SOLARIS - char *ifname; - ill_t ill; - - if (ptr == (void *)-1) - return "!"; - if (ptr == NULL) - return "-"; - - if (kmemcpy((char *)&ill, (u_long)ptr, sizeof(ill)) == -1) - return "X"; - ifname = malloc(ill.ill_name_length + 1); - if (kmemcpy(ifname, (u_long)ill.ill_name, - ill.ill_name_length) == -1) - return "X"; - return ifname; -#else -# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ - defined(__OpenBSD__) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) -#else - char buf[32]; - int len; -# endif - struct ifnet netif; - - if (ptr == (void *)-1) - return "!"; - if (ptr == NULL) - return "-"; - - if (kmemcpy((char *)&netif, (u_long)ptr, sizeof(netif)) == -1) - return "X"; -# if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ - defined(__OpenBSD__) || \ - (defined(__FreeBSD__) && (__FreeBSD_version >= 501113)) - return strdup(netif.if_xname); -# else - if (kstrncpy(buf, (u_long)netif.if_name, sizeof(buf)) == -1) - return "X"; - if (netif.if_unit < 10) - len = 2; - else if (netif.if_unit < 1000) - len = 3; - else if (netif.if_unit < 10000) - len = 4; - else - len = 5; - buf[sizeof(buf) - len] = '\0'; - sprintf(buf + strlen(buf), "%d", netif.if_unit % 10000); - return strdup(buf); -# endif -#endif -} diff --git a/contrib/ipfilter/lib/addkeep.c b/contrib/ipfilter/lib/addkeep.c deleted file mode 100644 index bbc7759fbc93..000000000000 --- a/contrib/ipfilter/lib/addkeep.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: addkeep.c,v 1.12 2003/12/01 01:59:42 darrenr Exp $ - */ - -#include "ipf.h" - - -/* - * Parses "keep state" and "keep frags" stuff on the end of a line. - */ -int addkeep(cp, fp, linenum) -char ***cp; -struct frentry *fp; -int linenum; -{ - char *s; - - (*cp)++; - if (!**cp) { - fprintf(stderr, "%d: Missing state/frag after keep\n", - linenum); - return -1; - } - - if (!strcasecmp(**cp, "state")) { - fp->fr_flags |= FR_KEEPSTATE; - (*cp)++; - if (**cp && !strcasecmp(**cp, "limit")) { - (*cp)++; - fp->fr_statemax = atoi(**cp); - (*cp)++; - } - if (**cp && !strcasecmp(**cp, "scan")) { - (*cp)++; - if (!strcmp(**cp, "*")) { - fp->fr_isc = NULL; - fp->fr_isctag[0] = '\0'; - } else { - strncpy(fp->fr_isctag, **cp, - sizeof(fp->fr_isctag)); - fp->fr_isctag[sizeof(fp->fr_isctag)-1] = '\0'; - fp->fr_isc = NULL; - } - (*cp)++; - } else - fp->fr_isc = (struct ipscan *)-1; - } else if (!strncasecmp(**cp, "frag", 4)) { - fp->fr_flags |= FR_KEEPFRAG; - (*cp)++; - } else if (!strcasecmp(**cp, "state-age")) { - if (fp->fr_ip.fi_p == IPPROTO_TCP) { - fprintf(stderr, "%d: cannot use state-age with tcp\n", - linenum); - return -1; - } - if ((fp->fr_flags & FR_KEEPSTATE) == 0) { - fprintf(stderr, "%d: state-age with no 'keep state'\n", - linenum); - return -1; - } - (*cp)++; - if (!**cp) { - fprintf(stderr, "%d: state-age with no arg\n", - linenum); - return -1; - } - fp->fr_age[0] = atoi(**cp); - s = strchr(**cp, '/'); - if (s != NULL) { - s++; - fp->fr_age[1] = atoi(s); - } else - fp->fr_age[1] = fp->fr_age[0]; - } else { - fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n", - linenum, **cp); - return -1; - } - return 0; -} diff --git a/contrib/ipfilter/lib/extras.c b/contrib/ipfilter/lib/extras.c deleted file mode 100644 index 9087ca69c1ab..000000000000 --- a/contrib/ipfilter/lib/extras.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: extras.c,v 1.12 2002/07/13 12:06:49 darrenr Exp $ - */ - -#include "ipf.h" - - -/* - * deal with extra bits on end of the line - */ -int extras(cp, fr, linenum) -char ***cp; -struct frentry *fr; -int linenum; -{ - u_short secmsk; - u_long opts; - int notopt; - - opts = 0; - secmsk = 0; - notopt = 0; - (*cp)++; - if (!**cp) - return -1; - - while (**cp) { - if (!strcasecmp(**cp, "not") || !strcasecmp(**cp, "no")) { - notopt = 1; - (*cp)++; - continue; - } else if (!strncasecmp(**cp, "ipopt", 5)) { - if (!notopt) - fr->fr_flx |= FI_OPTIONS; - fr->fr_mflx |= FI_OPTIONS; - goto nextopt; - } else if (!strcasecmp(**cp, "lowttl")) { - if (!notopt) - fr->fr_flx |= FI_LOWTTL; - fr->fr_mflx |= FI_LOWTTL; - goto nextopt; - } else if (!strcasecmp(**cp, "bad-src")) { - if (!notopt) - fr->fr_flx |= FI_BADSRC; - fr->fr_mflx |= FI_BADSRC; - goto nextopt; - } else if (!strncasecmp(**cp, "mbcast", 6)) { - if (!notopt) - fr->fr_flx |= FI_MBCAST; - fr->fr_mflx |= FI_MBCAST; - goto nextopt; - } else if (!strncasecmp(**cp, "nat", 3)) { - if (!notopt) - fr->fr_flx |= FI_NATED; - fr->fr_mflx |= FI_NATED; - goto nextopt; - } else if (!strncasecmp(**cp, "frag", 4)) { - if (!notopt) - fr->fr_flx |= FI_FRAG; - fr->fr_mflx |= FI_FRAG; - goto nextopt; - } else if (!strncasecmp(**cp, "opt", 3)) { - if (!*(*cp + 1)) { - fprintf(stderr, "%d: opt missing arguements\n", - linenum); - return -1; - } - (*cp)++; - if (!(opts = optname(cp, &secmsk, linenum))) - return -1; - - if (notopt) { - if (!secmsk) { - fr->fr_optmask |= opts; - } else { - fr->fr_optmask |= (opts & ~0x0100); - fr->fr_secmask |= secmsk; - } - fr->fr_secbits &= ~secmsk; - fr->fr_optbits &= ~opts; - } else { - fr->fr_optmask |= opts; - fr->fr_secmask |= secmsk; - fr->fr_optbits |= opts; - fr->fr_secbits |= secmsk; - } - } else if (!strncasecmp(**cp, "short", 5)) { - if (fr->fr_tcpf) { - fprintf(stderr, - "%d: short cannot be used with TCP flags\n", - linenum); - return -1; - } - - if (!notopt) - fr->fr_flx |= FI_SHORT; - fr->fr_mflx |= FI_SHORT; - goto nextopt; - } else - return -1; -nextopt: - notopt = 0; - opts = 0; - secmsk = 0; - (*cp)++; - } - return 0; -} diff --git a/contrib/ipfilter/lib/genmask.c b/contrib/ipfilter/lib/genmask.c deleted file mode 100644 index 238e5b62afeb..000000000000 --- a/contrib/ipfilter/lib/genmask.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: genmask.c,v 1.7 2003/11/11 13:40:15 darrenr Exp $ - */ - -#include "ipf.h" - - -int genmask(msk, mskp) -char *msk; -u_32_t *mskp; -{ - char *endptr = 0L; - int bits; - - if (strchr(msk, '.') || strchr(msk, 'x') || strchr(msk, ':')) { - /* possibly of the form xxx.xxx.xxx.xxx - * or 0xYYYYYYYY */ -#ifdef USE_INET6 - if (use_inet6) { - if (inet_pton(AF_INET6, msk, mskp) != 1) - return -1; - } else -#endif - if (inet_aton(msk, (struct in_addr *)mskp) == 0) - return -1; - } else { - /* - * set x most significant bits - */ - bits = (int)strtol(msk, &endptr, 0); -#ifdef USE_INET6 - if ((*endptr != '\0') || - ((bits > 32) && !use_inet6) || (bits < 0) || - ((bits > 128) && use_inet6)) -#else - if (*endptr != '\0' || bits > 32 || bits < 0) -#endif - return -1; -#ifdef USE_INET6 - if (use_inet6) - fill6bits(bits, mskp); - else -#endif - if (bits == 0) - *mskp = 0; - else - *mskp = htonl(0xffffffff << (32 - bits)); - } - return 0; -} diff --git a/contrib/ipfilter/lib/getline.c b/contrib/ipfilter/lib/getline.c deleted file mode 100644 index 7d06d4367b28..000000000000 --- a/contrib/ipfilter/lib/getline.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: getline.c,v 1.3 2001/06/09 17:09:24 darrenr Exp $ - */ - -#include -#if !defined(__SVR4) && !defined(__GNUC__) -#include -#endif -#include -#include "ipf.h" - - -/* - * Similar to fgets(3) but can handle '\\' and NL is converted to NUL. - * Returns NULL if error occured, EOF encounterd or input line is too long. - */ -char *getline(str, size, file, linenum) -register char *str; -size_t size; -FILE *file; -int *linenum; -{ - char *p; - int s, len; - - do { - for (p = str, s = size;; p += (len - 1), s -= (len - 1)) { - /* - * if an error occured, EOF was encounterd, or there - * was no room to put NUL, return NULL. - */ - if (fgets(p, s, file) == NULL) - return (NULL); - len = strlen(p); - if (p[len - 1] != '\n') { - p[len] = '\0'; - break; - } - (*linenum)++; - p[len - 1] = '\0'; - if (len < 2 || p[len - 2] != '\\') - break; - else - /* - * Convert '\\' to a space so words don't - * run together - */ - p[len - 2] = ' '; - } - } while (*str == '\0'); - return (str); -} diff --git a/contrib/ipfilter/lib/hexdump.c b/contrib/ipfilter/lib/hexdump.c deleted file mode 100644 index 86e731ee4a23..000000000000 --- a/contrib/ipfilter/lib/hexdump.c +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#include "ipf.h" - -void hexdump(out, addr, len, ascii) -FILE *out; -void *addr; -int len, ascii; -{ - FILE *fpout; - u_char *s, *t; - int i; - - fpout = out ? out : stdout; - for (i = 0, s = addr; i < len; i++, s++) { - fprintf(fpout, "%02x", *s); - if (i % 16 == 15) { - if (ascii != 0) { - fputc('\t', fpout); - for (t = s - 15; t<= s; t++) - fputc(ISPRINT(*t) ? *t : '.', fpout); - } - fputc('\n', fpout); - } else if (i % 4 == 3) { - fputc(' ', fpout); - } - } -} diff --git a/contrib/ipfilter/lib/hostmask.c b/contrib/ipfilter/lib/hostmask.c deleted file mode 100644 index 4ee41e16b94f..000000000000 --- a/contrib/ipfilter/lib/hostmask.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: hostmask.c,v 1.10 2002/01/28 06:50:46 darrenr Exp $ - */ - -#include "ipf.h" - - -/* - * returns -1 if neither "hostmask/num" or "hostmask mask addr" are - * found in the line segments, there is an error processing this information, - * or there is an error processing ports information. - */ -int hostmask(seg, proto, ifname, sa, msk, linenum) -char ***seg, *proto, *ifname; -u_32_t *sa, *msk; -int linenum; -{ - struct in_addr maskaddr; - char *s; - - if ((s = strchr(**seg, '='))) { - *s++ = '\0'; - if (!strcmp(**seg, "pool")) { - *sa = atoi(s); - return 1; - } - } - - /* - * is it possibly hostname/num ? - */ - if ((s = strchr(**seg, '/')) || - ((s = strchr(**seg, ':')) && !strchr(s + 1, ':'))) { - *s++ ='\0'; - if (genmask(s, msk) == -1) { - fprintf(stderr, "%d: bad mask (%s)\n", linenum, s); - return -1; - } - if (hostnum(sa, **seg, linenum, ifname) == -1) { - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; - } - *sa &= *msk; - (*seg)++; - return 0; - } - - /* - * look for extra segments if "mask" found in right spot - */ - if (*(*seg+1) && *(*seg+2) && !strcasecmp(*(*seg+1), "mask")) { - if (hostnum(sa, **seg, linenum, ifname) == -1) { - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; - } - (*seg)++; - (*seg)++; - if (inet_aton(**seg, &maskaddr) == 0) { - fprintf(stderr, "%d: bad mask (%s)\n", linenum, **seg); - return -1; - } - *msk = maskaddr.s_addr; - (*seg)++; - *sa &= *msk; - return 0; - } - - if (**seg) { - u_32_t k; - - if (hostnum(sa, **seg, linenum, ifname) == -1) { - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; - } - (*seg)++; - k = *sa ? 0xffffffff : 0; -#ifdef USE_INET6 - if (use_inet6) { - msk[1] = k; - msk[2] = k; - msk[3] = k; - } -#endif - *msk = k; - return 0; - } - fprintf(stderr, "%d: bad host (%s)\n", linenum, **seg); - return -1; -} diff --git a/contrib/ipfilter/lib/hostnum.c b/contrib/ipfilter/lib/hostnum.c deleted file mode 100644 index 2ec0529a2981..000000000000 --- a/contrib/ipfilter/lib/hostnum.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: hostnum.c,v 1.10.2.1 2004/12/09 19:41:20 darrenr Exp $ - */ - -#include - -#include "ipf.h" - - -/* - * returns an ip address as a long var as a result of either a DNS lookup or - * straight inet_addr() call - */ -int hostnum(ipa, host, linenum, ifname) -u_32_t *ipa; -char *host; -int linenum; -char *ifname; -{ - struct in_addr ip; - - if (!strcasecmp("any", host) || - (ifname && *ifname && !strcasecmp(ifname, host))) - return 0; - -#ifdef USE_INET6 - if (use_inet6) { - if (inet_pton(AF_INET6, host, ipa) == 1) - return 0; - else - return -1; - } -#endif - if (ISDIGIT(*host) && inet_aton(host, &ip)) { - *ipa = ip.s_addr; - return 0; - } - - if (!strcasecmp("", host)) - host = thishost; - - return gethost(host, ipa); -} diff --git a/contrib/ipfilter/lib/loglevel.c b/contrib/ipfilter/lib/loglevel.c deleted file mode 100644 index 47dd8bac0273..000000000000 --- a/contrib/ipfilter/lib/loglevel.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: loglevel.c,v 1.5 2001/06/09 17:09:24 darrenr Exp $ - */ - -#include "ipf.h" - - -int loglevel(cpp, facpri, linenum) -char **cpp; -u_int *facpri; -int linenum; -{ - int fac, pri; - char *s; - - fac = 0; - pri = 0; - if (!*++cpp) { - fprintf(stderr, "%d: %s\n", linenum, - "missing identifier after level"); - return -1; - } - - s = strchr(*cpp, '.'); - if (s) { - *s++ = '\0'; - fac = fac_findname(*cpp); - if (fac == -1) { - fprintf(stderr, "%d: %s %s\n", linenum, - "Unknown facility", *cpp); - return -1; - } - pri = pri_findname(s); - if (pri == -1) { - fprintf(stderr, "%d: %s %s\n", linenum, - "Unknown priority", s); - return -1; - } - } else { - pri = pri_findname(*cpp); - if (pri == -1) { - fprintf(stderr, "%d: %s %s\n", linenum, - "Unknown priority", *cpp); - return -1; - } - } - *facpri = fac|pri; - return 0; -} diff --git a/contrib/ipfilter/lib/make_range.c b/contrib/ipfilter/lib/make_range.c deleted file mode 100644 index e4335cddf18b..000000000000 --- a/contrib/ipfilter/lib/make_range.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: make_range.c,v 1.2 2002/05/18 07:27:52 darrenr Exp $ - */ -#include "ipf.h" - - -alist_t *make_range(not, a1, a2) -int not; -struct in_addr a1, a2; -{ - alist_t *a; - - a = (alist_t *)calloc(1, sizeof(*a)); - if (a != NULL) { - a->al_1 = a1.s_addr; - a->al_2 = a2.s_addr; - a->al_not = not; - } - return a; -} diff --git a/contrib/ipfilter/lib/natparse.c b/contrib/ipfilter/lib/natparse.c deleted file mode 100644 index 9937380f35a7..000000000000 --- a/contrib/ipfilter/lib/natparse.c +++ /dev/null @@ -1,728 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if !defined(lint) -static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: natparse.c,v 1.8.2.1 2004/12/09 19:41:21 darrenr Exp $"; -#endif - -#include -#include -#include - -#include "ipf.h" -#include "opts.h" - - -void nat_setgroupmap(n) -ipnat_t *n; -{ - if (n->in_outmsk == n->in_inmsk) - n->in_ippip = 1; - else if (n->in_flags & IPN_AUTOPORTMAP) { - n->in_ippip = ~ntohl(n->in_inmsk); - if (n->in_outmsk != 0xffffffff) - n->in_ippip /= (~ntohl(n->in_outmsk) + 1); - n->in_ippip++; - if (n->in_ippip == 0) - n->in_ippip = 1; - n->in_ppip = USABLE_PORTS / n->in_ippip; - } else { - n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); - n->in_nip = 0; - if (!(n->in_ppip = n->in_pmin)) - n->in_ppip = 1; - n->in_ippip = USABLE_PORTS / n->in_ppip; - } -} - - - -ipnat_t *natparse(line, linenum) -char *line; -int linenum; -{ - static ipnat_t ipn; - struct protoent *pr; - char *dnetm = NULL, *dport = NULL, *proto = NULL; - char *s, *t, *cps[31], **cpp; - int i, cnt; - - - if ((s = strchr(line, '\n'))) - *s = '\0'; - if ((s = strchr(line, '#'))) - *s = '\0'; - while (*line && ISSPACE(*line)) - line++; - if (!*line) - return NULL; - - bzero((char *)&ipn, sizeof(ipn)); - cnt = 0; - - for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) - cps[++i] = strtok(NULL, " \b\t\r\n"); - - cps[i] = NULL; - - if (cnt < 3) { - fprintf(stderr, "%d: not enough segments in line\n", linenum); - return NULL; - } - - cpp = cps; - - if (!strcasecmp(*cpp, "map")) - ipn.in_redir = NAT_MAP; - else if (!strcasecmp(*cpp, "map-block")) - ipn.in_redir = NAT_MAPBLK; - else if (!strcasecmp(*cpp, "rdr")) - ipn.in_redir = NAT_REDIRECT; - else if (!strcasecmp(*cpp, "bimap")) - ipn.in_redir = NAT_BIMAP; - else { - fprintf(stderr, "%d: unknown mapping: \"%s\"\n", - linenum, *cpp); - return NULL; - } - - cpp++; - - strncpy(ipn.in_ifnames[0], *cpp, sizeof(ipn.in_ifnames[0]) - 1); - ipn.in_ifnames[0][sizeof(ipn.in_ifnames[0]) - 1] = '\0'; - cpp++; - - if (!strcasecmp(*cpp, "from") || (**cpp == '!')) { - if (!strcmp(*cpp, "!")) { - cpp++; - if (strcasecmp(*cpp, "from")) { - fprintf(stderr, "Missing from after !\n"); - return NULL; - } - ipn.in_flags |= IPN_NOTSRC; - } else if (**cpp == '!') { - if (strcasecmp(*cpp + 1, "from")) { - fprintf(stderr, "Missing from after !\n"); - return NULL; - } - ipn.in_flags |= IPN_NOTSRC; - } - if ((ipn.in_flags & IPN_NOTSRC) && - (ipn.in_redir & (NAT_MAP|NAT_MAPBLK))) { - fprintf(stderr, "Cannot use '! from' with map\n"); - return NULL; - } - - ipn.in_flags |= IPN_FILTER; - cpp++; - if (ipn.in_redir == NAT_REDIRECT) { - if (hostmask(&cpp, proto, NULL, - (u_32_t *)&ipn.in_srcip, - (u_32_t *)&ipn.in_srcmsk, linenum) == -1) - return NULL; - - if (ports(&cpp, proto, &ipn.in_sport, - &ipn.in_scmp, &ipn.in_stop, linenum)) - return NULL; - } else { - if (hostmask(&cpp, proto, NULL, - (u_32_t *)&ipn.in_inip, - (u_32_t *)&ipn.in_inmsk, linenum) == -1) - return NULL; - - if (ports(&cpp, proto, &ipn.in_dport, - &ipn.in_dcmp, &ipn.in_dtop, linenum)) - return NULL; - } - - if (!strcmp(*cpp, "!")) { - cpp++; - ipn.in_flags |= IPN_NOTDST; - } else if (**cpp == '!') { - (*cpp)++; - ipn.in_flags |= IPN_NOTDST; - } - - if (strcasecmp(*cpp, "to")) { - fprintf(stderr, "%d: unexpected keyword (%s) - to\n", - linenum, *cpp); - return NULL; - } - if ((ipn.in_flags & IPN_NOTDST) && - (ipn.in_redir & (NAT_REDIRECT))) { - fprintf(stderr, "Cannot use '! to' with rdr\n"); - return NULL; - } - - if (!*++cpp) { - fprintf(stderr, "%d: missing host after to\n", linenum); - return NULL; - } - if (ipn.in_redir == NAT_REDIRECT) { - if (hostmask(&cpp, proto, NULL, - (u_32_t *)&ipn.in_outip, - (u_32_t *)&ipn.in_outmsk, linenum)) - return NULL; - - if (ports(&cpp, proto, &ipn.in_dport, - &ipn.in_dcmp, &ipn.in_dtop, linenum)) - return NULL; - ipn.in_pmin = htons(ipn.in_dport); - } else { - if (hostmask(&cpp, proto, NULL, - (u_32_t *)&ipn.in_srcip, - (u_32_t *)&ipn.in_srcmsk, linenum)) - return NULL; - - if (ports(&cpp, proto, &ipn.in_sport, - &ipn.in_scmp, &ipn.in_stop, linenum)) - return NULL; - } - } else { - s = *cpp; - if (!s) - return NULL; - t = strchr(s, '/'); - if (!t) - return NULL; - *t++ = '\0'; - if (ipn.in_redir == NAT_REDIRECT) { - if (hostnum((u_32_t *)&ipn.in_outip, s, linenum, NULL)) - return NULL; - if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) { - return NULL; - } - } else { - if (hostnum((u_32_t *)&ipn.in_inip, s, linenum, NULL)) - return NULL; - if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) { - return NULL; - } - } - cpp++; - if (!*cpp) - return NULL; - } - - if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) { - if (strcasecmp(*cpp, "port")) { - fprintf(stderr, "%d: missing fields - 1st port\n", - linenum); - return NULL; - } - - cpp++; - - if (!*cpp) { - fprintf(stderr, - "%d: missing fields (destination port)\n", - linenum); - return NULL; - } - - if (ISDIGIT(**cpp) && (s = strchr(*cpp, '-'))) - *s++ = '\0'; - else - s = NULL; - - if (!portnum(*cpp, proto, &ipn.in_pmin, linenum)) - return NULL; - ipn.in_pmin = htons(ipn.in_pmin); - cpp++; - - if (!strcmp(*cpp, "-")) { - cpp++; - s = *cpp++; - } - - if (s) { - if (!portnum(s, proto, &ipn.in_pmax, linenum)) - return NULL; - ipn.in_pmax = htons(ipn.in_pmax); - } else - ipn.in_pmax = ipn.in_pmin; - } - - if (!*cpp) { - fprintf(stderr, "%d: missing fields (->)\n", linenum); - return NULL; - } - if (strcmp(*cpp, "->")) { - fprintf(stderr, "%d: missing ->\n", linenum); - return NULL; - } - cpp++; - - if (!*cpp) { - fprintf(stderr, "%d: missing fields (%s)\n", - linenum, ipn.in_redir ? "destination" : "target"); - return NULL; - } - - if (ipn.in_redir == NAT_MAP) { - if (!strcasecmp(*cpp, "range")) { - cpp++; - ipn.in_flags |= IPN_IPRANGE; - if (!*cpp) { - fprintf(stderr, "%d: missing fields (%s)\n", - linenum, - ipn.in_redir ? "destination":"target"); - return NULL; - } - } - } - - if (ipn.in_flags & IPN_IPRANGE) { - dnetm = strrchr(*cpp, '-'); - if (dnetm == NULL) { - cpp++; - if (*cpp && !strcmp(*cpp, "-") && *(cpp + 1)) - dnetm = *(cpp + 1); - } else - *dnetm++ = '\0'; - if (dnetm == NULL || *dnetm == '\0') { - fprintf(stderr, - "%d: desination range not specified\n", - linenum); - return NULL; - } - } else if (ipn.in_redir != NAT_REDIRECT) { - dnetm = strrchr(*cpp, '/'); - if (dnetm == NULL) { - cpp++; - if (*cpp && !strcasecmp(*cpp, "netmask")) - dnetm = *++cpp; - } - if (dnetm == NULL) { - fprintf(stderr, - "%d: missing fields (dest netmask)\n", - linenum); - return NULL; - } - if (*dnetm == '/') - *dnetm++ = '\0'; - } - - if (ipn.in_redir == NAT_REDIRECT) { - dnetm = strchr(*cpp, ','); - if (dnetm != NULL) { - ipn.in_flags |= IPN_SPLIT; - *dnetm++ = '\0'; - } - if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum, NULL)) - return NULL; - } else { - if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum, NULL)) - return NULL; - } - cpp++; - - if (ipn.in_redir & NAT_MAPBLK) { - if (*cpp && strcasecmp(*cpp, "ports")) { - fprintf(stderr, - "%d: expected \"ports\" - got \"%s\"\n", - linenum, *cpp); - return NULL; - } - cpp++; - if (*cpp) { - ipn.in_pmin = atoi(*cpp); - cpp++; - } else - ipn.in_pmin = 0; - } else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) { - if (*cpp && strrchr(*cpp, '/') != NULL) { - fprintf(stderr, "%d: No netmask supported in %s\n", - linenum, "destination host for redirect"); - return NULL; - } - /* If it's a in_redir, expect target port */ - - if (!*cpp || strcasecmp(*cpp, "port")) { - fprintf(stderr, "%d: missing fields - 2nd port (%s)\n", - linenum, *cpp); - return NULL; - } - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing fields (destination port)\n", - linenum); - return NULL; - } - if (!portnum(*cpp, proto, &ipn.in_pnext, linenum)) - return NULL; - ipn.in_pnext = htons(ipn.in_pnext); - cpp++; - } - if (dnetm && *dnetm == '/') - *dnetm++ = '\0'; - - if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) { - if (ipn.in_flags & IPN_IPRANGE) { - if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm, - linenum, NULL) == -1) - return NULL; - } else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk)) - return NULL; - } else { - if (ipn.in_flags & IPN_SPLIT) { - if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm, - linenum, NULL) == -1) - return NULL; - } else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk)) - return NULL; - if (!*cpp) { - ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */ - proto = "tcp"; - } else { - if (!strcasecmp(*cpp, "tcp")) - ipn.in_flags |= IPN_TCP; - else if (!strcasecmp(*cpp, "udp")) - ipn.in_flags |= IPN_UDP; - else if (!strcasecmp(*cpp, "tcp/udp")) - ipn.in_flags |= IPN_TCPUDP; - else if (!strcasecmp(*cpp, "tcpudp")) - ipn.in_flags |= IPN_TCPUDP; - else if (!strcasecmp(*cpp, "ip")) - ipn.in_flags |= IPN_ANY; - else { - ipn.in_flags |= IPN_ANY; - ipn.in_p = getproto(*cpp); - } - proto = *cpp; - cpp++; - - if (*cpp && !strcasecmp(*cpp, "round-robin")) { - cpp++; - ipn.in_flags |= IPN_ROUNDR; - } - - if (*cpp && !strcasecmp(*cpp, "frag")) { - cpp++; - ipn.in_flags |= IPN_FRAG; - } - - if (*cpp && !strcasecmp(*cpp, "age")) { - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: age with no parameters\n", - linenum); - return NULL; - } - - ipn.in_age[0] = atoi(*cpp); - s = strchr(*cpp, '/'); - if (s != NULL) - ipn.in_age[1] = atoi(s + 1); - else - ipn.in_age[1] = ipn.in_age[0]; - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "mssclamp")) { - cpp++; - if (*cpp) { - ipn.in_mssclamp = atoi(*cpp); - cpp++; - } else { - fprintf(stderr, - "%d: mssclamp with no parameters\n", - linenum); - return NULL; - } - } - - if (*cpp) { - fprintf(stderr, - "%d: extra junk at the end of rdr: %s\n", - linenum, *cpp); - return NULL; - } - } - } - - if (!(ipn.in_flags & IPN_SPLIT)) - ipn.in_inip &= ipn.in_inmsk; - if ((ipn.in_flags & IPN_IPRANGE) == 0) - ipn.in_outip &= ipn.in_outmsk; - ipn.in_srcip &= ipn.in_srcmsk; - - if ((ipn.in_redir & NAT_MAPBLK) != 0) - nat_setgroupmap(&ipn); - - if (*cpp && !strcasecmp(*cpp, "frag")) { - cpp++; - ipn.in_flags |= IPN_ROUNDR; - } - - if (!*cpp) - return &ipn; - - if (ipn.in_redir != NAT_BIMAP && !strcasecmp(*cpp, "proxy")) { - if (ipn.in_redir == NAT_BIMAP) { - fprintf(stderr, "%d: cannot use proxy with bimap\n", - linenum); - return NULL; - } - - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing parameter for \"proxy\"\n", - linenum); - return NULL; - } - dport = NULL; - - if (!strcasecmp(*cpp, "port")) { - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing parameter for \"port\"\n", - linenum); - return NULL; - } - - dport = *cpp; - cpp++; - - if (!*cpp) { - fprintf(stderr, - "%d: missing parameter for \"proxy\"\n", - linenum); - return NULL; - } - } else { - fprintf(stderr, - "%d: missing keyword \"port\"\n", linenum); - return NULL; - } - - if ((proto = strchr(*cpp, '/'))) { - *proto++ = '\0'; - ipn.in_p = getproto(proto); - } else - ipn.in_p = 0; - - if (dport && !portnum(dport, proto, &ipn.in_dport, linenum)) - return NULL; - ipn.in_dport = htons(ipn.in_dport); - - (void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel)); - cpp++; - - if (*cpp) { - fprintf(stderr, - "%d: too many parameters for \"proxy\"\n", - linenum); - return NULL; - } - return &ipn; - } - - - if (!strcasecmp(*cpp, "icmpidmap")) { - - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: icmpidmap misses protocol and range\n", - linenum); - return NULL; - }; - - if (!strcasecmp(*cpp, "icmp")) - ipn.in_flags = IPN_ICMPQUERY; - else { - fprintf(stderr, "%d: icmpidmap only valid for icmp\n", - linenum); - return NULL; - } - cpp++; - - if (!*cpp) { - fprintf(stderr, "%d: no icmp id argument found\n", - linenum); - return NULL; - } - - if (!(t = strchr(*cpp, ':'))) { - fprintf(stderr, - "%d: no icmp id range detected in \"%s\"\n", - linenum, *cpp); - return NULL; - } - *t++ = '\0'; - - if (!icmpidnum(*cpp, &ipn.in_pmin, linenum) || - !icmpidnum(t, &ipn.in_pmax, linenum)) - return NULL; - } else if (!strcasecmp(*cpp, "portmap")) { - if (ipn.in_redir == NAT_BIMAP) { - fprintf(stderr, "%d: cannot use proxy with bimap\n", - linenum); - return NULL; - } - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing expression following portmap\n", - linenum); - return NULL; - } - - if (!strcasecmp(*cpp, "tcp")) - ipn.in_flags |= IPN_TCP; - else if (!strcasecmp(*cpp, "udp")) - ipn.in_flags |= IPN_UDP; - else if (!strcasecmp(*cpp, "tcpudp")) - ipn.in_flags |= IPN_TCPUDP; - else if (!strcasecmp(*cpp, "tcp/udp")) - ipn.in_flags |= IPN_TCPUDP; - else { - fprintf(stderr, - "%d: expected protocol name - got \"%s\"\n", - linenum, *cpp); - return NULL; - } - proto = *cpp; - cpp++; - - if (!*cpp) { - fprintf(stderr, "%d: no port range found\n", linenum); - return NULL; - } - - if (!strcasecmp(*cpp, "auto")) { - ipn.in_flags |= IPN_AUTOPORTMAP; - ipn.in_pmin = htons(1024); - ipn.in_pmax = htons(65535); - nat_setgroupmap(&ipn); - } else { - if (!(t = strchr(*cpp, ':'))) { - fprintf(stderr, - "%d: no port range in \"%s\"\n", - linenum, *cpp); - return NULL; - } - *t++ = '\0'; - if (!portnum(*cpp, proto, &ipn.in_pmin, linenum) || - !portnum(t, proto, &ipn.in_pmax, linenum)) - return NULL; - } - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "round-robin")) { - cpp++; - ipn.in_flags |= IPN_ROUNDR; - } - - if (*cpp && !strcasecmp(*cpp, "age")) { - cpp++; - if (!*cpp) { - fprintf(stderr, "%d: age with no parameters\n", - linenum); - return NULL; - } - s = strchr(*cpp, '/'); - if (s != NULL) - ipn.in_age[1] = atoi(s + 1); - else - ipn.in_age[1] = ipn.in_age[0]; - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "mssclamp")) { - cpp++; - if (*cpp) { - ipn.in_mssclamp = atoi(*cpp); - cpp++; - } else { - fprintf(stderr, "%d: mssclamp with no parameters\n", - linenum); - return NULL; - } - } - - if (*cpp) { - fprintf(stderr, "%d: extra junk at the end of the line: %s\n", - linenum, *cpp); - return NULL; - } - - ipn.in_pmin = htons(ipn.in_pmin); - ipn.in_pmax = htons(ipn.in_pmax); - return &ipn; -} - - -void natparsefile(fd, file, opts) -int fd; -char *file; -int opts; -{ - char line[512], *s; - ipnat_t *np; - FILE *fp; - int linenum = 0; - - if (strcmp(file, "-")) { - if (!(fp = fopen(file, "r"))) { - fprintf(stderr, "%s: open: %s\n", file, - STRERROR(errno)); - exit(1); - } - } else - fp = stdin; - - while (getline(line, sizeof(line) - 1, fp, &linenum)) { - line[sizeof(line) - 1] = '\0'; - if ((s = strchr(line, '\n'))) - *s = '\0'; - - if (!(np = natparse(line, linenum))) { - if (*line) - fprintf(stderr, "%d: syntax error in \"%s\"\n", - linenum, line); - } else { - if ((opts & OPT_VERBOSE) && np) - printnat(np, opts); - if (!(opts & OPT_DONOTHING)) { - if (!(opts & OPT_REMOVE)) { - if (ioctl(fd, SIOCADNAT, &np) == -1) - perror("ioctl(SIOCADNAT)"); - } else if (ioctl(fd, SIOCRMNAT, &np) == -1) - perror("ioctl(SIOCRMNAT)"); - } - } - } - if (fp != stdin) - fclose(fp); -} - - -int icmpidnum(str, id, linenum) -char *str; -u_short *id; -int linenum; -{ - int i; - - - i = atoi(str); - - if ((i<0) || (i>65535)) { - fprintf(stderr, "%d: invalid icmp id\"%s\".\n", linenum, str); - return 0; - } - - *id = (u_short)i; - - return 1; -} diff --git a/contrib/ipfilter/lib/parse.c b/contrib/ipfilter/lib/parse.c deleted file mode 100644 index 1a49d16bbd7e..000000000000 --- a/contrib/ipfilter/lib/parse.c +++ /dev/null @@ -1,752 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: parse.c,v 1.34.2.1 2004/12/09 19:41:21 darrenr Exp $ - */ -#include -#include "ipf.h" -#include "opts.h" - -static frentry_t *fp = NULL; - -/* parse() - * - * parse a line read from the input filter rule file - */ -struct frentry *parse(line, linenum) -char *line; -int linenum; -{ - static fripf_t fip; - char *cps[31], **cpp, *endptr, *proto = NULL, *s; - struct protoent *p = NULL; - int i, cnt = 1, j; - u_int k; - - if (fp == NULL) { - fp = malloc(sizeof(*fp)); - if (fp == NULL) - return NULL; - } - - while (*line && ISSPACE(*line)) - line++; - if (!*line) - return NULL; - - bzero((char *)fp, sizeof(*fp)); - bzero((char *)&fip, sizeof(fip)); - fp->fr_v = use_inet6 ? 6 : 4; - fp->fr_ipf = &fip; - fp->fr_dsize = sizeof(fip); - fp->fr_ip.fi_v = fp->fr_v; - fp->fr_mip.fi_v = 0xf; - fp->fr_type = FR_T_NONE; - fp->fr_loglevel = 0xffff; - fp->fr_isc = (void *)-1; - fp->fr_tag = FR_NOTAG; - - /* - * break line up into max of 20 segments - */ - if (opts & OPT_DEBUG) - fprintf(stderr, "parse [%s]\n", line); - for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) - cps[++i] = strtok(NULL, " \b\t\r\n"); - cps[i] = NULL; - - if (cnt < 3) { - fprintf(stderr, "%d: not enough segments in line\n", linenum); - return NULL; - } - - cpp = cps; - /* - * The presence of an '@' followed by a number gives the position in - * the current rule list to insert this one. - */ - if (**cpp == '@') - fp->fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1; - - /* - * Check the first keyword in the rule and any options that are - * expected to follow it. - */ - if (!strcasecmp("block", *cpp)) { - fp->fr_flags |= FR_BLOCK; - if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) && - (i = 19)) - fp->fr_flags |= FR_FAKEICMP; - else if (!strncasecmp(*(cpp+1), "return-icmp", 11) && (i = 11)) - fp->fr_flags |= FR_RETICMP; - if (fp->fr_flags & FR_RETICMP) { - cpp++; - if (strlen(*cpp) == i) { - if (*(cpp + 1) && **(cpp +1) == '(') { - cpp++; - i = 0; - } else - i = -1; - } - - /* - * The ICMP code is not required to follow in ()'s - */ - if ((i >= 0) && (*(*cpp + i) == '(')) { - i++; - j = icmpcode(*cpp + i); - if (j == -1) { - fprintf(stderr, - "%d: unrecognised icmp code %s\n", - linenum, *cpp + 20); - return NULL; - } - fp->fr_icode = j; - } - } else if (!strncasecmp(*(cpp+1), "return-rst", 10)) { - fp->fr_flags |= FR_RETRST; - cpp++; - } - } else if (!strcasecmp("count", *cpp)) { - fp->fr_flags |= FR_ACCOUNT; - } else if (!strcasecmp("pass", *cpp)) { - fp->fr_flags |= FR_PASS; - } else if (!strcasecmp("auth", *cpp)) { - fp->fr_flags |= FR_AUTH; - } else if (fp->fr_arg != 0) { - printf("skip %u", fp->fr_arg); - } else if (!strcasecmp("preauth", *cpp)) { - fp->fr_flags |= FR_PREAUTH; - } else if (!strcasecmp("nomatch", *cpp)) { - fp->fr_flags |= FR_NOMATCH; - } else if (!strcasecmp("skip", *cpp)) { - cpp++; - if (ratoui(*cpp, &k, 0, UINT_MAX)) - fp->fr_arg = k; - else { - fprintf(stderr, "%d: integer must follow skip\n", - linenum); - return NULL; - } - } else if (!strcasecmp("log", *cpp)) { - fp->fr_flags |= FR_LOG; - if (!strcasecmp(*(cpp+1), "body")) { - fp->fr_flags |= FR_LOGBODY; - cpp++; - } - if (!strcasecmp(*(cpp+1), "first")) { - fp->fr_flags |= FR_LOGFIRST; - cpp++; - } - if (*cpp && !strcasecmp(*(cpp+1), "or-block")) { - fp->fr_flags |= FR_LOGORBLOCK; - cpp++; - } - if (!strcasecmp(*(cpp+1), "level")) { - cpp++; - if (loglevel(cpp, &fp->fr_loglevel, linenum) == -1) - return NULL; - cpp++; - } - } else { - /* - * Doesn't start with one of the action words - */ - fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp); - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum); - return NULL; - } - - /* - * Get the direction for filtering. Impose restrictions on direction - * if blocking with returning ICMP or an RST has been requested. - */ - if (!strcasecmp("in", *cpp)) - fp->fr_flags |= FR_INQUE; - else if (!strcasecmp("out", *cpp)) { - fp->fr_flags |= FR_OUTQUE; - if (fp->fr_flags & FR_RETICMP) { - fprintf(stderr, - "%d: Can only use return-icmp with 'in'\n", - linenum); - return NULL; - } else if (fp->fr_flags & FR_RETRST) { - fprintf(stderr, - "%d: Can only use return-rst with 'in'\n", - linenum); - return NULL; - } - } - if (!*++cpp) { - fprintf(stderr, "%d: missing source specification\n", linenum); - return NULL; - } - - if (!strcasecmp("log", *cpp)) { - if (!*++cpp) { - fprintf(stderr, "%d: missing source specification\n", - linenum); - return NULL; - } - if (FR_ISPASS(fp->fr_flags)) - fp->fr_flags |= FR_LOGP; - else if (FR_ISBLOCK(fp->fr_flags)) - fp->fr_flags |= FR_LOGB; - if (*cpp && !strcasecmp(*cpp, "body")) { - fp->fr_flags |= FR_LOGBODY; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "first")) { - fp->fr_flags |= FR_LOGFIRST; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "or-block")) { - if (!FR_ISPASS(fp->fr_flags)) { - fprintf(stderr, - "%d: or-block must be used with pass\n", - linenum); - return NULL; - } - fp->fr_flags |= FR_LOGORBLOCK; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "level")) { - if (loglevel(cpp, &fp->fr_loglevel, linenum) == -1) - return NULL; - cpp++; - cpp++; - } - } - - if (*cpp && !strcasecmp("quick", *cpp)) { - if (fp->fr_arg != 0) { - fprintf(stderr, "%d: cannot use skip with quick\n", - linenum); - return NULL; - } - cpp++; - fp->fr_flags |= FR_QUICK; - } - - /* - * Parse rule options that are available if a rule is tied to an - * interface. - */ - *fp->fr_ifname = '\0'; - *fp->fr_oifname = '\0'; - if (*cpp && !strcasecmp(*cpp, "on")) { - if (!*++cpp) { - fprintf(stderr, "%d: interface name missing\n", - linenum); - return NULL; - } - (void)strncpy(fp->fr_ifname, *cpp, IFNAMSIZ-1); - fp->fr_ifname[IFNAMSIZ-1] = '\0'; - cpp++; - if (!*cpp) { - if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) { - fprintf(stderr, - "%d: %s can only be used with TCP\n", - linenum, "return-rst"); - return NULL; - } - return fp; - } - - if (!strcasecmp(*cpp, "out-via")) { - if (fp->fr_flags & FR_OUTQUE) { - fprintf(stderr, - "out-via must be used with in\n"); - return NULL; - } - cpp++; - (void)strncpy(fp->fr_oifname, *cpp, IFNAMSIZ-1); - fp->fr_oifname[IFNAMSIZ-1] = '\0'; - cpp++; - } else if (!strcasecmp(*cpp, "in-via")) { - if (fp->fr_flags & FR_INQUE) { - fprintf(stderr, - "in-via must be used with out\n"); - return NULL; - } - cpp++; - (void)strncpy(fp->fr_oifname, *cpp, IFNAMSIZ-1); - fp->fr_oifname[IFNAMSIZ-1] = '\0'; - cpp++; - } - - if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) { - cpp++; - if (to_interface(&fp->fr_dif, *cpp, linenum)) - return NULL; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) { - cpp++; - if (to_interface(&fp->fr_tif, *cpp, linenum)) - return NULL; - cpp++; - } else if (*cpp && !strcasecmp(*cpp, "fastroute")) { - if (!(fp->fr_flags & FR_INQUE)) { - fprintf(stderr, - "can only use %s with 'in'\n", - "fastroute"); - return NULL; - } - fp->fr_flags |= FR_FASTROUTE; - cpp++; - } - - /* - * Set the "other" interface name. Lets you specify both - * inbound and outbound interfaces for state rules. Do not - * prevent both interfaces from being the same. - */ - strcpy(fp->fr_ifnames[3], "*"); - if ((*cpp != NULL) && (*(cpp + 1) != NULL) && - ((((fp->fr_flags & FR_INQUE) != 0) && - (strcasecmp(*cpp, "out-via") == 0)) || - (((fp->fr_flags & FR_OUTQUE) != 0) && - (strcasecmp(*cpp, "in-via") == 0)))) { - cpp++; - - s = strchr(*cpp, ','); - if (s != NULL) { - *s++ = '\0'; - (void)strncpy(fp->fr_ifnames[3], s, - IFNAMSIZ - 1); - fp->fr_ifnames[3][IFNAMSIZ - 1] = '\0'; - } - - (void)strncpy(fp->fr_ifnames[2], *cpp, IFNAMSIZ - 1); - fp->fr_ifnames[2][IFNAMSIZ - 1] = '\0'; - cpp++; - } else - strcpy(fp->fr_ifnames[2], "*"); - - } - - if (*cpp && !strcasecmp(*cpp, "tos")) { - if (!*++cpp) { - fprintf(stderr, "%d: tos missing value\n", linenum); - return NULL; - } - fp->fr_tos = strtol(*cpp, NULL, 0); - fp->fr_mip.fi_tos = 0xff; - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "ttl")) { - if (!*++cpp) { - fprintf(stderr, "%d: ttl missing hopcount value\n", - linenum); - return NULL; - } - if (ratoi(*cpp, &i, 0, 255)) - fp->fr_ttl = i; - else { - fprintf(stderr, "%d: invalid ttl (%s)\n", - linenum, *cpp); - return NULL; - } - fp->fr_mip.fi_ttl = 0xff; - cpp++; - } - - /* - * check for "proto " only decode udp/tcp/icmp as protoname - */ - if (*cpp && !strcasecmp(*cpp, "proto")) { - if (!*++cpp) { - fprintf(stderr, "%d: protocol name missing\n", linenum); - return NULL; - } - fp->fr_type = FR_T_IPF; - proto = *cpp++; - if (!strcasecmp(proto, "tcp/udp")) { - fp->fr_flx |= FI_TCPUDP; - fp->fr_mflx |= FI_TCPUDP; - } else if (use_inet6 && !strcasecmp(proto, "icmp")) { - fprintf(stderr, -"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n", - linenum); - return NULL; - } else { - fp->fr_proto = getproto(proto); - fp->fr_mip.fi_p = 0xff; - } - } - if ((fp->fr_proto != IPPROTO_TCP) && - ((fp->fr_flags & FR_RETMASK) == FR_RETRST)) { - fprintf(stderr, "%d: %s can only be used with TCP\n", - linenum, "return-rst"); - return NULL; - } - - /* - * get the from host and bit mask to use against packets - */ - - if (!*cpp) { - fprintf(stderr, "%d: missing source specification\n", linenum); - return NULL; - } - if (!strcasecmp(*cpp, "all")) { - cpp++; - if (!*cpp) { - if (fp->fr_type == FR_T_NONE) { - fp->fr_dsize = 0; - fp->fr_data = NULL; - } - return fp; - } - fp->fr_type = FR_T_IPF; -#ifdef IPFILTER_BPF - } else if (!strcmp(*cpp, "{")) { - struct bpf_program bpf; - struct pcap *p; - char **cp; - u_32_t l; - - if (fp->fr_type != FR_T_NONE) { - fprintf(stderr, - "%d: cannot mix BPF/ipf matching\n", linenum); - return NULL; - } - fp->fr_type = FR_T_BPFOPC; - cpp++; - if (!strncmp(*cpp, "0x", 2)) { - fp->fr_data = malloc(4); - for (cp = cpp, i = 0; *cp; cp++, i++) { - if (!strcmp(*cp, "}")) - break; - fp->fr_data = realloc(fp->fr_data, - (i + 1) * 4); - l = strtoul(*cp, NULL, 0); - ((u_32_t *)fp->fr_data)[i] = l; - } - if (!*cp) { - fprintf(stderr, "Missing closing '}'\n"); - return NULL; - } - fp->fr_dsize = i * sizeof(l); - bpf.bf_insns = fp->fr_data; - bpf.bf_len = fp->fr_dsize / sizeof(struct bpf_insn); - } else { - for (cp = cpp; *cp; cp++) { - if (!strcmp(*cp, "}")) - break; - (*cp)[-1] = ' '; - } - if (!*cp) { - fprintf(stderr, "Missing closing '}'\n"); - return NULL; - } - - bzero((char *)&bpf, sizeof(bpf)); - p = pcap_open_dead(DLT_RAW, 1); - if (!p) { - fprintf(stderr, "pcap_open_dead failed\n"); - return NULL; - } - - if (pcap_compile(p, &bpf, *cpp, 1, 0xffffffff)) { - pcap_perror(p, "ipf"); - pcap_close(p); - fprintf(stderr, "pcap parsing failed\n"); - return NULL; - } - pcap_close(p); - fp->fr_dsize = bpf.bf_len * sizeof(struct bpf_insn); - fp->fr_data = bpf.bf_insns; - if (!bpf_validate(fp->fr_data, bpf.bf_len)) { - fprintf(stderr, "BPF validation failed\n"); - return NULL; - } - if (opts & OPT_DEBUG) - bpf_dump(&bpf, 0); - } - cpp = cp; - (*cpp)++; -#endif - } else { - fp->fr_type = FR_T_IPF; - - if (strcasecmp(*cpp, "from")) { - fprintf(stderr, "%d: unexpected keyword (%s) - from\n", - linenum, *cpp); - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: missing host after from\n", - linenum); - return NULL; - } - if (**cpp == '!') { - fp->fr_flags |= FR_NOTSRCIP; - (*cpp)++; - } else if (!strcmp(*cpp, "!")) { - fp->fr_flags |= FR_NOTSRCIP; - cpp++; - } - - s = *cpp; - i = hostmask(&cpp, proto, fp->fr_ifname, (u_32_t *)&fp->fr_src, - (u_32_t *)&fp->fr_smsk, linenum); - if (i == -1) - return NULL; - if (*fp->fr_ifname && !strcasecmp(s, fp->fr_ifname)) - fp->fr_satype = FRI_DYNAMIC; - if (i == 1) { - if (fp->fr_v == 6) { - fprintf(stderr, - "can only use pools with ipv4\n"); - return NULL; - } - fp->fr_satype = FRI_LOOKUP; - } - - if (ports(&cpp, proto, &fp->fr_sport, &fp->fr_scmp, - &fp->fr_stop, linenum)) - return NULL; - - if (!*cpp) { - fprintf(stderr, "%d: missing to fields\n", linenum); - return NULL; - } - - /* - * do the same for the to field (destination host) - */ - if (strcasecmp(*cpp, "to")) { - fprintf(stderr, "%d: unexpected keyword (%s) - to\n", - linenum, *cpp); - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: missing host after to\n", linenum); - return NULL; - } - - if (**cpp == '!') { - fp->fr_flags |= FR_NOTDSTIP; - (*cpp)++; - } else if (!strcmp(*cpp, "!")) { - fp->fr_flags |= FR_NOTDSTIP; - cpp++; - } - - s = *cpp; - i = hostmask(&cpp, proto, fp->fr_ifname, (u_32_t *)&fp->fr_dst, - (u_32_t *)&fp->fr_dmsk, linenum); - if (i == -1) - return NULL; - if (*fp->fr_ifname && !strcasecmp(s, fp->fr_ifname)) - fp->fr_datype = FRI_DYNAMIC; - if (i == 1) { - if (fp->fr_v == 6) { - fprintf(stderr, - "can only use pools with ipv4\n"); - return NULL; - } - fp->fr_datype = FRI_LOOKUP; - } - - if (ports(&cpp, proto, &fp->fr_dport, &fp->fr_dcmp, - &fp->fr_dtop, linenum)) - return NULL; - } - - if (fp->fr_type == FR_T_IPF) { - /* - * check some sanity, make sure we don't have icmp checks - * with tcp or udp or visa versa. - */ - if (fp->fr_proto && (fp->fr_dcmp || fp->fr_scmp) && - fp->fr_proto != IPPROTO_TCP && - fp->fr_proto != IPPROTO_UDP) { - fprintf(stderr, - "%d: port operation on non tcp/udp\n",linenum); - return NULL; - } - if (fp->fr_icmp && fp->fr_proto != IPPROTO_ICMP) { - fprintf(stderr, - "%d: icmp comparisons on wrong protocol\n", - linenum); - return NULL; - } - - if (!*cpp) - return fp; - - if (*cpp && (fp->fr_type == FR_T_IPF) && - !strcasecmp(*cpp, "flags")) { - if (!*++cpp) { - fprintf(stderr, "%d: no flags present\n", - linenum); - return NULL; - } - fp->fr_tcpf = tcp_flags(*cpp, &fp->fr_tcpfm, linenum); - cpp++; - } - - /* - * extras... - */ - if ((fp->fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") || - !strcasecmp(*cpp, "and"))) - if (extras(&cpp, fp, linenum)) - return NULL; - - /* - * icmp types for use with the icmp protocol - */ - if (*cpp && !strcasecmp(*cpp, "icmp-type")) { - if (fp->fr_proto != IPPROTO_ICMP && - fp->fr_proto != IPPROTO_ICMPV6) { - fprintf(stderr, - "%d: icmp with wrong protocol (%d)\n", - linenum, fp->fr_proto); - return NULL; - } - if (addicmp(&cpp, fp, linenum)) - return NULL; - fp->fr_icmp = htons(fp->fr_icmp); - fp->fr_icmpm = htons(fp->fr_icmpm); - } - } - - /* - * Keep something... - */ - while (*cpp && !strcasecmp(*cpp, "keep")) - if (addkeep(&cpp, fp, linenum)) - return NULL; - - /* - * This is here to enforce the old interface binding behaviour. - * That is, "on X" is equivalent to " on X -via -,X" - */ - if (fp->fr_flags & FR_KEEPSTATE) { - if (*fp->fr_ifnames[0] && !*fp->fr_ifnames[3]) { - bcopy(fp->fr_ifnames[0], fp->fr_ifnames[3], - sizeof(fp->fr_ifnames[3])); - strncpy(fp->fr_ifnames[2], "*", - sizeof(fp->fr_ifnames[3])); - } - } - - /* - * head of a new group ? - */ - if (*cpp && !strcasecmp(*cpp, "head")) { - if (fp->fr_arg != 0) { - fprintf(stderr, "%d: cannot use skip with head\n", - linenum); - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: head without group #\n", linenum); - return NULL; - } - if (strlen(*cpp) > FR_GROUPLEN) { - fprintf(stderr, "%d: head name too long #\n", linenum); - return NULL; - } - strncpy(fp->fr_grhead, *cpp, FR_GROUPLEN); - cpp++; - } - - /* - * reference to an already existing group ? - */ - if (*cpp && !strcasecmp(*cpp, "group")) { - if (!*++cpp) { - fprintf(stderr, "%d: group without group #\n", - linenum); - return NULL; - } - if (strlen(*cpp) > FR_GROUPLEN) { - fprintf(stderr, "%d: group name too long #\n", linenum); - return NULL; - } - strncpy(fp->fr_group, *cpp, FR_GROUPLEN); - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "tag")) { - if (!*++cpp) { - fprintf(stderr, "%d: tag id missing value\n", linenum); - return NULL; - } - fp->fr_tag = strtol(*cpp, NULL, 0); - cpp++; - } - - /* - * pps counter - */ - if (*cpp && !strcasecmp(*cpp, "pps")) { - if (!*++cpp) { - fprintf(stderr, "%d: pps without rate\n", linenum); - return NULL; - } - if (ratoui(*cpp, &k, 0, INT_MAX)) - fp->fr_pps = k; - else { - fprintf(stderr, "%d: invalid pps rate (%s)\n", - linenum, *cpp); - return NULL; - } - cpp++; - } - - /* - * leftovers...yuck - */ - if (*cpp && **cpp) { - fprintf(stderr, "%d: unknown words at end: [", linenum); - for (; *cpp; cpp++) - fprintf(stderr, "%s ", *cpp); - fprintf(stderr, "]\n"); - return NULL; - } - - /* - * lazy users... - */ - if (fp->fr_type == FR_T_IPF) { - if ((fp->fr_tcpf || fp->fr_tcpfm) && - (fp->fr_proto != IPPROTO_TCP)) { - fprintf(stderr, - "%d: TCP protocol not specified\n", linenum); - return NULL; - } - if (!(fp->fr_flx & FI_TCPUDP) && - (fp->fr_proto != IPPROTO_TCP) && - (fp->fr_proto != IPPROTO_UDP) && - (fp->fr_dcmp || fp->fr_scmp)) { - if (!fp->fr_proto) { - fp->fr_flx |= FI_TCPUDP; - fp->fr_mflx |= FI_TCPUDP; - } else { - fprintf(stderr, - "%d: port check for non-TCP/UDP\n", - linenum); - return NULL; - } - } - } - if (*fp->fr_oifname && strcmp(fp->fr_oifname, "*") && - !(fp->fr_flags & FR_KEEPSTATE)) { - fprintf(stderr, "%d: *-via must be used %s\n", - linenum, "with keep-state"); - return NULL; - } - return fp; -} diff --git a/contrib/ipfilter/lib/portnum.c b/contrib/ipfilter/lib/portnum.c deleted file mode 100644 index 4079f464c21f..000000000000 --- a/contrib/ipfilter/lib/portnum.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * - * $Id: portnum.c,v 1.6.4.1 2004/12/09 19:41:22 darrenr Exp $ - */ - -#include - -#include "ipf.h" - - -/* - * find the port number given by the name, either from getservbyname() or - * straight atoi(). Return 1 on success, 0 on failure - */ -int portnum(name, proto, port, linenum) -char *name, *proto; -u_short *port; -int linenum; -{ - struct servent *sp, *sp2; - u_short p1 = 0; - int i; - - if (ISDIGIT(*name)) { - if (ratoi(name, &i, 0, USHRT_MAX)) { - *port = (u_short)i; - return 1; - } - fprintf(stderr, "%d: unknown port \"%s\"\n", linenum, name); - return 0; - } - if (proto != NULL && strcasecmp(proto, "tcp/udp") != 0) { - sp = getservbyname(name, proto); - if (sp) { - *port = ntohs(sp->s_port); - return 1; - } - fprintf(stderr, "%d: unknown service \"%s\".\n", linenum, name); - return 0; - } - sp = getservbyname(name, "tcp"); - if (sp) - p1 = sp->s_port; - sp2 = getservbyname(name, "udp"); - if (!sp || !sp2) { - fprintf(stderr, "%d: unknown tcp/udp service \"%s\".\n", - linenum, name); - return 0; - } - if (p1 != sp2->s_port) { - fprintf(stderr, "%d: %s %d/tcp is a different port to ", - linenum, name, p1); - fprintf(stderr, "%d: %s %d/udp\n", linenum, name, sp->s_port); - return 0; - } - *port = ntohs(p1); - return 1; -} diff --git a/contrib/ipfilter/lib/ports.c b/contrib/ipfilter/lib/ports.c deleted file mode 100644 index 9a44e2c06a2d..000000000000 --- a/contrib/ipfilter/lib/ports.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ports.c,v 1.9.4.1 2004/12/09 19:41:22 darrenr Exp $ - */ - -#include - -#include "ipf.h" - - -/* - * check for possible presence of the port fields in the line - */ -int ports(seg, proto, pp, cp, tp, linenum) -char ***seg; -char *proto; -u_short *pp; -int *cp; -u_short *tp; -int linenum; -{ - int comp = -1; - - if (!*seg || !**seg || !***seg) - return 0; - if (!strcasecmp(**seg, "port") && *(*seg + 1) && *(*seg + 2)) { - (*seg)++; - if (ISALNUM(***seg) && *(*seg + 2)) { - if (portnum(**seg, proto, pp, linenum) == 0) - return -1; - (*seg)++; - if (!strcmp(**seg, "<>")) - comp = FR_OUTRANGE; - else if (!strcmp(**seg, "><")) - comp = FR_INRANGE; - else { - fprintf(stderr, - "%d: unknown range operator (%s)\n", - linenum, **seg); - return -1; - } - (*seg)++; - if (**seg == NULL) { - fprintf(stderr, "%d: missing 2nd port value\n", - linenum); - return -1; - } - if (portnum(**seg, proto, tp, linenum) == 0) - return -1; - } else if (!strcmp(**seg, "=") || !strcasecmp(**seg, "eq")) - comp = FR_EQUAL; - else if (!strcmp(**seg, "!=") || !strcasecmp(**seg, "ne")) - comp = FR_NEQUAL; - else if (!strcmp(**seg, "<") || !strcasecmp(**seg, "lt")) - comp = FR_LESST; - else if (!strcmp(**seg, ">") || !strcasecmp(**seg, "gt")) - comp = FR_GREATERT; - else if (!strcmp(**seg, "<=") || !strcasecmp(**seg, "le")) - comp = FR_LESSTE; - else if (!strcmp(**seg, ">=") || !strcasecmp(**seg, "ge")) - comp = FR_GREATERTE; - else { - fprintf(stderr, "%d: unknown comparator (%s)\n", - linenum, **seg); - return -1; - } - if (comp != FR_OUTRANGE && comp != FR_INRANGE) { - (*seg)++; - if (portnum(**seg, proto, pp, linenum) == 0) - return -1; - } - *cp = comp; - (*seg)++; - } - return 0; -} diff --git a/contrib/ipfilter/lib/ratoi.c b/contrib/ipfilter/lib/ratoi.c deleted file mode 100644 index fb8552dfcc15..000000000000 --- a/contrib/ipfilter/lib/ratoi.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ratoi.c,v 1.4 2001/06/09 17:09:25 darrenr Exp $ - */ - -#include "ipf.h" - - -int ratoi(ps, pi, min, max) -char *ps; -int *pi, min, max; -{ - int i; - char *pe; - - i = (int)strtol(ps, &pe, 0); - if (*pe != '\0' || i < min || i > max) - return 0; - *pi = i; - return 1; -} diff --git a/contrib/ipfilter/lib/ratoui.c b/contrib/ipfilter/lib/ratoui.c deleted file mode 100644 index 191f87f4d116..000000000000 --- a/contrib/ipfilter/lib/ratoui.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: ratoui.c,v 1.4 2001/06/09 17:09:25 darrenr Exp $ - */ - -#include "ipf.h" - - -int ratoui(ps, pi, min, max) -char *ps; -u_int *pi, min, max; -{ - u_int i; - char *pe; - - i = (u_int)strtol(ps, &pe, 0); - if (*pe != '\0' || i < min || i > max) - return 0; - *pi = i; - return 1; -} diff --git a/contrib/ipfilter/lib/to_interface.c b/contrib/ipfilter/lib/to_interface.c deleted file mode 100644 index 8f2c16f04377..000000000000 --- a/contrib/ipfilter/lib/to_interface.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: to_interface.c,v 1.8 2002/01/28 06:50:48 darrenr Exp $ - */ - -#include "ipf.h" - - -int to_interface(fdp, to, linenum) -frdest_t *fdp; -char *to; -int linenum; -{ - char *s; - - s = strchr(to, ':'); - fdp->fd_ifp = NULL; - if (s) { - *s++ = '\0'; - if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum, NULL) == -1) - return -1; - } - (void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1); - fdp->fd_ifname[sizeof(fdp->fd_ifname) - 1] = '\0'; - return 0; -} diff --git a/contrib/ipfilter/linux.h b/contrib/ipfilter/linux.h deleted file mode 100644 index 61fd821c2adb..000000000000 --- a/contrib/ipfilter/linux.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 1993-1998 by Darren Reed. - * - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and due credit is given - * to the original author and the contributors. The author accepts no - * responsibility and is not changed in any way. - * - * I hate legaleese, don't you ? - * $Id: linux.h,v 2.1 1999/08/04 17:30:10 darrenr Exp $ - */ - -#include -#ifdef MODULE -#include -#include -#endif /* MODULE */ - -#include "ip_compat.h" diff --git a/contrib/ipfilter/man/ipf.1 b/contrib/ipfilter/man/ipf.1 deleted file mode 100644 index 5ea06fa74c35..000000000000 --- a/contrib/ipfilter/man/ipf.1 +++ /dev/null @@ -1,109 +0,0 @@ -.TH IPF 1 -.SH NAME -ipf \- alters packet filtering lists for IP packet input and ouput -.SH SYNOPSIS -.B ipf -[ -.B \-AdDEInorsUvyzZ -] [ -.B \-l - -] [ -.B \-F - -] -.B \-f -<\fIfilename\fP> -[ -.B \-f -<\fIfilename\fP> -[...]] -.SH DESCRIPTION -.PP -\fBipf\fP opens the filenames listed (treating "\-" as stdin) and parses the -file for a set of rules which are to be added or removed from the packet -filter rule set. -.PP -Each rule processed by \fBipf\fP -is added to the kernel's internal lists if there are no parsing problems. -Rules are added to the end of the internal lists, matching the order in -which they appear when given to \fBipf\fP. -.SH OPTIONS -.TP -.B \-A -Set the list to make changes to the active list (default). -.TP -.B \-d -Turn debug mode on. Causes a hexdump of filter rules to be generated as -it processes each one. -.TP -.B \-D -Disable the filter (if enabled). Not effective for loadable kernel versions. -.TP -.B \-E -Enable the filter (if disabled). Not effective for loadable kernel versions. -.TP -.BR \-F \0 -This option specifies which filter list to flush. The parameter should -either be "i" (input), "o" (output) or "a" (remove all filter rules). -Either a single letter or an entire word starting with the appropriate -letter maybe used. This option maybe before, or after, any other with -the order on the command line being that used to execute options. -.TP -.BR \-f \0 -This option specifies which files -\fBipf\fP should use to get input from for modifying the packet filter rule -lists. -.TP -.B \-I -Set the list to make changes to the inactive list. -.TP -.B \-l \0 -Use of the \fB-l\fP flag toggles default logging of packets. Valid -arguments to this option are \fBpass\fP, \fBblock\fP and \fBnomatch\fP. -When an option is set, any packet which exits filtering and matches the -set category is logged. This is most useful for causing all packets -which don't match any of the loaded rules to be logged. -.TP -.B \-n -This flag (no-change) prevents \fBipf\fP from actually making any ioctl -calls or doing anything which would alter the currently running kernel. -.TP -.B \-o -Force rules by default to be added/deleted to/from the output list, rather -than the (default) input list. -.TP -.B \-r -Remove matching filter rules rather than add them to the internal lists -.TP -.B \-s -Swap the active filter list in use to be the "other" one. -.TP -.B \-U -(SOLARIS 2 ONLY) Block packets travelling along the data stream which aren't -recognised as IP packets. They will be printed out on the console. -.TP -.B \-v -Turn verbose mode on. Displays information relating to rule processing. -.TP -.B \-y -(SOLARIS 2 ONLY) Manually resync the in-kernel interface list maintained -by IP Filter with the current interface status list. -.TP -.B \-z -For each rule in the input file, reset the statistics for it to zero and -display the statistics prior to them being zero'd. -.TP -.B \-Z -Zero global statistics held in the kernel for filtering only (this doesn't -affect fragment or state statistics). -.DT -.SH SEE ALSO -ipfstat(1), ipftest(1), ipf(5), mkfilters(1) -.SH DIAGNOSTICS -.PP -Needs to be run as root for the packet filtering lists to actually -be affected inside the kernel. -.SH BUGS -.PP -If you find any, please send email to me at darrenr@cyber.com.au diff --git a/contrib/ipfilter/man/ipnat.1 b/contrib/ipfilter/man/ipnat.1 deleted file mode 100644 index f24141546171..000000000000 --- a/contrib/ipfilter/man/ipnat.1 +++ /dev/null @@ -1,48 +0,0 @@ -.TH IPNAT 1 -.SH NAME -ipnat \- user interface to the NAT -.SH SYNOPSIS -.B ipnat -[ -.B \-lnrsvCF -] -.B \-f <\fIfilename\fP> -.SH DESCRIPTION -.PP -\fBipnat\fP opens the filename given (treating "\-" as stdin) and parses the -file for a set of rules which are to be added or removed from the IP NAT. -.PP -Each rule processed by \fBipnat\fP -is added to the kernels internal lists if there are no parsing problems. -Rules are added to the end of the internal lists, matching the order in -which they appear when given to \fBipnat\fP. -.SH OPTIONS -.TP -.B \-C -delete all entries in the current NAT rule listing (NAT rules) -.TP -.B \-F -delete all active entries in the current NAT translation table (currently -active NAT mappings) -.TP -.B \-l -Show the list of current NAT table entry mappings. -.TP -.B \-n -This flag (no-change) prevents \fBipf\fP from actually making any ioctl -calls or doing anything which would alter the currently running kernel. -.TP -.B \-s -Retrieve and display NAT statistics -.TP -.B \-r -Remove matching NAT rules rather than add them to the internal lists -.TP -.B \-v -Turn verbose mode on. Displays information relating to rule processing -and active rules/table entries. -.DT -.SH FILES -/dev/ipnat -.SH SEE ALSO -ipnat(5), ipf(8), ipfstat(8) diff --git a/contrib/ipfilter/man/man.sed b/contrib/ipfilter/man/man.sed deleted file mode 100644 index 0be8dab0dc7b..000000000000 --- a/contrib/ipfilter/man/man.sed +++ /dev/null @@ -1 +0,0 @@ -DF . Ä..– CVSD~MakefileDipf.1D€ipf.4Dipf.5D‚ diff --git a/contrib/ipfilter/misc.c b/contrib/ipfilter/misc.c deleted file mode 100644 index e39b98fd76f3..000000000000 --- a/contrib/ipfilter/misc.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#if (SOLARIS2 >= 7) -# define _SYS_VARARGS_H -# define _VARARGS_H -#endif -#if defined(__STDC__) -# include -#else -# include -#endif -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include -#include "ip_fil.h" -#include "ipf.h" -#include "ipt.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)misc.c 1.3 2/4/96 (C) 1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: misc.c,v 2.2.2.9 2002/12/06 11:40:27 darrenr Exp $"; -#endif - -extern int opts; - - -void printpacket(ip) -ip_t *ip; -{ - tcphdr_t *tcp; - u_short len; - - if (ip->ip_v == 4) - len = ntohs(ip->ip_len); - else if (ip->ip_v == 6) - len = ntohs(((u_short *)ip)[2]) + 40; - else - len = 0; - - if ((opts & OPT_HEX) == OPT_HEX) { - u_char *s; - int i; - - for (s = (u_char *)ip, i = 0; i < len; i++) { - printf("%02x", *s++ & 0xff); - if (len - i > 1) { - i++; - printf("%02x", *s++ & 0xff); - } - if (i + 1 != len) - putchar(' '); - } - putchar('\n'); - return; - } - - if (ip->ip_v == 6) { - printpacket6(ip); - return; - } - - tcp = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2)); - printf("ip %d(%d) %d", ntohs(ip->ip_len), ip->ip_hl << 2, ip->ip_p); - if (ip->ip_off & IP_OFFMASK) - printf(" @%d", ip->ip_off << 3); - (void)printf(" %s", inet_ntoa(ip->ip_src)); - if (!(ip->ip_off & IP_OFFMASK)) - if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) - (void)printf(",%d", ntohs(tcp->th_sport)); - (void)printf(" > "); - (void)printf("%s", inet_ntoa(ip->ip_dst)); - if (!(ip->ip_off & IP_OFFMASK)) { - if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP) - (void)printf(",%d", ntohs(tcp->th_dport)); - if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags)) { - putchar(' '); - if (tcp->th_flags & TH_FIN) - putchar('F'); - if (tcp->th_flags & TH_SYN) - putchar('S'); - if (tcp->th_flags & TH_RST) - putchar('R'); - if (tcp->th_flags & TH_PUSH) - putchar('P'); - if (tcp->th_flags & TH_ACK) - putchar('A'); - if (tcp->th_flags & TH_URG) - putchar('U'); - if (tcp->th_flags & TH_ECN) - putchar('E'); - if (tcp->th_flags & TH_CWR) - putchar('C'); - } - } - putchar('\n'); -} - - -/* - * This is meant to work without the IPv6 header files being present or - * the inet_ntop() library. - */ -void printpacket6(ip) -ip_t *ip; -{ - u_char *buf, p, hops; - u_short plen, *addrs; - tcphdr_t *tcp; - u_32_t flow; - - buf = (u_char *)ip; - tcp = (tcphdr_t *)(buf + 40); - p = buf[6]; - hops = buf[7]; - flow = ntohl(*(u_32_t *)buf); - flow &= 0xfffff; - plen = ntohs(*((u_short *)buf +2)); - addrs = (u_short *)buf + 4; - - printf("ip6/%d %d %#x %d", buf[0] & 0xf, plen, flow, p); - printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), - ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), - ntohs(addrs[6]), ntohs(addrs[7])); - if (plen >= 4) - if (p == IPPROTO_TCP || p == IPPROTO_UDP) - (void)printf(",%d", ntohs(tcp->th_sport)); - printf(" >"); - addrs += 8; - printf(" %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - ntohs(addrs[0]), ntohs(addrs[1]), ntohs(addrs[2]), - ntohs(addrs[3]), ntohs(addrs[4]), ntohs(addrs[5]), - ntohs(addrs[6]), ntohs(addrs[7])); - if (plen >= 4) - if (p == IPPROTO_TCP || p == IPPROTO_UDP) - (void)printf(",%d", ntohs(tcp->th_dport)); - putchar('\n'); -} - - -#if defined(__STDC__) -void verbose(char *fmt, ...) -#else -void verbose(fmt, va_alist) -char *fmt; -va_dcl -#endif -{ - va_list pvar; - - va_start(pvar, fmt); - if (opts & OPT_VERBOSE) - vprintf(fmt, pvar); - va_end(pvar); -} - - -#ifdef __STDC__ -void debug(char *fmt, ...) -#else -void debug(fmt, va_alist) -char *fmt; -va_dcl -#endif -{ - va_list pvar; - - va_start(pvar, fmt); - if (opts & OPT_DEBUG) - vprintf(fmt, pvar); - va_end(pvar); -} diff --git a/contrib/ipfilter/ml_ipl.c b/contrib/ipfilter/ml_ipl.c deleted file mode 100644 index 4db9a9b06722..000000000000 --- a/contrib/ipfilter/ml_ipl.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * responsibility and is not changed in any way. - * - * I hate legaleese, don't you ? - */ -/* - * 29/12/94 Added code from Marc Huber to allow it to allocate - * its own major char number! Way cool patch! - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(sun4c) || defined(sun4m) -#include -#endif - -#ifndef IPL_NAME -#define IPL_NAME "/dev/ipl" -#endif - -extern int iplattach(), iplopen(), iplclose(), iplioctl(), iplread(); -extern int nulldev(), iplidentify(), errno; - -struct cdevsw ipldevsw = -{ - iplopen, iplclose, iplread, nulldev, - iplioctl, nulldev, nulldev, nulldev, - 0, nulldev, -}; - - -struct dev_ops ipl_ops = -{ - 1, - iplidentify, - iplattach, - iplopen, - iplclose, - iplread, - NULL, /* write */ - NULL, /* strategy */ - NULL, /* dump */ - 0, /* psize */ - iplioctl, - NULL, /* reset */ - NULL /* mmap */ -}; - -int ipl_major = 0; - -#ifdef sun4m -struct vdldrv vd = -{ - VDMAGIC_PSEUDO, - "ipl", - &ipl_ops, - NULL, - &ipldevsw, - 0, - 0, - NULL, - NULL, - NULL, - 0, - 1, -}; -#else /* sun4m */ -struct vdldrv vd = -{ - VDMAGIC_PSEUDO, /* magic */ - "ipl", /* name */ -#ifdef sun4c - &ipl_ops, /* dev_ops */ -#else - NULL, /* struct mb_ctlr *mb_ctlr */ - NULL, /* struct mb_driver *mb_driver */ - NULL, /* struct mb_device *mb_device */ - 0, /* num ctlrs */ - 1, /* numdevs */ -#endif /* sun4c */ - NULL, /* bdevsw */ - &ipldevsw, /* cdevsw */ - 0, /* block major */ - 0, /* char major */ -}; -#endif /* sun4m */ - -extern int vd_unuseddev(); -extern struct cdevsw cdevsw[]; -extern int nchrdev; - -xxxinit(fc, vdp, vdi, vds) -u_int fc; -struct vddrv *vdp; -caddr_t vdi; -struct vdstat *vds; -{ - struct vdlinkage *v; - int i; - - switch (fc) - { - case VDLOAD: - while (ipl_major < nchrdev && - cdevsw[ipl_major].d_open != vd_unuseddev) - ipl_major++; - if (ipl_major == nchrdev) - return ENODEV; - vd.Drv_charmajor = ipl_major; - vdp->vdd_vdtab = (struct vdlinkage *)&vd; - return ipl_attach(vdi); - case VDUNLOAD: - return unload(vdp, vdi); - - case VDSTAT: - return 0; - - default: - return EIO; - } -} - -static unload(vdp, vdi) - struct vddrv *vdp; - struct vdioctl_unload *vdi; -{ - int i; - - (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); - return ipldetach(); -} - - -static int ipl_attach(vdi) -struct vdioctl_load *vdi; -{ - struct vnode *vp; - struct vattr vattr; - int error = 0, fmode = S_IFCHR|0600; - - (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); - vattr_null(&vattr); - vattr.va_type = MFTOVT(fmode); - vattr.va_mode = (fmode & 07777); - vattr.va_rdev = ipl_major<<8; - - error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); - if (error == 0) - VN_RELE(vp); - return iplattach(0); -} diff --git a/contrib/ipfilter/mlf_ipl.c b/contrib/ipfilter/mlf_ipl.c deleted file mode 100644 index b39a14d0d877..000000000000 --- a/contrib/ipfilter/mlf_ipl.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* - * 29/12/94 Added code from Marc Huber to allow it to allocate - * its own major char number! Way cool patch! - */ - - -#include - -#ifdef IPFILTER_LKM -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -# define ACTUALLY_LKM_NOT_KERNEL -#else -# ifndef __FreeBSD_cc_version -# include -# else -# if __FreeBSD_cc_version < 430000 -# include -# endif -# endif -#endif -#include -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) -# ifndef ACTUALLY_LKM_NOT_KERNEL -# include "opt_devfs.h" -# endif -# include -# include -# ifdef DEVFS -# include -# endif /*DEVFS*/ -#endif -#include -#include -#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if BSD >= 199506 -# include -#endif -#if (__FreeBSD_version >= 300000) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "netinet/ipl.h" -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_state.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_auth.h" -#include "netinet/ip_frag.h" - - -#if !defined(VOP_LEASE) && defined(LEASE_CHECK) -#define VOP_LEASE LEASE_CHECK -#endif - -int xxxinit __P((struct lkm_table *, int, int)); - -#ifdef SYSCTL_OID -int sysctl_ipf_int SYSCTL_HANDLER_ARGS; -# define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ - ptr, val, sysctl_ipf_int, "I", descr); -# define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ -# define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) -SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, - &fr_tcpidletimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, - &fr_tcphalfclosed, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, - &fr_tcpclosewait, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, - &fr_tcplastack, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, - &fr_tcptimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, - &fr_tcpclosed, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, - &fr_udptimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, - &fr_icmptimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, - &fr_defnatage, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, - &fr_ipfrttl, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, - &fr_running, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, - &fr_statesize, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, - &fr_statemax, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, - &fr_authsize, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, - &fr_authused, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, - &fr_defaultauthage, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ippr_ftp_pasvonly, CTLFLAG_RW, - &ippr_ftp_pasvonly, 0, ""); -#endif - -#ifdef DEVFS -static void *ipf_devfs[IPL_LOGSIZE]; -#endif - -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) -int ipl_major = 0; - -static struct cdevsw ipldevsw = -{ - iplopen, /* open */ - iplclose, /* close */ - iplread, /* read */ - (void *)nullop, /* write */ - iplioctl, /* ioctl */ - (void *)nullop, /* stop */ - (void *)nullop, /* reset */ - (void *)NULL, /* tty */ - (void *)nullop, /* select */ - (void *)nullop, /* mmap */ - NULL /* strategy */ -}; - -MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); - -extern struct cdevsw cdevsw[]; -extern int vd_unuseddev __P((void)); -extern int nchrdev; -#else - -static struct cdevsw ipl_cdevsw = { - iplopen, iplclose, iplread, nowrite, /* 79 */ - iplioctl, nostop, noreset, nodevtotty, -#if (__FreeBSD_version >= 300000) - seltrue, nommap, nostrategy, "ipl", -#else - noselect, nommap, nostrategy, "ipl", -#endif - NULL, -1 -}; -#endif - -static void ipl_drvinit __P((void *)); - -#ifdef ACTUALLY_LKM_NOT_KERNEL -static int if_ipl_unload __P((struct lkm_table *, int)); -static int if_ipl_load __P((struct lkm_table *, int)); -static int if_ipl_remove __P((void)); -static int ipl_major = CDEV_MAJOR; - -static int iplaction __P((struct lkm_table *, int)); -static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, - IPL_SCAN, IPL_SYNC, IPL_POOL, NULL }; - -extern int lkmenodev __P((void)); - -static int iplaction(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) - int i = ipl_major; - struct lkm_dev *args = lkmtp->private.lkm_dev; -#endif - int err = 0; - - switch (cmd) - { - case LKM_E_LOAD : - if (lkmexists(lkmtp)) - return EEXIST; - -#if !defined(__FreeBSD_version) || (__FreeBSD_version < 220000) - for (i = 0; i < nchrdev; i++) - if (cdevsw[i].d_open == lkmenodev || - cdevsw[i].d_open == iplopen) - break; - if (i == nchrdev) { - printf("IP Filter: No free cdevsw slots\n"); - return ENODEV; - } - - ipl_major = i; - args->lkm_offset = i; /* slot in cdevsw[] */ -#endif - printf("IP Filter: loaded into slot %d\n", ipl_major); - err = if_ipl_load(lkmtp, cmd); - if (!err) - ipl_drvinit((void *)NULL); - return err; - break; - case LKM_E_UNLOAD : - err = if_ipl_unload(lkmtp, cmd); - if (!err) { - printf("IP Filter: unloaded from slot %d\n", - ipl_major); -#ifdef DEVFS - if (ipf_devfs[IPL_LOGIPF]) - devfs_remove_dev(ipf_devfs[IPL_LOGIPF]); - if (ipf_devfs[IPL_LOGNAT]) - devfs_remove_dev(ipf_devfs[IPL_LOGNAT]); - if (ipf_devfs[IPL_LOGSTATE]) - devfs_remove_dev(ipf_devfs[IPL_LOGSTATE]); - if (ipf_devfs[IPL_LOGAUTH]) - devfs_remove_dev(ipf_devfs[IPL_LOGAUTH]); - if (ipf_devfs[IPL_LOGSCAN]) - devfs_remove_dev(ipf_devfs[IPL_LOGSCAN]); - if (ipf_devfs[IPL_LOGSYNC]) - devfs_remove_dev(ipf_devfs[IPL_LOGSYNC]); - if (ipf_devfs[IPL_LOGLOOKUP]) - devfs_remove_dev(ipf_devfs[IPL_LOGLOOKUP]); -#endif - } - return err; - case LKM_E_STAT : - break; - default: - err = EIO; - break; - } - return 0; -} - - -static int if_ipl_remove __P((void)) -{ - char *name; - struct nameidata nd; - int error, i; - - for (i = 0; (name = ipf_devfiles[i]); i++) { - NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); - if ((error = namei(&nd))) - return (error); - VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); -#if (__FreeBSD_version >= 300000) - VOP_LOCK(nd.ni_vp, LK_RETRY | LK_EXCLUSIVE, curproc); - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); - - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - if (nd.ni_vp != NULLVP) - vput(nd.ni_vp); -#else - VOP_LOCK(nd.ni_vp); - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); -#endif - } - - return 0; -} - - -static int if_ipl_unload(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ - int error = 0; - - error = ipldetach(); - if (!error) - error = if_ipl_remove(); - return error; -} - - -static int if_ipl_load(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ - struct nameidata nd; - struct vattr vattr; - int error = 0, fmode = S_IFCHR|0600, i; - char *name; - - error = iplattach(); - if (error) - return error; - (void) if_ipl_remove(); - - for (i = 0; (name = ipf_devfiles[i]); i++) { - NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); - if ((error = namei(&nd))) - return error; - if (nd.ni_vp != NULL) { - VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - vrele(nd.ni_vp); - return (EEXIST); - } - VATTR_NULL(&vattr); - vattr.va_type = VCHR; - vattr.va_mode = (fmode & 07777); - vattr.va_rdev = (ipl_major << 8) | i; - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); -#if (__FreeBSD_version >= 300000) - vput(nd.ni_dvp); -#endif - if (error) - return error; - } - return 0; -} - -#endif /* actually LKM */ - -#if defined(__FreeBSD_version) && (__FreeBSD_version < 220000) -/* - * strlen isn't present in 2.1.* kernels. - */ -size_t strlen(string) -char *string; -{ - register char *s; - - for (s = string; *s; s++) - ; - return (size_t)(s - string); -} - - -int xxxinit(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; -{ - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); -} -#else /* __FREEBSD_version >= 220000 */ -# ifdef IPFILTER_LKM -# include - -# if (__FreeBSD_version >= 300000) -MOD_DEV(if_ipl, LM_DT_CHAR, CDEV_MAJOR, &ipl_cdevsw); -# else -MOD_DECL(if_ipl); - - -static struct lkm_dev _module = { - LM_DEV, - LKM_VERSION, - IPL_VERSION, - CDEV_MAJOR, - LM_DT_CHAR, - { (void *)&ipl_cdevsw } -}; -# endif - - -int if_ipl __P((struct lkm_table *, int, int)); - - -int if_ipl(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd, ver; -{ -# if (__FreeBSD_version >= 300000) - MOD_DISPATCH(if_ipl, lkmtp, cmd, ver, iplaction, iplaction, iplaction); -# else - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); -# endif -} -# endif /* IPFILTER_LKM */ -static ipl_devsw_installed = 0; - -static void ipl_drvinit __P((void *unused)) -{ - dev_t dev; -# ifdef DEVFS - void **tp = ipf_devfs; -# endif - - if (!ipl_devsw_installed ) { - dev = makedev(CDEV_MAJOR, 0); - cdevsw_add(&dev, &ipl_cdevsw, NULL); - ipl_devsw_installed = 1; - -# ifdef DEVFS - tp[IPL_LOGIPF] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGIPF, - DV_CHR, 0, 0, 0600, "ipf"); - tp[IPL_LOGNAT] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGNAT, - DV_CHR, 0, 0, 0600, "ipnat"); - tp[IPL_LOGSTATE] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGSTATE, - DV_CHR, 0, 0, 0600, - "ipstate"); - tp[IPL_LOGAUTH] = devfs_add_devswf(&ipl_cdevsw, IPL_LOGAUTH, - DV_CHR, 0, 0, 0600, - "ipauth"); -# endif - } -} - - -#ifdef SYSCTL_IPF -int -sysctl_ipf_int SYSCTL_HANDLER_ARGS -{ - int error = 0; - - if (arg1) - error = SYSCTL_OUT(req, arg1, sizeof(int)); - else - error = SYSCTL_OUT(req, &arg2, sizeof(int)); - - if (error || !req->newptr) - return (error); - - if (!arg1) - error = EPERM; - else { - if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0)) - error = EBUSY; - else - error = SYSCTL_IN(req, arg1, sizeof(int)); - } - return (error); -} -#endif - - -# if defined(IPFILTER_LKM) || \ - defined(__FreeBSD_version) && (__FreeBSD_version >= 220000) -SYSINIT(ipldev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,ipl_drvinit,NULL) -# endif /* IPFILTER_LKM */ -#endif /* _FreeBSD_version */ diff --git a/contrib/ipfilter/mlfk_ipl.c b/contrib/ipfilter/mlfk_ipl.c deleted file mode 100644 index 0f50feab0f59..000000000000 --- a/contrib/ipfilter/mlfk_ipl.c +++ /dev/null @@ -1,271 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 2000 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include - -#if __FreeBSD_version >= 502116 -static struct cdev *ipf_devs[IPL_LOGSIZE]; -#else -static dev_t ipf_devs[IPL_LOGSIZE]; -#endif - -static int sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ); -static int ipf_modload(void); -static int ipf_modunload(void); - -SYSCTL_DECL(_net_inet); -#define SYSCTL_IPF(parent, nbr, name, access, ptr, val, descr) \ - SYSCTL_OID(parent, nbr, name, CTLTYPE_INT|access, \ - ptr, val, sysctl_ipf_int, "I", descr); -#define CTLFLAG_OFF 0x00800000 /* IPFilter must be disabled */ -#define CTLFLAG_RWO (CTLFLAG_RW|CTLFLAG_OFF) -SYSCTL_NODE(_net_inet, OID_AUTO, ipf, CTLFLAG_RW, 0, "IPF"); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_flags, CTLFLAG_RW, &fr_flags, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_pass, CTLFLAG_RW, &fr_pass, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_active, CTLFLAG_RD, &fr_active, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpidletimeout, CTLFLAG_RWO, - &fr_tcpidletimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcphalfclosed, CTLFLAG_RWO, - &fr_tcphalfclosed, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosewait, CTLFLAG_RWO, - &fr_tcpclosewait, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcplastack, CTLFLAG_RWO, - &fr_tcplastack, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcptimeout, CTLFLAG_RWO, - &fr_tcptimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_tcpclosed, CTLFLAG_RWO, - &fr_tcpclosed, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udptimeout, CTLFLAG_RWO, - &fr_udptimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_udpacktimeout, CTLFLAG_RWO, - &fr_udpacktimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_icmptimeout, CTLFLAG_RWO, - &fr_icmptimeout, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defnatage, CTLFLAG_RWO, - &fr_defnatage, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_ipfrttl, CTLFLAG_RW, - &fr_ipfrttl, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_running, CTLFLAG_RD, - &fr_running, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statesize, CTLFLAG_RWO, - &fr_statesize, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_statemax, CTLFLAG_RWO, - &fr_statemax, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_nattable_sz, CTLFLAG_RWO, - &ipf_nattable_sz, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_natrules_sz, CTLFLAG_RWO, - &ipf_natrules_sz, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_rdrrules_sz, CTLFLAG_RWO, - &ipf_rdrrules_sz, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, ipf_hostmap_sz, CTLFLAG_RWO, - &ipf_hostmap_sz, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authsize, CTLFLAG_RWO, - &fr_authsize, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_authused, CTLFLAG_RD, - &fr_authused, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_defaultauthage, CTLFLAG_RW, - &fr_defaultauthage, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_chksrc, CTLFLAG_RW, &fr_chksrc, 0, ""); -SYSCTL_IPF(_net_inet_ipf, OID_AUTO, fr_minttl, CTLFLAG_RW, &fr_minttl, 0, ""); - -#define CDEV_MAJOR 79 -#if __FreeBSD_version >= 501000 -static struct cdevsw ipl_cdevsw = { -#if __FreeBSD_version >= 502103 - .d_version = D_VERSION, - .d_flags = 0, /* D_NEEDGIANT - Should be SMP safe */ -#endif - .d_open = iplopen, - .d_close = iplclose, - .d_read = iplread, - .d_ioctl = iplioctl, - .d_name = "ipl", - .d_maj = CDEV_MAJOR, -}; -#else -static struct cdevsw ipl_cdevsw = { - /* open */ iplopen, - /* close */ iplclose, - /* read */ iplread, - /* write */ iplwrite, - /* ioctl */ iplioctl, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ nostrategy, - /* name */ "ipl", - /* maj */ CDEV_MAJOR, - /* dump */ nodump, - /* psize */ nopsize, - /* flags */ 0, -# if (__FreeBSD_version < 500043) - /* bmaj */ -1, -# endif - /* kqfilter */ NULL -}; -#endif - -static char *ipf_devfiles[] = { IPL_NAME, IPNAT_NAME, IPSTATE_NAME, IPAUTH_NAME, - IPSYNC_NAME, IPSCAN_NAME, IPLOOKUP_NAME, NULL }; - - -static int -ipfilter_modevent(module_t mod, int type, void *unused) -{ - int error = 0; - - switch (type) - { - case MOD_LOAD : - error = ipf_modload(); - break; - - case MOD_UNLOAD : - error = ipf_modunload(); - break; - default: - error = EINVAL; - break; - } - return error; -} - - -static int -ipf_modload() -{ - char *defpass, *c, *str; - int i, j, error; - - error = iplattach(); - if (error) - return error; - - for (i = 0; i < IPL_LOGSIZE; i++) - ipf_devs[i] = NULL; - - for (i = 0; (str = ipf_devfiles[i]); i++) { - c = NULL; - for(j = strlen(str); j > 0; j--) - if (str[j] == '/') { - c = str + j + 1; - break; - } - if (!c) - c = str; - ipf_devs[i] = make_dev(&ipl_cdevsw, i, 0, 0, 0600, c); - } - - if (FR_ISPASS(fr_pass)) - defpass = "pass"; - else if (FR_ISBLOCK(fr_pass)) - defpass = "block"; - else - defpass = "no-match -> block"; - - printf("%s initialized. Default = %s all, Logging = %s%s\n", - ipfilter_version, defpass, -#ifdef IPFILTER_LOG - "enabled", -#else - "disabled", -#endif -#ifdef IPFILTER_COMPILED - " (COMPILED)" -#else - "" -#endif - ); - return 0; -} - - -static int -ipf_modunload() -{ - int error, i; - - if (fr_refcnt) - return EBUSY; - - if (fr_running >= 0) { - error = ipldetach(); - if (error != 0) - return error; - } else - error = 0; - - fr_running = -2; - - for (i = 0; ipf_devfiles[i]; i++) { - if (ipf_devs[i] != NULL) - destroy_dev(ipf_devs[i]); - } - - printf("%s unloaded\n", ipfilter_version); - - return error; -} - - -static moduledata_t ipfiltermod = { - "ipfilter", - ipfilter_modevent, - 0 -}; - - -DECLARE_MODULE(ipfilter, ipfiltermod, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY); -#ifdef MODULE_VERSION -MODULE_VERSION(ipfilter, 1); -#endif - - -#ifdef SYSCTL_IPF -int -sysctl_ipf_int ( SYSCTL_HANDLER_ARGS ) -{ - int error = 0; - - if (arg1) - error = SYSCTL_OUT(req, arg1, sizeof(int)); - else - error = SYSCTL_OUT(req, &arg2, sizeof(int)); - - if (error || !req->newptr) - return (error); - - if (!arg1) - error = EPERM; - else { - if ((oidp->oid_kind & CTLFLAG_OFF) && (fr_running > 0)) - error = EBUSY; - else - error = SYSCTL_IN(req, arg1, sizeof(int)); - } - return (error); -} -#endif diff --git a/contrib/ipfilter/mlh_rule.c b/contrib/ipfilter/mlh_rule.c deleted file mode 100644 index e71c7be1c0b7..000000000000 --- a/contrib/ipfilter/mlh_rule.c +++ /dev/null @@ -1,114 +0,0 @@ -/* $NetBSD$ */ - -/* - * Copyright (C) 1993-1998 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - */ -/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ - -/*typedef unsigned int spustate_t;*/ -struct uio; - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ip_compat.h" -#include "ip_fil.h" -#include "ip_rules.h" - - -/* - * Driver Header - */ -static drv_info_t ipf_drv_info = { - "IP Filter Rules", /* type */ - "pseudo", /* class */ - DRV_PSEUDO|DRV_SAVE_CONF|DRV_MP_SAFE, /* flags */ - -1, /* b_major */ - -1, /* c_major */ - NULL, /* cdio */ - NULL, /* gio_private */ - NULL, /* cdio_private */ -}; - - -extern struct mod_operations gio_mod_ops; -static drv_info_t ipf_drv_info; -extern struct mod_conf_data ipf_conf_data; - -static struct mod_type_data ipf_drv_link = { - IPL_VERSION, (void *)NULL -}; - -static struct modlink ipf_mod_link[] = { - { &gio_mod_ops, (void *)&ipf_drv_link }, - { NULL, (void *)NULL } -}; - -struct modwrapper ipf_wrapper = { - MODREV, - ipf_load, - ipf_unload, - (void (*)())NULL, - (void *)&ipf_conf_data, - ipf_mod_link -}; - - -static int ipf_load(void *arg) -{ - int i; - - i = ipfrule_add(); - if (!i) - fr_refcnt--; -#ifdef IPFDEBUG - printf("IP Filter Rules: ipfrule_add() = %d\n", i); -#endif - if (!i) - cmn_err(CE_CONT, "IP Filter Rules: Loaded\n"); - return i; -} - - -static int ipf_unload(void *arg) -{ - int i; - - i = ipfrule_remove(); - if (!i) - fr_refcnt--; -#ifdef IPFDEBUG - printf("IP Filter Rules: ipfrule_remove() = %d\n", i); -#endif - if (!i) - cmn_err(CE_CONT, "IP Filter Rules: Unloaded\n"); - return i; -} diff --git a/contrib/ipfilter/mli_ipl.c b/contrib/ipfilter/mli_ipl.c deleted file mode 100644 index 235a5af21f17..000000000000 --- a/contrib/ipfilter/mli_ipl.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * (C)opyright 1997 by Marc Boucher. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ - -/* TODO: (MARCXXX) - - ipl_init failure -> open ENODEV or whatever - - prevent multiple LKM loads - - surround access to ifnet structures by IFNET_LOCK()/IFNET_UNLOCK() ? - - m != m1 problem -*/ - -#include -#include -#ifdef IPFILTER_LKM -#include -#endif -#include -#include -#include -#include -#include -#ifdef IFF_DRVRLOCK /* IRIX6 */ -#include -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ipl.h" -#include "ip_compat.h" -#include "ip_fil.h" -#include "ip_nat.h" - -/*#define IPFDEBUG 1*/ - -unsigned IPL_EXTERN(devflag) = D_MP; -#ifdef IPFILTER_LKM -char *IPL_EXTERN(mversion) = M_VERSION; -#endif - -kmutex_t ipl_mutex, ipf_mutex, ipfi_mutex, ipf_rw; -kmutex_t ipf_frag, ipf_state, ipf_nat, ipf_natfrag, ipf_auth; - -int (*fr_checkp) __P((struct ip *, int, void *, int, mb_t **)); - -#ifdef IPFILTER_LKM -static int *ipff_addr = 0; -static int ipff_value; -static __psunsigned_t *ipfk_addr = 0; -static __psunsigned_t ipfk_code[4]; -#endif - -typedef struct nif { - struct nif *nf_next; - struct ifnet *nf_ifp; -#if IRIX < 605 - int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *); -#else - int (*nf_output)(struct ifnet *, struct mbuf *, struct sockaddr *, - struct rtentry *); -#endif - char nf_name[IFNAMSIZ]; - int nf_unit; -} nif_t; - -static nif_t *nif_head = 0; -static int nif_interfaces = 0; -extern int in_interfaces; - -extern ipnat_t *nat_list; - -static int -#if IRIX < 605 -ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst) -#else -ipl_if_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, - struct rtentry *rt) -#endif -{ - nif_t *nif; - - MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ - for (nif = nif_head; nif; nif = nif->nf_next) - if (nif->nf_ifp == ifp) - break; - - MUTEX_EXIT(&ipfi_mutex); - if (!nif) { - printf("IP Filter: ipl_if_output intf %x NOT FOUND\n", ifp); - return ENETDOWN; - } - -#if IPFDEBUG >= 4 - static unsigned int cnt = 0; - if ((++cnt % 200) == 0) - printf("IP Filter: ipl_if_output(ifp=0x%lx, m=0x%lx, dst=0x%lx), m_type=%d m_flags=0x%lx m_off=0x%lx\n", ifp, m, dst, m->m_type, (unsigned long)(m->m_flags), m->m_off); -#endif - if (fr_checkp) { - struct mbuf *m1 = m; - struct ip *ip; - int hlen; - - switch(m->m_type) { - case MT_DATA: - if (m->m_flags & M_BCAST) { -#if IPFDEBUG >= 2 - printf("IP Filter: ipl_if_output: passing M_BCAST\n"); -#endif - break; - } - /* FALLTHROUGH */ - case MT_HEADER: -#if IPFDEBUG >= 4 - if (!MBUF_IS_CLUSTER(m) && ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) { - printf("IP Filter: ipl_if_output: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off); - goto done; - } -#endif - if (m->m_len < sizeof(char)) { - printf("IP Filter: ipl_if_output: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (unsigned long)(m->m_flags)); - goto done; - } - ip = mtod(m, struct ip *); - if (ip->ip_v != IPVERSION) { -#if IPFDEBUG >= 4 - printf("IP Filter: ipl_if_output: bad ip_v m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off); -#endif - goto done; - } - - hlen = ip->ip_hl << 2; - if ((*fr_checkp)(ip, hlen, ifp, 1, &m1)) - return EHOSTUNREACH; - - if (!m1) - return 0; - - m = m1; - break; - - default: - printf("IP Filter: ipl_if_output: bad m_type=%d m_flags=0x%lxm_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off); - break; - } - } -done: -#if IRIX < 605 - return (*nif->nf_output)(ifp, m, dst); -#else - return (*nif->nf_output)(ifp, m, dst, rt); -#endif -} - -int -IPL_EXTERN(_kernel)(struct ifnet *rcvif, struct mbuf *m) -{ -#if IPFDEBUG >= 4 - static unsigned int cnt = 0; - if ((++cnt % 200) == 0) - printf("IP Filter: ipl_ipfilter_kernel(rcvif=0x%lx, m=0x%lx\n", rcvif, m); -#endif - - /* - * Check if we want to allow this packet to be processed. - * Consider it to be bad if not. - */ - if (fr_checkp) { - struct mbuf *m1 = m; - struct ip *ip; - int hlen; - - if ((m->m_type != MT_DATA) && (m->m_type != MT_HEADER)) { - printf("IP Filter: ipl_ipfilter_kernel: bad m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off); - return IPF_ACCEPTIT; - } - -#if IPFDEBUG >= 4 - if (!MBUF_IS_CLUSTER(m) && ((m->m_off < MMINOFF) || (m->m_off > MMAXOFF))) { - printf("IP Filter: ipl_ipfilter_kernel: bad m_off m_type=%d m_flags=0x%lx m_off=0x%lx\n", m->m_type, (unsigned long)(m->m_flags), m->m_off); - return IPF_ACCEPTIT; - } -#endif - if (m->m_len < sizeof(char)) { - printf("IP Filter: ipl_ipfilter_kernel: mbuf block too small (m_len=%d) for IP vers+hlen, m_type=%d m_flags=0x%lx\n", m->m_len, m->m_type, (unsigned long)(m->m_flags)); - return IPF_ACCEPTIT; - } - ip = mtod(m, struct ip *); - if (ip->ip_v != IPVERSION) { - printf("IP Filter: ipl_ipfilter_kernel: bad ip_v\n"); - m_freem(m); - return IPF_DROPIT; - } - - hlen = ip->ip_hl << 2; - if ((*fr_checkp)(ip, hlen, rcvif, 0, &m1) || !m1) - return IPF_DROPIT; - if (m != m1) - printf("IP Filter: ipl_ipfilter_kernel: m != m1\n"); - } - - return IPF_ACCEPTIT; -} - -static int -ipfilterattach(void) -{ -#ifdef IPFILTER_LKM - __psunsigned_t *addr_ff, *addr_fk; - - st_findaddr("ipfilterflag", &addr_ff); -#if IPFDEBUG >= 4 - printf("IP Filter: st_findaddr ipfilterflag=0x%lx\n", addr_ff); -#endif - if (!addr_ff) - return ESRCH; - - st_findaddr("ipfilter_kernel", &addr_fk); -#if IPFDEBUG >= 4 - printf("IP Filter: st_findaddr ipfilter_kernel=0x%lx\n", addr_fk); -#endif - if (!addr_fk) - return ESRCH; - - MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ - - ipff_addr = (int *)addr_ff; - - ipff_value = *ipff_addr; - *ipff_addr = 0; - - - ipfk_addr = addr_fk; - - bcopy(ipfk_addr, ipfk_code, - sizeof(ipfk_code)); - - /* write a "li t4, ipl_ipfilter_kernel" instruction */ - ipfk_addr[0] = 0x3c0c0000 | - (((__psunsigned_t)IPL_EXTERN(_kernel) >> 16) & 0xffff); - ipfk_addr[1] = 0x358c0000 | - ((__psunsigned_t)IPL_EXTERN(_kernel) & 0xffff); - /* write a "jr t4" instruction" */ - ipfk_addr[2] = 0x01800008; - - /* write a "nop" instruction */ - ipfk_addr[3] = 0; - - icache_inval(ipfk_addr, sizeof(ipfk_code)); - - *ipff_addr = 1; /* enable ipfilter_kernel */ - - MUTEX_EXIT(&ipfi_mutex); -#else - extern int ipfilterflag; - - ipfilterflag = 1; -#endif - - return 0; -} - -/* - * attach the packet filter to each non-loopback interface that is running - */ -static void -nifattach() -{ - struct ifnet *ifp; - struct frentry *f; - ipnat_t *np; - nif_t *nif; - - MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ - - for (ifp = ifnet; ifp; ifp = ifp->if_next) { - if ((!(ifp->if_flags & IFF_RUNNING)) || - (ifp->if_flags & IFF_LOOPBACK)) - continue; - - /* - * Look for entry already setup for this device - */ - for (nif = nif_head; nif; nif = nif->nf_next) - if (nif->nf_ifp == ifp) - break; - if (nif) - continue; - - if (ifp->if_output == ipl_if_output) { - printf("IP Filter: ERROR INTF 0x%lx STILL ATTACHED\n", - ifp); - continue; - } -#if IPFDEBUG >= 4 - printf("IP Filter: nifattach nif %x opt %x\n", - ifp, ifp->if_output); -#endif - KMALLOC(nif, nif_t *); - if (!nif) { - printf("IP Filter: malloc(%d) for nif_t failed\n", - sizeof(nif_t)); - continue; - } - - nif->nf_ifp = ifp; - strncpy(nif->nf_name, ifp->if_name, sizeof(nif->nf_name)); - nif->nf_name[sizeof(nif->nf_name) - 1] = '\0'; - nif->nf_unit = ifp->if_unit; - - nif->nf_next = nif_head; - nif_head = nif; - - /* - * Activate any rules directly associated with this interface - */ - MUTEX_ENTER(&ipf_mutex); - for (f = ipfilter[0][0]; f; f = f->fr_next) { - if ((f->fr_ifa == (struct ifnet *)-1)) { - if (f->fr_ifname[0] && - (GETUNIT(f->fr_ifname, 4) == ifp)) - f->fr_ifa = ifp; - } - } - for (f = ipfilter[1][0]; f; f = f->fr_next) { - if ((f->fr_ifa == (struct ifnet *)-1)) { - if (f->fr_ifname[0] && - (GETUNIT(f->fr_ifname, 4) == ifp)) - f->fr_ifa = ifp; - } - } - MUTEX_EXIT(&ipf_mutex); - MUTEX_ENTER(&ipf_nat); - for (np = nat_list; np; np = np->in_next) { - if ((np->in_ifp == (void *)-1)) { - if (np->in_ifname[0] && - (GETUNIT(np->in_ifname, 4) == ifp)) - np->in_ifp = (void *)ifp; - } - } - MUTEX_EXIT(&ipf_nat); - - nif->nf_output = ifp->if_output; - ifp->if_output = ipl_if_output; - -#if IPFDEBUG >= 4 - printf("IP Filter: nifattach: ifp(%lx)->if_output FROM %lx TO %lx\n", - ifp, nif->nf_output, ifp->if_output); -#endif - - printf("IP Filter: attach to [%s,%d]\n", - nif->nf_name, ifp->if_unit); - } - if (!nif_head) - printf("IP Filter: not attached to any interfaces\n"); - - nif_interfaces = in_interfaces; - - MUTEX_EXIT(&ipfi_mutex); - - return; -} - -/* - * look for bad consistancies between the list of interfaces the filter knows - * about and those which are currently configured. - */ -int -ipfsync(void) -{ - register struct frentry *f; - register ipnat_t *np; - register nif_t *nif, **qp; - register struct ifnet *ifp; - - MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ - for (qp = &nif_head; (nif = *qp); ) { - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if ((nif->nf_ifp == ifp) && - (nif->nf_unit == ifp->if_unit) && - !strcmp(nif->nf_name, ifp->if_name)) { - break; - } - if (ifp) { - qp = &nif->nf_next; - continue; - } - printf("IP Filter: detaching [%s]\n", nif->nf_name); - *qp = nif->nf_next; - - /* - * Disable any rules directly associated with this interface - */ - MUTEX_ENTER(&ipf_mutex); - for (f = ipfilter[0][0]; f; f = f->fr_next) - if (f->fr_ifa == (void *)nif->nf_ifp) - f->fr_ifa = (struct ifnet *)-1; - for (f = ipfilter[1][0]; f; f = f->fr_next) - if (f->fr_ifa == (void *)nif->nf_ifp) - f->fr_ifa = (struct ifnet *)-1; - MUTEX_EXIT(&ipf_mutex); - MUTEX_ENTER(&ipf_nat); - for (np = nat_list; np; np = np->in_next) - if (np->in_ifp == (void *)nif->nf_ifp) - np->in_ifp =(struct ifnet *)-1; - MUTEX_EXIT(&ipf_nat); - - KFREE(nif); - nif = *qp; - } - MUTEX_EXIT(&ipfi_mutex); - - nifattach(); - - return 0; -} - - -/* - * unhook the IP filter from all defined interfaces with IP addresses - */ -static void -nifdetach() -{ - struct ifnet *ifp; - nif_t *nif, **qp; - - MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ - /* - * Make two passes, first get rid of all the unknown devices, next - * unlink known devices. - */ - for (qp = &nif_head; (nif = *qp); ) { - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (nif->nf_ifp == ifp) - break; - if (ifp) { - qp = &nif->nf_next; - continue; - } - printf("IP Filter: removing [%s]\n", nif->nf_name); - *qp = nif->nf_next; - KFREE(nif); - } - - while ((nif = nif_head)) { - nif_head = nif->nf_next; - for (ifp = ifnet; ifp; ifp = ifp->if_next) - if (nif->nf_ifp == ifp) - break; - if (ifp) { - printf("IP Filter: detaching [%s,%d]\n", - nif->nf_name, ifp->if_unit); - -#if IPFDEBUG >= 4 - printf("IP Filter: nifdetach: ifp(%lx)->if_output FROM %lx TO %lx\n", - ifp, ifp->if_output, nif->nf_output); -#endif - ifp->if_output = nif->nf_output; - } - KFREE(nif); - } - MUTEX_EXIT(&ipfi_mutex); - - return; -} - - -static void -ipfilterdetach(void) -{ -#ifdef IPFILTER_LKM - MUTEX_ENTER(&ipfi_mutex); /* sets interrupt priority level to splhi */ - - if (ipff_addr) { - *ipff_addr = 0; - - if (ipfk_addr) - bcopy(ipfk_code, ipfk_addr, sizeof(ipfk_code)); - - *ipff_addr = ipff_value; - } - - MUTEX_EXIT(&ipfi_mutex); -#else - extern int ipfilterflag; - - ipfilterflag = 0; -#endif -} - -/* called by ipldetach() */ -void -ipfilter_sgi_detach(void) -{ - nifdetach(); - - ipfilterdetach(); -} - -/* called by iplattach() */ -int -ipfilter_sgi_attach(void) -{ - int error; - - nif_interfaces = 0; - - error = ipfilterattach(); - - if (!error) - nifattach(); - - return error; -} - -/* this function is called from ipfr_slowtimer at 500ms intervals to - keep our interface list in sync */ -void -ipfilter_sgi_intfsync(void) -{ - MUTEX_ENTER(&ipfi_mutex); - if (nif_interfaces != in_interfaces) { - /* if the number of interfaces has changed, resync */ - MUTEX_EXIT(&ipfi_mutex); - ipfsync(); - } else - MUTEX_EXIT(&ipfi_mutex); -} - -#ifdef IPFILTER_LKM -/* this routine should be treated as an interrupt routine and should - not call any routines that would cause it to sleep, such as: biowait(), - sleep(), psema() or delay(). -*/ -int -IPL_EXTERN(unload)(void) -{ - int error = 0; - - error = ipldetach(); - - LOCK_DEALLOC(ipl_mutex.l); - LOCK_DEALLOC(ipf_rw.l); - LOCK_DEALLOC(ipf_auth.l); - LOCK_DEALLOC(ipf_natfrag.l); - LOCK_DEALLOC(ipf_nat.l); - LOCK_DEALLOC(ipf_state.l); - LOCK_DEALLOC(ipf_frag.l); - LOCK_DEALLOC(ipf_mutex.l); - LOCK_DEALLOC(ipfi_mutex.l); - - return error; -} -#endif - -void -IPL_EXTERN(init)(void) -{ -#ifdef IPFILTER_LKM - int error; -#endif - - ipfi_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_frag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_state.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_nat.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_natfrag.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_auth.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipf_rw.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - ipl_mutex.l = LOCK_ALLOC((uchar_t)-1, IPF_LOCK_PL, (lkinfo_t *)-1, KM_NOSLEEP); - - if (!ipfi_mutex.l || !ipf_mutex.l || !ipf_frag.l || !ipf_state.l || - !ipf_nat.l || !ipf_natfrag.l || !ipf_auth.l || !ipf_rw.l || - !ipl_mutex.l) - panic("IP Filter: LOCK_ALLOC failed"); - -#ifdef IPFILTER_LKM - error = iplattach(); - if (error) { - IPL_EXTERN(unload)(); - } -#endif - - return; -} - diff --git a/contrib/ipfilter/mln_ipl.c b/contrib/ipfilter/mln_ipl.c deleted file mode 100644 index b170940e8921..000000000000 --- a/contrib/ipfilter/mln_ipl.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* - * 29/12/94 Added code from Marc Huber to allow it to allocate - * its own major char number! Way cool patch! - */ - - -#include - -/* - * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns - * on those hooks. We don't need any special mods with this! - */ -#if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \ - (defined(NetBSD1_2) && NetBSD1_2 > 1) -# define NETBSD_PF -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ipl.h" -#include "ip_compat.h" -#include "ip_fil.h" - -#if !defined(__NetBSD_Version__) || __NetBSD_Version__ < 103050000 -#define vn_lock(v,f) VOP_LOCK(v) -#endif - -#if !defined(VOP_LEASE) && defined(LEASE_CHECK) -#define VOP_LEASE LEASE_CHECK -#endif - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif - - -extern int lkmenodev __P((void)); - -#if (NetBSD >= 199706) || (defined(OpenBSD) && (OpenBSD >= 200211)) -int if_ipl_lkmentry __P((struct lkm_table *, int, int)); -#else -#if defined(OpenBSD) -int if_ipl __P((struct lkm_table *, int, int)); -#else -int xxxinit __P((struct lkm_table *, int, int)); -#endif -#endif -static int ipl_unload __P((void)); -static int ipl_load __P((void)); -static int ipl_remove __P((void)); -static int iplaction __P((struct lkm_table *, int)); -static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, - NULL }; - - -#if (defined(NetBSD1_0) && (NetBSD1_0 > 1)) || \ - (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199511)) -# if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) -extern const struct cdevsw ipl_cdevsw; -# else -struct cdevsw ipldevsw = -{ - iplopen, /* open */ - iplclose, /* close */ - iplread, /* read */ - 0, /* write */ - iplioctl, /* ioctl */ - 0, /* stop */ - 0, /* tty */ - 0, /* select */ - 0, /* mmap */ - NULL /* strategy */ -}; -# endif -#else -struct cdevsw ipldevsw = -{ - iplopen, /* open */ - iplclose, /* close */ - iplread, /* read */ - (void *)nullop, /* write */ - iplioctl, /* ioctl */ - (void *)nullop, /* stop */ -#ifndef OpenBSD - (void *)nullop, /* reset */ -#endif - (void *)NULL, /* tty */ - (void *)nullop, /* select */ - (void *)nullop, /* mmap */ - NULL /* strategy */ -}; -#endif -int ipl_major = 0; - -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) -MOD_DEV(IPL_VERSION, "ipl", NULL, -1, &ipl_cdevsw, -1); -#else -MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw); -#endif - -extern int vd_unuseddev __P((void)); -extern struct cdevsw cdevsw[]; -extern int nchrdev; - - -#if (NetBSD >= 199706) || (defined(OpenBSD) && (OpenBSD >= 200211)) -int if_ipl_lkmentry(lkmtp, cmd, ver) -#else -#if defined(OpenBSD) -int if_ipl(lkmtp, cmd, ver) -#else -int xxxinit(lkmtp, cmd, ver) -#endif -#endif -struct lkm_table *lkmtp; -int cmd, ver; -{ - DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction); -} - -#ifdef OpenBSD -int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */ -#endif - -static int iplaction(lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; -{ - struct lkm_dev *args = lkmtp->private.lkm_dev; - int err = 0; -#if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000) - int i; -#endif - - switch (cmd) - { - case LKM_E_LOAD : - if (lkmexists(lkmtp)) - return EEXIST; - -#if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000) - for (i = 0; i < nchrdev; i++) - if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev || - cdevsw[i].d_open == iplopen) - break; - if (i == nchrdev) { - printf("IP Filter: No free cdevsw slots\n"); - return ENODEV; - } - - ipl_major = i; - args->lkm_offset = i; /* slot in cdevsw[] */ -#else - err = devsw_attach(args->lkm_devname, - args->lkm_bdev, &args->lkm_bdevmaj, - args->lkm_cdev, &args->lkm_cdevmaj); - if (err != 0) - return (err); - ipl_major = args->lkm_cdevmaj; -#endif - printf("IP Filter: loaded into slot %d\n", ipl_major); - return ipl_load(); - case LKM_E_UNLOAD : -#if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000) - devsw_detach(args->lkm_bdev, args->lkm_cdev); - args->lkm_bdevmaj = -1; - args->lkm_cdevmaj = -1; -#endif - err = ipl_unload(); - if (!err) - printf("IP Filter: unloaded from slot %d\n", - ipl_major); - break; - case LKM_E_STAT : - break; - default: - err = EIO; - break; - } - return err; -} - - -static int ipl_remove() -{ - char *name; - struct nameidata nd; - int error, i; - - for (i = 0; (name = ipf_devfiles[i]); i++) { - NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc); - if ((error = namei(&nd))) - return (error); - VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE); -#ifdef OpenBSD - VOP_LOCK(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc); -#else -# if !defined(__NetBSD_Version__) || (__NetBSD_Version__ < 106000000) - vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY); -# endif -#endif - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); - } - return 0; -} - - -static int ipl_unload() -{ - int error = 0; - - /* - * Unloading - remove the filter rule check from the IP - * input/output stream. - */ -#if defined(__NetBSD__) - error = ipl_disable(); -#else - error = ipldetach(); -#endif - - if (!error) - error = ipl_remove(); - return error; -} - - -static int ipl_load() -{ - struct nameidata nd; - struct vattr vattr; - int error = 0, fmode = S_IFCHR|0600, i; - char *name; - - /* - * XXX Remove existing device nodes prior to creating new ones - * XXX using the assigned LKM device slot's major number. In a - * XXX perfect world we could use the ones specified by cdevsw[]. - */ - (void)ipl_remove(); - - error = ipl_enable(); - if (error) - return error; - - for (i = 0; (name = ipf_devfiles[i]); i++) { - NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc); - if ((error = namei(&nd))) - return error; - if (nd.ni_vp != NULL) { - VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); - if (nd.ni_dvp == nd.ni_vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); - vrele(nd.ni_vp); - return (EEXIST); - } - VATTR_NULL(&vattr); - vattr.va_type = VCHR; - vattr.va_mode = (fmode & 07777); - vattr.va_rdev = (ipl_major << 8) | i; - VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE); - error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr); - if (error) - return error; - } - return error; -} diff --git a/contrib/ipfilter/mls_ipl.c b/contrib/ipfilter/mls_ipl.c deleted file mode 100644 index 5a70ab9d35a1..000000000000 --- a/contrib/ipfilter/mls_ipl.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* - * 29/12/94 Added code from Marc Huber to allow it to allocate - * its own major char number! Way cool patch! - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(sun4c) || defined(sun4m) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include "ipl.h" -#include "ip_compat.h" -#include "ip_fil.h" - - -#if !defined(lint) -static const char sccsid[] = "@(#)mls_ipl.c 2.6 10/15/95 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: mls_ipl.c,v 2.2.2.2 2002/04/10 05:05:54 darrenr Exp $"; -#endif - -extern int ipldetach __P((void)); -#ifndef IPFILTER_LOG -#define iplread nulldev -#endif -extern int nulldev __P((void)); -extern int errno; -extern int iplidentify __P((char *)); - -extern int nodev __P((void)); - -static int unload __P((void)); -static int ipl_attach __P((void)); -int xxxinit __P((u_int, struct vddrv *, caddr_t, struct vdstat *)); -static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, - NULL }; - - -struct cdevsw ipldevsw = -{ - iplopen, iplclose, iplread, nulldev, - iplioctl, nulldev, nulldev, nulldev, - 0, nulldev, -}; - - -struct dev_ops ipl_ops = -{ - 1, - iplidentify, - iplattach, - iplopen, - iplclose, - iplread, - NULL, /* write */ - NULL, /* strategy */ - NULL, /* dump */ - 0, /* psize */ - iplioctl, - NULL, /* reset */ - NULL /* mmap */ -}; - -int ipl_major = 0; - -#ifdef sun4m -struct vdldrv vd = -{ - VDMAGIC_PSEUDO, - IPL_VERSION, - &ipl_ops, - NULL, - &ipldevsw, - 0, - 0, - NULL, - NULL, - NULL, - 0, - 1, -}; -#else /* sun4m */ -struct vdldrv vd = -{ - VDMAGIC_PSEUDO, /* magic */ - IPL_VERSION, -#ifdef sun4c - &ipl_ops, /* dev_ops */ -#else - NULL, /* struct mb_ctlr *mb_ctlr */ - NULL, /* struct mb_driver *mb_driver */ - NULL, /* struct mb_device *mb_device */ - 0, /* num ctlrs */ - 1, /* numdevs */ -#endif /* sun4c */ - NULL, /* bdevsw */ - &ipldevsw, /* cdevsw */ - 0, /* block major */ - 0, /* char major */ -}; -#endif /* sun4m */ - -extern int vd_unuseddev __P((void)); -extern struct cdevsw cdevsw[]; -extern int nchrdev; - -xxxinit(fc, vdp, data, vds) -u_int fc; -struct vddrv *vdp; -caddr_t data; -struct vdstat *vds; -{ - struct vdioctl_load *vdi = (struct vdioctl_load *)data; - - switch (fc) - { - case VDLOAD: - { - struct vdconf *vdc; - if (vdi && vdi->vdi_userconf) - for (vdc = vdi->vdi_userconf; vdc->vdc_type; vdc++) - if (vdc->vdc_type == VDCCHARMAJOR) { - ipl_major = vdc->vdc_data; - break; - } - - if (!ipl_major) { - while (ipl_major < nchrdev && - cdevsw[ipl_major].d_open != vd_unuseddev) - ipl_major++; - if (ipl_major == nchrdev) - return ENODEV; - } - vdp->vdd_vdtab = (struct vdlinkage *)&vd; - vd.Drv_charmajor = ipl_major; - return ipl_attach(); - } - case VDUNLOAD: - return unload(); - case VDSTAT: - return 0; - default: - return EIO; - } -} - - -static int unload() -{ - char *name; - int err, i; - - err = ipldetach(); - if (err) - return err; - for (i = 0; (name = ipf_devfiles[i]); i++) - (void) vn_remove(name, UIO_SYSSPACE, FILE); - return 0; -} - - -static int ipl_attach() -{ - struct vnode *vp; - struct vattr vattr; - int error = 0, fmode = S_IFCHR|0600, i; - char *name; - - error = iplattach(); - if (error) - return error; - - for (i = 0; (name = ipf_devfiles[i]); i++) { - (void) vn_remove(name, UIO_SYSSPACE, FILE); - vattr_null(&vattr); - vattr.va_type = MFTOVT(fmode); - vattr.va_mode = (fmode & 07777); - vattr.va_rdev = (ipl_major << 8) | i; - - error = vn_create(name, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); - if (error) { - printf("IP Filter: vn_create(%s) = %d\n", name, error); - break; - } else { - VN_RELE(vp); - } - } - return error; -} diff --git a/contrib/ipfilter/natparse.c b/contrib/ipfilter/natparse.c deleted file mode 100644 index 72462340b1a5..000000000000 --- a/contrib/ipfilter/natparse.c +++ /dev/null @@ -1,902 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -# include -#else -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) -# include -# include -#endif -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "ipf.h" - -#if defined(sun) && !SOLARIS2 -# define STRERROR(x) sys_errlist[x] -extern char *sys_errlist[]; -#else -# define STRERROR(x) strerror(x) -#endif - -#if !defined(lint) -static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; -static const char rcsid[] = "@(#)$Id: natparse.c,v 1.17.2.29 2003/05/15 17:45:34 darrenr Exp $"; -#endif - - -#if SOLARIS -#define bzero(a,b) memset(a,0,b) -#endif - -extern void printnat __P((ipnat_t *, int)); -extern int countbits __P((u_32_t)); -extern char *proto; - -ipnat_t *natparse __P((char *, int, int *)); -void natparsefile __P((int, char *, int)); -void nat_setgroupmap __P((struct ipnat *)); - - -void nat_setgroupmap(n) -ipnat_t *n; -{ - if (n->in_outmsk == n->in_inmsk) - n->in_ippip = 1; - else if (n->in_flags & IPN_AUTOPORTMAP) { - n->in_ippip = ~ntohl(n->in_inmsk); - if (n->in_outmsk != 0xffffffff) - n->in_ippip /= (~ntohl(n->in_outmsk) + 1); - n->in_ippip++; - if (n->in_ippip == 0) - n->in_ippip = 1; - n->in_ppip = USABLE_PORTS / n->in_ippip; - } else { - n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); - n->in_nip = 0; - if (!(n->in_ppip = n->in_pmin)) - n->in_ppip = 1; - n->in_ippip = USABLE_PORTS / n->in_ppip; - } -} - - -/* - * Parse a line of input from the ipnat configuration file - * - * status: - * < 0 error - * = 0 OK - * > 0 programmer error - */ -ipnat_t *natparse(line, linenum, status) -char *line; -int linenum; -int *status; -{ - static ipnat_t ipn; - struct protoent *pr; - char *dnetm = NULL, *dport = NULL; - char *s, *t, *cps[31], **cpp; - int i, cnt; - char *port1a = NULL, *port1b = NULL, *port2a = NULL; - - *status = 100; /* default to error */ - proto = NULL; - - /* - * Search for end of line and comment marker, advance of leading spaces - */ - if ((s = strchr(line, '\n'))) - *s = '\0'; - if ((s = strchr(line, '#'))) - *s = '\0'; - while (*line && isspace(*line)) - line++; - if (!*line) { - *status = 0; - return NULL; - } - - bzero((char *)&ipn, sizeof(ipn)); - cnt = 0; - - /* - * split line upto into segments. - */ - for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) - cps[++i] = strtok(NULL, " \b\t\r\n"); - - cps[i] = NULL; - - if (cnt < 3) { - fprintf(stderr, "%d: not enough segments in line\n", linenum); - *status = -1; - return NULL; - } - - cpp = cps; - - /* - * Check first word is a recognised keyword and then is the interface - */ - if (!strcasecmp(*cpp, "map")) - ipn.in_redir = NAT_MAP; - else if (!strcasecmp(*cpp, "map-block")) - ipn.in_redir = NAT_MAPBLK; - else if (!strcasecmp(*cpp, "rdr")) - ipn.in_redir = NAT_REDIRECT; - else if (!strcasecmp(*cpp, "bimap")) - ipn.in_redir = NAT_BIMAP; - else { - fprintf(stderr, "%d: unknown mapping: \"%s\"\n", - linenum, *cpp); - *status = -1; - return NULL; - } - - cpp++; - - strncpy(ipn.in_ifname, *cpp, sizeof(ipn.in_ifname) - 1); - ipn.in_ifname[sizeof(ipn.in_ifname) - 1] = '\0'; - cpp++; - - /* - * If the first word after the interface is "from" or is a ! then - * the expanded syntax is being used so parse it differently. - */ - if (!strcasecmp(*cpp, "from") || (**cpp == '!')) { - if (!strcmp(*cpp, "!")) { - cpp++; - if (strcasecmp(*cpp, "from")) { - fprintf(stderr, "Missing from after !\n"); - *status = -1; - return NULL; - } - ipn.in_flags |= IPN_NOTSRC; - } else if (**cpp == '!') { - if (strcasecmp(*cpp + 1, "from")) { - fprintf(stderr, "Missing from after !\n"); - *status = -1; - return NULL; - } - ipn.in_flags |= IPN_NOTSRC; - } - if ((ipn.in_flags & IPN_NOTSRC) && - (ipn.in_redir & (NAT_MAP|NAT_MAPBLK))) { - fprintf(stderr, "Cannot use '! from' with map\n"); - *status = -1; - return NULL; - } - - ipn.in_flags |= IPN_FILTER; - cpp++; - if (ipn.in_redir == NAT_REDIRECT) { - if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip, - (u_32_t *)&ipn.in_srcmsk, &ipn.in_sport, - &ipn.in_scmp, &ipn.in_stop, linenum)) { - *status = -1; - return NULL; - } - } else { - if (hostmask(&cpp, (u_32_t *)&ipn.in_inip, - (u_32_t *)&ipn.in_inmsk, &ipn.in_sport, - &ipn.in_scmp, &ipn.in_stop, linenum)) { - *status = -1; - return NULL; - } - } - - if (!strcmp(*cpp, "!")) { - cpp++; - ipn.in_flags |= IPN_NOTDST; - } else if (**cpp == '!') { - (*cpp)++; - ipn.in_flags |= IPN_NOTDST; - } - - if (strcasecmp(*cpp, "to")) { - fprintf(stderr, "%d: unexpected keyword (%s) - to\n", - linenum, *cpp); - *status = -1; - return NULL; - } - if ((ipn.in_flags & IPN_NOTDST) && - (ipn.in_redir & (NAT_REDIRECT))) { - fprintf(stderr, "Cannot use '! to' with rdr\n"); - *status = -1; - return NULL; - } - - if (!*++cpp) { - fprintf(stderr, "%d: missing host after to\n", linenum); - *status = -1; - return NULL; - } - if (ipn.in_redir == NAT_REDIRECT) { - if (hostmask(&cpp, (u_32_t *)&ipn.in_outip, - (u_32_t *)&ipn.in_outmsk, &ipn.in_dport, - &ipn.in_dcmp, &ipn.in_dtop, linenum)) { - *status = -1; - return NULL; - } - ipn.in_pmin = htons(ipn.in_dport); - } else { - if (hostmask(&cpp, (u_32_t *)&ipn.in_srcip, - (u_32_t *)&ipn.in_srcmsk, &ipn.in_dport, - &ipn.in_dcmp, &ipn.in_dtop, linenum)) { - *status = -1; - return NULL; - } - } - } else { - s = *cpp; - if (!s) { - fprintf(stderr, "%d: short line\n", linenum); - *status = -1; - return NULL; - } - t = strchr(s, '/'); - if (!t) { - fprintf(stderr, "%d: no netmask on LHS\n", linenum); - *status = -1; - return NULL; - } - *t++ = '\0'; - if (ipn.in_redir == NAT_REDIRECT) { - if (hostnum((u_32_t *)&ipn.in_outip, s, linenum) == -1){ - *status = -1; - return NULL; - } - if (genmask(t, (u_32_t *)&ipn.in_outmsk) == -1) { - *status = -1; - return NULL; - } - } else { - if (hostnum((u_32_t *)&ipn.in_inip, s, linenum) == -1) { - *status = -1; - return NULL; - } - if (genmask(t, (u_32_t *)&ipn.in_inmsk) == -1) { - *status = -1; - return NULL; - } - } - cpp++; - if (!*cpp) { - fprintf(stderr, "%d: short line\n", linenum); - *status = -1; - return NULL; - } - } - - /* - * If it is a standard redirect then we expect it to have a port - * match after the hostmask. - */ - if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) { - if (strcasecmp(*cpp, "port")) { - fprintf(stderr, "%d: missing fields - 1st port\n", - linenum); - *status = -1; - return NULL; - } - - cpp++; - - if (!*cpp) { - fprintf(stderr, - "%d: missing fields (destination port)\n", - linenum); - *status = -1; - return NULL; - } - - if (isdigit(**cpp) && (s = strchr(*cpp, '-'))) - *s++ = '\0'; - else - s = NULL; - - port1a = *cpp++; - - if (!strcmp(*cpp, "-")) { - cpp++; - s = *cpp++; - } - - if (s) - port1b = s; - else - ipn.in_pmax = ipn.in_pmin; - } - - /* - * In the middle of the NAT rule syntax is -> to indicate the - * direction of translation. - */ - if (!*cpp) { - fprintf(stderr, "%d: missing fields (->)\n", linenum); - *status = -1; - return NULL; - } - if (strcmp(*cpp, "->")) { - fprintf(stderr, "%d: missing ->\n", linenum); - *status = -1; - return NULL; - } - cpp++; - - if (!*cpp) { - fprintf(stderr, "%d: missing fields (%s)\n", - linenum, ipn.in_redir ? "destination" : "target"); - *status = -1; - return NULL; - } - - if (ipn.in_redir == NAT_MAP) { - if (!strcasecmp(*cpp, "range")) { - cpp++; - ipn.in_flags |= IPN_IPRANGE; - if (!*cpp) { - fprintf(stderr, "%d: missing fields (%s)\n", - linenum, - ipn.in_redir ? "destination":"target"); - *status = -1; - return NULL; - } - } - } - - if (ipn.in_flags & IPN_IPRANGE) { - dnetm = strrchr(*cpp, '-'); - if (dnetm == NULL) { - cpp++; - if (*cpp && !strcmp(*cpp, "-") && *(cpp + 1)) - dnetm = *(cpp + 1); - } else - *dnetm++ = '\0'; - if (dnetm == NULL || *dnetm == '\0') { - fprintf(stderr, - "%d: desination range not specified\n", - linenum); - *status = -1; - return NULL; - } - } else if (ipn.in_redir != NAT_REDIRECT) { - dnetm = strrchr(*cpp, '/'); - if (dnetm == NULL) { - cpp++; - if (*cpp && !strcasecmp(*cpp, "netmask")) - dnetm = *++cpp; - } - if (dnetm == NULL) { - fprintf(stderr, - "%d: missing fields (dest netmask)\n", - linenum); - *status = -1; - return NULL; - } - if (*dnetm == '/') - *dnetm++ = '\0'; - } - - if (ipn.in_redir == NAT_REDIRECT) { - dnetm = strchr(*cpp, ','); - if (dnetm != NULL) { - ipn.in_flags |= IPN_SPLIT; - *dnetm++ = '\0'; - } - if (hostnum((u_32_t *)&ipn.in_inip, *cpp, linenum) == -1) { - *status = -1; - return NULL; - } -#if SOLARIS - if (ntohl(ipn.in_inip) == INADDR_LOOPBACK) { - fprintf(stderr, - "localhost as destination not supported\n"); - *status = -1; - return NULL; - } -#endif - } else { - if (!strcmp(*cpp, ipn.in_ifname)) - *cpp = "0"; - if (hostnum((u_32_t *)&ipn.in_outip, *cpp, linenum) == -1) { - *status = -1; - return NULL; - } - } - cpp++; - - if (ipn.in_redir & NAT_MAPBLK) { - if (*cpp) { - if (strcasecmp(*cpp, "ports")) { - fprintf(stderr, - "%d: expected \"ports\" - got \"%s\"\n", - linenum, *cpp); - *status = -1; - return NULL; - } - cpp++; - if (*cpp == NULL) { - fprintf(stderr, - "%d: missing argument to \"ports\"\n", - linenum); - *status = -1; - return NULL; - } - if (!strcasecmp(*cpp, "auto")) - ipn.in_flags |= IPN_AUTOPORTMAP; - else - ipn.in_pmin = atoi(*cpp); - cpp++; - } else - ipn.in_pmin = 0; - } else if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) { - if (*cpp && (strrchr(*cpp, '/') != NULL)) { - fprintf(stderr, "%d: No netmask supported in %s\n", - linenum, "destination host for redirect"); - *status = -1; - return NULL; - } - - if (!*cpp) { - fprintf(stderr, "%d: Missing destination port %s\n", - linenum, "in redirect"); - *status = -1; - return NULL; - } - - /* If it's a in_redir, expect target port */ - - if (strcasecmp(*cpp, "port")) { - fprintf(stderr, "%d: missing fields - 2nd port (%s)\n", - linenum, *cpp); - *status = -1; - return NULL; - } - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing fields (destination port)\n", - linenum); - *status = -1; - return NULL; - } - - port2a = *cpp++; - } - if (dnetm && *dnetm == '/') - *dnetm++ = '\0'; - - if (ipn.in_redir & (NAT_MAP|NAT_MAPBLK)) { - if (ipn.in_flags & IPN_IPRANGE) { - if (hostnum((u_32_t *)&ipn.in_outmsk, dnetm, - linenum) == -1) { - *status = -1; - return NULL; - } - } else if (genmask(dnetm, (u_32_t *)&ipn.in_outmsk)) { - *status = -1; - return NULL; - } - } else { - if (ipn.in_flags & IPN_SPLIT) { - if (hostnum((u_32_t *)&ipn.in_inmsk, dnetm, - linenum) == -1) { - *status = -1; - return NULL; - } - } else if (genmask("255.255.255.255", (u_32_t *)&ipn.in_inmsk)){ - *status = -1; - return NULL; - } - if (!*cpp) { - ipn.in_flags |= IPN_TCP; /* XXX- TCP only by default */ - proto = "tcp"; - } else { - proto = *cpp++; - if (!strcasecmp(proto, "tcp")) - ipn.in_flags |= IPN_TCP; - else if (!strcasecmp(proto, "udp")) - ipn.in_flags |= IPN_UDP; - else if (!strcasecmp(proto, "tcp/udp")) - ipn.in_flags |= IPN_TCPUDP; - else if (!strcasecmp(proto, "tcpudp")) { - ipn.in_flags |= IPN_TCPUDP; - proto = "tcp/udp"; - } else if (!strcasecmp(proto, "ip")) - ipn.in_flags |= IPN_ANY; - else { - ipn.in_flags |= IPN_ANY; - if ((pr = getprotobyname(proto))) - ipn.in_p = pr->p_proto; - else { - if (!isdigit(*proto)) { - fprintf(stderr, - "%d: Unknown protocol %s\n", - linenum, proto); - *status = -1; - return NULL; - } else - ipn.in_p = atoi(proto); - } - } - if ((ipn.in_flags & IPN_TCPUDP) == 0) { - port1a = "0"; - port2a = "0"; - } - - if (*cpp && !strcasecmp(*cpp, "round-robin")) { - cpp++; - ipn.in_flags |= IPN_ROUNDR; - } - - if (*cpp && !strcasecmp(*cpp, "frag")) { - cpp++; - ipn.in_flags |= IPN_FRAG; - } - - if (*cpp && !strcasecmp(*cpp, "age")) { - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: age with no parameters\n", - linenum); - *status = -1; - return NULL; - } - - ipn.in_age[0] = atoi(*cpp); - s = index(*cpp, '/'); - if (s != NULL) - ipn.in_age[1] = atoi(s + 1); - else - ipn.in_age[1] = ipn.in_age[0]; - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "mssclamp")) { - cpp++; - if (*cpp) { - ipn.in_mssclamp = atoi(*cpp); - cpp++; - } else { - fprintf(stderr, - "%d: mssclamp with no parameters\n", - linenum); - *status = -1; - return NULL; - } - } - - if (*cpp) { - fprintf(stderr, - "%d: extra junk at the end of the line: %s\n", - linenum, *cpp); - *status = -1; - return NULL; - } - } - } - - if ((ipn.in_redir == NAT_REDIRECT) && !(ipn.in_flags & IPN_FILTER)) { - if (!portnum(port1a, &ipn.in_pmin, linenum)) { - *status = -1; - return NULL; - } - ipn.in_pmin = htons(ipn.in_pmin); - if (port1b != NULL) { - if (!portnum(port1b, &ipn.in_pmax, linenum)) { - *status = -1; - return NULL; - } - ipn.in_pmax = htons(ipn.in_pmax); - } else - ipn.in_pmax = ipn.in_pmin; - } - - if ((ipn.in_redir & NAT_BIMAP) == NAT_REDIRECT) { - if (!portnum(port2a, &ipn.in_pnext, linenum)) { - *status = -1; - return NULL; - } - ipn.in_pnext = htons(ipn.in_pnext); - } - - if (!(ipn.in_flags & IPN_SPLIT)) - ipn.in_inip &= ipn.in_inmsk; - if ((ipn.in_flags & IPN_IPRANGE) == 0) - ipn.in_outip &= ipn.in_outmsk; - ipn.in_srcip &= ipn.in_srcmsk; - - if ((ipn.in_redir & NAT_MAPBLK) != 0) - nat_setgroupmap(&ipn); - - if (*cpp && !*(cpp+1) && !strcasecmp(*cpp, "frag")) { - cpp++; - ipn.in_flags |= IPN_FRAG; - } - - if (!*cpp) { - *status = 0; - return &ipn; - } - - if (ipn.in_redir != NAT_BIMAP && !strcasecmp(*cpp, "proxy")) { - u_short pport; - - if (ipn.in_redir == NAT_BIMAP) { - fprintf(stderr, "%d: cannot use proxy with bimap\n", - linenum); - *status = -1; - return NULL; - } - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing parameter for \"proxy\"\n", - linenum); - *status = -1; - return NULL; - } - dport = NULL; - - if (!strcasecmp(*cpp, "port")) { - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing parameter for \"port\"\n", - linenum); - *status = -1; - return NULL; - } - - dport = *cpp; - cpp++; - - if (!*cpp) { - fprintf(stderr, - "%d: missing parameter for \"proxy\"\n", - linenum); - *status = -1; - return NULL; - } - } else { - fprintf(stderr, - "%d: missing keyword \"port\"\n", linenum); - *status = -1; - return NULL; - } - - if ((proto = index(*cpp, '/'))) { - *proto++ = '\0'; - if ((pr = getprotobyname(proto))) - ipn.in_p = pr->p_proto; - else - ipn.in_p = atoi(proto); - } else - ipn.in_p = 0; - - if (dport && !portnum(dport, &pport, linenum)) - return NULL; - if (ipn.in_dcmp != 0) { - if (pport != ipn.in_dport) { - fprintf(stderr, - "%d: mismatch in port numbers\n", - linenum); - return NULL; - } - } else - ipn.in_dport = htons(pport); - - (void) strncpy(ipn.in_plabel, *cpp, sizeof(ipn.in_plabel)); - cpp++; - - } else if (ipn.in_redir != NAT_BIMAP && !strcasecmp(*cpp, "portmap")) { - if (ipn.in_redir == NAT_BIMAP) { - fprintf(stderr, "%d: cannot use portmap with bimap\n", - linenum); - *status = -1; - return NULL; - } - cpp++; - if (!*cpp) { - fprintf(stderr, - "%d: missing expression following portmap\n", - linenum); - *status = -1; - return NULL; - } - - if (!strcasecmp(*cpp, "tcp")) - ipn.in_flags |= IPN_TCP; - else if (!strcasecmp(*cpp, "udp")) - ipn.in_flags |= IPN_UDP; - else if (!strcasecmp(*cpp, "tcpudp")) - ipn.in_flags |= IPN_TCPUDP; - else if (!strcasecmp(*cpp, "tcp/udp")) - ipn.in_flags |= IPN_TCPUDP; - else { - fprintf(stderr, - "%d: expected protocol name - got \"%s\"\n", - linenum, *cpp); - *status = -1; - return NULL; - } - proto = *cpp; - cpp++; - - if (!*cpp) { - fprintf(stderr, "%d: no port range found\n", linenum); - *status = -1; - return NULL; - } - - if (!strcasecmp(*cpp, "auto")) { - ipn.in_flags |= IPN_AUTOPORTMAP; - ipn.in_pmin = htons(1024); - ipn.in_pmax = htons(65535); - nat_setgroupmap(&ipn); - cpp++; - } else { - if (!(t = strchr(*cpp, ':'))) { - fprintf(stderr, - "%d: no port range in \"%s\"\n", - linenum, *cpp); - *status = -1; - return NULL; - } - *t++ = '\0'; - if (!portnum(*cpp, &ipn.in_pmin, linenum) || - !portnum(t, &ipn.in_pmax, linenum)) { - *status = -1; - return NULL; - } - ipn.in_pmin = htons(ipn.in_pmin); - ipn.in_pmax = htons(ipn.in_pmax); - cpp++; - } - } - - if (*cpp && !strcasecmp(*cpp, "frag")) { - cpp++; - ipn.in_flags |= IPN_FRAG; - } - - if (*cpp && !strcasecmp(*cpp, "age")) { - cpp++; - if (!*cpp) { - fprintf(stderr, "%d: age with no parameters\n", - linenum); - *status = -1; - return NULL; - } - ipn.in_age[0] = atoi(*cpp); - s = index(*cpp, '/'); - if (s != NULL) - ipn.in_age[1] = atoi(s + 1); - else - ipn.in_age[1] = ipn.in_age[0]; - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "mssclamp")) { - cpp++; - if (*cpp) { - ipn.in_mssclamp = atoi(*cpp); - cpp++; - } else { - fprintf(stderr, "%d: mssclamp with no parameters\n", - linenum); - *status = -1; - return NULL; - } - } - - if (*cpp) { - fprintf(stderr, "%d: extra junk at the end of the line: %s\n", - linenum, *cpp); - *status = -1; - return NULL; - } - - *status = 0; - return &ipn; -} - - -void natparsefile(fd, file, opts) -int fd; -char *file; -int opts; -{ - char line[512], *s; - ipnat_t *np; - FILE *fp; - int linenum = 0; - int parsestatus; - - if (strcmp(file, "-")) { - if (!(fp = fopen(file, "r"))) { - fprintf(stderr, "%s: open: %s\n", file, - STRERROR(errno)); - exit(1); - } - } else - fp = stdin; - - while (fgets(line, sizeof(line) - 1, fp)) { - linenum++; - line[sizeof(line) - 1] = '\0'; - if ((s = strchr(line, '\n'))) - *s = '\0'; - - parsestatus = 1; - np = natparse(line, linenum, &parsestatus); - if (parsestatus != 0) { - if (*line) { - fprintf(stderr, "%d: syntax error in \"%s\"\n", - linenum, line); - } - fprintf(stderr, "%s: %s error (%d), quitting\n", - file, - ((parsestatus < 0)? "parse": "internal"), - parsestatus); - exit(1); - } - if (np) { - if ((opts & OPT_VERBOSE) && np) - printnat(np, opts); - if (!(opts & OPT_NODO)) { - if (!(opts & OPT_REMOVE)) { - if (ioctl(fd, SIOCADNAT, &np) == -1) { - fprintf(stderr, "%d:", - linenum); - perror("ioctl(SIOCADNAT)"); - } - } else if (ioctl(fd, SIOCRMNAT, &np) == -1) { - fprintf(stderr, "%d:", linenum); - perror("ioctl(SIOCRMNAT)"); - } - } - } - } - if (fp != stdin) - fclose(fp); -} diff --git a/contrib/ipfilter/net/.cvsignore b/contrib/ipfilter/net/.cvsignore deleted file mode 100644 index 19f86f493ab1..000000000000 --- a/contrib/ipfilter/net/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -done diff --git a/contrib/ipfilter/opt.c b/contrib/ipfilter/opt.c deleted file mode 100644 index 825a5e346dd0..000000000000 --- a/contrib/ipfilter/opt.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef linux -#include -#endif -#include -#include -#include -#include "ip_compat.h" -#include -#include "ip_fil.h" -#include "ipf.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$Id: opt.c,v 2.2.2.3 2002/12/06 11:40:27 darrenr Exp $"; -#endif - -extern int opts; - -struct ipopt_names ionames[] ={ - { IPOPT_NOP, 0x000001, 1, "nop" }, - { IPOPT_RR, 0x000002, 7, "rr" }, /* 1 route */ - { IPOPT_ZSU, 0x000004, 3, "zsu" }, - { IPOPT_MTUP, 0x000008, 3, "mtup" }, - { IPOPT_MTUR, 0x000010, 3, "mtur" }, - { IPOPT_ENCODE, 0x000020, 3, "encode" }, - { IPOPT_TS, 0x000040, 8, "ts" }, /* 1 TS */ - { IPOPT_TR, 0x000080, 3, "tr" }, - { IPOPT_SECURITY,0x000100, 11, "sec" }, - { IPOPT_SECURITY,0x000100, 11, "sec-class" }, - { IPOPT_LSRR, 0x000200, 7, "lsrr" }, /* 1 route */ - { IPOPT_E_SEC, 0x000400, 3, "e-sec" }, - { IPOPT_CIPSO, 0x000800, 3, "cipso" }, - { IPOPT_SATID, 0x001000, 4, "satid" }, - { IPOPT_SSRR, 0x002000, 7, "ssrr" }, /* 1 route */ - { IPOPT_ADDEXT, 0x004000, 3, "addext" }, - { IPOPT_VISA, 0x008000, 3, "visa" }, - { IPOPT_IMITD, 0x010000, 3, "imitd" }, - { IPOPT_EIP, 0x020000, 3, "eip" }, - { IPOPT_FINN, 0x040000, 3, "finn" }, - { 0, 0, 0, (char *)NULL } /* must be last */ -}; - -struct ipopt_names secclass[] = { - { IPSO_CLASS_RES4, 0x01, 0, "reserv-4" }, - { IPSO_CLASS_TOPS, 0x02, 0, "topsecret" }, - { IPSO_CLASS_SECR, 0x04, 0, "secret" }, - { IPSO_CLASS_RES3, 0x08, 0, "reserv-3" }, - { IPSO_CLASS_CONF, 0x10, 0, "confid" }, - { IPSO_CLASS_UNCL, 0x20, 0, "unclass" }, - { IPSO_CLASS_RES2, 0x40, 0, "reserv-2" }, - { IPSO_CLASS_RES1, 0x80, 0, "reserv-1" }, - { 0, 0, 0, NULL } /* must be last */ -}; - - -static u_char seclevel __P((char *)); -int addipopt __P((char *, struct ipopt_names *, int, char *)); - -static u_char seclevel(slevel) -char *slevel; -{ - struct ipopt_names *so; - - for (so = secclass; so->on_name; so++) - if (!strcasecmp(slevel, so->on_name)) - break; - - if (!so->on_name) { - fprintf(stderr, "no such security level: %s\n", slevel); - return 0; - } - return (u_char)so->on_value; -} - - -int addipopt(op, io, len, class) -char *op; -struct ipopt_names *io; -int len; -char *class; -{ - int olen = len; - struct in_addr ipadr; - u_short val; - u_char lvl; - char *s; - - if ((len + io->on_siz) > 48) { - fprintf(stderr, "options too long\n"); - return 0; - } - len += io->on_siz; - *op++ = io->on_value; - if (io->on_siz > 1) { - s = op; - *op++ = io->on_siz; - *op++ = IPOPT_MINOFF; - - if (class) { - switch (io->on_value) - { - case IPOPT_SECURITY : - lvl = seclevel(class); - *(op - 1) = lvl; - break; - case IPOPT_LSRR : - case IPOPT_SSRR : - ipadr.s_addr = inet_addr(class); - s[IPOPT_OLEN] = IPOPT_MINOFF - 1 + 4; - bcopy((char *)&ipadr, op, sizeof(ipadr)); - break; - case IPOPT_SATID : - val = atoi(class); - bcopy((char *)&val, op, 2); - break; - } - } - - op += io->on_siz - 3; - if (len & 3) { - *op++ = IPOPT_NOP; - len++; - } - } - if (opts & OPT_DEBUG) - fprintf(stderr, "bo: %s %d %#x: %d\n", - io->on_name, io->on_value, io->on_bit, len); - return len - olen; -} - - -u_32_t buildopts(cp, op, len) -char *cp, *op; -int len; -{ - struct ipopt_names *io; - u_32_t msk = 0; - char *s, *t; - int inc; - - for (s = strtok(cp, ","); s; s = strtok(NULL, ",")) { - if ((t = strchr(s, '='))) - *t++ = '\0'; - for (io = ionames; io->on_name; io++) { - if (strcasecmp(s, io->on_name) || (msk & io->on_bit)) - continue; - if ((inc = addipopt(op, io, len, t))) { - op += inc; - len += inc; - } - msk |= io->on_bit; - break; - } - if (!io->on_name) { - fprintf(stderr, "unknown IP option name %s\n", s); - return 0; - } - } - *op++ = IPOPT_EOL; - len++; - return len; -} diff --git a/contrib/ipfilter/opt_inet6.h b/contrib/ipfilter/opt_inet6.h deleted file mode 100644 index 43e7657e1ae3..000000000000 --- a/contrib/ipfilter/opt_inet6.h +++ /dev/null @@ -1 +0,0 @@ -#define INET6 diff --git a/contrib/ipfilter/parse.c b/contrib/ipfilter/parse.c deleted file mode 100644 index 0d8a617d4aa3..000000000000 --- a/contrib/ipfilter/parse.c +++ /dev/null @@ -1,1510 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include "ip_fil.h" -#include "ipf.h" -#include "facpri.h" - -#if !defined(lint) -static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed"; -static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $"; -#endif - -extern struct ipopt_names ionames[], secclass[]; -extern int opts; -extern int use_inet6; - -int addicmp __P((char ***, struct frentry *, int)); -int extras __P((char ***, struct frentry *, int)); - -int icmpcode __P((char *)), addkeep __P((char ***, struct frentry *, int)); -int to_interface __P((frdest_t *, char *, int)); -void print_toif __P((char *, frdest_t *)); -void optprint __P((u_short *, u_long, u_long)); -int loglevel __P((char **, u_int *, int)); -void printlog __P((frentry_t *)); -void printifname __P((char *, char *, void *)); - -extern char *proto; -extern char flagset[]; -extern u_char flags[]; - - -/* parse() - * - * parse a line read from the input filter rule file - * - * status: - * < 0 error - * = 0 OK - * > 0 programmer error - */ -struct frentry *parse(line, linenum, status) -char *line; -int linenum; -int *status; /* good, bad, or indifferent */ -{ - static struct frentry fil; - char *cps[31], **cpp, *endptr, *s; - struct protoent *p = NULL; - int i, cnt = 1, j, ch; - u_int k; - - *status = 100; /* default to error */ - - while (*line && isspace(*line)) - line++; - if (!*line) { - *status = 0; - return NULL; - } - - bzero((char *)&fil, sizeof(fil)); - fil.fr_mip.fi_v = 0xf; - fil.fr_ip.fi_v = use_inet6 ? 6 : 4; - fil.fr_loglevel = 0xffff; - - /* - * break line up into max of 20 segments - */ - if (opts & OPT_DEBUG) - fprintf(stderr, "parse [%s]\n", line); - for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++) - cps[++i] = strtok(NULL, " \b\t\r\n"); - cps[i] = NULL; - - if (cnt < 3) { - fprintf(stderr, "%d: not enough segments in line\n", linenum); - *status = -1; - return NULL; - } - - cpp = cps; - /* - * The presence of an '@' followed by a number gives the position in - * the current rule list to insert this one. - */ - if (**cpp == '@') - fil.fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1; - - - /* - * Check the first keyword in the rule and any options that are - * expected to follow it. - */ - if (!strcasecmp("block", *cpp)) { - fil.fr_flags |= FR_BLOCK; - if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) && - (i = 19)) - fil.fr_flags |= FR_FAKEICMP; - else if (!strncasecmp(*(cpp+1), "return-icmp", 11) && (i = 11)) - fil.fr_flags |= FR_RETICMP; - if (fil.fr_flags & FR_RETICMP) { - cpp++; - if (strlen(*cpp) == i) { - if (*(cpp + 1) && **(cpp +1) == '(') { - cpp++; - i = 0; - } else - i = -1; - } - - /* - * The ICMP code is not required to follow in ()'s - */ - if ((i >= 0) && (*(*cpp + i) == '(')) { - i++; - j = icmpcode(*cpp + i); - if (j == -1) { - fprintf(stderr, - "%d: unrecognised icmp code %s\n", - linenum, *cpp + 20); - *status = -1; - return NULL; - } - fil.fr_icode = j; - } - } else if (!strcasecmp(*(cpp+1), "return-rst")) { - fil.fr_flags |= FR_RETRST; - cpp++; - } - } else if (!strcasecmp("count", *cpp)) { - fil.fr_flags |= FR_ACCOUNT; - } else if (!strcasecmp("pass", *cpp)) { - fil.fr_flags |= FR_PASS; - } else if (!strcasecmp("nomatch", *cpp)) { - fil.fr_flags |= FR_NOMATCH; - } else if (!strcasecmp("auth", *cpp)) { - fil.fr_flags |= FR_AUTH; - if (!strncasecmp(*(cpp+1), "return-rst", 10)) { - fil.fr_flags |= FR_RETRST; - cpp++; - } - } else if (!strcasecmp("preauth", *cpp)) { - fil.fr_flags |= FR_PREAUTH; - } else if (!strcasecmp("skip", *cpp)) { - cpp++; - if (ratoui(*cpp, &k, 0, UINT_MAX)) - fil.fr_skip = k; - else { - fprintf(stderr, "%d: integer must follow skip\n", - linenum); - *status = -1; - return NULL; - } - } else if (!strcasecmp("log", *cpp)) { - fil.fr_flags |= FR_LOG; - if (!strcasecmp(*(cpp+1), "body")) { - fil.fr_flags |= FR_LOGBODY; - cpp++; - } - if (!strcasecmp(*(cpp+1), "first")) { - fil.fr_flags |= FR_LOGFIRST; - cpp++; - } - if (*cpp && !strcasecmp(*(cpp+1), "or-block")) { - fil.fr_flags |= FR_LOGORBLOCK; - cpp++; - } - if (!strcasecmp(*(cpp+1), "level")) { - cpp++; - if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1) { - /* NB loglevel prints its own error message */ - *status = -1; - return NULL; - } - cpp++; - } - } else { - /* - * Doesn't start with one of the action words - */ - fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp); - *status = -1; - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum); - *status = -1; - return NULL; - } - - /* - * Get the direction for filtering. Impose restrictions on direction - * if blocking with returning ICMP or an RST has been requested. - */ - if (!strcasecmp("in", *cpp)) - fil.fr_flags |= FR_INQUE; - else if (!strcasecmp("out", *cpp)) { - fil.fr_flags |= FR_OUTQUE; - if (fil.fr_flags & FR_RETICMP) { - fprintf(stderr, - "%d: Can only use return-icmp with 'in'\n", - linenum); - *status = -1; - return NULL; - } else if (fil.fr_flags & FR_RETRST) { - fprintf(stderr, - "%d: Can only use return-rst with 'in'\n", - linenum); - *status = -1; - return NULL; - } - } - if (!*++cpp) { - fprintf(stderr, "%d: missing source specification\n", linenum); - *status = -1; - return NULL; - } - - if (!strcasecmp("log", *cpp)) { - if (!*++cpp) { - fprintf(stderr, "%d: missing source specification\n", - linenum); - *status = -1; - return NULL; - } - if (fil.fr_flags & FR_PASS) - fil.fr_flags |= FR_LOGP; - else if (fil.fr_flags & FR_BLOCK) - fil.fr_flags |= FR_LOGB; - if (*cpp && !strcasecmp(*cpp, "body")) { - fil.fr_flags |= FR_LOGBODY; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "first")) { - fil.fr_flags |= FR_LOGFIRST; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "or-block")) { - if (!(fil.fr_flags & FR_PASS)) { - fprintf(stderr, - "%d: or-block must be used with pass\n", - linenum); - *status = -1; - return NULL; - } - fil.fr_flags |= FR_LOGORBLOCK; - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "level")) { - if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1) { - *status = -1; - return NULL; - } - cpp++; - cpp++; - } - } - - if (*cpp && !strcasecmp("quick", *cpp)) { - if (fil.fr_skip != 0) { - fprintf(stderr, "%d: cannot use skip with quick\n", - linenum); - *status = -1; - return NULL; - } - cpp++; - fil.fr_flags |= FR_QUICK; - } - - /* - * Parse rule options that are available if a rule is tied to an - * interface. - */ - *fil.fr_ifname = '\0'; - *fil.fr_oifname = '\0'; - if (*cpp && !strcasecmp(*cpp, "on")) { - if (!*++cpp) { - fprintf(stderr, "%d: interface name missing\n", - linenum); - *status = -1; - return NULL; - } - - s = index(*cpp, ','); - if (s != NULL) { - *s++ = '\0'; - (void)strncpy(fil.fr_ifnames[1], s, IFNAMSIZ - 1); - fil.fr_ifnames[1][IFNAMSIZ - 1] = '\0'; - } else - strcpy(fil.fr_ifnames[1], "*"); - - (void)strncpy(fil.fr_ifnames[0], *cpp, IFNAMSIZ - 1); - fil.fr_ifnames[0][IFNAMSIZ - 1] = '\0'; - - cpp++; - if (!*cpp) { - if ((fil.fr_flags & FR_RETMASK) == FR_RETRST) { - fprintf(stderr, - "%d: %s can only be used with TCP\n", - linenum, "return-rst"); - *status = -1; - return NULL; - } - *status = 0; - return &fil; - } - - if (*cpp) { - if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) { - cpp++; - if (to_interface(&fil.fr_dif, *cpp, linenum)) { - *status = -1; - return NULL; - } - cpp++; - } - if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) { - cpp++; - if (to_interface(&fil.fr_tif, *cpp, linenum)) { - *status = -1; - return NULL; - } - cpp++; - } else if (*cpp && !strcasecmp(*cpp, "fastroute")) { - if (!(fil.fr_flags & FR_INQUE)) { - fprintf(stderr, - "can only use %s with 'in'\n", - "fastroute"); - *status = -1; - return NULL; - } - fil.fr_flags |= FR_FASTROUTE; - cpp++; - } - } - - /* - * Set the "other" interface name. Lets you specify both - * inbound and outbound interfaces for state rules. Do not - * prevent both interfaces from being the same. - */ - strcpy(fil.fr_ifnames[3], "*"); - if ((*cpp != NULL) && (*(cpp + 1) != NULL) && - ((((fil.fr_flags & FR_INQUE) != 0) && - (strcasecmp(*cpp, "out-via") == 0)) || - (((fil.fr_flags & FR_OUTQUE) != 0) && - (strcasecmp(*cpp, "in-via") == 0)))) { - cpp++; - - s = index(*cpp, ','); - if (s != NULL) { - *s++ = '\0'; - (void)strncpy(fil.fr_ifnames[3], s, - IFNAMSIZ - 1); - fil.fr_ifnames[3][IFNAMSIZ - 1] = '\0'; - } - - (void)strncpy(fil.fr_ifnames[2], *cpp, IFNAMSIZ - 1); - fil.fr_ifnames[2][IFNAMSIZ - 1] = '\0'; - cpp++; - } else - strcpy(fil.fr_ifnames[2], "*"); - } - if (*cpp && !strcasecmp(*cpp, "tos")) { - if (!*++cpp) { - fprintf(stderr, "%d: tos missing value\n", linenum); - *status = -1; - return NULL; - } - fil.fr_tos = strtol(*cpp, NULL, 0); - fil.fr_mip.fi_tos = 0xff; - cpp++; - } - - if (*cpp && !strcasecmp(*cpp, "ttl")) { - if (!*++cpp) { - fprintf(stderr, "%d: ttl missing hopcount value\n", - linenum); - *status = -1; - return NULL; - } - if (ratoi(*cpp, &i, 0, 255)) - fil.fr_ttl = i; - else { - fprintf(stderr, "%d: invalid ttl (%s)\n", - linenum, *cpp); - *status = -1; - return NULL; - } - fil.fr_mip.fi_ttl = 0xff; - cpp++; - } - - /* - * check for "proto " only decode udp/tcp/icmp as protoname - */ - proto = NULL; - if (*cpp && !strcasecmp(*cpp, "proto")) { - if (!*++cpp) { - fprintf(stderr, "%d: protocol name missing\n", linenum); - *status = -1; - return NULL; - } - proto = *cpp++; - if (!strcasecmp(proto, "tcp/udp")) { - fil.fr_ip.fi_fl |= FI_TCPUDP; - fil.fr_mip.fi_fl |= FI_TCPUDP; - } else if (use_inet6 && !strcasecmp(proto, "icmp")) { - fprintf(stderr, -"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n", - linenum); - } else { - if (!(p = getprotobyname(proto)) && !isdigit(*proto)) { - fprintf(stderr, - "%d: unknown protocol (%s)\n", - linenum, proto); - *status = -1; - return NULL; - } - if (p) - fil.fr_proto = p->p_proto; - else if (isdigit(*proto)) { - i = (int)strtol(proto, &endptr, 0); - if (*endptr != '\0' || i < 0 || i > 255) { - fprintf(stderr, - "%d: unknown protocol (%s)\n", - linenum, proto); - *status = -1; - return NULL; - } - fil.fr_proto = i; - } - fil.fr_mip.fi_p = 0xff; - } - } - if ((fil.fr_proto != IPPROTO_TCP) && - ((fil.fr_flags & FR_RETMASK) == FR_RETRST)) { - fprintf(stderr, "%d: %s can only be used with TCP\n", - linenum, "return-rst"); - *status = -1; - return NULL; - } - - /* - * get the from host and bit mask to use against packets - */ - - if (!*cpp) { - fprintf(stderr, "%d: missing source specification\n", linenum); - *status = -1; - return NULL; - } - if (!strcasecmp(*cpp, "all")) { - cpp++; - if (!*cpp) { - *status = 0; - return &fil; - } - } else { - if (strcasecmp(*cpp, "from")) { - fprintf(stderr, "%d: unexpected keyword (%s) - from\n", - linenum, *cpp); - *status = -1; - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: missing host after from\n", - linenum); - *status = -1; - return NULL; - } - if (!strcmp(*cpp, "!")) { - fil.fr_flags |= FR_NOTSRCIP; - if (!*++cpp) { - fprintf(stderr, - "%d: missing host after from\n", - linenum); - *status = -1; - return NULL; - } - } else if (**cpp == '!') { - fil.fr_flags |= FR_NOTSRCIP; - (*cpp)++; - } - ch = 0; - if (hostmask(&cpp, (u_32_t *)&fil.fr_src, - (u_32_t *)&fil.fr_smsk, &fil.fr_sport, &ch, - &fil.fr_stop, linenum)) { - *status = -1; - return NULL; - } - - if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) && - (fil.fr_proto != IPPROTO_UDP) && - !(fil.fr_ip.fi_fl & FI_TCPUDP)) { - fprintf(stderr, - "%d: cannot use port and neither tcp or udp\n", - linenum); - *status = -1; - return NULL; - } - - fil.fr_scmp = ch; - if (!*cpp) { - fprintf(stderr, "%d: missing to fields\n", linenum); - *status = -1; - return NULL; - } - - /* - * do the same for the to field (destination host) - */ - if (strcasecmp(*cpp, "to")) { - fprintf(stderr, "%d: unexpected keyword (%s) - to\n", - linenum, *cpp); - *status = -1; - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: missing host after to\n", linenum); - *status = -1; - return NULL; - } - ch = 0; - if (!strcmp(*cpp, "!")) { - fil.fr_flags |= FR_NOTDSTIP; - if (!*++cpp) { - fprintf(stderr, - "%d: missing host after from\n", - linenum); - *status = -1; - return NULL; - } - } else if (**cpp == '!') { - fil.fr_flags |= FR_NOTDSTIP; - (*cpp)++; - } - if (hostmask(&cpp, (u_32_t *)&fil.fr_dst, - (u_32_t *)&fil.fr_dmsk, &fil.fr_dport, &ch, - &fil.fr_dtop, linenum)) { - *status = -1; - return NULL; - } - if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) && - (fil.fr_proto != IPPROTO_UDP) && - !(fil.fr_ip.fi_fl & FI_TCPUDP)) { - fprintf(stderr, - "%d: cannot use port and neither tcp or udp\n", - linenum); - *status = -1; - return NULL; - } - - fil.fr_dcmp = ch; - } - - /* - * check some sanity, make sure we don't have icmp checks with tcp - * or udp or visa versa. - */ - if (fil.fr_proto && (fil.fr_dcmp || fil.fr_scmp) && - fil.fr_proto != IPPROTO_TCP && fil.fr_proto != IPPROTO_UDP) { - fprintf(stderr, "%d: port operation on non tcp/udp\n", linenum); - *status = -1; - return NULL; - } - if (fil.fr_icmp && fil.fr_proto != IPPROTO_ICMP) { - fprintf(stderr, "%d: icmp comparisons on wrong protocol\n", - linenum); - *status = -1; - return NULL; - } - - if (!*cpp) { - *status = 0; - return &fil; - } - - if (*cpp && !strcasecmp(*cpp, "flags")) { - if (!*++cpp) { - fprintf(stderr, "%d: no flags present\n", linenum); - *status = -1; - return NULL; - } - fil.fr_tcpf = tcp_flags(*cpp, &fil.fr_tcpfm, linenum); - cpp++; - } - - /* - * extras... - */ - if ((fil.fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") || - !strcasecmp(*cpp, "and"))) - if (extras(&cpp, &fil, linenum)) { - *status = -1; - return NULL; - } - - /* - * icmp types for use with the icmp protocol - */ - if (*cpp && !strcasecmp(*cpp, "icmp-type")) { - if (fil.fr_proto != IPPROTO_ICMP && - fil.fr_proto != IPPROTO_ICMPV6) { - fprintf(stderr, - "%d: icmp with wrong protocol (%d)\n", - linenum, fil.fr_proto); - *status = -1; - return NULL; - } - if (addicmp(&cpp, &fil, linenum)) { - *status = -1; - return NULL; - } - fil.fr_icmp = htons(fil.fr_icmp); - fil.fr_icmpm = htons(fil.fr_icmpm); - } - - /* - * Keep something... - */ - while (*cpp && !strcasecmp(*cpp, "keep")) - if (addkeep(&cpp, &fil, linenum)) { - *status = -1; - return NULL; - } - - /* - * This is here to enforce the old interface binding behaviour. - * That is, "on X" is equivalent to " on X -via -,X" - */ - if (fil.fr_flags & FR_KEEPSTATE) { - if (*fil.fr_ifnames[0] && !*fil.fr_ifnames[3]) { - bcopy(fil.fr_ifnames[0], fil.fr_ifnames[3], - sizeof(fil.fr_ifnames[3])); - strncpy(fil.fr_ifnames[2], "*", - sizeof(fil.fr_ifnames[3])); - } - } - - /* - * head of a new group ? - */ - if (*cpp && !strcasecmp(*cpp, "head")) { - if (fil.fr_skip != 0) { - fprintf(stderr, "%d: cannot use skip with head\n", - linenum); - *status = -1; - return NULL; - } - if (!*++cpp) { - fprintf(stderr, "%d: head without group #\n", linenum); - *status = -1; - return NULL; - } - if (ratoui(*cpp, &k, 0, UINT_MAX)) - fil.fr_grhead = (u_32_t)k; - else { - fprintf(stderr, "%d: invalid group (%s)\n", - linenum, *cpp); - *status = -1; - return NULL; - } - cpp++; - } - - /* - * head of a new group ? - */ - if (*cpp && !strcasecmp(*cpp, "group")) { - if (!*++cpp) { - fprintf(stderr, "%d: group without group #\n", - linenum); - *status = -1; - return NULL; - } - if (ratoui(*cpp, &k, 0, UINT_MAX)) - fil.fr_group = k; - else { - fprintf(stderr, "%d: invalid group (%s)\n", - linenum, *cpp); - *status = -1; - return NULL; - } - cpp++; - } - - /* - * leftovers...yuck - */ - if (*cpp && **cpp) { - fprintf(stderr, "%d: unknown words at end: [", linenum); - for (; *cpp; cpp++) - fprintf(stderr, "%s ", *cpp); - fprintf(stderr, "]\n"); - *status = -1; - return NULL; - } - - /* - * lazy users... - */ - if ((fil.fr_tcpf || fil.fr_tcpfm) && fil.fr_proto != IPPROTO_TCP) { - fprintf(stderr, "%d: TCP protocol not specified\n", linenum); - *status = -1; - return NULL; - } - if (!(fil.fr_ip.fi_fl & FI_TCPUDP) && (fil.fr_proto != IPPROTO_TCP) && - (fil.fr_proto != IPPROTO_UDP) && (fil.fr_dcmp || fil.fr_scmp)) { - if (!fil.fr_proto) { - fil.fr_ip.fi_fl |= FI_TCPUDP; - fil.fr_mip.fi_fl |= FI_TCPUDP; - } else { - fprintf(stderr, - "%d: port comparisons for non-TCP/UDP\n", - linenum); - *status = -1; - return NULL; - } - } -/* - if ((fil.fr_flags & FR_KEEPFRAG) && - (!(fil.fr_ip.fi_fl & FI_FRAG) || !(fil.fr_ip.fi_fl & FI_FRAG))) { - fprintf(stderr, - "%d: must use 'with frags' with 'keep frags'\n", - linenum); - *status = -1; - return NULL; - } -*/ - *status = 0; - return &fil; -} - - -int loglevel(cpp, facpri, linenum) -char **cpp; -u_int *facpri; -int linenum; -{ - int fac, pri; - char *s; - - fac = 0; - pri = 0; - if (!*++cpp) { - fprintf(stderr, "%d: %s\n", linenum, - "missing identifier after level"); - return -1; - } - - s = index(*cpp, '.'); - if (s) { - *s++ = '\0'; - fac = fac_findname(*cpp); - if (fac == -1) { - fprintf(stderr, "%d: %s %s\n", linenum, - "Unknown facility", *cpp); - return -1; - } - pri = pri_findname(s); - if (pri == -1) { - fprintf(stderr, "%d: %s %s\n", linenum, - "Unknown priority", s); - return -1; - } - } else { - pri = pri_findname(*cpp); - if (pri == -1) { - fprintf(stderr, "%d: %s %s\n", linenum, - "Unknown priority", *cpp); - return -1; - } - } - *facpri = fac|pri; - return 0; -} - - -int to_interface(fdp, to, linenum) -frdest_t *fdp; -char *to; -int linenum; -{ - char *s; - - s = index(to, ':'); - fdp->fd_ifp = NULL; - if (s) { - *s++ = '\0'; - if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum) == -1) - return -1; - } - (void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1); - fdp->fd_ifname[sizeof(fdp->fd_ifname) - 1] = '\0'; - return 0; -} - - -void print_toif(tag, fdp) -char *tag; -frdest_t *fdp; -{ - printf("%s %s%s", tag, fdp->fd_ifname, - (fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)"); -#ifdef USE_INET6 - if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) { - char ipv6addr[80]; - - inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr, - sizeof(fdp->fd_ip6)); - printf(":%s", ipv6addr); - } else -#endif - if (fdp->fd_ip.s_addr) - printf(":%s", inet_ntoa(fdp->fd_ip)); - putchar(' '); -} - - -/* - * deal with extra bits on end of the line - */ -int extras(cp, fr, linenum) -char ***cp; -struct frentry *fr; -int linenum; -{ - u_short secmsk; - u_long opts; - int notopt; - char oflags; - - opts = 0; - secmsk = 0; - notopt = 0; - (*cp)++; - if (!**cp) - return -1; - - while (**cp && (!strncasecmp(**cp, "ipopt", 5) || - !strcasecmp(**cp, "not") || !strncasecmp(**cp, "opt", 3) || - !strncasecmp(**cp, "frag", 4) || !strcasecmp(**cp, "no") || - !strcasecmp(**cp, "short"))) { - if (***cp == 'n' || ***cp == 'N') { - notopt = 1; - (*cp)++; - continue; - } else if (***cp == 'i' || ***cp == 'I') { - if (!notopt) - fr->fr_ip.fi_fl |= FI_OPTIONS; - fr->fr_mip.fi_fl |= FI_OPTIONS; - goto nextopt; - } else if (***cp == 'f' || ***cp == 'F') { - if (!notopt) - fr->fr_ip.fi_fl |= FI_FRAG; - fr->fr_mip.fi_fl |= FI_FRAG; - goto nextopt; - } else if (***cp == 'o' || ***cp == 'O') { - if (!*(*cp + 1)) { - fprintf(stderr, - "%d: opt missing arguements\n", - linenum); - return -1; - } - (*cp)++; - if (!(opts = optname(cp, &secmsk, linenum))) - return -1; - oflags = FI_OPTIONS; - } else if (***cp == 's' || ***cp == 'S') { - if (fr->fr_tcpf) { - fprintf(stderr, - "%d: short cannot be used with TCP flags\n", - linenum); - return -1; - } - - if (!notopt) - fr->fr_ip.fi_fl |= FI_SHORT; - fr->fr_mip.fi_fl |= FI_SHORT; - goto nextopt; - } else - return -1; - - if (!notopt || !opts) - fr->fr_mip.fi_fl |= oflags; - if (notopt) { - if (!secmsk) { - fr->fr_mip.fi_optmsk |= opts; - } else { - fr->fr_mip.fi_optmsk |= (opts & ~0x0100); - } - } else { - fr->fr_mip.fi_optmsk |= opts; - } - fr->fr_mip.fi_secmsk |= secmsk; - - if (notopt) { - fr->fr_ip.fi_fl &= (~oflags & 0xf); - fr->fr_ip.fi_optmsk &= ~opts; - fr->fr_ip.fi_secmsk &= ~secmsk; - } else { - fr->fr_ip.fi_fl |= oflags; - fr->fr_ip.fi_optmsk |= opts; - fr->fr_ip.fi_secmsk |= secmsk; - } -nextopt: - notopt = 0; - opts = 0; - oflags = 0; - secmsk = 0; - (*cp)++; - } - return 0; -} - - -u_32_t optname(cp, sp, linenum) -char ***cp; -u_short *sp; -int linenum; -{ - struct ipopt_names *io, *so; - u_long msk = 0; - u_short smsk = 0; - char *s; - int sec = 0; - - for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { - for (io = ionames; io->on_name; io++) - if (!strcasecmp(s, io->on_name)) { - msk |= io->on_bit; - break; - } - if (!io->on_name) { - fprintf(stderr, "%d: unknown IP option name %s\n", - linenum, s); - return 0; - } - if (!strcasecmp(s, "sec-class")) - sec = 1; - } - - if (sec && !*(*cp + 1)) { - fprintf(stderr, "%d: missing security level after sec-class\n", - linenum); - return 0; - } - - if (sec) { - (*cp)++; - for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) { - for (so = secclass; so->on_name; so++) - if (!strcasecmp(s, so->on_name)) { - smsk |= so->on_bit; - break; - } - if (!so->on_name) { - fprintf(stderr, - "%d: no such security level: %s\n", - linenum, s); - return 0; - } - } - if (smsk) - *sp = smsk; - } - return msk; -} - - -#ifdef __STDC__ -void optprint(u_short *sec, u_long optmsk, u_long optbits) -#else -void optprint(sec, optmsk, optbits) -u_short *sec; -u_long optmsk, optbits; -#endif -{ - u_short secmsk = sec[0], secbits = sec[1]; - struct ipopt_names *io, *so; - char *s; - - s = " opt "; - for (io = ionames; io->on_name; io++) - if ((io->on_bit & optmsk) && - ((io->on_bit & optmsk) == (io->on_bit & optbits))) { - if ((io->on_value != IPOPT_SECURITY) || - (!secmsk && !secbits)) { - printf("%s%s", s, io->on_name); - if (io->on_value == IPOPT_SECURITY) - io++; - s = ","; - } - } - - - if (secmsk & secbits) { - printf("%ssec-class", s); - s = " "; - for (so = secclass; so->on_name; so++) - if ((secmsk & so->on_bit) && - ((so->on_bit & secmsk) == (so->on_bit & secbits))) { - printf("%s%s", s, so->on_name); - s = ","; - } - } - - if ((optmsk && (optmsk != optbits)) || - (secmsk && (secmsk != secbits))) { - s = " "; - printf(" not opt"); - if (optmsk != optbits) { - for (io = ionames; io->on_name; io++) - if ((io->on_bit & optmsk) && - ((io->on_bit & optmsk) != - (io->on_bit & optbits))) { - if ((io->on_value != IPOPT_SECURITY) || - (!secmsk && !secbits)) { - printf("%s%s", s, io->on_name); - s = ","; - if (io->on_value == - IPOPT_SECURITY) - io++; - } else - io++; - } - } - - if (secmsk != secbits) { - printf("%ssec-class", s); - s = " "; - for (so = secclass; so->on_name; so++) - if ((so->on_bit & secmsk) && - ((so->on_bit & secmsk) != - (so->on_bit & secbits))) { - printf("%s%s", s, so->on_name); - s = ","; - } - } - } -} - -char *icmptypes[] = { - "echorep", (char *)NULL, (char *)NULL, "unreach", "squench", - "redir", (char *)NULL, (char *)NULL, "echo", "routerad", - "routersol", "timex", "paramprob", "timest", "timestrep", - "inforeq", "inforep", "maskreq", "maskrep", "END" -}; - -/* - * set the icmp field to the correct type if "icmp" word is found - */ -int addicmp(cp, fp, linenum) -char ***cp; -struct frentry *fp; -int linenum; -{ - char **t; - int i; - - (*cp)++; - if (!**cp) - return -1; - - if (isdigit(***cp)) { - if (!ratoi(**cp, &i, 0, 255)) { - fprintf(stderr, - "%d: Invalid icmp-type (%s) specified\n", - linenum, **cp); - return -1; - } - } else if (fp->fr_proto == IPPROTO_ICMPV6) { - fprintf(stderr, "%d: Unknown ICMPv6 type (%s) specified, %s", - linenum, **cp, "(use numeric value instead)\n"); - return -1; - } else { - for (t = icmptypes, i = 0; ; t++, i++) { - if (!*t) - continue; - if (!strcasecmp("END", *t)) { - i = -1; - break; - } - if (!strcasecmp(*t, **cp)) - break; - } - if (i == -1) { - fprintf(stderr, - "%d: Invalid icmp-type (%s) specified\n", - linenum, **cp); - return -1; - } - } - fp->fr_icmp = (u_short)(i << 8); - fp->fr_icmpm = (u_short)0xff00; - (*cp)++; - if (!**cp) - return 0; - - if (**cp && strcasecmp("code", **cp)) - return 0; - (*cp)++; - if (isdigit(***cp)) { - if (!ratoi(**cp, &i, 0, 255)) { - fprintf(stderr, - "%d: Invalid icmp code (%s) specified\n", - linenum, **cp); - return -1; - } - } else { - i = icmpcode(**cp); - if (i == -1) { - fprintf(stderr, - "%d: Invalid icmp code (%s) specified\n", - linenum, **cp); - return -1; - } - } - i &= 0xff; - fp->fr_icmp |= (u_short)i; - fp->fr_icmpm = (u_short)0xffff; - (*cp)++; - return 0; -} - - -#define MAX_ICMPCODE 15 - -char *icmpcodes[] = { - "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag", - "srcfail", "net-unk", "host-unk", "isolate", "net-prohib", - "host-prohib", "net-tos", "host-tos", "filter-prohib", "host-preced", - "preced-cutoff", NULL }; -/* - * Return the number for the associated ICMP unreachable code. - */ -int icmpcode(str) -char *str; -{ - char *s; - int i, len; - - if ((s = strrchr(str, ')'))) - *s = '\0'; - if (isdigit(*str)) { - if (!ratoi(str, &i, 0, 255)) - return -1; - else - return i; - } - len = strlen(str); - for (i = 0; icmpcodes[i]; i++) - if (!strncasecmp(str, icmpcodes[i], MIN(len, - strlen(icmpcodes[i])) )) - return i; - return -1; -} - - -/* - * set the icmp field to the correct type if "icmp" word is found - */ -int addkeep(cp, fp, linenum) -char ***cp; -struct frentry *fp; -int linenum; -{ - char *s; - - (*cp)++; - if (!**cp) { - fprintf(stderr, "%d: Missing keyword after keep\n", - linenum); - return -1; - } - - if (strcasecmp(**cp, "state") == 0) - fp->fr_flags |= FR_KEEPSTATE; - else if (strncasecmp(**cp, "frag", 4) == 0) - fp->fr_flags |= FR_KEEPFRAG; - else if (strcasecmp(**cp, "state-age") == 0) { - if (fp->fr_ip.fi_p == IPPROTO_TCP) { - fprintf(stderr, "%d: cannot use state-age with tcp\n", - linenum); - return -1; - } - if ((fp->fr_flags & FR_KEEPSTATE) == 0) { - fprintf(stderr, "%d: state-age with no 'keep state'\n", - linenum); - return -1; - } - (*cp)++; - if (!**cp) { - fprintf(stderr, "%d: state-age with no arg\n", - linenum); - return -1; - } - fp->fr_age[0] = atoi(**cp); - s = index(**cp, '/'); - if (s != NULL) { - s++; - fp->fr_age[1] = atoi(s); - } else - fp->fr_age[1] = fp->fr_age[0]; - } else { - fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n", - linenum, **cp); - return -1; - } - (*cp)++; - return 0; -} - - -void printifname(format, name, ifp) -char *format, *name; -void *ifp; -{ - printf("%s%s", format, name); - if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*")) - printf("(!)"); -} - - -/* - * print the filter structure in a useful way - */ -void printfr(fp) -struct frentry *fp; -{ - struct protoent *p; - u_short sec[2]; - char *s; - u_char *t; - int pr; - - if (fp->fr_flags & FR_PASS) - printf("pass"); - if (fp->fr_flags & FR_NOMATCH) - printf("nomatch"); - else if (fp->fr_flags & FR_BLOCK) { - printf("block"); - if (fp->fr_flags & FR_RETICMP) { - if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP) - printf(" return-icmp-as-dest"); - else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP) - printf(" return-icmp"); - if (fp->fr_icode) { - if (fp->fr_icode <= MAX_ICMPCODE) - printf("(%s)", - icmpcodes[(int)fp->fr_icode]); - else - printf("(%d)", fp->fr_icode); - } - } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) - printf(" return-rst"); - } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) { - printlog(fp); - } else if (fp->fr_flags & FR_ACCOUNT) - printf("count"); - else if (fp->fr_flags & FR_AUTH) { - printf("auth"); - if ((fp->fr_flags & FR_RETMASK) == FR_RETRST) - printf(" return-rst"); - } else if (fp->fr_flags & FR_PREAUTH) - printf("preauth"); - else if (fp->fr_skip) - printf("skip %hu", fp->fr_skip); - - if (fp->fr_flags & FR_OUTQUE) - printf(" out "); - else - printf(" in "); - - if (((fp->fr_flags & FR_LOGB) == FR_LOGB) || - ((fp->fr_flags & FR_LOGP) == FR_LOGP)) { - printlog(fp); - putchar(' '); - } - - if (fp->fr_flags & FR_QUICK) - printf("quick "); - - if (*fp->fr_ifname) { - printifname("on ", fp->fr_ifname, fp->fr_ifa); - if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*")) - printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]); - putchar(' '); - - if (*fp->fr_dif.fd_ifname) - print_toif("dup-to", &fp->fr_dif); - if (*fp->fr_tif.fd_ifname) - print_toif("to", &fp->fr_tif); - if (fp->fr_flags & FR_FASTROUTE) - printf("fastroute "); - - if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) || - (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) { - if (fp->fr_flags & FR_OUTQUE) - printf("in-via "); - else - printf("out-via "); - - if (*fp->fr_ifnames[2]) { - printifname("", fp->fr_ifnames[2], - fp->fr_ifas[2]); - putchar(','); - } - - if (*fp->fr_ifnames[3]) - printifname("", fp->fr_ifnames[3], - fp->fr_ifas[3]); - putchar(' '); - } - } - - if (fp->fr_mip.fi_tos) - printf("tos %#x ", fp->fr_tos); - if (fp->fr_mip.fi_ttl) - printf("ttl %d ", fp->fr_ttl); - if (fp->fr_ip.fi_fl & FI_TCPUDP) { - printf("proto tcp/udp "); - pr = -1; - } else if ((pr = fp->fr_mip.fi_p)) { - if ((p = getprotobynumber(fp->fr_proto))) - printf("proto %s ", p->p_name); - else - printf("proto %d ", fp->fr_proto); - } - - printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : ""); - printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr, - (u_32_t *)&fp->fr_smsk.s_addr); - if (fp->fr_scmp) - printportcmp(pr, &fp->fr_tuc.ftu_src); - - printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : ""); - printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr, - (u_32_t *)&fp->fr_dmsk.s_addr); - if (fp->fr_dcmp) - printportcmp(pr, &fp->fr_tuc.ftu_dst); - - if ((fp->fr_ip.fi_fl & ~FI_TCPUDP) || - (fp->fr_mip.fi_fl & ~FI_TCPUDP) || - fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk || - fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk) { - printf(" with"); - if (fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk || - fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk) { - sec[0] = fp->fr_mip.fi_secmsk; - sec[1] = fp->fr_ip.fi_secmsk; - optprint(sec, - fp->fr_mip.fi_optmsk, fp->fr_ip.fi_optmsk); - } else if (fp->fr_mip.fi_fl & FI_OPTIONS) { - if (!(fp->fr_ip.fi_fl & FI_OPTIONS)) - printf(" not"); - printf(" ipopt"); - } - if (fp->fr_mip.fi_fl & FI_SHORT) { - if (!(fp->fr_ip.fi_fl & FI_SHORT)) - printf(" not"); - printf(" short"); - } - if (fp->fr_mip.fi_fl & FI_FRAG) { - if (!(fp->fr_ip.fi_fl & FI_FRAG)) - printf(" not"); - printf(" frag"); - } - } - if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm != 0) { - int type = fp->fr_icmp, code; - - type = ntohs(fp->fr_icmp); - code = type & 0xff; - type /= 256; - if (type < (sizeof(icmptypes) / sizeof(char *) - 1) && - icmptypes[type]) - printf(" icmp-type %s", icmptypes[type]); - else - printf(" icmp-type %d", type); - if (ntohs(fp->fr_icmpm) & 0xff) - printf(" code %d", code); - } - if (fp->fr_proto == IPPROTO_ICMPV6 && fp->fr_icmpm != 0) { - int type = fp->fr_icmp, code; - - type = ntohs(fp->fr_icmp); - code = type & 0xff; - type /= 256; - printf(" icmp-type %d", type); - if (ntohs(fp->fr_icmpm) & 0xff) - printf(" code %d", code); - } - if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) { - printf(" flags "); - if (fp->fr_tcpf & ~TCPF_ALL) - printf("0x%x", fp->fr_tcpf); - else - for (s = flagset, t = flags; *s; s++, t++) - if (fp->fr_tcpf & *t) - (void)putchar(*s); - if (fp->fr_tcpfm) { - (void)putchar('/'); - if (fp->fr_tcpfm & ~TCPF_ALL) - printf("0x%x", fp->fr_tcpfm); - else - for (s = flagset, t = flags; *s; s++, t++) - if (fp->fr_tcpfm & *t) - (void)putchar(*s); - } - } - - if (fp->fr_flags & FR_KEEPSTATE) - printf(" keep state"); - if (fp->fr_flags & FR_KEEPFRAG) - printf(" keep frags"); - if (fp->fr_age[0] != 0 || fp->fr_age[1]!= 0) - printf(" state-age %u/%u", fp->fr_age[0], fp->fr_age[1]); - if (fp->fr_grhead) - printf(" head %d", fp->fr_grhead); - if (fp->fr_group) - printf(" group %d", fp->fr_group); - (void)putchar('\n'); -} - -void binprint(fp) -struct frentry *fp; -{ - int i = sizeof(*fp), j = 0; - u_char *s; - - for (s = (u_char *)fp; i; i--, s++) { - j++; - printf("%02x ", *s); - if (j == 16) { - printf("\n"); - j = 0; - } - } - putchar('\n'); - (void)fflush(stdout); -} - - -void printlog(fp) -frentry_t *fp; -{ - char *s, *u; - - printf("log"); - if (fp->fr_flags & FR_LOGBODY) - printf(" body"); - if (fp->fr_flags & FR_LOGFIRST) - printf(" first"); - if (fp->fr_flags & FR_LOGORBLOCK) - printf(" or-block"); - if (fp->fr_loglevel != 0xffff) { - printf(" level "); - if (fp->fr_loglevel & LOG_FACMASK) { - s = fac_toname(fp->fr_loglevel); - if (s == NULL) - s = "!!!"; - } else - s = ""; - u = pri_toname(fp->fr_loglevel); - if (u == NULL) - u = "!!!"; - if (*s) - printf("%s.%s", s, u); - else - printf("%s", u); - } -} diff --git a/contrib/ipfilter/pcap.h b/contrib/ipfilter/pcap.h deleted file mode 100644 index aa2479811a89..000000000000 --- a/contrib/ipfilter/pcap.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * $Id: pcap.h,v 2.2.2.1 2001/06/26 10:43:20 darrenr Exp $ - */ -/* - * This header file is constructed to match the version described by - * PCAP_VERSION_MAJ. - * - * The structure largely derives from libpcap which wouldn't include - * nicely without bpf. - */ -typedef struct pcap_filehdr { - u_int pc_id; - u_short pc_v_maj; - u_short pc_v_min; - u_int pc_zone; - u_int pc_sigfigs; - u_int pc_slen; - u_int pc_type; -} pcaphdr_t; - -#define TCPDUMP_MAGIC 0xa1b2c3d4 - -#define PCAP_VERSION_MAJ 2 - -typedef struct pcap_pkthdr { - struct timeval ph_ts; - u_int ph_clen; - u_int ph_len; -} pcappkt_t; - diff --git a/contrib/ipfilter/printnat.c b/contrib/ipfilter/printnat.c deleted file mode 100644 index 5a12b32165bd..000000000000 --- a/contrib/ipfilter/printnat.c +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Copyright (C) 1993-2001 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - * - * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#if !defined(__SVR4) && !defined(__svr4__) -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) -# include -# include -#endif -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include -#include -#include -#include -#include -#include "netinet/ip_compat.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_nat.h" -#include "netinet/ip_state.h" -#include "netinet/ip_proxy.h" -#include "ipf.h" -#include "kmem.h" - -#if defined(sun) && !SOLARIS2 -# define STRERROR(x) sys_errlist[x] -extern char *sys_errlist[]; -#else -# define STRERROR(x) strerror(x) -#endif - -#if !defined(lint) -static const char rcsid[] = "@(#)$Id: printnat.c,v 1.1.2.15 2003/03/22 15:31:49 darrenr Exp $"; -#endif - - -#if SOLARIS -#define bzero(a,b) memset(a,0,b) -#endif -#ifdef USE_INET6 -extern int use_inet6; -#endif - -extern char thishost[MAXHOSTNAMELEN]; - -extern int countbits __P((u_32_t)); - -void printnat __P((ipnat_t *, int)); -char *getnattype __P((ipnat_t *)); -void printactivenat __P((nat_t *, int)); -void printhostmap __P((hostmap_t *, u_int)); -char *getsumd __P((u_32_t)); - -static void printaps __P((ap_session_t *, int)); - -static void printaps(aps, opts) -ap_session_t *aps; -int opts; -{ - ipsec_pxy_t ipsec; - ap_session_t ap; - ftpinfo_t ftp; - aproxy_t apr; - raudio_t ra; - - if (kmemcpy((char *)&ap, (long)aps, sizeof(ap))) - return; - if (kmemcpy((char *)&apr, (long)ap.aps_apr, sizeof(apr))) - return; - printf("\tproxy %s/%d use %d flags %x\n", apr.apr_label, - apr.apr_p, apr.apr_ref, apr.apr_flags); - printf("\t\tproto %d flags %#x bytes ", ap.aps_p, ap.aps_flags); -#ifdef USE_QUAD_T - printf("%qu pkts %qu", (unsigned long long)ap.aps_bytes, - (unsigned long long)ap.aps_pkts); -#else - printf("%lu pkts %lu", ap.aps_bytes, ap.aps_pkts); -#endif - printf(" data %s size %d\n", ap.aps_data ? "YES" : "NO", ap.aps_psiz); - if ((ap.aps_p == IPPROTO_TCP) && (opts & OPT_VERBOSE)) { - printf("\t\tstate[%u,%u], sel[%d,%d]\n", - ap.aps_state[0], ap.aps_state[1], - ap.aps_sel[0], ap.aps_sel[1]); -#if (defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011)) || \ - (__FreeBSD_version >= 300000) || defined(OpenBSD) - printf("\t\tseq: off %hd/%hd min %x/%x\n", - ap.aps_seqoff[0], ap.aps_seqoff[1], - ap.aps_seqmin[0], ap.aps_seqmin[1]); - printf("\t\tack: off %hd/%hd min %x/%x\n", - ap.aps_ackoff[0], ap.aps_ackoff[1], - ap.aps_ackmin[0], ap.aps_ackmin[1]); -#else - printf("\t\tseq: off %hd/%hd min %lx/%lx\n", - ap.aps_seqoff[0], ap.aps_seqoff[1], - ap.aps_seqmin[0], ap.aps_seqmin[1]); - printf("\t\tack: off %hd/%hd min %lx/%lx\n", - ap.aps_ackoff[0], ap.aps_ackoff[1], - ap.aps_ackmin[0], ap.aps_ackmin[1]); -#endif - } - - if (!strcmp(apr.apr_label, "raudio") && ap.aps_psiz == sizeof(ra)) { - if (kmemcpy((char *)&ra, (long)ap.aps_data, sizeof(ra))) - return; - printf("\tReal Audio Proxy:\n"); - printf("\t\tSeen PNA: %d\tVersion: %d\tEOS: %d\n", - ra.rap_seenpna, ra.rap_version, ra.rap_eos); - printf("\t\tMode: %#x\tSBF: %#x\n", ra.rap_mode, ra.rap_sbf); - printf("\t\tPorts:pl %hu, pr %hu, sr %hu\n", - ra.rap_plport, ra.rap_prport, ra.rap_srport); - } else if (!strcmp(apr.apr_label, "ftp") && - (ap.aps_psiz == sizeof(ftp))) { - if (kmemcpy((char *)&ftp, (long)ap.aps_data, sizeof(ftp))) - return; - printf("\tFTP Proxy:\n"); - printf("\t\tpassok: %d\n", ftp.ftp_passok); - ftp.ftp_side[0].ftps_buf[FTP_BUFSZ - 1] = '\0'; - ftp.ftp_side[1].ftps_buf[FTP_BUFSZ - 1] = '\0'; - printf("\tClient:\n"); - printf("\t\tseq %08x%08x len %d junk %d cmds %d\n", - ftp.ftp_side[0].ftps_seq[1], - ftp.ftp_side[0].ftps_seq[0], - ftp.ftp_side[0].ftps_len, - ftp.ftp_side[0].ftps_junk, ftp.ftp_side[0].ftps_cmds); - printf("\t\tbuf ["); - printbuf(ftp.ftp_side[0].ftps_buf, FTP_BUFSZ, 1); - printf("]\n\tServer:\n"); - printf("\t\tseq %08x%08x len %d junk %d cmds %d\n", - ftp.ftp_side[1].ftps_seq[1], - ftp.ftp_side[1].ftps_seq[0], - ftp.ftp_side[1].ftps_len, - ftp.ftp_side[1].ftps_junk, ftp.ftp_side[1].ftps_cmds); - printf("\t\tbuf ["); - printbuf(ftp.ftp_side[1].ftps_buf, FTP_BUFSZ, 1); - printf("]\n"); - } else if (!strcmp(apr.apr_label, "ipsec") && - (ap.aps_psiz == sizeof(ipsec))) { - if (kmemcpy((char *)&ipsec, (long)ap.aps_data, sizeof(ipsec))) - return; - printf("\tIPSec Proxy:\n"); - printf("\t\tICookie %08x%08x RCookie %08x%08x %s\n", - (u_int)ntohl(ipsec.ipsc_icookie[0]), - (u_int)ntohl(ipsec.ipsc_icookie[1]), - (u_int)ntohl(ipsec.ipsc_rcookie[0]), - (u_int)ntohl(ipsec.ipsc_rcookie[1]), - ipsec.ipsc_rckset ? "(Set)" : "(Not set)"); - } -} - - -/* - * Get a nat filter type given its kernel address. - */ -char *getnattype(ipnat) -ipnat_t *ipnat; -{ - static char unknownbuf[20]; - ipnat_t ipnatbuff; - char *which; - - if (!ipnat || (ipnat && kmemcpy((char *)&ipnatbuff, (long)ipnat, - sizeof(ipnatbuff)))) - return "???"; - - switch (ipnatbuff.in_redir) - { - case NAT_MAP : - which = "MAP"; - break; - case NAT_MAPBLK : - which = "MAP-BLOCK"; - break; - case NAT_REDIRECT : - which = "RDR"; - break; - case NAT_BIMAP : - which = "BIMAP"; - break; - default : - sprintf(unknownbuf, "unknown(%04x)", - ipnatbuff.in_redir & 0xffffffff); - which = unknownbuf; - break; - } - return which; -} - - -void printactivenat(nat, opts) -nat_t *nat; -int opts; -{ - u_int hv1, hv2; - - printf("%s %-15s", getnattype(nat->nat_ptr), inet_ntoa(nat->nat_inip)); - - if ((nat->nat_flags & IPN_TCPUDP) != 0) - printf(" %-5hu", ntohs(nat->nat_inport)); - - printf(" <- -> %-15s",inet_ntoa(nat->nat_outip)); - - if ((nat->nat_flags & IPN_TCPUDP) != 0) - printf(" %-5hu", ntohs(nat->nat_outport)); - - printf(" [%s", inet_ntoa(nat->nat_oip)); - if ((nat->nat_flags & IPN_TCPUDP) != 0) - printf(" %hu", ntohs(nat->nat_oport)); - printf("]"); - - if (opts & OPT_VERBOSE) { - printf("\n\tage %lu use %hu sumd %s/", - nat->nat_age, nat->nat_use, getsumd(nat->nat_sumd[0])); - hv1 = NAT_HASH_FN(nat->nat_inip.s_addr, nat->nat_inport, - 0xffffffff), - hv1 = NAT_HASH_FN(nat->nat_oip.s_addr, hv1 + nat->nat_oport, - NAT_TABLE_SZ), - hv2 = NAT_HASH_FN(nat->nat_outip.s_addr, nat->nat_outport, - 0xffffffff), - hv2 = NAT_HASH_FN(nat->nat_oip.s_addr, hv2 + nat->nat_oport, - NAT_TABLE_SZ), - printf("%s pr %u bkt %d/%d flags %x drop %d/%d\n", - getsumd(nat->nat_sumd[1]), nat->nat_p, - hv1, hv2, nat->nat_flags, - nat->nat_drop[0], nat->nat_drop[1]); - printf("\tifp %s ", getifname(nat->nat_ifp)); -#ifdef USE_QUAD_T - printf("bytes %qu pkts %qu", - (unsigned long long)nat->nat_bytes, - (unsigned long long)nat->nat_pkts); -#else - printf("bytes %lu pkts %lu", nat->nat_bytes, nat->nat_pkts); -#endif -#if SOLARIS - printf(" %lx", nat->nat_ipsumd); -#endif - } - - putchar('\n'); - if (nat->nat_aps) - printaps(nat->nat_aps, opts); -} - - -void printhostmap(hmp, hv) -hostmap_t *hmp; -u_int hv; -{ - printf("%s -> ", inet_ntoa(hmp->hm_realip)); - printf("%s ", inet_ntoa(hmp->hm_mapip)); - printf("(use = %d hv = %u)\n", hmp->hm_ref, hv); -} - - -char *getsumd(sum) -u_32_t sum; -{ - static char sumdbuf[17]; - - if (sum & NAT_HW_CKSUM) - sprintf(sumdbuf, "hw(%#0x)", sum & 0xffff); - else - sprintf(sumdbuf, "%#0x", sum); - return sumdbuf; -} - - -/* - * Print out a NAT rule - */ -void printnat(np, opts) -ipnat_t *np; -int opts; -{ - struct protoent *pr; - struct servent *sv; - int bits; - - pr = getprotobynumber(np->in_p); - - switch (np->in_redir) - { - case NAT_REDIRECT : - printf("rdr"); - break; - case NAT_MAP : - printf("map"); - break; - case NAT_MAPBLK : - printf("map-block"); - break; - case NAT_BIMAP : - printf("bimap"); - break; - default : - fprintf(stderr, "unknown value for in_redir: %#x\n", - np->in_redir); - break; - } - - printf(" %s ", np->in_ifname); - - if (np->in_flags & IPN_FILTER) { - if (np->in_flags & IPN_NOTSRC) - printf("! "); - printf("from "); - if (np->in_redir == NAT_REDIRECT) { - printhostmask(4, (u_32_t *)&np->in_srcip, - (u_32_t *)&np->in_srcmsk); - } else { - printhostmask(4, (u_32_t *)&np->in_inip, - (u_32_t *)&np->in_inmsk); - } - if (np->in_scmp) - printportcmp(np->in_p, &np->in_tuc.ftu_src); - - if (np->in_flags & IPN_NOTDST) - printf(" !"); - printf(" to "); - if (np->in_redir == NAT_REDIRECT) { - printhostmask(4, (u_32_t *)&np->in_outip, - (u_32_t *)&np->in_outmsk); - } else { - printhostmask(4, (u_32_t *)&np->in_srcip, - (u_32_t *)&np->in_srcmsk); - } - if (np->in_dcmp) - printportcmp(np->in_p, &np->in_tuc.ftu_dst); - } - - if (np->in_redir == NAT_REDIRECT) { - if (!(np->in_flags & IPN_FILTER)) { - printf("%s", inet_ntoa(np->in_out[0])); - bits = countbits(np->in_out[1].s_addr); - if (bits != -1) - printf("/%d ", bits); - else - printf("/%s ", inet_ntoa(np->in_out[1])); - printf("port %d", ntohs(np->in_pmin)); - if (np->in_pmax != np->in_pmin) - printf("- %d", ntohs(np->in_pmax)); - } - printf(" -> %s", inet_ntoa(np->in_in[0])); - if (np->in_flags & IPN_SPLIT) - printf(",%s", inet_ntoa(np->in_in[1])); - printf(" port %d", ntohs(np->in_pnext)); - if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) - printf(" tcp/udp"); - else if ((np->in_flags & IPN_TCP) == IPN_TCP) - printf(" tcp"); - else if ((np->in_flags & IPN_UDP) == IPN_UDP) - printf(" udp"); - else if (np->in_p == 0) - printf(" ip"); - else if (np->in_p != 0) { - if (pr != NULL) - printf(" %s", pr->p_name); - else - printf(" %d", np->in_p); - } - if (np->in_flags & IPN_ROUNDR) - printf(" round-robin"); - if (np->in_flags & IPN_FRAG) - printf(" frag"); - if (np->in_age[0]) - printf(" age %d/%d", np->in_age[0], np->in_age[1]); - if (np->in_mssclamp) - printf(" mssclamp %u", np->in_mssclamp); - printf("\n"); - if (opts & OPT_DEBUG) - printf("\tspc %lu flg %#x max %u use %d\n", - np->in_space, np->in_flags, - np->in_pmax, np->in_use); - } else { - if (!(np->in_flags & IPN_FILTER)) { - printf("%s/", inet_ntoa(np->in_in[0])); - bits = countbits(np->in_in[1].s_addr); - if (bits != -1) - printf("%d", bits); - else - printf("%s", inet_ntoa(np->in_in[1])); - } - printf(" -> "); - if (np->in_flags & IPN_IPRANGE) { - printf("range %s-", inet_ntoa(np->in_out[0])); - printf("%s", inet_ntoa(np->in_out[1])); - } else { - printf("%s/", inet_ntoa(np->in_out[0])); - bits = countbits(np->in_out[1].s_addr); - if (bits != -1) - printf("%d", bits); - else - printf("%s", inet_ntoa(np->in_out[1])); - } - if (*np->in_plabel) { - printf(" proxy port"); - if (np->in_dcmp != 0) - np->in_dport = htons(np->in_dport); - if (np->in_dport != 0) { - if (pr != NULL) - sv = getservbyport(np->in_dport, - pr->p_name); - else - sv = getservbyport(np->in_dport, NULL); - if (sv != NULL) - printf(" %s", sv->s_name); - else - printf(" %hu", ntohs(np->in_dport)); - } - printf(" %.*s/", (int)sizeof(np->in_plabel), - np->in_plabel); - if (pr != NULL) - fputs(pr->p_name, stdout); - else - printf("%d", np->in_p); - } else if (np->in_redir == NAT_MAPBLK) { - if ((np->in_pmin == 0) && - (np->in_flags & IPN_AUTOPORTMAP)) - printf(" ports auto"); - else - printf(" ports %d", np->in_pmin); - if (opts & OPT_DEBUG) - printf("\n\tip modulous %d", np->in_pmax); - } else if (np->in_pmin || np->in_pmax) { - printf(" portmap"); - if ((np->in_flags & IPN_TCPUDP) == IPN_TCPUDP) - printf(" tcp/udp"); - else if (np->in_flags & IPN_TCP) - printf(" tcp"); - else if (np->in_flags & IPN_UDP) - printf(" udp"); - if (np->in_flags & IPN_AUTOPORTMAP) { - printf(" auto"); - if (opts & OPT_DEBUG) - printf(" [%d:%d %d %d]", - ntohs(np->in_pmin), - ntohs(np->in_pmax), - np->in_ippip, np->in_ppip); - } else { - printf(" %d:%d", ntohs(np->in_pmin), - ntohs(np->in_pmax)); - } - } - if (np->in_flags & IPN_FRAG) - printf(" frag"); - if (np->in_age[0]) - printf(" age %d/%d", np->in_age[0], np->in_age[1]); - printf("\n"); - if (opts & OPT_DEBUG) { - struct in_addr nip; - - nip.s_addr = htonl(np->in_nextip.s_addr); - - printf("\tspace %lu nextip %s pnext %d", np->in_space, - inet_ntoa(nip), np->in_pnext); - printf(" flags %x use %u\n", - np->in_flags, np->in_use); - } - } -} diff --git a/contrib/ipfilter/printstate.c b/contrib/ipfilter/printstate.c deleted file mode 100644 index 624493b4686c..000000000000 --- a/contrib/ipfilter/printstate.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#if defined(__sgi) && (IRIX > 602) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if __FreeBSD_version >= 300000 -# include -#endif -#include "kmem.h" -#include "netinet/ip_compat.h" -#include "ipf.h" -#include "netinet/ip_fil.h" -#include "netinet/ip_state.h" - -#define PRINTF (void)printf -#define FPRINTF (void)fprintf - -ipstate_t *printstate(sp, opts) -ipstate_t *sp; -int opts; -{ - ipstate_t ips; - - if (kmemcpy((char *)&ips, (u_long)sp, sizeof(ips))) - return NULL; - - PRINTF("%s -> ", hostname(ips.is_v, &ips.is_src.in4)); - PRINTF("%s ttl %ld pass %#x pr %d state %d/%d\n", - hostname(ips.is_v, &ips.is_dst.in4), - ips.is_age, ips.is_pass, ips.is_p, - ips.is_state[0], ips.is_state[1]); -#ifdef USE_QUAD_T - PRINTF("\tpkts %qu bytes %qu", (unsigned long long) ips.is_pkts, - (unsigned long long) ips.is_bytes); -#else - PRINTF("\tpkts %ld bytes %ld", ips.is_pkts, ips.is_bytes); -#endif - if (ips.is_p == IPPROTO_TCP) { -#if defined(NetBSD) && (NetBSD >= 199905) && (NetBSD < 1991011) || \ -(__FreeBSD_version >= 220000) || defined(__OpenBSD__) - PRINTF("\t%hu -> %hu %x:%x (max %x:%x)\n", - ntohs(ips.is_sport), ntohs(ips.is_dport), - ips.is_send, ips.is_dend, - ips.is_maxsend, ips.is_maxdend); - PRINTF("\t%u<<%d:%u<<%d", - ips.is_maxswin>>ips.is_swscale, ips.is_swscale, - ips.is_maxdwin>>ips.is_dwscale, ips.is_dwscale); -#else - PRINTF("\t%hu -> %hu %x:%x (max %x:%x)\n", - ntohs(ips.is_sport), ntohs(ips.is_dport), - ips.is_send, ips.is_dend, - ips.is_maxsend, ips.is_maxdend); - PRINTF("\t%u<<%d:%u<<%d", - ips.is_maxswin>>ips.is_swscale, ips.is_swscale, - ips.is_maxdwin>>ips.is_dwscale, ips.is_dwscale); -#endif - } else if (ips.is_p == IPPROTO_UDP) - PRINTF(" %hu -> %hu", ntohs(ips.is_sport), - ntohs(ips.is_dport)); - else if (ips.is_p == IPPROTO_ICMP -#ifdef USE_INET6 - || ips.is_p == IPPROTO_ICMPV6 -#endif - ) - PRINTF(" id %hu seq %hu type %d", ntohs(ips.is_icmp.ics_id), - ntohs(ips.is_icmp.ics_seq), ips.is_icmp.ics_type); - - PRINTF("\n\t"); - - /* - * Print out bits set in the result code for the state being - * kept as they would for a rule. - */ - if (ips.is_pass & FR_PASS) { - PRINTF("pass"); - } else if (ips.is_pass & FR_BLOCK) { - PRINTF("block"); - switch (ips.is_pass & FR_RETMASK) - { - case FR_RETICMP : - PRINTF(" return-icmp"); - break; - case FR_FAKEICMP : - PRINTF(" return-icmp-as-dest"); - break; - case FR_RETRST : - PRINTF(" return-rst"); - break; - default : - break; - } - } else if ((ips.is_pass & FR_LOGMASK) == FR_LOG) { - PRINTF("log"); - if (ips.is_pass & FR_LOGBODY) - PRINTF(" body"); - if (ips.is_pass & FR_LOGFIRST) - PRINTF(" first"); - } else if (ips.is_pass & FR_ACCOUNT) - PRINTF("count"); - - if (ips.is_pass & FR_OUTQUE) - PRINTF(" out"); - else - PRINTF(" in"); - - if ((ips.is_pass & FR_LOG) != 0) { - PRINTF(" log"); - if (ips.is_pass & FR_LOGBODY) - PRINTF(" body"); - if (ips.is_pass & FR_LOGFIRST) - PRINTF(" first"); - if (ips.is_pass & FR_LOGORBLOCK) - PRINTF(" or-block"); - } - if (ips.is_pass & FR_QUICK) - PRINTF(" quick"); - if (ips.is_pass & FR_KEEPFRAG) - PRINTF(" keep frags"); - /* a given; no? */ - if (ips.is_pass & FR_KEEPSTATE) - PRINTF(" keep state"); - PRINTF("\tIPv%d", ips.is_v); - PRINTF("\n"); - - PRINTF("\tpkt_flags & %x(%x) = %x,\t", - ips.is_flags & 0xf, ips.is_flags, - ips.is_flags >> 4); - PRINTF("\tpkt_options & %x = %x\n", ips.is_optmsk, - ips.is_opt); - PRINTF("\tpkt_security & %x = %x, pkt_auth & %x = %x\n", - ips.is_secmsk, ips.is_sec, ips.is_authmsk, - ips.is_auth); - PRINTF("\tinterfaces: in %s", getifname(ips.is_ifp[0])); - PRINTF(",%s", getifname(ips.is_ifp[1])); - PRINTF(" out %s", getifname(ips.is_ifp[2])); - PRINTF(",%s\n", getifname(ips.is_ifp[3])); - - return ips.is_next; -} diff --git a/contrib/ipfilter/relay.c b/contrib/ipfilter/relay.c deleted file mode 100644 index 6a67433c61a9..000000000000 --- a/contrib/ipfilter/relay.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Sample program to be used as a transparent proxy. - * - * Must be executed with permission enough to do an ioctl on /dev/ipl - * or equivalent. This is just a sample and is only alpha quality. - * - Darren Reed (8 April 1996) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000) -# include -# define USE_POLL -#endif -#include "ip_nat.h" - -#define RELAY_BUFSZ 8192 - -char ibuff[RELAY_BUFSZ]; -char obuff[RELAY_BUFSZ]; - -int relay(ifd, ofd, rfd) -int ifd, ofd, rfd; -{ -#ifdef USE_POLL - struct pollfd set[3]; -#else - fd_set rfds, wfds; -#endif - char *irh, *irt, *rrh, *rrt; - char *iwh, *iwt, *rwh, *rwt; - int nfd, n, rw; - - irh = irt = ibuff; - iwh = iwt = obuff; - nfd = ifd; - if (nfd < ofd) - nfd = ofd; - if (nfd < rfd) - nfd = rfd; - -#ifdef USE_POLL - set[0].fd = rfd; - set[1].fd = ifd; - set[2].fd = ofd; -#endif - - while (1) { -#ifdef USE_POLL - set[0].events = (iwh < (obuff + RELAY_BUFSZ) ? POLLIN : 0) | - (irh > irt ? POLLOUT : 0); - set[1].events = (irh < (ibuff + RELAY_BUFSZ) ? POLLIN : 0); - set[2].events = (iwh > iwt ? POLLOUT : 0); - - switch ((n = poll(set, 3, INFTIM))) -#else - FD_ZERO(&rfds); - FD_ZERO(&wfds); - if (irh > irt) - FD_SET(rfd, &wfds); - if (irh < (ibuff + RELAY_BUFSZ)) - FD_SET(ifd, &rfds); - if (iwh > iwt) - FD_SET(ofd, &wfds); - if (iwh < (obuff + RELAY_BUFSZ)) - FD_SET(rfd, &rfds); - - switch ((n = select(nfd + 1, &rfds, &wfds, NULL, NULL))) -#endif - { - case -1 : - case 0 : - return -1; - default : -#ifdef USE_POLL - if (set[1].revents & POLLIN) -#else - if (FD_ISSET(ifd, &rfds)) -#endif - { - rw = read(ifd, irh, ibuff + RELAY_BUFSZ - irh); - if (rw == -1) - return -1; - if (rw == 0) - return 0; - irh += rw; - n--; - } -#ifdef USE_POLL - if (set[2].revents & POLLOUT) -#else - if (n && FD_ISSET(ofd, &wfds)) -#endif - { - rw = write(ofd, iwt, iwh - iwt); - if (rw == -1) - return -1; - iwt += rw; - n--; - } -#ifdef USE_POLL - if (set[0].revents & POLLIN) -#else - if (n && FD_ISSET(rfd, &rfds)) -#endif - { - rw = read(rfd, iwh, obuff + RELAY_BUFSZ - iwh); - if (rw == -1) - return -1; - if (rw == 0) - return 0; - iwh += rw; - n--; - } -#ifdef USE_POLL - if (set[0].revents & POLLOUT) -#else - if (n && FD_ISSET(rfd, &wfds)) -#endif - { - rw = write(rfd, irt, irh - irt); - if (rw == -1) - return -1; - irt += rw; - n--; - } - if (irh == irt) - irh = irt = ibuff; - if (iwh == iwt) - iwh = iwt = obuff; - } - } -} - -main(argc, argv) -int argc; -char *argv[]; -{ - struct sockaddr_in sin; - natlookup_t nl; - natlookup_t *nlp = &nl; - int fd, sl = sizeof(sl), se; - - openlog(argv[0], LOG_PID|LOG_NDELAY, LOG_DAEMON); - if ((fd = open("/dev/ipnat", O_RDONLY)) == -1) { - se = errno; - perror("open"); - errno = se; - syslog(LOG_ERR, "open: %m\n"); - exit(-1); - } - - bzero(&nl, sizeof(nl)); - nl.nl_flags = IPN_TCP; - - bzero(&sin, sizeof(sin)); - sin.sin_family = AF_INET; - sl = sizeof(sin); - if (getsockname(0, (struct sockaddr *)&sin, &sl) == -1) { - se = errno; - perror("getsockname"); - errno = se; - syslog(LOG_ERR, "getsockname: %m\n"); - exit(-1); - } else { - nl.nl_inip.s_addr = sin.sin_addr.s_addr; - nl.nl_inport = sin.sin_port; - } - - bzero(&sin, sizeof(sin)); - sin.sin_family = AF_INET; - sl = sizeof(sin); - if (getpeername(0, (struct sockaddr *)&sin, &sl) == -1) { - se = errno; - perror("getpeername"); - errno = se; - syslog(LOG_ERR, "getpeername: %m\n"); - exit(-1); - } else { - nl.nl_outip.s_addr = sin.sin_addr.s_addr; - nl.nl_outport = sin.sin_port; - } - - if (ioctl(fd, SIOCGNATL, &nlp) == -1) { - se = errno; - perror("ioctl"); - errno = se; - syslog(LOG_ERR, "ioctl: %m\n"); - exit(-1); - } - - sin.sin_port = nl.nl_realport; - sin.sin_addr = nl.nl_realip; - sl = sizeof(sin); - - fd = socket(AF_INET, SOCK_STREAM, 0); - if (connect(fd, (struct sockaddr *)&sin, sl) == -1) { - se = errno; - perror("connect"); - errno = se; - syslog(LOG_ERR, "connect: %m\n"); - exit(-1); - } - - (void) ioctl(fd, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); - (void) ioctl(0, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); - (void) ioctl(1, F_SETFL, ioctl(fd, F_GETFL, 0)|O_NONBLOCK); - - syslog(LOG_NOTICE, "connected to %s,%d\n", inet_ntoa(sin.sin_addr), - ntohs(sin.sin_port)); - if (relay(0, 1, fd) == -1) { - se = errno; - perror("relay"); - errno = se; - syslog(LOG_ERR, "relay: %m\n"); - exit(-1); - } - exit(0); -} diff --git a/contrib/ipfilter/rules/.cvsignore b/contrib/ipfilter/rules/.cvsignore deleted file mode 100644 index 3e757656cf36..000000000000 --- a/contrib/ipfilter/rules/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -new diff --git a/contrib/ipfilter/rules/rules.sed b/contrib/ipfilter/rules/rules.sed deleted file mode 100644 index 050d9b6ab710..000000000000 --- a/contrib/ipfilter/rules/rules.sed +++ /dev/null @@ -1,5 +0,0 @@ -WÆ . Ä..'& CVSWÜ example.1WÝ -example.10WÞ -example.11Wß -example.12Wà -example.13Wá example.2Wâ example.3Wã example.4Wä example.5Wå example.6Wæ example.7Wç example.8Wè example.9Wé diff --git a/contrib/ipfilter/samples/.cvsignore b/contrib/ipfilter/samples/.cvsignore deleted file mode 100644 index 4d38251c2f4f..000000000000 --- a/contrib/ipfilter/samples/.cvsignore +++ /dev/null @@ -1,4 +0,0 @@ -userauth -proxy -relay -trans_relay diff --git a/contrib/ipfilter/solaris.c b/contrib/ipfilter/solaris.c deleted file mode 100644 index aa139d3b042a..000000000000 --- a/contrib/ipfilter/solaris.c +++ /dev/null @@ -1,2131 +0,0 @@ -/* - * Copyright (C) 1993-2002 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -/* #pragma ident "@(#)solaris.c 1.12 6/5/96 (C) 1995 Darren Reed"*/ -#pragma ident "@(#)$Id: solaris.c,v 2.15.2.30 2002/04/23 14:57:51 darrenr Exp $" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if SOLARIS2 >= 6 -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ip_compat.h" -#include "ipl.h" -#include "ip_fil.h" -#include "ip_nat.h" -#include "ip_state.h" - - -char _depends_on[] = "drv/ip"; - - -void solipdrvattach __P((void)); -int solipdrvdetach __P((void)); - -void solattach __P((void)); -int soldetach __P((void)); - -extern struct filterstats frstats[]; -extern KRWLOCK_T ipf_mutex, ipfs_mutex, ipf_nat, ipf_solaris; -extern kmutex_t ipf_rw; -extern int fr_running; -extern int fr_flags; - -extern ipnat_t *nat_list; - -static qif_t *qif_head = NULL; -static int ipf_getinfo __P((dev_info_t *, ddi_info_cmd_t, - void *, void **)); -static int ipf_probe __P((dev_info_t *)); -static int ipf_identify __P((dev_info_t *)); -static int ipf_attach __P((dev_info_t *, ddi_attach_cmd_t)); -static int ipf_detach __P((dev_info_t *, ddi_detach_cmd_t)); -static qif_t *qif_from_queue __P((queue_t *)); -static void fr_donotip __P((int, qif_t *, queue_t *, mblk_t *, - mblk_t *, ip_t *, size_t)); -static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH, - NULL }; -static int (*ipf_ip_inp) __P((queue_t *, mblk_t *)) = NULL; - - -#if SOLARIS2 >= 7 -extern void ipfr_slowtimer __P((void *)); -timeout_id_t ipfr_timer_id; -static timeout_id_t synctimeoutid = 0; -#else -extern void ipfr_slowtimer __P((void)); -int ipfr_timer_id; -static int synctimeoutid = 0; -#endif -int ipf_debug = 0; -int ipf_debug_verbose = 0; - -/* #undef IPFDEBUG 1 */ -/* #undef IPFDEBUG_VERBOSE 1 */ -#ifdef IPFDEBUG -void printire __P((ire_t *)); -#endif -#define isdigit(x) ((x) >= '0' && (x) <= '9') - -static int fr_precheck __P((mblk_t **, queue_t *, qif_t *, int)); - - -static struct cb_ops ipf_cb_ops = { - iplopen, - iplclose, - nodev, /* strategy */ - nodev, /* print */ - nodev, /* dump */ - iplread, - nodev, /* write */ - iplioctl, /* ioctl */ - nodev, /* devmap */ - nodev, /* mmap */ - nodev, /* segmap */ - nochpoll, /* poll */ - ddi_prop_op, - NULL, - D_MTSAFE, -#if SOLARIS2 > 4 - CB_REV, - nodev, /* aread */ - nodev, /* awrite */ -#endif -}; - -static struct dev_ops ipf_ops = { - DEVO_REV, - 0, - ipf_getinfo, - ipf_identify, - ipf_probe, - ipf_attach, - ipf_detach, - nodev, /* reset */ - &ipf_cb_ops, - (struct bus_ops *)0 -}; - -extern struct mod_ops mod_driverops; -static struct modldrv iplmod = { - &mod_driverops, IPL_VERSION, &ipf_ops }; -static struct modlinkage modlink1 = { MODREV_1, &iplmod, NULL }; - -#if SOLARIS2 >= 6 -static size_t hdrsizes[57][2] = { - { 0, 0 }, - { IFT_OTHER, 0 }, - { IFT_1822, 14 }, /* 14 for ire0 ?? */ - { IFT_HDH1822, 0 }, - { IFT_X25DDN, 0 }, - { IFT_X25, 0 }, - { IFT_ETHER, 14 }, - { IFT_ISO88023, 14 }, - { IFT_ISO88024, 0 }, - { IFT_ISO88025, 0 }, - { IFT_ISO88026, 0 }, - { IFT_STARLAN, 0 }, - { IFT_P10, 0 }, - { IFT_P80, 0 }, - { IFT_HY, 0 }, - { IFT_FDDI, 24 }, - { IFT_LAPB, 0 }, - { IFT_SDLC, 0 }, - { IFT_T1, 0 }, - { IFT_CEPT, 0 }, - { IFT_ISDNBASIC, 0 }, - { IFT_ISDNPRIMARY, 0 }, - { IFT_PTPSERIAL, 0 }, - { IFT_PPP, 0 }, - { IFT_LOOP, 0 }, - { IFT_EON, 0 }, - { IFT_XETHER, 0 }, - { IFT_NSIP, 0 }, - { IFT_SLIP, 0 }, - { IFT_ULTRA, 0 }, - { IFT_DS3, 0 }, - { IFT_SIP, 0 }, - { IFT_FRELAY, 0 }, - { IFT_RS232, 0 }, - { IFT_PARA, 0 }, - { IFT_ARCNET, 0 }, - { IFT_ARCNETPLUS, 0 }, - { IFT_ATM, 0 }, - { IFT_MIOX25, 0 }, - { IFT_SONET, 0 }, - { IFT_X25PLE, 0 }, - { IFT_ISO88022LLC, 0 }, - { IFT_LOCALTALK, 0 }, - { IFT_SMDSDXI, 0 }, - { IFT_FRELAYDCE, 0 }, - { IFT_V35, 0 }, - { IFT_HSSI, 0 }, - { IFT_HIPPI, 0 }, - { IFT_MODEM, 0 }, - { IFT_AAL5, 0 }, - { IFT_SONETPATH, 0 }, - { IFT_SONETVT, 0 }, - { IFT_SMDSICIP, 0 }, - { IFT_PROPVIRTUAL, 0 }, - { IFT_PROPMUX, 0 }, -}; -#endif /* SOLARIS2 >= 6 */ - -static dev_info_t *ipf_dev_info = NULL; - - -int _init() -{ - int ipfinst; - - ipfinst = mod_install(&modlink1); -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: _init() = %d", ipfinst); -#endif - return ipfinst; -} - - -int _fini(void) -{ - int ipfinst; - - ipfinst = mod_remove(&modlink1); -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: _fini() = %d", ipfinst); -#endif - return ipfinst; -} - - -int _info(modinfop) -struct modinfo *modinfop; -{ - int ipfinst; - - ipfinst = mod_info(&modlink1, modinfop); -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: _info(%x) = %x", - modinfop, ipfinst); -#endif - if (fr_running > 0) - ipfsync(); - return ipfinst; -} - - -static int ipf_probe(dip) -dev_info_t *dip; -{ - if (fr_running < 0) - return DDI_PROBE_FAILURE; -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: ipf_probe(%x)", dip); -#endif - return DDI_PROBE_SUCCESS; -} - - -static int ipf_identify(dip) -dev_info_t *dip; -{ -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: ipf_identify(%x)", dip); -#endif - if (strcmp(ddi_get_name(dip), "ipf") == 0) - return (DDI_IDENTIFIED); - return (DDI_NOT_IDENTIFIED); -} - - -static void ipf_ire_walk(ire, arg) -ire_t *ire; -void *arg; -{ - qif_t *qif = arg; - - if ((ire->ire_type == IRE_CACHE) && -#if SOLARIS2 >= 6 - (ire->ire_ipif != NULL) && - (ire->ire_ipif->ipif_ill == qif->qf_ill) -#else - (ire_to_ill(ire) == qif->qf_ill) -#endif - ) { -#if SOLARIS2 >= 8 - mblk_t *m = ire->ire_fp_mp; -#else - mblk_t *m = ire->ire_ll_hdr_mp; -#endif - if (m != NULL) - qif->qf_hl = m->b_wptr - m->b_rptr; - } -} - - -static int ipf_attach(dip, cmd) -dev_info_t *dip; -ddi_attach_cmd_t cmd; -{ -#ifdef IPFDEBUG - int instance; - - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: ipf_attach(%x,%x)", dip, cmd); -#endif - switch (cmd) { - case DDI_ATTACH: - if (fr_running < 0) - break; -#ifdef IPFDEBUG - instance = ddi_get_instance(dip); - - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: attach ipf instance %d", instance); -#endif - if (ddi_create_minor_node(dip, "ipf", S_IFCHR, IPL_LOGIPF, - DDI_PSEUDO, 0) == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - goto attach_failed; - } - if (ddi_create_minor_node(dip, "ipnat", S_IFCHR, IPL_LOGNAT, - DDI_PSEUDO, 0) == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - goto attach_failed; - } - if (ddi_create_minor_node(dip, "ipstate", S_IFCHR,IPL_LOGSTATE, - DDI_PSEUDO, 0) == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - goto attach_failed; - } - if (ddi_create_minor_node(dip, "ipauth", S_IFCHR, IPL_LOGAUTH, - DDI_PSEUDO, 0) == DDI_FAILURE) { - ddi_remove_minor_node(dip, NULL); - goto attach_failed; - } - ipf_dev_info = dip; - sync(); - /* - * Initialize mutex's - */ - if (iplattach() == -1) - goto attach_failed; - /* - * Lock people out while we set things up. - */ - WRITE_ENTER(&ipf_solaris); - solattach(); - solipdrvattach(); - RWLOCK_EXIT(&ipf_solaris); - cmn_err(CE_CONT, "%s, attaching complete.\n", - ipfilter_version); - sync(); - if (fr_running == 0) - fr_running = 1; - if (ipfr_timer_id == 0) - ipfr_timer_id = timeout(ipfr_slowtimer, NULL, - drv_usectohz(500000)); - if (fr_running == 1) - return DDI_SUCCESS; -#if SOLARIS2 >= 8 - case DDI_RESUME : - case DDI_PM_RESUME : - if (ipfr_timer_id == 0) - ipfr_timer_id = timeout(ipfr_slowtimer, NULL, - drv_usectohz(500000)); - return DDI_SUCCESS; -#endif - default: - return DDI_FAILURE; - } - -attach_failed: - cmn_err(CE_NOTE, "IP Filter: failed to attach\n"); - /* - * Use our own detach routine to toss - * away any stuff we allocated above. - */ - (void) ipf_detach(dip, DDI_DETACH); - return DDI_FAILURE; -} - - -static int ipf_detach(dip, cmd) -dev_info_t *dip; -ddi_detach_cmd_t cmd; -{ - int i; - -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: ipf_detach(%x,%x)", dip, cmd); -#endif - switch (cmd) { - case DDI_DETACH: - if (fr_running <= 0) - break; - /* - * Make sure we're the only one's modifying things. With - * this lock others should just fall out of the loop. - */ - mutex_enter(&ipf_rw); - if (ipfr_timer_id != 0) { - untimeout(ipfr_timer_id); - ipfr_timer_id = 0; - } - mutex_exit(&ipf_rw); - WRITE_ENTER(&ipf_solaris); - mutex_enter(&ipf_rw); - if (fr_running <= 0) { - mutex_exit(&ipf_rw); - return DDI_FAILURE; - } - fr_running = -1; - mutex_exit(&ipf_rw); - /* NOTE: ipf_solaris rwlock is released in ipldetach */ - - /* - * Undo what we did in ipf_attach, freeing resources - * and removing things we installed. The system - * framework guarantees we are not active with this devinfo - * node in any other entry points at this time. - */ - ddi_prop_remove_all(dip); - i = ddi_get_instance(dip); - ddi_remove_minor_node(dip, NULL); - sync(); - i = solipdrvdetach(); - if (i > 0) { - cmn_err(CE_CONT, "IP Filter: still attached (%d)\n", i); - return DDI_FAILURE; - } - if (!soldetach()) { - cmn_err(CE_CONT, "%s detached\n", ipfilter_version); - return (DDI_SUCCESS); - } -#if SOLARIS2 >= 8 - case DDI_SUSPEND : - case DDI_PM_SUSPEND : - if (ipfr_timer_id != 0) { - untimeout(ipfr_timer_id); - ipfr_timer_id = 0; - } - if (synctimeoutid) { - untimeout(synctimeoutid); - synctimeoutid = 0; - } - return DDI_SUCCESS; -#endif - default: - return (DDI_FAILURE); - } - return DDI_FAILURE; -} - - -static int ipf_getinfo(dip, infocmd, arg, result) -dev_info_t *dip; -ddi_info_cmd_t infocmd; -void *arg, **result; -{ - int error; - - if (fr_running <= 0) - return DDI_FAILURE; - error = DDI_FAILURE; -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: ipf_getinfo(%x,%x,%x)", - dip, infocmd, arg); -#endif - switch (infocmd) { - case DDI_INFO_DEVT2DEVINFO: - *result = ipf_dev_info; - error = DDI_SUCCESS; - break; - case DDI_INFO_DEVT2INSTANCE: - *result = (void *)getminor((dev_t) arg); - error = DDI_SUCCESS; - break; - default: - break; - } - return (error); -} - -/* - * find the filter structure setup for this queue - */ -static qif_t *qif_from_queue(q) -queue_t *q; -{ - qif_t *qif; - - for (qif = qif_head; qif; qif = qif->qf_next) - if ((qif->qf_iptr == q->q_ptr) || (qif->qf_optr == q->q_ptr)) - break; - return qif; -} - - -/* - * OK, this is pretty scrappy code, but then it's essentially just here for - * debug purposes and that's it. Packets should not normally come through - * here, and if they do, well, we would like to see as much information as - * possible about them and what they claim to hold. - */ -void fr_donotip(out, qif, q, m, mt, ip, off) -int out; -qif_t *qif; -queue_t *q; -mblk_t *m, *mt; -ip_t *ip; -size_t off; -{ - u_char *s, outb[256], *t; - int i; - - outb[0] = '\0'; - outb[1] = '\0'; - outb[2] = '\0'; - outb[3] = '\0'; - s = ip ? (u_char *)ip : outb; - if (!ip && (m == mt) && m->b_cont && (MTYPE(m) != M_DATA)) - m = m->b_cont; - - cmn_err(CE_CONT, " !IP %s:%d %d %p %p %p %d %p/%d %p/%d %p %d %d %p\n", - qif ? qif->qf_name : "?", out, qif ? qif->qf_hl : -1, q, - q ? q->q_ptr : NULL, q ? q->q_qinfo : NULL, - mt->b_wptr - mt->b_rptr, m, MTYPE(m), mt, MTYPE(mt), m->b_rptr, - m->b_wptr - m->b_rptr, off, ip); - cmn_err(CE_CONT, "%02x%02x%02x%02x\n", *s, *(s+1), *(s+2), *(s+3)); - while (m != mt) { - i = 0; - t = outb; - s = mt->b_rptr; - sprintf((char *)t, "%d:", MTYPE(mt)); - t += strlen((char *)t); - for (; (i < 100) && (s < mt->b_wptr); i++) { - sprintf((char *)t, "%02x%s", *s++, - ((i & 3) == 3) ? " " : ""); - t += ((i & 3) == 3) ? 3 : 2; - } - *t++ = '\n'; - *t = '\0'; - cmn_err(CE_CONT, "%s", outb); - mt = mt->b_cont; - } - i = 0; - t = outb; - s = m->b_rptr; - sprintf((char *)t, "%d:", MTYPE(m)); - t += strlen((char *)t); - for (; (i < 100) && (s < m->b_wptr); i++) { - sprintf((char *)t, "%02x%s", *s++, ((i & 3) == 3) ? " " : ""); - t += ((i & 3) == 3) ? 3 : 2; - } - *t++ = '\n'; - *t = '\0'; - cmn_err(CE_CONT, "%s", outb); -} - - -/* - * find the first data mblk, if present, in the chain we're processing. Also - * make a few sanity checks to try prevent the filter from causing a panic - - * none of the nice IP sanity checks (including checksumming) should have been - * done yet (for incoming packets) - dangerous! - */ -static int fr_precheck(mp, q, qif, out) -mblk_t **mp; -queue_t *q; -qif_t *qif; -int out; -{ - register mblk_t *m, *mt = *mp; - register ip_t *ip; - size_t hlen, len, off, off2, mlen, iphlen, plen, woff; - int err, synced = 0, sap, p, realigned = 0, multi = 0; - u_char *bp; -#if SOLARIS2 >= 8 - ip6_t *ip6; -#endif -#ifndef sparc - u_short __ipoff; -#endif -tryagain: - ip = NULL; - m = NULL; - /* - * If there is only M_DATA for a packet going out, then any header - * information (which would otherwise appear in an M_PROTO mblk before - * the M_DATA) is prepended before the IP header. We need to set the - * offset to account for this. - see MMM - */ - off = (out) ? qif->qf_hl : 0; - - /* - * If the message protocol block indicates that there isn't a data - * block following it, just return back. - */ - bp = (u_char *)ALIGN32(mt->b_rptr); - if (MTYPE(mt) == M_PROTO || MTYPE(mt) == M_PCPROTO) { - dl_unitdata_ind_t *dl = (dl_unitdata_ind_t *)bp; - if (dl->dl_primitive == DL_UNITDATA_IND) { - multi = dl->dl_group_address; - m = mt->b_cont; - /* - * This is a complete kludge to try and work around - * some bizarre packets which drop through into - * fr_donotip. - */ - if (m && multi && ((*((u_char *)m->b_rptr) == 0x0) && - ((*((u_char *)m->b_rptr + 2) == 0x45)))) { - ip = (ip_t *)(m->b_rptr + 2); - off = 2; - } else - off = 0; - } else if (dl->dl_primitive != DL_UNITDATA_REQ) { - ip = (ip_t *)dl; - if ((ip->ip_v == IPVERSION) && - (ip->ip_hl == (sizeof(*ip) >> 2)) && - (ntohs(ip->ip_len) == mt->b_wptr - mt->b_rptr)) { - off = 0; - m = mt; - } else { - frstats[out].fr_notdata++; - return 0; - } - } - } - - /* - * Find the first data block, count the data blocks in this chain and - * the total amount of data. - */ - if (ip == NULL) - for (m = mt; m && (MTYPE(m) != M_DATA); m = m->b_cont) - off = 0; /* Any non-M_DATA cancels the offset */ - - if (!m) { - frstats[out].fr_nodata++; - return 0; /* No data blocks */ - } - - ip = (ip_t *)(m->b_rptr + off); /* MMM */ - - /* - * We might have a 1st data block which is really M_PROTO, i.e. it is - * only big enough for the link layer header - */ - while ((u_char *)ip >= m->b_wptr) { - len = (u_char *)ip - m->b_wptr; - m = m->b_cont; - if (m == NULL) - return 0; /* not enough data for IP */ - ip = (ip_t *)(m->b_rptr + len); - } - off = (u_char *)ip - m->b_rptr; - if (off != 0) - m->b_rptr = (u_char *)ip; - - len = m->b_wptr - m->b_rptr; - if (m->b_wptr < m->b_rptr) { - cmn_err(CE_NOTE, "!IP Filter: Bad packet: wptr %p < rptr %p", - m->b_wptr, m->b_rptr); - frstats[out].fr_bad++; - return -1; - } - - mlen = msgdsize(m); - sap = qif->qf_ill->ill_sap; - - if (sap == 0x800) { - u_short tlen; - - hlen = sizeof(*ip); - - /* XXX - might not be aligned (from ppp?) */ - ((char *)&tlen)[0] = ((char *)&ip->ip_len)[0]; - ((char *)&tlen)[1] = ((char *)&ip->ip_len)[1]; - - plen = ntohs(tlen); - - sap = 0; - } -#if SOLARIS2 >= 8 - else if (sap == IP6_DL_SAP) { - u_short tlen; - - hlen = sizeof(ip6_t); - ip6 = (ip6_t *)ip; - /* XXX - might not be aligned (from ppp?) */ - ((char *)&tlen)[0] = ((char *)&ip6->ip6_plen)[0]; - ((char *)&tlen)[1] = ((char *)&ip6->ip6_plen)[1]; - plen = ntohs(tlen); - if (!plen) - return -1; /* Jumbo gram */ - plen += sizeof(*ip6); - } -#endif - else { - plen = 0; - hlen = 0; - sap = -1; - } - - /* - * Ok, the IP header isn't on a 32bit aligned address so junk it. - */ - if (((u_long)ip & 0x3) || (plen > mlen) || (len < hlen) || - (sap == -1)) { - mblk_t *m1, *m2; - u_char *s, c; - int v; - - /* - * Junk using pullupmsg - it's next to useless. - */ -fixalign: - if (off) - m->b_rptr -= off; - c = *(u_char *)ip; - c >>= 4; - if (c != 4 -#if SOLARIS2 >= 8 - && c != 6 -#endif - ) { - frstats[out].fr_notip++; - return (fr_flags & FF_BLOCKNONIP) ? -1 : 0; - } - - if (realigned) - return -1; - realigned = 1; - off2 = (size_t)((u_long)ip & 0x3); - if (off2) - off2 = 4 - off2; - len = msgdsize(m); - m2 = allocb(len + off2, BPRI_HI); - if (m2 == NULL) { - frstats[out].fr_pull[1]++; - return -1; - } - - MTYPE(m2) = M_DATA; - if (m->b_rptr != (u_char *)ip) - m2->b_rptr += off2; - m2->b_wptr = m2->b_rptr + len; - m1 = m; - s = (u_char *)m->b_rptr; - for (bp = m2->b_rptr; m1 && (bp < m2->b_wptr); bp += len) { - len = MIN(m1->b_wptr - s, m2->b_wptr - bp); - bcopy(s, bp, len); - m1 = m1->b_cont; - if (m1) - s = m1->b_rptr; - } - - if (mt != m && mt->b_cont == m && !off) { - /* - * check if the buffer we're changing is chained in- - * between other buffers and unlink/relink as required. - */ - (void) unlinkb(mt); /* should return 'm' */ - m1 = unlinkb(m); - if (m1) - linkb(m2, m1); - freemsg(m); - linkb(mt, m2); - } else { - if (m == mt) { - m1 = unlinkb(mt); - if (m1) - linkb(m2, m1); - } - freemsg(mt); - *mp = m2; - mt = m2; - } - - frstats[out].fr_pull[0]++; - synced = 1; - off = 0; - goto tryagain; - } - - if (((sap == 0) && (ip->ip_v != IP_VERSION)) -#if SOLARIS2 >= 8 - || ((sap == IP6_DL_SAP) && ((ip6->ip6_vfc >> 4) != 6)) -#endif - ) { - m->b_rptr -= off; - return -2; - } - -#ifndef sparc -# if SOLARIS2 >= 8 - if (sap == IP6_DL_SAP) { - ip6->ip6_plen = plen - sizeof(*ip6); - } else { -# endif - __ipoff = (u_short)ip->ip_off; - - ip->ip_len = plen; - ip->ip_off = ntohs(__ipoff); -# if SOLARIS2 >= 8 - } -# endif -#endif - if (sap == 0) - iphlen = ip->ip_hl << 2; -#if SOLARIS2 >= 8 - else if (sap == IP6_DL_SAP) - iphlen = sizeof(ip6_t); -#endif - - if (( -#if SOLARIS2 >= 8 - (sap == IP6_DL_SAP) && (mlen < plen)) || - ((sap == 0) && -#endif - ((iphlen < hlen) || (iphlen > plen) || (mlen < plen)))) { - /* - * Bad IP packet or not enough data/data length mismatches - */ -#ifndef sparc -# if SOLARIS2 >= 8 - if (sap == IP6_DL_SAP) { - ip6->ip6_plen = htons(plen - sizeof(*ip6)); - } else { -# endif - __ipoff = (u_short)ip->ip_off; - - ip->ip_len = htons(plen); - ip->ip_off = htons(__ipoff); -# if SOLARIS2 >= 8 - } -# endif -#endif - m->b_rptr -= off; - frstats[out].fr_bad++; - return -1; - } - - /* - * Make hlen the total size of the IP header plus TCP/UDP/ICMP header - * (if it is one of these three). - */ - if (sap == 0) - p = ip->ip_p; -#if SOLARIS2 >= 8 - else if (sap == IP6_DL_SAP) - p = ip6->ip6_nxt; - - if ((sap == IP6_DL_SAP) || ((ip->ip_off & IP_OFFMASK) == 0)) -#else - if ((ip->ip_off & IP_OFFMASK) == 0) -#endif - switch (p) - { - case IPPROTO_TCP : - hlen += sizeof(tcphdr_t); - break; - case IPPROTO_UDP : - hlen += sizeof(udphdr_t); - break; - case IPPROTO_ICMP : - /* 76 bytes is enough for a complete ICMP error. */ - hlen += 76 + sizeof(icmphdr_t); - break; - default : - break; - } - - woff = 0; - if (hlen > mlen) { - hlen = mlen; - } else if (m->b_wptr - m->b_rptr > plen) { - woff = m->b_wptr - m->b_rptr - plen; - m->b_wptr -= woff; - } - - /* - * If we don't have enough data in the mblk or we haven't yet copied - * enough (above), then copy some more. - */ - if ((hlen > len)) { - if (!pullupmsg(m, (int)hlen)) { - cmn_err(CE_NOTE, "pullupmsg failed"); - frstats[out].fr_pull[1]++; - return -1; - } - frstats[out].fr_pull[0]++; - ip = (ip_t *)ALIGN32(m->b_rptr); - } - qif->qf_m = m; - qif->qf_q = q; - qif->qf_off = off; - qif->qf_len = len; - err = fr_check(ip, iphlen, qif->qf_ill, out, qif, mp); - if (err == 2) { - goto fixalign; - } - /* - * Copy back the ip header data if it was changed, we haven't yet - * freed the message and we aren't going to drop the packet. - * BUT only do this if there were no changes to the buffer, else - * we can't be sure that the ip pointer is still correct! - */ - if (*mp != NULL) { - if (*mp == mt) { - m->b_wptr += woff; - m->b_rptr -= off; -#ifndef sparc -# if SOLARIS2 >= 8 - if (sap == IP6_DL_SAP) { - ip6->ip6_plen = htons(plen - sizeof(*ip6)); - } else { -# endif - __ipoff = (u_short)ip->ip_off; - /* - * plen is useless because of NAT. - */ - ip->ip_len = htons(ip->ip_len); - ip->ip_off = htons(__ipoff); -# if SOLARIS2 >= 8 - } -# endif -#endif - } else - cmn_err(CE_NOTE, - "!IP Filter: *mp %p mt %p %s", *mp, mt, - "mblk changed, cannot revert ip_len, ip_off"); - } - return err; -} - - -/* - * Only called for M_IOCACK messages - */ -void fr_qif_update(qif, mp) -qif_t *qif; -mblk_t *mp; -{ - struct iocblk *iocp; - - if (!qif || !mp) - return; - iocp = (struct iocblk *)mp->b_rptr; - if (mp->b_cont && (iocp->ioc_cmd == DL_IOC_HDR_INFO)) { - mp = mp->b_cont; - if (MTYPE(mp) == M_PROTO && mp->b_cont) { - mp = mp->b_cont; - if (MTYPE(mp) == M_DATA) { - qif->qf_hl = mp->b_wptr - mp->b_rptr; - } - } - } -} - - -int fr_qin(q, mb) -queue_t *q; -mblk_t *mb; -{ - int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0, err = 0; - qif_t qf, *qif; - -#ifdef IPFDEBUG_VERBOSE - if (ipf_debug_verbose) - cmn_err(CE_CONT, - "fr_qin(%lx,%lx) ptr %lx type 0x%x ref %d len %d\n", - q, q->q_ptr, mb, MTYPE(mb), mb->b_datap->db_ref, - msgdsize(mb)); -#endif - - /* - * IPFilter is still in the packet path but not enabled. Drop whatever - * it is that has come through. - */ - if (fr_running <= 0) { - mb->b_prev = NULL; - freemsg(mb); - return 0; - } - - type = MTYPE(mb); - - /* - * If a mblk has more than one reference, make a copy, filter that and - * free a reference to the original. - */ - if (mb->b_datap->db_ref > 1) { - mblk_t *m1; - - m1 = copymsg(mb); - if (!m1) { - frstats[0].fr_drop++; - mb->b_prev = NULL; - freemsg(mb); - return 0; - } - mb->b_prev = NULL; - freemsg(mb); - mb = m1; - frstats[0].fr_copy++; - } - - READ_ENTER(&ipf_solaris); -again: - if (fr_running <= 0) { - mb->b_prev = NULL; - freemsg(mb); - RWLOCK_EXIT(&ipf_solaris); - return 0; - } - READ_ENTER(&ipfs_mutex); - if (!(qif = qif_from_queue(q))) { - for (qif = qif_head; qif; qif = qif->qf_next) - if (&qif->qf_rqinit == q->q_qinfo && qif->qf_rqinfo && - qif->qf_rqinfo->qi_putp) { - pnext = qif->qf_rqinfo->qi_putp; - frstats[0].fr_notip++; - RWLOCK_EXIT(&ipfs_mutex); - if (!synced) { - ipfsync(); - synced = 1; - goto again; - } - RWLOCK_EXIT(&ipf_solaris); - /* fr_donotip(0, NULL, q, mb, mb, NULL, 0); */ - return (*pnext)(q, mb); - } - RWLOCK_EXIT(&ipfs_mutex); - if (!synced) { - ipfsync(); - synced = 1; - goto again; - } - cmn_err(CE_WARN, - "!IP Filter: dropped: fr_qin(%x,%x): type %x qif %x", - q, mb, type, qif); - cmn_err(CE_CONT, - "!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n", - q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv, - q->q_nbsrv); - cmn_err(CE_CONT, "!IP Filter: info: putp %x srvp %x info %x\n", - q->q_qinfo->qi_putp, q->q_qinfo->qi_srvp, -#if SOLARIS > 3 - q->q_qinfo->qi_infop -#else - 0 -#endif - ); - frstats[0].fr_drop++; - mb->b_prev = NULL; - freemsg(mb); - RWLOCK_EXIT(&ipf_solaris); - return 0; - } - - qif->qf_incnt++; - pnext = qif->qf_rqinfo->qi_putp; - if (type == M_IOCACK) - fr_qif_update(qif, mb); - bcopy((char *)qif, (char *)&qf, sizeof(qf)); - if (datamsg(type) || (type == M_BREAK)) - err = fr_precheck(&mb, q, &qf, 0); - - RWLOCK_EXIT(&ipfs_mutex); - - if ((err == 0) && (mb != NULL)) { - if (pnext) { - RWLOCK_EXIT(&ipf_solaris); - return (*pnext)(q, mb); - } - - cmn_err(CE_WARN, - "!IP Filter: inp NULL: qif %x %s q %x info %x", - qif, qf.qf_name, q, q->q_qinfo); - } - - if (err == -2) { - if (synced == 0) { - ipfsync(); - synced = 1; - goto again; - } - frstats[0].fr_notip++; - if (!(fr_flags & FF_BLOCKNONIP) && (pnext != NULL)) { - RWLOCK_EXIT(&ipf_solaris); - return (*pnext)(q, mb); - } - } - - - if (mb) { - mb->b_prev = NULL; - freemsg(mb); - } - RWLOCK_EXIT(&ipf_solaris); - return 1; -} - - -int fr_qout(q, mb) -queue_t *q; -mblk_t *mb; -{ - int (*pnext) __P((queue_t *, mblk_t *)), type, synced = 0, err = 0; - qif_t qf, *qif; - -#ifdef IPFDEBUG_VERBOSE - if (ipf_debug_verbose) - cmn_err(CE_CONT, - "fr_qout(%lx,%lx) ptr %lx type 0x%x ref %d len %d\n", - q, q->q_ptr, mb, MTYPE(mb), mb->b_datap->db_ref, - msgdsize(mb)); -#endif - - if (fr_running <= 0) { - mb->b_prev = NULL; - freemsg(mb); - return 0; - } - - type = MTYPE(mb); - -#if SOLARIS2 >= 6 - if ((!dohwcksum || mb->b_ick_flag != ICK_VALID) && - (mb->b_datap->db_ref > 1)) -#else - if (mb->b_datap->db_ref > 1) -#endif - { - mblk_t *m1; - - m1 = copymsg(mb); - if (!m1) { - frstats[1].fr_drop++; - mb->b_prev = NULL; - freemsg(mb); - return 0; - } - mb->b_prev = NULL; - freemsg(mb); - mb = m1; - frstats[1].fr_copy++; - } - - READ_ENTER(&ipf_solaris); -again: - if (fr_running <= 0) { - mb->b_prev = NULL; - freemsg(mb); - RWLOCK_EXIT(&ipf_solaris); - return 0; - } - READ_ENTER(&ipfs_mutex); - if (!(qif = qif_from_queue(q))) { - for (qif = qif_head; qif; qif = qif->qf_next) - if (&qif->qf_wqinit == q->q_qinfo && qif->qf_wqinfo && - qif->qf_wqinfo->qi_putp) { - pnext = qif->qf_wqinfo->qi_putp; - RWLOCK_EXIT(&ipfs_mutex); - frstats[1].fr_notip++; - if (!synced) { - ipfsync(); - synced = 1; - goto again; - } - /* fr_donotip(1, NULL, q, mb, mb, NULL, 0); */ - RWLOCK_EXIT(&ipf_solaris); - return (*pnext)(q, mb); - } - RWLOCK_EXIT(&ipfs_mutex); - if (!synced) { - ipfsync(); - synced = 1; - goto again; - } - cmn_err(CE_WARN, - "!IP Filter: dropped: fr_qout(%x,%x): type %x: qif %x", - q, mb, type, qif); - cmn_err(CE_CONT, - "!IP Filter: info %x next %x ptr %x fsrv %x bsrv %x\n", - q->q_qinfo, q->q_next, q->q_ptr, q->q_nfsrv, - q->q_nbsrv); - cmn_err(CE_CONT, "!IP Filter: info: putp %x srvp %x info %x\n", - q->q_qinfo->qi_putp, q->q_qinfo->qi_srvp, -#if SOLARIS > 3 - q->q_qinfo->qi_infop -#else - 0 -#endif - ); - if (q->q_nfsrv) - cmn_err(CE_CONT, - "!IP Filter: nfsrv: info %x next %x ptr %x\n", - q->q_nfsrv->q_qinfo, q->q_nfsrv->q_next, - q->q_nfsrv->q_ptr); - if (q->q_nbsrv) - cmn_err(CE_CONT, - "!IP Filter: nbsrv: info %x next %x ptr %x\n", - q->q_nbsrv->q_qinfo, q->q_nbsrv->q_next, - q->q_nbsrv->q_ptr); - frstats[1].fr_drop++; - mb->b_prev = NULL; - freemsg(mb); - RWLOCK_EXIT(&ipf_solaris); - return 0; - } - - qif->qf_outcnt++; - pnext = qif->qf_wqinfo->qi_putp; - if (type == M_IOCACK) - fr_qif_update(qif, mb); - bcopy((char *)qif, (char *)&qf, sizeof(qf)); - if (datamsg(type) || (type == M_BREAK)) - err = fr_precheck(&mb, q, &qf, 1); - - RWLOCK_EXIT(&ipfs_mutex); - - if ((err == 0) && (mb != NULL)) { - if (pnext) { - RWLOCK_EXIT(&ipf_solaris); - return (*pnext)(q, mb); - } - - cmn_err(CE_WARN, - "!IP Filter: outp NULL: qif %x %s q %x info %x", - qif, qf.qf_name, q, q->q_qinfo); - } - - if (err == -2) { - if (synced == 0) { - ipfsync(); - synced = 1; - goto again; - } - frstats[1].fr_notip++; - if (!(fr_flags & FF_BLOCKNONIP) && (pnext != NULL)) { - RWLOCK_EXIT(&ipf_solaris); - return (*pnext)(q, mb); - } - } - - if (mb) { - mb->b_prev = NULL; - freemsg(mb); - } - RWLOCK_EXIT(&ipf_solaris); - return 1; -} - - -void ipf_synctimeout(arg) -void *arg; -{ - if (fr_running < 0) - return; - READ_ENTER(&ipf_solaris); - ipfsync(); - WRITE_ENTER(&ipfs_mutex); - synctimeoutid = 0; - RWLOCK_EXIT(&ipfs_mutex); - RWLOCK_EXIT(&ipf_solaris); -} - - -static int ipf_ip_qin(q, mb) -queue_t *q; -mblk_t *mb; -{ - struct iocblk *ioc; - int ret; - - if (fr_running <= 0) { - mb->b_prev = NULL; - freemsg(mb); - return 0; - } - - if (MTYPE(mb) != M_IOCTL) - return (*ipf_ip_inp)(q, mb); - - READ_ENTER(&ipf_solaris); - if (fr_running <= 0) { - RWLOCK_EXIT(&ipf_solaris); - mb->b_prev = NULL; - freemsg(mb); - return 0; - } - ioc = (struct iocblk *)mb->b_rptr; - - switch (ioc->ioc_cmd) - { - case DL_IOC_HDR_INFO: - fr_qif_update(qif_from_queue(q), mb); - break; - case I_LINK: - case I_UNLINK: - case SIOCSIFADDR: - case SIOCSIFFLAGS: -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: ipf_ip_qin() M_IOCTL type=0x%x", - ioc->ioc_cmd); -#endif - WRITE_ENTER(&ipfs_mutex); - if (synctimeoutid == 0) { - synctimeoutid = timeout(ipf_synctimeout, - NULL, - drv_usectohz(1000000) /*1 sec*/ - ); - } - RWLOCK_EXIT(&ipfs_mutex); - break; - default: - break; - } - RWLOCK_EXIT(&ipf_solaris); - return (*ipf_ip_inp)(q, mb); -} - -static int ipdrvattcnt = 0; -extern struct streamtab ipinfo; - -void solipdrvattach() -{ -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: solipdrvattach() %d ipinfo=0x%lx", - ipdrvattcnt, &ipinfo); -#endif - - if (++ipdrvattcnt == 1) { - if (ipf_ip_inp == NULL) { - ipf_ip_inp = ipinfo.st_wrinit->qi_putp; - ipinfo.st_wrinit->qi_putp = ipf_ip_qin; - } - } -} - -int solipdrvdetach() -{ -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, "IP Filter: solipdrvdetach() %d ipinfo=0x%lx", - ipdrvattcnt, &ipinfo); -#endif - - WRITE_ENTER(&ipfs_mutex); - if (--ipdrvattcnt <= 0) { - if (ipf_ip_inp && (ipinfo.st_wrinit->qi_putp == ipf_ip_qin)) { - ipinfo.st_wrinit->qi_putp = ipf_ip_inp; - ipf_ip_inp = NULL; - } - if (synctimeoutid) { - untimeout(synctimeoutid); - synctimeoutid = 0; - } - } - RWLOCK_EXIT(&ipfs_mutex); - return ipdrvattcnt; -} - -/* - * attach the packet filter to each interface that is defined as having an - * IP address associated with it and save some of the info. for that struct - * so we're not out of date as soon as the ill disappears - but we must sync - * to be correct! - */ -void solattach() -{ - queue_t *in, *out; - struct frentry *f; - qif_t *qif, *qf2; - ipnat_t *np; - size_t len; - ill_t *il; - - for (il = ill_g_head; il; il = il->ill_next) { - in = il->ill_rq; - if (!in || !il->ill_wq) - continue; - - out = il->ill_wq->q_next; - - WRITE_ENTER(&ipfs_mutex); - /* - * Look for entry already setup for this device - */ - for (qif = qif_head; qif; qif = qif->qf_next) - if (qif->qf_iptr == in->q_ptr && - qif->qf_optr == out->q_ptr) - break; - if (qif) { - RWLOCK_EXIT(&ipfs_mutex); - continue; - } -#ifdef IPFDEBUGX - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: il %x ipt %x opt %x ipu %x opu %x i %x/%x", - il, in->q_ptr, out->q_ptr, in->q_qinfo->qi_putp, - out->q_qinfo->qi_putp, out->q_qinfo, in->q_qinfo); -#endif - KMALLOC(qif, qif_t *); - if (!qif) { - cmn_err(CE_WARN, - "IP Filter: malloc(%d) for qif_t failed", - sizeof(qif_t)); - RWLOCK_EXIT(&ipfs_mutex); - continue; - } - - if (in->q_qinfo->qi_putp == fr_qin) { - for (qf2 = qif_head; qf2; qf2 = qf2->qf_next) - if (&qf2->qf_rqinit == in->q_qinfo) { - qif->qf_rqinfo = qf2->qf_rqinfo; - break; - } - if (!qf2) { -#ifdef IPFDEBUGX - if (ipf_debug) - cmn_err(CE_WARN, - "IP Filter: rq:%s put %x qi %x", - il->ill_name, in->q_qinfo->qi_putp, - in->q_qinfo); -#endif - RWLOCK_EXIT(&ipfs_mutex); - KFREE(qif); - continue; - } - } else - qif->qf_rqinfo = in->q_qinfo; - - if (out->q_qinfo->qi_putp == fr_qout) { - for (qf2 = qif_head; qf2; qf2 = qf2->qf_next) - if (&qf2->qf_wqinit == out->q_qinfo) { - qif->qf_wqinfo = qf2->qf_wqinfo; - break; - } - if (!qf2) { -#ifdef IPFDEBUGX - if (ipf_debug) - cmn_err(CE_WARN, - "IP Filter: wq:%s put %x qi %x", - il->ill_name, out->q_qinfo->qi_putp, - out->q_qinfo); -#endif - RWLOCK_EXIT(&ipfs_mutex); - KFREE(qif); - continue; - } - } else - qif->qf_wqinfo = out->q_qinfo; - - qif->qf_ill = il; - qif->qf_in = in; - qif->qf_out = out; - qif->qf_iptr = in->q_ptr; - qif->qf_optr = out->q_ptr; -#if SOLARIS2 < 8 - qif->qf_hl = il->ill_hdr_length; -#else - { - ire_t *ire; - mblk_t *m; - - qif->qf_hl = 0; - qif->qf_sap = il->ill_sap; -# if 0 - /* - * Can't seem to lookup a route for the IP address on the - * interface itself. - */ - ire = ire_route_lookup(il->ill_ipif->ipif_lcl_addr, 0xffffffff, - 0, 0, NULL, NULL, NULL, - MATCH_IRE_DSTONLY|MATCH_IRE_RECURSIVE); - if ((ire != NULL) && (m = ire->ire_fp_mp)) - qif->qf_hl = m->b_wptr - m->b_rptr; -# endif - if ((qif->qf_hl == 0) && (il->ill_type > 0) && - (il->ill_type < 0x37) && - (hdrsizes[il->ill_type][0] == il->ill_type)) - qif->qf_hl = hdrsizes[il->ill_type][1]; - - /* DREADFUL VLAN HACK - JUST HERE TO CHECK IT WORKS */ - if (il->ill_type == IFT_ETHER && - il->ill_name[0] == 'c' && il->ill_name[1] == 'e' && - isdigit(il->ill_name[2]) && il->ill_name_length >= 6) { - cmn_err(CE_NOTE, "VLAN HACK ENABLED"); - qif->qf_hl += 4; - } - /* DREADFUL VLAN HACK - JUST HERE TO CHECK IT WORKS */ - - if (qif->qf_hl == 0 && il->ill_type != IFT_OTHER) - cmn_err(CE_WARN, - "Unknown layer 2 header size for %s type %d", - il->ill_name, il->ill_type); - } - - /* - * XXX Awful hack for PPP; fix when PPP/snoop fixed. - */ - if (il->ill_type == IFT_ETHER && !il->ill_bcast_addr_length) - qif->qf_hl = 0; -#endif - strncpy(qif->qf_name, il->ill_name, sizeof(qif->qf_name)); - qif->qf_name[sizeof(qif->qf_name) - 1] = '\0'; - - qif->qf_next = qif_head; - qif_head = qif; - - /* - * Activate any rules directly associated with this interface - */ - WRITE_ENTER(&ipf_mutex); - for (f = ipfilter[0][fr_active]; f; f = f->fr_next) { - if ((f->fr_ifa == (struct ifnet *)-1)) { - len = strlen(f->fr_ifname) + 1; - if ((len != 0) && - (len == (size_t)il->ill_name_length) && - !strncmp(il->ill_name, f->fr_ifname, len)) - f->fr_ifa = il; - } - } - for (f = ipfilter[1][fr_active]; f; f = f->fr_next) { - if ((f->fr_ifa == (struct ifnet *)-1)) { - len = strlen(f->fr_ifname) + 1; - if ((len != 0) && - (len == (size_t)il->ill_name_length) && - !strncmp(il->ill_name, f->fr_ifname, len)) - f->fr_ifa = il; - } - } -#if SOLARIS2 >= 8 - for (f = ipfilter6[0][fr_active]; f; f = f->fr_next) { - if ((f->fr_ifa == (struct ifnet *)-1)) { - len = strlen(f->fr_ifname) + 1; - if ((len != 0) && - (len == (size_t)il->ill_name_length) && - !strncmp(il->ill_name, f->fr_ifname, len)) - f->fr_ifa = il; - } - } - for (f = ipfilter6[1][fr_active]; f; f = f->fr_next) { - if ((f->fr_ifa == (struct ifnet *)-1)) { - len = strlen(f->fr_ifname) + 1; - if ((len != 0) && - (len == (size_t)il->ill_name_length) && - !strncmp(il->ill_name, f->fr_ifname, len)) - f->fr_ifa = il; - } - } -#endif - RWLOCK_EXIT(&ipf_mutex); - WRITE_ENTER(&ipf_nat); - for (np = nat_list; np; np = np->in_next) { - if ((np->in_ifp == (struct ifnet *)-1)) { - len = strlen(np->in_ifname) + 1; - if ((len != 0) && - (len == (size_t)il->ill_name_length) && - !strncmp(il->ill_name, np->in_ifname, len)) - np->in_ifp = il; - } - } - RWLOCK_EXIT(&ipf_nat); - - bcopy((caddr_t)qif->qf_rqinfo, (caddr_t)&qif->qf_rqinit, - sizeof(struct qinit)); - qif->qf_rqinit.qi_putp = fr_qin; -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: solattach: in queue(%lx)->q_qinfo FROM %lx TO %lx", - in, in->q_qinfo, &qif->qf_rqinit); -#endif - in->q_qinfo = &qif->qf_rqinit; - - bcopy((caddr_t)qif->qf_wqinfo, (caddr_t)&qif->qf_wqinit, - sizeof(struct qinit)); - qif->qf_wqinit.qi_putp = fr_qout; -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: solattach: out queue(%lx)->q_qinfo FROM %lx TO %lx", - out, out->q_qinfo, &qif->qf_wqinit); -#endif - out->q_qinfo = &qif->qf_wqinit; - - ire_walk(ipf_ire_walk, (char *)qif); - RWLOCK_EXIT(&ipfs_mutex); - cmn_err(CE_CONT, "IP Filter: attach to [%s,%d] - %s\n", - qif->qf_name, il->ill_ppa, -#if SOLARIS2 >= 8 - il->ill_isv6 ? "IPv6" : "IPv4" -#else - "IPv4" -#endif - ); - } - if (!qif_head) - cmn_err(CE_CONT, "IP Filter: not attached to any interfaces\n"); - return; -} - - -/* - * look for bad consistancies between the list of interfaces the filter knows - * about and those which are currently configured. - */ -int ipfsync() -{ - register struct frentry *f; - register ipnat_t *np; - register qif_t *qif, **qp; - register ill_t *il; - queue_t *in, *out; - - WRITE_ENTER(&ipfs_mutex); - for (qp = &qif_head; (qif = *qp); ) { - for (il = ill_g_head; il; il = il->ill_next) - if ((qif->qf_ill == il) && - !strcmp(qif->qf_name, il->ill_name)) { -#if SOLARIS2 < 8 - mblk_t *m = il->ill_hdr_mp; - - qif->qf_hl = il->ill_hdr_length; - if (m && qif->qf_hl != (m->b_wptr - m->b_rptr)) - cmn_err(CE_NOTE, - "IP Filter: ILL Header Length Mismatch\n"); -#endif - break; - } - if (il) { - qp = &qif->qf_next; - continue; - } - cmn_err(CE_CONT, "IP Filter: detaching [%s] - %s\n", - qif->qf_name, -#if SOLARIS2 >= 8 - (qif->qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4" -#else - "IPv4" -#endif - ); - *qp = qif->qf_next; - - /* - * Disable any rules directly associated with this interface - */ - WRITE_ENTER(&ipf_nat); - for (np = nat_list; np; np = np->in_next) - if (np->in_ifp == (void *)qif->qf_ill) - np->in_ifp = (struct ifnet *)-1; - RWLOCK_EXIT(&ipf_nat); - WRITE_ENTER(&ipf_mutex); - for (f = ipfilter[0][fr_active]; f; f = f->fr_next) - if (f->fr_ifa == (void *)qif->qf_ill) - f->fr_ifa = (struct ifnet *)-1; - for (f = ipfilter[1][fr_active]; f; f = f->fr_next) - if (f->fr_ifa == (void *)qif->qf_ill) - f->fr_ifa = (struct ifnet *)-1; -#if SOLARIS2 >= 8 - for (f = ipfilter6[0][fr_active]; f; f = f->fr_next) - if (f->fr_ifa == (void *)qif->qf_ill) - f->fr_ifa = (struct ifnet *)-1; - for (f = ipfilter6[1][fr_active]; f; f = f->fr_next) - if (f->fr_ifa == (void *)qif->qf_ill) - f->fr_ifa = (struct ifnet *)-1; -#endif - -#if 0 /* XXX */ - /* - * As well as the ill disappearing when a device is unplumb'd, - * it also appears that the associated queue structures also - * disappear - at least in the case of ppp, which is the most - * volatile here. Thanks to Greg for finding this problem. - */ - /* - * Restore q_qinfo pointers in interface queues - */ - out = qif->qf_out; - in = qif->qf_in; - if (in) { -# ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: ipfsync: in queue(%lx)->q_qinfo FROM %lx TO %lx", - in, in->q_qinfo, qif->qf_rqinfo); -# endif - in->q_qinfo = qif->qf_rqinfo; - } - if (out) { -# ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: ipfsync: out queue(%lx)->q_qinfo FROM %lx TO %lx", - out, out->q_qinfo, qif->qf_wqinfo); -# endif - out->q_qinfo = qif->qf_wqinfo; - } -#endif /* XXX */ - RWLOCK_EXIT(&ipf_mutex); - KFREE(qif); - qif = *qp; - } - RWLOCK_EXIT(&ipfs_mutex); - solattach(); - - frsync(); - /* - * Resync. any NAT `connections' using this interface and its IP #. - */ - for (il = ill_g_head; il; il = il->ill_next) { - ip_natsync((void *)il); - ip_statesync((void *)il); - } - return 0; -} - - -/* - * unhook the IP filter from all defined interfaces with IP addresses - */ -int soldetach() -{ - queue_t *in, *out; - qif_t *qif, **qp; - ill_t *il; - - WRITE_ENTER(&ipfs_mutex); - /* - * Make two passes, first get rid of all the unknown devices, next - * unlink known devices. - */ - for (qp = &qif_head; (qif = *qp); ) { - for (il = ill_g_head; il; il = il->ill_next) - if (qif->qf_ill == il) - break; - if (il) { - qp = &qif->qf_next; - continue; - } - cmn_err(CE_CONT, "IP Filter: removing [%s]\n", qif->qf_name); - *qp = qif->qf_next; - KFREE(qif); - } - - while ((qif = qif_head)) { - qif_head = qif->qf_next; - for (il = ill_g_head; il; il = il->ill_next) - if (qif->qf_ill == il) - break; - if (il) { - in = qif->qf_in; - out = qif->qf_out; - cmn_err(CE_CONT, "IP Filter: detaching [%s,%d] - %s\n", - qif->qf_name, il->ill_ppa, -#if SOLARIS2 >= 8 - (qif->qf_sap == IP6_DL_SAP) ? "IPv6" : "IPv4" -#else - "IPv4" -#endif - ); - -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: soldetach: in queue(%lx)->q_qinfo FROM %lx TO %lx", - in, in->q_qinfo, qif->qf_rqinfo); -#endif - in->q_qinfo = qif->qf_rqinfo; - - /* - * and the write queue... - */ -#ifdef IPFDEBUG - if (ipf_debug) - cmn_err(CE_NOTE, - "IP Filter: soldetach: out queue(%lx)->q_qinfo FROM %lx TO %lx", - out, out->q_qinfo, qif->qf_wqinfo); -#endif - out->q_qinfo = qif->qf_wqinfo; - } - KFREE(qif); - } - RWLOCK_EXIT(&ipfs_mutex); - return ipldetach(); -} - - -#ifdef IPFDEBUG -void printire(ire) -ire_t *ire; -{ - if (!ipf_debug) - return; - printf("ire: ll_hdr_mp %p rfq %p stq %p src_addr %x max_frag %d\n", -# if SOLARIS2 >= 8 - NULL, -# else - ire->ire_ll_hdr_mp, -# endif - ire->ire_rfq, ire->ire_stq, - ire->ire_src_addr, ire->ire_max_frag); - printf("ire: mask %x addr %x gateway_addr %x type %d\n", - ire->ire_mask, ire->ire_addr, ire->ire_gateway_addr, - ire->ire_type); - printf("ire: ll_hdr_length %d ll_hdr_saved_mp %p\n", - ire->ire_ll_hdr_length, -# if SOLARIS2 >= 8 - NULL -# else - ire->ire_ll_hdr_saved_mp -# endif - ); -} -#endif - - -int ipfr_fastroute(ip, mb, mpp, fin, fdp) -ip_t *ip; -mblk_t *mb, **mpp; -fr_info_t *fin; -frdest_t *fdp; -{ -#ifdef USE_INET6 - ip6_t *ip6 = (ip6_t *)ip; -#endif - ire_t *ir, *dir, *gw; - struct in_addr dst; - queue_t *q = NULL; - mblk_t *mp = NULL; - size_t hlen = 0; - frentry_t *fr; - frdest_t fd; - ill_t *ifp; - u_char *s; - qif_t *qf; - int p; - -#ifndef sparc - u_short __iplen, __ipoff; -#endif - qf = fin->fin_qif; - - /* - * If this is a duplicate mblk then we want ip to point at that - * data, not the original, if and only if it is already pointing at - * the current mblk data. - */ - if ((ip == (ip_t *)qf->qf_m->b_rptr) && (qf->qf_m != mb)) - ip = (ip_t *)mb->b_rptr; - - /* - * If there is another M_PROTO, we don't want it - */ - if (*mpp != mb) { - mp = *mpp; - (void) unlinkb(mp); - mp = (*mpp)->b_cont; - (*mpp)->b_cont = NULL; - (*mpp)->b_prev = NULL; - freemsg(*mpp); - *mpp = mp; - } - - if (!fdp) { - ipif_t *ipif; - - ifp = fin->fin_ifp; - ipif = ifp->ill_ipif; - if (!ipif) - goto bad_fastroute; -#if SOLARIS2 > 5 - ir = ire_ctable_lookup(ipif->ipif_local_addr, 0, IRE_LOCAL, - NULL, NULL, MATCH_IRE_TYPE); -#else - ir = ire_lookup_myaddr(ipif->ipif_local_addr); -#endif - if (!ir) - ir = (ire_t *)-1; - - fd.fd_ifp = (struct ifnet *)ir; - fd.fd_ip = ip->ip_dst; - fdp = &fd; - } - - ir = (ire_t *)fdp->fd_ifp; - - if (fdp->fd_ip.s_addr) - dst = fdp->fd_ip; - else - dst.s_addr = fin->fin_fi.fi_daddr; - -#if SOLARIS2 >= 6 - gw = NULL; - if (fin->fin_v == 4) { - p = ip->ip_p; - dir = ire_route_lookup(dst.s_addr, 0xffffffff, 0, 0, NULL, - &gw, NULL, MATCH_IRE_DSTONLY| - MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE); - } -# ifdef USE_INET6 - else if (fin->fin_v == 6) { - p = ip6->ip6_nxt; - dir = ire_route_lookup_v6(&ip6->ip6_dst, NULL, 0, 0, - NULL, &gw, NULL, MATCH_IRE_DSTONLY| - MATCH_IRE_DEFAULT|MATCH_IRE_RECURSIVE); - } -# endif -#else - dir = ire_lookup(dst.s_addr); -#endif -#if SOLARIS2 < 8 - if (dir) - if (!dir->ire_ll_hdr_mp || !dir->ire_ll_hdr_length) - dir = NULL; -#else - if (dir) - if (!dir->ire_fp_mp || !dir->ire_dlureq_mp) - dir = NULL; -#endif - - if (!ir) - ir = dir; - - if (ir && dir) { - ifp = ire_to_ill(ir); - if (ifp == NULL) - goto bad_fastroute; - fr = fin->fin_fr; - - /* - * In case we're here due to "to " being used with - * "keep state", check that we're going in the correct - * direction. - */ - if ((fr != NULL) && (fdp->fd_ifp != NULL) && - (fin->fin_rev != 0) && (fdp == &fr->fr_tif)) - return 1; - - fin->fin_ifp = ifp; - if (fin->fin_out == 0) { - fin->fin_fr = ipacct[1][fr_active]; - if ((fin->fin_fr != NULL) && - (fr_scanlist(FR_NOMATCH, ip, fin, mb)&FR_ACCOUNT)){ - ATOMIC_INCL(frstats[1].fr_acct); - } - fin->fin_fr = NULL; - if (!fr || !(fr->fr_flags & FR_RETMASK)) - (void) fr_checkstate(ip, fin); - (void) ip_natout(ip, fin); - } -#ifndef sparc - if (fin->fin_v == 4) { - __iplen = (u_short)ip->ip_len, - __ipoff = (u_short)ip->ip_off; - - ip->ip_len = htons(__iplen); - ip->ip_off = htons(__ipoff); - } -#endif - -#if SOLARIS2 < 8 - mp = dir->ire_ll_hdr_mp; - hlen = dir->ire_ll_hdr_length; -#else - mp = dir->ire_fp_mp; - hlen = mp ? mp->b_wptr - mp->b_rptr : 0; - mp = dir->ire_dlureq_mp; -#endif - if (mp != NULL) { - s = mb->b_rptr; - if ( -#if SOLARIS2 >= 6 - (dohwcksum && - ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC) || -#endif - (hlen && (s - mb->b_datap->db_base) >= hlen)) { - s -= hlen; - mb->b_rptr = (u_char *)s; - bcopy((char *)mp->b_rptr, (char *)s, hlen); - } else { - mblk_t *mp2; - - mp2 = copyb(mp); - if (!mp2) - goto bad_fastroute; - linkb(mp2, mb); - mb = mp2; - } - } - *mpp = mb; - - if (ir->ire_stq) - q = ir->ire_stq; - else if (ir->ire_rfq) - q = WR(ir->ire_rfq); - if (q) { - mb->b_prev = NULL; - mb->b_queue = q; - RWLOCK_EXIT(&ipfs_mutex); - RWLOCK_EXIT(&ipf_solaris); -#if SOLARIS2 >= 6 - if ((p == IPPROTO_TCP) && dohwcksum && - (ifp->ill_ick.ick_magic == ICK_M_CTL_MAGIC)) { - tcphdr_t *tcp; - u_32_t t; - - tcp = (tcphdr_t *)((char *)ip + fin->fin_hlen); - t = ip->ip_src.s_addr; - t += ip->ip_dst.s_addr; - t += 30; - t = (t & 0xffff) + (t >> 16); - tcp->th_sum = t & 0xffff; - } -#endif - putnext(q, mb); - READ_ENTER(&ipf_solaris); - READ_ENTER(&ipfs_mutex); - ipl_frouteok[0]++; - *mpp = NULL; - return 0; - } - } -bad_fastroute: - mb->b_prev = NULL; - freemsg(mb); - ipl_frouteok[1]++; - *mpp = NULL; - return -1; -} - - -void copyout_mblk(m, off, len, buf) -mblk_t *m; -size_t off, len; -char *buf; -{ - u_char *s, *bp = (u_char *)buf; - size_t mlen, olen, clen; - - for (; m && len; m = m->b_cont) { - if (MTYPE(m) != M_DATA) - continue; - s = m->b_rptr; - mlen = m->b_wptr - s; - olen = MIN(off, mlen); - if ((olen == mlen) || (olen < off)) { - off -= olen; - continue; - } else if (olen) { - off -= olen; - s += olen; - mlen -= olen; - } - clen = MIN(mlen, len); - bcopy(s, bp, clen); - len -= clen; - bp += clen; - } -} - - -void copyin_mblk(m, off, len, buf) -mblk_t *m; -size_t off, len; -char *buf; -{ - u_char *s, *bp = (u_char *)buf; - size_t mlen, olen, clen; - - for (; m && len; m = m->b_cont) { - if (MTYPE(m) != M_DATA) - continue; - s = m->b_rptr; - mlen = m->b_wptr - s; - olen = MIN(off, mlen); - if ((olen == mlen) || (olen < off)) { - off -= olen; - continue; - } else if (olen) { - off -= olen; - s += olen; - mlen -= olen; - } - clen = MIN(mlen, len); - bcopy(bp, s, clen); - len -= clen; - bp += clen; - } -} - - -int fr_verifysrc(ipa, ifp) -struct in_addr ipa; -void *ifp; -{ - ire_t *ir, *dir, *gw; - -#if SOLARIS2 >= 6 - dir = ire_route_lookup(ipa.s_addr, 0xffffffff, 0, 0, NULL, &gw, NULL, - MATCH_IRE_DSTONLY|MATCH_IRE_DEFAULT| - MATCH_IRE_RECURSIVE); -#else - dir = ire_lookup(ipa.s_addr); -#endif - - if (!dir) - return 0; - return (ire_to_ill(dir) == ifp); -} diff --git a/contrib/ipfilter/test/.cvsignore b/contrib/ipfilter/test/.cvsignore deleted file mode 100644 index 5825abcde9c7..000000000000 --- a/contrib/ipfilter/test/.cvsignore +++ /dev/null @@ -1,87 +0,0 @@ -results -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -i1 -i2 -i3 -i4 -i5 -i6 -i7 -i8 -i9 -i10 -i11 -f1 -f2 -f3 -f4 -f5 -f6 -f7 -f8 -f9 -f10 -f11 -f12 -f13 -f14 -n1 -n2 -n3 -n4 -n5 -n6 -n7 -f15 -f16 -ipv6.1 -ipv6.2 -l1 -ni1 -ni2 -ni3 -ni4 -f17 -in1 -in2 -in3 -in4 -p1 -p2 -i12 -ip1 -p3 -i13 -ni5 -ni6 -i14 -in5 -ipv6.3 -n8 -n9 -n10 -n11 -ni7 -ni8 -ni9 -ni10 -ni11 -ni12 -n12 -in6 -i15 -ni13 -ni14 -ni15 -ni16 diff --git a/contrib/ipfilter/test/expected/1 b/contrib/ipfilter/test/expected/1 deleted file mode 100644 index 93b733336d39..000000000000 --- a/contrib/ipfilter/test/expected/1 +++ /dev/null @@ -1,16 +0,0 @@ -block -block -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -pass -pass diff --git a/contrib/ipfilter/test/expected/10 b/contrib/ipfilter/test/expected/10 deleted file mode 100644 index bc0d83ec88f2..000000000000 --- a/contrib/ipfilter/test/expected/10 +++ /dev/null @@ -1,108 +0,0 @@ -nomatch -block -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -pass -block -block -block -nomatch -nomatch -block -pass -pass -pass -nomatch -nomatch -pass -block -block -nomatch -nomatch -nomatch -block -pass -pass -nomatch -nomatch -nomatch -pass -block -block -block -block -block -block -pass -pass -pass -pass -pass -pass -nomatch -block -block -block -nomatch -block -nomatch -pass -pass -pass -nomatch -pass -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -pass -pass -pass -pass -pass -block -block -nomatch -block -nomatch -block -pass -pass -nomatch -pass -nomatch -pass -block -block -block -block -block -block -pass -pass -pass -pass -pass -pass -block -block -block -nomatch -nomatch -block diff --git a/contrib/ipfilter/test/expected/11 b/contrib/ipfilter/test/expected/11 deleted file mode 100644 index eb00875e01a9..000000000000 --- a/contrib/ipfilter/test/expected/11 +++ /dev/null @@ -1,66 +0,0 @@ -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch diff --git a/contrib/ipfilter/test/expected/12 b/contrib/ipfilter/test/expected/12 deleted file mode 100644 index f94cf768273a..000000000000 --- a/contrib/ipfilter/test/expected/12 +++ /dev/null @@ -1,54 +0,0 @@ -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block diff --git a/contrib/ipfilter/test/expected/14 b/contrib/ipfilter/test/expected/14 deleted file mode 100644 index d06d92b3e02a..000000000000 --- a/contrib/ipfilter/test/expected/14 +++ /dev/null @@ -1,40 +0,0 @@ -nomatch -block -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -pass -pass -pass -nomatch -block -block -block -block -block -pass -pass -pass -pass -pass diff --git a/contrib/ipfilter/test/expected/2 b/contrib/ipfilter/test/expected/2 deleted file mode 100644 index 03b71cdb9ea9..000000000000 --- a/contrib/ipfilter/test/expected/2 +++ /dev/null @@ -1,36 +0,0 @@ -block -block -nomatch -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -nomatch -pass -pass diff --git a/contrib/ipfilter/test/expected/3 b/contrib/ipfilter/test/expected/3 deleted file mode 100644 index d06d92b3e02a..000000000000 --- a/contrib/ipfilter/test/expected/3 +++ /dev/null @@ -1,40 +0,0 @@ -nomatch -block -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -pass -pass -pass -nomatch -block -block -block -block -block -pass -pass -pass -pass -pass diff --git a/contrib/ipfilter/test/expected/4 b/contrib/ipfilter/test/expected/4 deleted file mode 100644 index d06d92b3e02a..000000000000 --- a/contrib/ipfilter/test/expected/4 +++ /dev/null @@ -1,40 +0,0 @@ -nomatch -block -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -block -block -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -pass -pass -pass -nomatch -block -block -block -block -block -pass -pass -pass -pass -pass diff --git a/contrib/ipfilter/test/expected/5 b/contrib/ipfilter/test/expected/5 deleted file mode 100644 index bc805805f136..000000000000 --- a/contrib/ipfilter/test/expected/5 +++ /dev/null @@ -1,1344 +0,0 @@ -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch diff --git a/contrib/ipfilter/test/expected/6 b/contrib/ipfilter/test/expected/6 deleted file mode 100644 index bc805805f136..000000000000 --- a/contrib/ipfilter/test/expected/6 +++ /dev/null @@ -1,1344 +0,0 @@ -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -block -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -pass -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -block -block -block -nomatch -block -block -block -block -block -block -block -block -block -block -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -pass -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -pass -pass -pass -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch diff --git a/contrib/ipfilter/test/expected/7 b/contrib/ipfilter/test/expected/7 deleted file mode 100644 index c53d6eaa0cb9..000000000000 --- a/contrib/ipfilter/test/expected/7 +++ /dev/null @@ -1,54 +0,0 @@ -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -block -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -pass -pass -pass diff --git a/contrib/ipfilter/test/expected/8 b/contrib/ipfilter/test/expected/8 deleted file mode 100644 index 398058a5ec52..000000000000 --- a/contrib/ipfilter/test/expected/8 +++ /dev/null @@ -1,36 +0,0 @@ -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -block -nomatch -nomatch -nomatch -pass -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch diff --git a/contrib/ipfilter/test/expected/9 b/contrib/ipfilter/test/expected/9 deleted file mode 100644 index a4572e6e94e0..000000000000 --- a/contrib/ipfilter/test/expected/9 +++ /dev/null @@ -1,108 +0,0 @@ -block -block -block -block -block -block -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -nomatch -nomatch -nomatch -nomatch -nomatch -pass -nomatch -nomatch -nomatch -nomatch -pass -pass -pass -pass -pass -pass -block -block -nomatch -nomatch -nomatch -nomatch -pass -pass -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -nomatch -block -block -nomatch diff --git a/contrib/ipfilter/test/expected/expected.sed b/contrib/ipfilter/test/expected/expected.sed deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/ipfilter/test/input/1 b/contrib/ipfilter/test/input/1 deleted file mode 100644 index 7c3ae8a3a3db..000000000000 --- a/contrib/ipfilter/test/input/1 +++ /dev/null @@ -1,4 +0,0 @@ -in 127.0.0.1 127.0.0.1 -in 1.1.1.1 1.2.1.1 -out 127.0.0.1 127.0.0.1 -out 1.1.1.1 1.2.1.1 diff --git a/contrib/ipfilter/test/input/10 b/contrib/ipfilter/test/input/10 deleted file mode 100644 index 254cee7316ff..000000000000 --- a/contrib/ipfilter/test/input/10 +++ /dev/null @@ -1,6 +0,0 @@ -in 1.1.1.1 2.1.1.1 opt lsrr -in 1.1.1.1 2.1.1.1 -in 1.1.1.1 2.1.1.1 opt ts -in 1.1.1.1 2.1.1.1 opt sec-class=topsecret -in 1.1.1.1 2.1.1.1 opt ssrr,sec-class=topsecret -in 1.1.1.1 2.1.1.1 opt sec diff --git a/contrib/ipfilter/test/input/11 b/contrib/ipfilter/test/input/11 deleted file mode 100644 index 4eda58eac04e..000000000000 --- a/contrib/ipfilter/test/input/11 +++ /dev/null @@ -1,11 +0,0 @@ -in on e0 tcp 1.1.1.1,1 2.1.2.2,23 S -in on e0 tcp 1.1.1.1,1 2.1.2.2,23 A -in on e1 tcp 2.1.2.2,23 1.1.1.1,1 A -in on e0 tcp 1.1.1.1,1 2.1.2.2,23 F -in on e0 tcp 1.1.1.1,1 2.1.2.2,23 A -in on e0 tcp 1.1.1.1,2 2.1.2.2,23 A -in on e1 udp 1.1.1.1,1 4.4.4.4,53 -in on e1 udp 2.2.2.2,2 4.4.4.4,53 -in on e0 udp 4.4.4.4,53 1.1.1.1,1 -in on e0 udp 4.4.4.4,1023 1.1.1.1,2049 -in on e0 udp 4.4.4.4,2049 1.1.1.1,1023 diff --git a/contrib/ipfilter/test/input/12 b/contrib/ipfilter/test/input/12 deleted file mode 100644 index 5d9c1de3590d..000000000000 --- a/contrib/ipfilter/test/input/12 +++ /dev/null @@ -1,35 +0,0 @@ -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF SYN -45 00 0028 0000 4000 3f 06 0000 01010101 02010101 -0401 0019 00000000 00000000 50 02 2000 0000 0000 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF ACK -45 00 0028 0000 4000 3f 06 0000 01010101 02010101 -0401 0019 00000000 00000000 50 10 2000 0000 0000 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 ACK -45 00 0028 0000 6000 3f 06 0000 01010101 02010101 -0401 0019 00000000 00000000 50 10 2000 0000 0000 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0 -45 00 001c 0000 6000 3f 06 0000 01010101 02010101 -0401 0019 00000000 - -# 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 ACK -45 00 001c 0000 6001 3f 06 0000 01010101 02010101 -00000000 50 10 2000 - -# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0 -45 00 0014 0000 6000 3f 11 0000 01010101 02010101 - -# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 0018 0000 2000 3f 11 0000 01010101 02010101 -0035 0035 - -# 1.1.1.1,1 -> 2.1.1.1,1 TTL=63 UDP MF FO=0 -45 00 001c 0000 2000 3f 11 0000 01010101 02010101 -0001 0001 0004 0000 - -# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 001c 0000 2000 3f 11 0000 01010101 02010101 -0035 0035 0004 0000 - diff --git a/contrib/ipfilter/test/input/13 b/contrib/ipfilter/test/input/13 deleted file mode 100644 index 56ec16d99b83..000000000000 --- a/contrib/ipfilter/test/input/13 +++ /dev/null @@ -1,39 +0,0 @@ -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF,MF,FO=0 SYN -45 00 0028 0001 4000 3f 06 0000 01010101 02010101 -0401 0019 00000000 00000000 50 02 2000 0000 0000 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP MF ACK -45 00 0024 0002 2000 3f 06 0000 01010101 02010101 -0401001900000000 0000000050102000 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP FO=2 ACK -45 00 002c 0002 0002 3f 06 0000 01010101 02010101 -0000000000010203 0405060708090a0b 0c0d0e0f10111213 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF MF FO=0 SYN -45 00 0028 0003 6000 3f 06 0000 01010101 02010101 -0401 0019 00000000 00000000 50 10 2000 0000 0000 - -# 1.1.1.1,1025 -> 2.1.1.1,25 TTL=63 TCP DF FO=0 -45 00 001c 0004 6000 3f 06 0000 01010101 02010101 -0401 0019 00000000 - -# 1.1.1.1 -> 2.1.1.1 TTL=63 TCP DF FO=1 SYN -45 00 001c 0005 6001 3f 06 0000 01010101 02010101 -00000000 50 10 2000 - -# 1.1.1.1 -> 2.1.1.1 TTL=63 UDP DF MF FO=0 -45 00 0014 0006 6000 3f 11 0000 01010101 02010101 - -# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP MF FO=0 -45 00 0018 0007 2000 3f 11 0000 01010101 02010101 -0035 0035 - -# 1.1.1.1,1 -> 2.1.1.1,1 TTL=63 UDP MF FO=0 -45 00 001c 0008 2000 3f 11 0000 01010101 02010101 -0035003500040000 - -# 1.1.1.1,53 -> 2.1.1.1,53 TTL=63 UDP FO=1 -45 00 001c 0008 0001 3f 11 0000 01010101 02010101 -0000000000000000 - diff --git a/contrib/ipfilter/test/input/14 b/contrib/ipfilter/test/input/14 deleted file mode 100644 index 16a806ffec7b..000000000000 --- a/contrib/ipfilter/test/input/14 +++ /dev/null @@ -1,5 +0,0 @@ -in 127.0.0.1 127.0.0.1 -in 1.1.1.1 1.2.1.1 -in 1.1.1.2 1.2.1.1 -in 1.1.2.2 1.2.1.1 -in 1.2.2.2 1.2.1.1 diff --git a/contrib/ipfilter/test/input/2 b/contrib/ipfilter/test/input/2 deleted file mode 100644 index d168af0c716a..000000000000 --- a/contrib/ipfilter/test/input/2 +++ /dev/null @@ -1,6 +0,0 @@ -in tcp 127.0.0.1,1 127.0.0.1,21 -in tcp 1.1.1.1,1 1.2.1.1,21 -in udp 127.0.0.1,1 127.0.0.1,21 -in udp 1.1.1.1,1 1.2.1.1,21 -in icmp 127.0.0.1 127.0.0.1 -in icmp 1.1.1.1 1.2.1.1 diff --git a/contrib/ipfilter/test/input/3 b/contrib/ipfilter/test/input/3 deleted file mode 100644 index 16a806ffec7b..000000000000 --- a/contrib/ipfilter/test/input/3 +++ /dev/null @@ -1,5 +0,0 @@ -in 127.0.0.1 127.0.0.1 -in 1.1.1.1 1.2.1.1 -in 1.1.1.2 1.2.1.1 -in 1.1.2.2 1.2.1.1 -in 1.2.2.2 1.2.1.1 diff --git a/contrib/ipfilter/test/input/4 b/contrib/ipfilter/test/input/4 deleted file mode 100644 index 2956d1b15454..000000000000 --- a/contrib/ipfilter/test/input/4 +++ /dev/null @@ -1,5 +0,0 @@ -in 127.0.0.1 127.0.0.1 -in 1.1.1.1 1.1.1.1 -in 1.1.1.1 1.1.1.2 -in 1.1.1.1 1.1.2.2 -in 1.1.1.1 1.2.2.2 diff --git a/contrib/ipfilter/test/input/5 b/contrib/ipfilter/test/input/5 deleted file mode 100644 index 41600c10763b..000000000000 --- a/contrib/ipfilter/test/input/5 +++ /dev/null @@ -1,28 +0,0 @@ -in tcp 1.1.1.1,0 2.2.2.2,2222 -in tcp 1.1.1.1,1 2.2.2.2,2222 -in tcp 1.1.1.1,23 2.2.2.2,2222 -in tcp 1.1.1.1,21 2.2.2.2,2222 -in tcp 1.1.1.1,1023 2.2.2.2,2222 -in tcp 1.1.1.1,1024 2.2.2.2,2222 -in tcp 1.1.1.1,1025 2.2.2.2,2222 -in tcp 1.1.1.1,32767 2.2.2.2,2222 -in tcp 1.1.1.1,32768 2.2.2.2,2222 -in tcp 1.1.1.1,65535 2.2.2.2,2222 -in tcp 1.1.1.1,5999 2.2.2.2,2222 -in tcp 1.1.1.1,6000 2.2.2.2,2222 -in tcp 1.1.1.1,6009 2.2.2.2,2222 -in tcp 1.1.1.1,6010 2.2.2.2,2222 -in udp 1.1.1.1,0 2.2.2.2,2222 -in udp 1.1.1.1,1 2.2.2.2,2222 -in udp 1.1.1.1,23 2.2.2.2,2222 -in udp 1.1.1.1,21 2.2.2.2,2222 -in udp 1.1.1.1,1023 2.2.2.2,2222 -in udp 1.1.1.1,1024 2.2.2.2,2222 -in udp 1.1.1.1,1025 2.2.2.2,2222 -in udp 1.1.1.1,32767 2.2.2.2,2222 -in udp 1.1.1.1,32768 2.2.2.2,2222 -in udp 1.1.1.1,65535 2.2.2.2,2222 -in udp 1.1.1.1,5999 2.2.2.2,2222 -in udp 1.1.1.1,6000 2.2.2.2,2222 -in udp 1.1.1.1,6009 2.2.2.2,2222 -in udp 1.1.1.1,6010 2.2.2.2,2222 diff --git a/contrib/ipfilter/test/input/6 b/contrib/ipfilter/test/input/6 deleted file mode 100644 index 21f0be3336c5..000000000000 --- a/contrib/ipfilter/test/input/6 +++ /dev/null @@ -1,28 +0,0 @@ -in tcp 2.2.2.2,2222 1.1.1.1,0 -in tcp 2.2.2.2,2222 1.1.1.1,1 -in tcp 2.2.2.2,2222 1.1.1.1,23 -in tcp 2.2.2.2,2222 1.1.1.1,21 -in tcp 2.2.2.2,2222 1.1.1.1,1023 -in tcp 2.2.2.2,2222 1.1.1.1,1024 -in tcp 2.2.2.2,2222 1.1.1.1,1025 -in tcp 2.2.2.2,2222 1.1.1.1,32767 -in tcp 2.2.2.2,2222 1.1.1.1,32768 -in tcp 2.2.2.2,2222 1.1.1.1,65535 -in tcp 2.2.2.2,2222 1.1.1.1,5999 -in tcp 2.2.2.2,2222 1.1.1.1,6000 -in tcp 2.2.2.2,2222 1.1.1.1,6009 -in tcp 2.2.2.2,2222 1.1.1.1,6010 -in udp 2.2.2.2,2222 1.1.1.1,0 -in udp 2.2.2.2,2222 1.1.1.1,1 -in udp 2.2.2.2,2222 1.1.1.1,23 -in udp 2.2.2.2,2222 1.1.1.1,21 -in udp 2.2.2.2,2222 1.1.1.1,1023 -in udp 2.2.2.2,2222 1.1.1.1,1024 -in udp 2.2.2.2,2222 1.1.1.1,1025 -in udp 2.2.2.2,2222 1.1.1.1,32767 -in udp 2.2.2.2,2222 1.1.1.1,32768 -in udp 2.2.2.2,2222 1.1.1.1,65535 -in udp 2.2.2.2,2222 1.1.1.1,5999 -in udp 2.2.2.2,2222 1.1.1.1,6000 -in udp 2.2.2.2,2222 1.1.1.1,6009 -in udp 2.2.2.2,2222 1.1.1.1,6010 diff --git a/contrib/ipfilter/test/input/7 b/contrib/ipfilter/test/input/7 deleted file mode 100644 index 2721af2fb71e..000000000000 --- a/contrib/ipfilter/test/input/7 +++ /dev/null @@ -1,9 +0,0 @@ -in icmp 1.1.1.1 2.1.1.1 echo -in icmp 1.1.1.1 2.1.1.1 echo,1 -in icmp 1.1.1.1 2.1.1.1 echo,3 -in icmp 1.1.1.1 2.1.1.1 unreach -in icmp 1.1.1.1 2.1.1.1 unreach,1 -in icmp 1.1.1.1 2.1.1.1 unreach,3 -in icmp 1.1.1.1 2.1.1.1 echorep -in icmp 1.1.1.1 2.1.1.1 echorep,1 -in icmp 1.1.1.1 2.1.1.1 echorep,3 diff --git a/contrib/ipfilter/test/input/8 b/contrib/ipfilter/test/input/8 deleted file mode 100644 index cace511fbeb8..000000000000 --- a/contrib/ipfilter/test/input/8 +++ /dev/null @@ -1,6 +0,0 @@ -in tcp 1.1.1.1,1 2.1.2.2,1 S -in tcp 1.1.1.1,1 2.1.2.2,1 SA -in tcp 1.1.1.1,1 2.1.2.2,1 SF -in tcp 1.1.1.1,1 2.1.2.2,1 SFPAUR -in tcp 1.1.1.1,1 2.1.2.2,1 PAU -in tcp 1.1.1.1,1 2.1.2.2,1 A diff --git a/contrib/ipfilter/test/input/9 b/contrib/ipfilter/test/input/9 deleted file mode 100644 index 33f3be392a7d..000000000000 --- a/contrib/ipfilter/test/input/9 +++ /dev/null @@ -1,6 +0,0 @@ -in 1.1.1.1 2.1.1.1 opt lsrr -in 1.1.1.1 2.1.1.1 opt lsrr,ssrr -in 1.1.1.1 2.1.1.1 opt ts -in 1.1.1.1 2.1.1.1 opt sec-class=topsecret -in 1.1.1.1 2.1.1.1 opt ssrr,sec-class=topsecret -in 1.1.1.1 2.1.1.1 opt sec diff --git a/contrib/ipfilter/test/input/input.sed b/contrib/ipfilter/test/input/input.sed deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/ipfilter/test/input/ipf6-1 b/contrib/ipfilter/test/input/ipf6-1 deleted file mode 100644 index 8cc2d175dc24..000000000000 --- a/contrib/ipfilter/test/input/ipf6-1 +++ /dev/null @@ -1,26 +0,0 @@ -[out,de0] -6000 0000 0020 3aff ef00 0000 0000 0000 -0000 0000 0001 0013 ff02 0000 0000 0000 -0000 0001 ff01 000b 8700 ea32 0000 0000 -ef00 0000 0000 0000 0000 0000 0001 000b -0101 0048 5487 5c6f - -[in,de0] -6000 0000 0020 3aff ef00 0000 0000 0000 -0000 0000 0001 000b ef00 0000 0000 0000 -0000 0000 0001 0013 8800 5322 6000 0000 -ef00 0000 0000 0000 0000 0000 0001 000b -0201 0800 2071 cce1 - -[out,de0] -6000 0000 0010 3a40 ef00 0000 0000 0000 -0000 0000 0001 0013 ef00 0000 0000 0000 -0000 0000 0001 000b 8000 3210 06ff 0002 -9ec3 3c3c 8a82 0300 - -[in,de0] -6000 0000 0010 3aff ef00 0000 0000 0000 -0000 0000 0001 000b ef00 0000 0000 0000 -0000 0000 0001 0013 8100 3110 06ff 0002 -9ec3 3c3c 8a82 0300 - diff --git a/contrib/ipfilter/test/regress/1 b/contrib/ipfilter/test/regress/1 deleted file mode 100644 index 6a2ede9e31c0..000000000000 --- a/contrib/ipfilter/test/regress/1 +++ /dev/null @@ -1,4 +0,0 @@ -block in all -pass in all -block out all -pass out all diff --git a/contrib/ipfilter/test/regress/10 b/contrib/ipfilter/test/regress/10 deleted file mode 100644 index 355298308e72..000000000000 --- a/contrib/ipfilter/test/regress/10 +++ /dev/null @@ -1,18 +0,0 @@ -block in from any to any with not ipopts -pass in from any to any with not opt sec-class topsecret -block in from any to any with not opt ssrr,sec-class topsecret -pass in from any to any with not opt ssrr,sec-class topsecret -block in from any to any with not opt ts,sec-class topsecret -pass in from any to any with not opt ts,sec-class topsecret -block in from any to any with not opt sec-class secret -pass in from any to any with not opt sec-class secret -block in from any to any with not opt lsrr,ssrr -pass in from any to any with not opt lsrr,ssrr -pass in from any to any with not ipopts -block in from any to any with not opt lsrr -pass in from any to any with not opt lsrr -block in from any to any with not opt ssrr,ts -pass in from any to any with not opt ssrr,ts -block in from any to any with not opt rr -pass in from any to any with not opt rr -block in from any to any with not opt sec-class topsecret diff --git a/contrib/ipfilter/test/regress/11 b/contrib/ipfilter/test/regress/11 deleted file mode 100644 index 0bf0a2a7322d..000000000000 --- a/contrib/ipfilter/test/regress/11 +++ /dev/null @@ -1,6 +0,0 @@ -pass in proto tcp from any to any port = 23 flags S/SA keep state -block in proto tcp from any to any port = 23 flags S/SA keep state -pass in proto udp from any to any port = 53 keep frags -block in proto udp from any to any port = 53 keep frags -pass in proto udp from any to any port = 53 keep state -block in proto udp from any to any port = 53 keep state diff --git a/contrib/ipfilter/test/regress/12 b/contrib/ipfilter/test/regress/12 deleted file mode 100644 index c29f839aa502..000000000000 --- a/contrib/ipfilter/test/regress/12 +++ /dev/null @@ -1,6 +0,0 @@ -pass in proto tcp from any port > 1024 to any port = 25 with not short -pass in proto tcp from any port > 1024 to any port = 25 -block in proto tcp from any to any with short -block in proto tcp from any to any with frag -pass in proto udp from any port = 53 to any port = 53 -block in proto udp from any port = 53 to any port = 53 with not short diff --git a/contrib/ipfilter/test/regress/13 b/contrib/ipfilter/test/regress/13 deleted file mode 100644 index f123e4781c86..000000000000 --- a/contrib/ipfilter/test/regress/13 +++ /dev/null @@ -1,6 +0,0 @@ -pass in proto tcp from any to any port = 25 flags S/SA keep frags -block in proto tcp from any to any port = 25 flags S/SA keep frags -pass in proto udp from any to any port = 53 keep frags -block in proto udp from any to any port = 53 keep frags -pass in proto tcp from any to any port = 25 flags S/SA keep state keep frags -block in proto tcp from any to any port = 25 flags S/SA keep state keep frags diff --git a/contrib/ipfilter/test/regress/14 b/contrib/ipfilter/test/regress/14 deleted file mode 100644 index aa54af8df11d..000000000000 --- a/contrib/ipfilter/test/regress/14 +++ /dev/null @@ -1,8 +0,0 @@ -block in from !1.1.1.1 to any -pass in from 1.1.1.1 to !any -block in from 1.1.1.1/24 to !any -pass in from !1.1.1.1/24 to any -block in from !1.1.1.1/16 to any -pass in from 1.1.1.1/16 to !any -block in from 1.1.1.1/0 to !any -pass in from !1.1.1.1/0 to any diff --git a/contrib/ipfilter/test/regress/2 b/contrib/ipfilter/test/regress/2 deleted file mode 100644 index e2f02a46e283..000000000000 --- a/contrib/ipfilter/test/regress/2 +++ /dev/null @@ -1,6 +0,0 @@ -block in proto tcp from any to any -pass in proto tcp from any to any -block in proto udp from any to any -pass in proto udp from any to any -block in proto icmp from any to any -pass in proto icmp from any to any diff --git a/contrib/ipfilter/test/regress/3 b/contrib/ipfilter/test/regress/3 deleted file mode 100644 index ee80729cfc9b..000000000000 --- a/contrib/ipfilter/test/regress/3 +++ /dev/null @@ -1,8 +0,0 @@ -block in from 1.1.1.1 to any -pass in from 1.1.1.1 to any -block in from 1.1.1.1/24 to any -pass in from 1.1.1.1/24 to any -block in from 1.1.1.1/16 to any -pass in from 1.1.1.1/16 to any -block in from 1.1.1.1/0 to any -pass in from 1.1.1.1/0 to any diff --git a/contrib/ipfilter/test/regress/4 b/contrib/ipfilter/test/regress/4 deleted file mode 100644 index bc8af2f0cae2..000000000000 --- a/contrib/ipfilter/test/regress/4 +++ /dev/null @@ -1,8 +0,0 @@ -block in from any to 1.1.1.1 -pass in from any to 1.1.1.1 -block in from any to 1.1.1.1/24 -pass in from any to 1.1.1.1/24 -block in from any to 1.1.1.1/16 -pass in from any to 1.1.1.1/16 -block in from any to 1.1.1.1/0 -pass in from any to 1.1.1.1/0 diff --git a/contrib/ipfilter/test/regress/5 b/contrib/ipfilter/test/regress/5 deleted file mode 100644 index 998eabd4b10b..000000000000 --- a/contrib/ipfilter/test/regress/5 +++ /dev/null @@ -1,48 +0,0 @@ -block in proto tcp from any port = 23 to any -block in proto udp from any port = 23 to any -block in proto tcp/udp from any port = 23 to any -pass in proto tcp from any port <= 1023 to any -pass in proto udp from any port <= 1023 to any -pass in proto tcp/udp from any port <= 1023 to any -block in proto tcp from any port >= 1024 to any -block in proto udp from any port >= 1024 to any -block in proto tcp/udp from any port >= 1024 to any -pass in proto tcp from any port >= 1024 to any -pass in proto udp from any port >= 1024 to any -pass in proto tcp/udp from any port >= 1024 to any -block in proto tcp from any port 0 >< 512 to any -block in proto udp from any port 0 >< 512 to any -block in proto tcp/udp from any port 0 >< 512 to any -pass in proto tcp from any port 0 >< 512 to any -pass in proto udp from any port 0 >< 512 to any -pass in proto tcp/udp from any port 0 >< 512 to any -block in proto tcp from any port 6000 <> 6009 to any -block in proto udp from any port 6000 <> 6009 to any -block in proto tcp/udp from any port 6000 <> 6009 to any -pass in proto tcp from any port 6000 <> 6009 to any -pass in proto udp from any port 6000 <> 6009 to any -pass in proto tcp/udp from any port 6000 <> 6009 to any -pass in proto tcp from any port = 23 to any -pass in proto udp from any port = 23 to any -pass in proto tcp/udp from any port = 23 to any -block in proto tcp from any port != 21 to any -block in proto udp from any port != 21 to any -block in proto tcp/udp from any port != 21 to any -pass in proto tcp from any port != 21 to any -pass in proto udp from any port != 21 to any -pass in proto tcp/udp from any port != 21 to any -block in proto tcp from any port < 1024 to any -block in proto udp from any port < 1024 to any -block in proto tcp/udp from any port < 1024 to any -pass in proto tcp from any port < 1024 to any -pass in proto udp from any port < 1024 to any -pass in proto tcp/udp from any port < 1024 to any -block in proto tcp from any port > 1023 to any -block in proto udp from any port > 1023 to any -block in proto tcp/udp from any port > 1023 to any -pass in proto tcp from any port > 1023 to any -pass in proto udp from any port > 1023 to any -pass in proto tcp/udp from any port > 1023 to any -block in proto tcp from any port <= 1023 to any -block in proto udp from any port <= 1023 to any -block in proto tcp/udp from any port <= 1023 to any diff --git a/contrib/ipfilter/test/regress/6 b/contrib/ipfilter/test/regress/6 deleted file mode 100644 index 291f09adcdbc..000000000000 --- a/contrib/ipfilter/test/regress/6 +++ /dev/null @@ -1,48 +0,0 @@ -block in proto tcp from any to any port = 23 -block in proto udp from any to any port = 23 -block in proto tcp/udp from any to any port = 23 -pass in proto tcp from any to any port <= 1023 -pass in proto udp from any to any port <= 1023 -pass in proto tcp/udp from any to any port <= 1023 -block in proto tcp from any to any port >= 1024 -block in proto udp from any to any port >= 1024 -block in proto tcp/udp from any to any port >= 1024 -pass in proto tcp from any to any port >= 1024 -pass in proto udp from any to any port >= 1024 -pass in proto tcp/udp from any to any port >= 1024 -block in proto tcp from any to any port 0 >< 512 -block in proto udp from any to any port 0 >< 512 -block in proto tcp/udp from any to any port 0 >< 512 -pass in proto tcp from any to any port 0 >< 512 -pass in proto udp from any to any port 0 >< 512 -pass in proto tcp/udp from any to any port 0 >< 512 -block in proto tcp from any to any port 6000 <> 6009 -block in proto udp from any to any port 6000 <> 6009 -block in proto tcp/udp from any to any port 6000 <> 6009 -pass in proto tcp from any to any port 6000 <> 6009 -pass in proto udp from any to any port 6000 <> 6009 -pass in proto tcp/udp from any to any port 6000 <> 6009 -pass in proto tcp from any to any port = 23 -pass in proto udp from any to any port = 23 -pass in proto tcp/udp from any to any port = 23 -block in proto tcp from any to any port != 21 -block in proto udp from any to any port != 21 -block in proto tcp/udp from any to any port != 21 -pass in proto tcp from any to any port != 21 -pass in proto udp from any to any port != 21 -pass in proto tcp/udp from any to any port != 21 -block in proto tcp from any to any port < 1024 -block in proto udp from any to any port < 1024 -block in proto tcp/udp from any to any port < 1024 -pass in proto tcp from any to any port < 1024 -pass in proto udp from any to any port < 1024 -pass in proto tcp/udp from any to any port < 1024 -block in proto tcp from any to any port > 1023 -block in proto udp from any to any port > 1023 -block in proto tcp/udp from any to any port > 1023 -pass in proto tcp from any to any port > 1023 -pass in proto udp from any to any port > 1023 -pass in proto tcp/udp from any to any port > 1023 -block in proto tcp from any to any port <= 1023 -block in proto udp from any to any port <= 1023 -block in proto tcp/udp from any to any port <= 1023 diff --git a/contrib/ipfilter/test/regress/7 b/contrib/ipfilter/test/regress/7 deleted file mode 100644 index 6848a688a374..000000000000 --- a/contrib/ipfilter/test/regress/7 +++ /dev/null @@ -1,6 +0,0 @@ -block in proto icmp from any to any icmp-type echo -pass in proto icmp from any to any icmp-type echo -block in proto icmp from any to any icmp-type unreach code 3 -pass in proto icmp from any to any icmp-type unreach code 3 -block in proto icmp from any to any icmp-type echorep -pass in proto icmp from any to any icmp-type echorep diff --git a/contrib/ipfilter/test/regress/8 b/contrib/ipfilter/test/regress/8 deleted file mode 100644 index 0f28fd261148..000000000000 --- a/contrib/ipfilter/test/regress/8 +++ /dev/null @@ -1,6 +0,0 @@ -block in proto tcp from any to any flags S -pass in proto tcp from any to any flags S -block in proto tcp from any to any flags S/SA -pass in proto tcp from any to any flags S/SA -block in proto tcp from any to any flags S/APU -pass in proto tcp from any to any flags S/APU diff --git a/contrib/ipfilter/test/regress/9 b/contrib/ipfilter/test/regress/9 deleted file mode 100644 index 17bc96737877..000000000000 --- a/contrib/ipfilter/test/regress/9 +++ /dev/null @@ -1,18 +0,0 @@ -block in from any to any with ipopts -pass in from any to any with opt sec-class topsecret -block in from any to any with opt ssrr,sec-class topsecret -pass in from any to any with opt ssrr,sec-class topsecret -block in from any to any with opt ts,sec-class topsecret -pass in from any to any with opt ts,sec-class topsecret -block in from any to any with opt sec-class secret -pass in from any to any with opt sec-class secret -block in from any to any with opt lsrr,ssrr -pass in from any to any with opt lsrr,ssrr -pass in from any to any with ipopts -block in from any to any with opt lsrr -pass in from any to any with opt lsrr -block in from any to any with opt ssrr,ts -pass in from any to any with opt ssrr,ts -block in from any to any with opt rr -pass in from any to any with opt rr -block in from any to any with opt sec-class topsecret diff --git a/contrib/ipfilter/test/regress/ipf6-1 b/contrib/ipfilter/test/regress/ipf6-1 deleted file mode 100644 index 814dfd6cd664..000000000000 --- a/contrib/ipfilter/test/regress/ipf6-1 +++ /dev/null @@ -1,3 +0,0 @@ -block in all -block out all -pass out proto 58 all keep state diff --git a/contrib/ipfilter/test/regress/regress.sed b/contrib/ipfilter/test/regress/regress.sed deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/contrib/ipfilter/test/test.sed b/contrib/ipfilter/test/test.sed deleted file mode 100644 index 3ce0cb16415e..000000000000 --- a/contrib/ipfilter/test/test.sed +++ /dev/null @@ -1,6 +0,0 @@ - Ç . Ä..0þ CVSGexpected0ÇinputDG$regress -  -.cvsignore -!Makefile -"dotest -#hextest diff --git a/contrib/ipfilter/todo b/contrib/ipfilter/todo deleted file mode 100644 index 5b2c05905214..000000000000 --- a/contrib/ipfilter/todo +++ /dev/null @@ -1,98 +0,0 @@ -BUGS: ------ -* fix "to " bug on FreeBSD 2.2.8 -fastroute works - -=============================================================================== -GENERAL: --------- - -* support redirection like "rdr tun0 0/32 port 80 ..." - -* use fr_tcpstate() with NAT code for increased NAT usage security or even - fr_checkstate() - suspect this is not possible. - -* add another alias for for interfaces ? as well as - all IP#'s associated with the box ? - -time permitting: - -* load balancing across interfaces - -* record buffering for TCP/UDP - -* modular application proxying --done - -* allow multiple ip addresses in a source route list for ipsend - -* port IP Filter to Linux -Not in this century. - -* document bimap - -* document NAT rule order processing - -* add more docs -in progress - -3.4: -XDDD. I agree. Bandwidth Shapping and QoS (Quality of Service, AKA -traffic priorization) should be *TOP* in the TO DO list. - -* Bandwidth limiting!!! -maybe for solaris, otherwise "ALTQ" -* More examples -* More documentation -* Load balancing features added to the NAT code, so that I can have -something coming in for 20.20.20.20:80 and it gets shuffled around between -internal addresses 10.10.10.1:8000 and 10.10.10.2:8000. or whatever. -- done, stage 1 (round robin/split) -The one thing that Cisco's PIX has on IPF that I can see is that -rewrites the sequence numbers with semi-random ones. -- done - -I would also love to see a more extensive NAT. It can choose to do -rdr and map based on saddr, daddr, sport and dport. (Does the kernel -module already have functionality for that and it just needs support in -the userland ipnat?) --sort of done - - * intrusion detection - detection of port scans - detection of multiple connection attempts - - * support for multiple log files - i.e. all connections to ftp and telnet logged to - a seperate log file - - * multiple levels of log severity with E-mail notification - of intrusion alerts or other high priority errors - - * poison pill facility - after detection of a port scan, start sending back - large packets of garbage or other packets to - otherwise confuse the intruder (ping of death?) - -IPv6: ------ -* NAT is yet not available, either as a null proxy or address translation - -BSD: -* "to " and "to :" are not supported, but "fastroute" is. - -Solaris: -* "to :" is not supported, but "fastroute" is and "to " are. - -Tru64: ------- -* IPv6 checksum calculation for RST's and ICMP packets is not done (there - are routines in the Tru64 kernel to do this but what is the interface?) - -does bimap allow equal sized subnets? - -make return-icmp 'intelligent' if no type is given about what type to use? - -reply-to - enforce packets to pass through interfaces in particular -combinations - opposite to "to", set reverse path interface - -- cgit v1.2.3