aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarren Reed <darrenr@FreeBSD.org>2005-04-25 17:31:50 +0000
committerDarren Reed <darrenr@FreeBSD.org>2005-04-25 17:31:50 +0000
commit144279dcb8a3b2717370088ac878f23066aee9e9 (patch)
treee2e1c7115044e6dfc86ff65598566fa32e5f7421
parentdfb9a48c6965171c72436fae97fdb25542af491f (diff)
downloadsrc-144279dcb8a3b2717370088ac878f23066aee9e9.tar.gz
src-144279dcb8a3b2717370088ac878f23066aee9e9.zip
import ipfilter 4.1.8 into the vendor branch
Notes
Notes: svn path=/vendor/ipfilter/dist/; revision=145510
-rw-r--r--contrib/ipfilter/.cvsignore28
-rw-r--r--contrib/ipfilter/BNF27
-rw-r--r--contrib/ipfilter/BSD/.cvsignore22
-rw-r--r--contrib/ipfilter/BSD/Makefile501
-rw-r--r--contrib/ipfilter/BSD/Makefile.ipsend19
-rw-r--r--contrib/ipfilter/BSD/kupgrade226
-rwxr-xr-xcontrib/ipfilter/BSD/make-devices2
-rw-r--r--contrib/ipfilter/FWTK/fwtk_transparent.diff16
-rw-r--r--contrib/ipfilter/FWTK/fwtkp6
-rw-r--r--contrib/ipfilter/FreeBSD-2.2/files.diffs6
-rw-r--r--contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs6
-rwxr-xr-xcontrib/ipfilter/FreeBSD-2.2/kinstall11
-rw-r--r--contrib/ipfilter/FreeBSD-3/INST.FreeBSD-32
-rwxr-xr-xcontrib/ipfilter/FreeBSD-3/kinstall8
-rwxr-xr-xcontrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.02
-rw-r--r--contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.12
-rw-r--r--contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.265
-rwxr-xr-xcontrib/ipfilter/FreeBSD-4.0/kinstall26
-rwxr-xr-xcontrib/ipfilter/FreeBSD-4.0/unkinstall2
-rw-r--r--contrib/ipfilter/FreeBSD/files.diffs6
-rw-r--r--contrib/ipfilter/FreeBSD/files.newconf.diffs6
-rw-r--r--contrib/ipfilter/FreeBSD/files.oldconf.diffs6
-rw-r--r--contrib/ipfilter/FreeBSD/filez.diffs12
-rwxr-xr-xcontrib/ipfilter/FreeBSD/kinstall10
-rw-r--r--contrib/ipfilter/HISTORY813
-rw-r--r--contrib/ipfilter/INST.FreeBSD-2.22
-rw-r--r--contrib/ipfilter/INSTALL.FreeBSD55
-rw-r--r--contrib/ipfilter/IPFILTER.LICENCE57
-rw-r--r--contrib/ipfilter/Makefile334
-rw-r--r--contrib/ipfilter/README3
-rw-r--r--contrib/ipfilter/STYLE.TXT57
-rw-r--r--contrib/ipfilter/WhatsNew40.txt90
-rw-r--r--contrib/ipfilter/bpf-ipf.h452
-rw-r--r--contrib/ipfilter/bpf_filter.c517
-rwxr-xr-xcontrib/ipfilter/bsdinstall9
-rwxr-xr-xcontrib/ipfilter/buildsunos149
-rw-r--r--contrib/ipfilter/etc/protocols3
-rw-r--r--contrib/ipfilter/etc/services2
-rw-r--r--contrib/ipfilter/fil.c6667
-rw-r--r--contrib/ipfilter/ip_auth.c540
-rw-r--r--contrib/ipfilter/ip_auth.h29
-rw-r--r--contrib/ipfilter/ip_compat.h2458
-rw-r--r--contrib/ipfilter/ip_fil.c2308
-rw-r--r--contrib/ipfilter/ip_fil.h1297
-rw-r--r--contrib/ipfilter/ip_fil_freebsd.c1692
-rw-r--r--contrib/ipfilter/ip_frag.c789
-rw-r--r--contrib/ipfilter/ip_frag.h64
-rw-r--r--contrib/ipfilter/ip_ftp_pxy.c1093
-rw-r--r--contrib/ipfilter/ip_h323_pxy.c177
-rw-r--r--contrib/ipfilter/ip_htable.c455
-rw-r--r--contrib/ipfilter/ip_htable.h71
-rw-r--r--contrib/ipfilter/ip_ipsec_pxy.c233
-rw-r--r--contrib/ipfilter/ip_irc_pxy.c435
-rw-r--r--contrib/ipfilter/ip_log.c586
-rw-r--r--contrib/ipfilter/ip_lookup.c530
-rw-r--r--contrib/ipfilter/ip_lookup.h65
-rw-r--r--contrib/ipfilter/ip_msnrpc_pxy.c328
-rw-r--r--contrib/ipfilter/ip_nat.c4779
-rw-r--r--contrib/ipfilter/ip_nat.h405
-rw-r--r--contrib/ipfilter/ip_netbios_pxy.c53
-rw-r--r--contrib/ipfilter/ip_pool.c786
-rw-r--r--contrib/ipfilter/ip_pool.h87
-rw-r--r--contrib/ipfilter/ip_pptp_pxy.c527
-rw-r--r--contrib/ipfilter/ip_proxy.c561
-rw-r--r--contrib/ipfilter/ip_proxy.h309
-rw-r--r--contrib/ipfilter/ip_raudio_pxy.c153
-rw-r--r--contrib/ipfilter/ip_rcmd_pxy.c165
-rw-r--r--contrib/ipfilter/ip_rpcb_pxy.c1460
-rw-r--r--contrib/ipfilter/ip_scan.c594
-rw-r--r--contrib/ipfilter/ip_scan.h108
-rw-r--r--contrib/ipfilter/ip_state.c3851
-rw-r--r--contrib/ipfilter/ip_state.h199
-rw-r--r--contrib/ipfilter/ip_sync.c1001
-rw-r--r--contrib/ipfilter/ip_sync.h117
-rw-r--r--contrib/ipfilter/ipf.h343
-rw-r--r--contrib/ipfilter/ipl.h10
-rw-r--r--contrib/ipfilter/iplang/.cvsignore9
-rw-r--r--contrib/ipfilter/iplang/Makefile35
-rw-r--r--contrib/ipfilter/iplang/iplang.h2
-rw-r--r--contrib/ipfilter/iplang/iplang_l.l23
-rw-r--r--contrib/ipfilter/iplang/iplang_y.y40
-rw-r--r--contrib/ipfilter/ipmon.h96
-rw-r--r--contrib/ipfilter/ipsd/Celler/ip_compat.h2
-rw-r--r--contrib/ipfilter/ipsd/Makefile4
-rw-r--r--contrib/ipfilter/ipsd/ipsd.c7
-rw-r--r--contrib/ipfilter/ipsd/ipsd.h5
-rw-r--r--contrib/ipfilter/ipsd/ipsdr.c7
-rw-r--r--contrib/ipfilter/ipsd/linux.h2
-rw-r--r--contrib/ipfilter/ipsd/sbpf.c2
-rw-r--r--contrib/ipfilter/ipsd/sdlpi.c4
-rw-r--r--contrib/ipfilter/ipsd/slinux.c5
-rw-r--r--contrib/ipfilter/ipsd/snit.c5
-rw-r--r--contrib/ipfilter/ipsend/.OLD/ip_compat.h2
-rw-r--r--contrib/ipfilter/ipsend/.cvsignore3
-rw-r--r--contrib/ipfilter/ipsend/44arp.c37
-rw-r--r--contrib/ipfilter/ipsend/Makefile12
-rw-r--r--contrib/ipfilter/ipsend/arp.c35
-rw-r--r--contrib/ipfilter/ipsend/dlcommon.c30
-rw-r--r--contrib/ipfilter/ipsend/dltest.h2
-rw-r--r--contrib/ipfilter/ipsend/hpux.c6
-rw-r--r--contrib/ipfilter/ipsend/in_var.h4
-rw-r--r--contrib/ipfilter/ipsend/ip.c98
-rw-r--r--contrib/ipfilter/ipsend/ip_var.h4
-rw-r--r--contrib/ipfilter/ipsend/ipresend.12
-rw-r--r--contrib/ipfilter/ipsend/ipresend.c33
-rw-r--r--contrib/ipfilter/ipsend/ipsend.12
-rw-r--r--contrib/ipfilter/ipsend/ipsend.54
-rw-r--r--contrib/ipfilter/ipsend/ipsend.c117
-rw-r--r--contrib/ipfilter/ipsend/ipsend.h24
-rw-r--r--contrib/ipfilter/ipsend/ipsopt.c28
-rw-r--r--contrib/ipfilter/ipsend/iptest.12
-rw-r--r--contrib/ipfilter/ipsend/iptest.c33
-rw-r--r--contrib/ipfilter/ipsend/iptests.c199
-rw-r--r--contrib/ipfilter/ipsend/larp.c14
-rw-r--r--contrib/ipfilter/ipsend/linux.h6
-rw-r--r--contrib/ipfilter/ipsend/lsock.c10
-rw-r--r--contrib/ipfilter/ipsend/resend.c41
-rw-r--r--contrib/ipfilter/ipsend/sbpf.c33
-rw-r--r--contrib/ipfilter/ipsend/sdlpi.c69
-rw-r--r--contrib/ipfilter/ipsend/sirix.c12
-rw-r--r--contrib/ipfilter/ipsend/slinux.c9
-rw-r--r--contrib/ipfilter/ipsend/snit.c9
-rw-r--r--contrib/ipfilter/ipsend/sock.c52
-rw-r--r--contrib/ipfilter/ipsend/sockraw.c89
-rw-r--r--contrib/ipfilter/ipsend/tcpip.h15
-rw-r--r--contrib/ipfilter/ipt.h8
-rw-r--r--contrib/ipfilter/kmem.h5
-rw-r--r--contrib/ipfilter/l4check/http.ok2
-rw-r--r--contrib/ipfilter/l4check/l4check.c25
-rw-r--r--contrib/ipfilter/lib/Makefile309
-rw-r--r--contrib/ipfilter/lib/addicmp.c94
-rw-r--r--contrib/ipfilter/lib/addipopt.c67
-rw-r--r--contrib/ipfilter/lib/addkeep.c86
-rw-r--r--contrib/ipfilter/lib/bcopywrap.c12
-rw-r--r--contrib/ipfilter/lib/binprint.c31
-rw-r--r--contrib/ipfilter/lib/buildopts.c44
-rw-r--r--contrib/ipfilter/lib/checkrev.c46
-rw-r--r--contrib/ipfilter/lib/count4bits.c40
-rw-r--r--contrib/ipfilter/lib/count6bits.c29
-rw-r--r--contrib/ipfilter/lib/debug.c37
-rw-r--r--contrib/ipfilter/lib/extras.c114
-rw-r--r--contrib/ipfilter/lib/facpri.c153
-rw-r--r--contrib/ipfilter/lib/facpri.h43
-rw-r--r--contrib/ipfilter/lib/fill6bits.c48
-rw-r--r--contrib/ipfilter/lib/flags.c25
-rw-r--r--contrib/ipfilter/lib/genmask.c56
-rw-r--r--contrib/ipfilter/lib/gethost.c36
-rw-r--r--contrib/ipfilter/lib/getifname.c76
-rw-r--r--contrib/ipfilter/lib/getline.c58
-rw-r--r--contrib/ipfilter/lib/getnattype.c54
-rw-r--r--contrib/ipfilter/lib/getport.c46
-rw-r--r--contrib/ipfilter/lib/getportproto.c32
-rw-r--r--contrib/ipfilter/lib/getproto.c21
-rw-r--r--contrib/ipfilter/lib/getsumd.c15
-rw-r--r--contrib/ipfilter/lib/hexdump.c30
-rw-r--r--contrib/ipfilter/lib/hostmask.c95
-rw-r--r--contrib/ipfilter/lib/hostname.c51
-rw-r--r--contrib/ipfilter/lib/hostnum.c49
-rw-r--r--contrib/ipfilter/lib/icmpcode.c49
-rw-r--r--contrib/ipfilter/lib/inet_addr.c210
-rw-r--r--contrib/ipfilter/lib/initparse.c20
-rw-r--r--contrib/ipfilter/lib/ionames.c40
-rw-r--r--contrib/ipfilter/lib/ipf_dotuning.c60
-rw-r--r--contrib/ipfilter/lib/ipft_ef.c130
-rw-r--r--contrib/ipfilter/lib/ipft_hx.c158
-rw-r--r--contrib/ipfilter/lib/ipft_pc.c252
-rw-r--r--contrib/ipfilter/lib/ipft_sn.c197
-rw-r--r--contrib/ipfilter/lib/ipft_td.c174
-rw-r--r--contrib/ipfilter/lib/ipft_tx.c331
-rw-r--r--contrib/ipfilter/lib/ipoptsec.c58
-rw-r--r--contrib/ipfilter/lib/kmem.c203
-rw-r--r--contrib/ipfilter/lib/kmem.h34
-rw-r--r--contrib/ipfilter/lib/kmemcpywrap.c15
-rw-r--r--contrib/ipfilter/lib/kvatoname.c31
-rw-r--r--contrib/ipfilter/lib/load_hash.c112
-rw-r--r--contrib/ipfilter/lib/load_hashnode.c61
-rw-r--r--contrib/ipfilter/lib/load_pool.c69
-rw-r--r--contrib/ipfilter/lib/load_poolnode.c63
-rw-r--r--contrib/ipfilter/lib/loglevel.c55
-rw-r--r--contrib/ipfilter/lib/make_range.c26
-rw-r--r--contrib/ipfilter/lib/mutex_emul.c80
-rw-r--r--contrib/ipfilter/lib/nametokva.c30
-rw-r--r--contrib/ipfilter/lib/nat_setgroupmap.c34
-rw-r--r--contrib/ipfilter/lib/natparse.c730
-rw-r--r--contrib/ipfilter/lib/ntomask.c38
-rw-r--r--contrib/ipfilter/lib/optname.c65
-rw-r--r--contrib/ipfilter/lib/optprint.c79
-rw-r--r--contrib/ipfilter/lib/optprintv6.c47
-rw-r--r--contrib/ipfilter/lib/optvalue.c34
-rw-r--r--contrib/ipfilter/lib/parse.c754
-rw-r--r--contrib/ipfilter/lib/portname.c42
-rw-r--r--contrib/ipfilter/lib/portnum.c64
-rw-r--r--contrib/ipfilter/lib/ports.c81
-rw-r--r--contrib/ipfilter/lib/print_toif.c32
-rw-r--r--contrib/ipfilter/lib/printactivenat.c85
-rw-r--r--contrib/ipfilter/lib/printaps.c112
-rw-r--r--contrib/ipfilter/lib/printbuf.c32
-rw-r--r--contrib/ipfilter/lib/printfr.c445
-rw-r--r--contrib/ipfilter/lib/printfraginfo.c29
-rw-r--r--contrib/ipfilter/lib/printhash.c144
-rw-r--r--contrib/ipfilter/lib/printhashnode.c52
-rw-r--r--contrib/ipfilter/lib/printhostmap.c13
-rw-r--r--contrib/ipfilter/lib/printhostmask.c46
-rw-r--r--contrib/ipfilter/lib/printifname.c20
-rw-r--r--contrib/ipfilter/lib/printip.c24
-rw-r--r--contrib/ipfilter/lib/printlog.c44
-rw-r--r--contrib/ipfilter/lib/printmask.c30
-rw-r--r--contrib/ipfilter/lib/printnat.c247
-rw-r--r--contrib/ipfilter/lib/printpacket.c89
-rw-r--r--contrib/ipfilter/lib/printpacket6.c43
-rw-r--r--contrib/ipfilter/lib/printpool.c108
-rw-r--r--contrib/ipfilter/lib/printpoolnode.c33
-rw-r--r--contrib/ipfilter/lib/printportcmp.c29
-rw-r--r--contrib/ipfilter/lib/printsbuf.c24
-rw-r--r--contrib/ipfilter/lib/printstate.c189
-rw-r--r--contrib/ipfilter/lib/printtunable.c21
-rw-r--r--contrib/ipfilter/lib/ratoi.c26
-rw-r--r--contrib/ipfilter/lib/ratoui.c26
-rw-r--r--contrib/ipfilter/lib/remove_hash.c53
-rw-r--r--contrib/ipfilter/lib/remove_hashnode.c58
-rw-r--r--contrib/ipfilter/lib/remove_pool.c50
-rw-r--r--contrib/ipfilter/lib/remove_poolnode.c57
-rw-r--r--contrib/ipfilter/lib/resetlexer.c17
-rw-r--r--contrib/ipfilter/lib/rwlock_emul.c125
-rw-r--r--contrib/ipfilter/lib/tcp_flags.c50
-rw-r--r--contrib/ipfilter/lib/tcpflags.c45
-rw-r--r--contrib/ipfilter/lib/tcpoptnames.c22
-rw-r--r--contrib/ipfilter/lib/to_interface.c31
-rw-r--r--contrib/ipfilter/lib/v6ionames.c27
-rw-r--r--contrib/ipfilter/lib/v6optvalue.c39
-rw-r--r--contrib/ipfilter/lib/var.c171
-rw-r--r--contrib/ipfilter/lib/verbose.c37
-rw-r--r--contrib/ipfilter/man/Makefile11
-rw-r--r--contrib/ipfilter/man/ipf.48
-rw-r--r--contrib/ipfilter/man/ipf.529
-rw-r--r--contrib/ipfilter/man/ipf.838
-rw-r--r--contrib/ipfilter/man/ipfilter.4241
-rw-r--r--contrib/ipfilter/man/ipfilter.4.mandoc267
-rw-r--r--contrib/ipfilter/man/ipfilter.52
-rw-r--r--contrib/ipfilter/man/ipfs.812
-rw-r--r--contrib/ipfilter/man/ipfstat.854
-rw-r--r--contrib/ipfilter/man/ipftest.1194
-rw-r--r--contrib/ipfilter/man/ipl.46
-rw-r--r--contrib/ipfilter/man/ipmon.569
-rw-r--r--contrib/ipfilter/man/ipmon.89
-rw-r--r--contrib/ipfilter/man/ipnat.42
-rw-r--r--contrib/ipfilter/man/ipnat.5147
-rw-r--r--contrib/ipfilter/man/ipnat.835
-rw-r--r--contrib/ipfilter/man/ippool.5155
-rw-r--r--contrib/ipfilter/man/ippool.8126
-rw-r--r--contrib/ipfilter/man/ipscan.552
-rw-r--r--contrib/ipfilter/man/ipscan.844
-rw-r--r--contrib/ipfilter/man/mkfilters.12
-rw-r--r--contrib/ipfilter/md5.c314
-rw-r--r--contrib/ipfilter/md5.h72
-rw-r--r--contrib/ipfilter/mlf_ipl.c164
-rw-r--r--contrib/ipfilter/mlf_rule.c168
-rw-r--r--contrib/ipfilter/mlfk_ipl.c306
-rw-r--r--contrib/ipfilter/mlfk_rule.c69
-rw-r--r--contrib/ipfilter/mlh_rule.c114
-rw-r--r--contrib/ipfilter/net/.cvsignore1
-rw-r--r--contrib/ipfilter/opts.h67
-rw-r--r--contrib/ipfilter/pcap-ipf.h35
-rw-r--r--contrib/ipfilter/perl/ipf-mrtg.pl2
-rw-r--r--contrib/ipfilter/perl/ipfmeta.pl210
-rw-r--r--contrib/ipfilter/perl/logfilter.pl2
-rw-r--r--contrib/ipfilter/radix.c1202
-rw-r--r--contrib/ipfilter/radix_ipf.h208
-rw-r--r--contrib/ipfilter/rules/.cvsignore1
-rw-r--r--contrib/ipfilter/rules/example.11
-rw-r--r--contrib/ipfilter/rules/example.101
-rw-r--r--contrib/ipfilter/rules/example.111
-rw-r--r--contrib/ipfilter/rules/example.121
-rw-r--r--contrib/ipfilter/rules/example.131
-rw-r--r--contrib/ipfilter/rules/example.21
-rw-r--r--contrib/ipfilter/rules/example.31
-rw-r--r--contrib/ipfilter/rules/example.41
-rw-r--r--contrib/ipfilter/rules/example.51
-rw-r--r--contrib/ipfilter/rules/example.61
-rw-r--r--contrib/ipfilter/rules/example.71
-rw-r--r--contrib/ipfilter/rules/example.81
-rw-r--r--contrib/ipfilter/rules/example.91
-rw-r--r--contrib/ipfilter/rules/example.sr1
-rw-r--r--contrib/ipfilter/rules/ip_rules3
-rw-r--r--contrib/ipfilter/rules/ipmon.conf24
-rw-r--r--contrib/ipfilter/rules/pool.conf4
-rw-r--r--contrib/ipfilter/samples/.cvsignore4
-rw-r--r--contrib/ipfilter/samples/Makefile10
-rw-r--r--contrib/ipfilter/samples/ipfilter-pb.gifbin795 -> 796 bytes
-rw-r--r--contrib/ipfilter/samples/proxy.c33
-rw-r--r--contrib/ipfilter/samples/relay.c196
-rw-r--r--contrib/ipfilter/samples/userauth.c12
-rw-r--r--contrib/ipfilter/snoop.h4
-rw-r--r--contrib/ipfilter/test/.cvsignore87
-rw-r--r--contrib/ipfilter/test/Makefile89
-rw-r--r--contrib/ipfilter/test/bpftest28
-rw-r--r--contrib/ipfilter/test/dotest3
-rwxr-xr-xcontrib/ipfilter/test/dotest64
-rw-r--r--contrib/ipfilter/test/expected/bpf-f120
-rw-r--r--contrib/ipfilter/test/expected/bpf14
-rw-r--r--contrib/ipfilter/test/expected/f174
-rw-r--r--contrib/ipfilter/test/expected/i110
-rw-r--r--contrib/ipfilter/test/expected/i117
-rw-r--r--contrib/ipfilter/test/expected/i1238
-rw-r--r--contrib/ipfilter/test/expected/i132
-rw-r--r--contrib/ipfilter/test/expected/i148
-rw-r--r--contrib/ipfilter/test/expected/i154
-rw-r--r--contrib/ipfilter/test/expected/i21
-rw-r--r--contrib/ipfilter/test/expected/i37
-rw-r--r--contrib/ipfilter/test/expected/i43
-rw-r--r--contrib/ipfilter/test/expected/i52
-rw-r--r--contrib/ipfilter/test/expected/i68
-rw-r--r--contrib/ipfilter/test/expected/i72
-rw-r--r--contrib/ipfilter/test/expected/i96
-rw-r--r--contrib/ipfilter/test/expected/in18
-rw-r--r--contrib/ipfilter/test/expected/in289
-rw-r--r--contrib/ipfilter/test/expected/in522
-rw-r--r--contrib/ipfilter/test/expected/in63
-rw-r--r--contrib/ipfilter/test/expected/ip168
-rw-r--r--contrib/ipfilter/test/expected/l16
-rw-r--r--contrib/ipfilter/test/expected/l1.b6
-rw-r--r--contrib/ipfilter/test/expected/n113
-rw-r--r--contrib/ipfilter/test/expected/n106
-rw-r--r--contrib/ipfilter/test/expected/n1151
-rw-r--r--contrib/ipfilter/test/expected/n124
-rw-r--r--contrib/ipfilter/test/expected/n446
-rw-r--r--contrib/ipfilter/test/expected/n56
-rw-r--r--contrib/ipfilter/test/expected/n710
-rw-r--r--contrib/ipfilter/test/expected/n85
-rw-r--r--contrib/ipfilter/test/expected/n95
-rw-r--r--contrib/ipfilter/test/expected/ni16
-rw-r--r--contrib/ipfilter/test/expected/ni108
-rw-r--r--contrib/ipfilter/test/expected/ni118
-rw-r--r--contrib/ipfilter/test/expected/ni125
-rw-r--r--contrib/ipfilter/test/expected/ni1332
-rw-r--r--contrib/ipfilter/test/expected/ni1432
-rw-r--r--contrib/ipfilter/test/expected/ni1532
-rw-r--r--contrib/ipfilter/test/expected/ni1632
-rw-r--r--contrib/ipfilter/test/expected/ni218
-rw-r--r--contrib/ipfilter/test/expected/ni36
-rw-r--r--contrib/ipfilter/test/expected/ni46
-rw-r--r--contrib/ipfilter/test/expected/ni593
-rw-r--r--contrib/ipfilter/test/expected/ni69
-rw-r--r--contrib/ipfilter/test/expected/ni74
-rw-r--r--contrib/ipfilter/test/expected/ni88
-rw-r--r--contrib/ipfilter/test/expected/ni95
-rw-r--r--contrib/ipfilter/test/expected/p119
-rw-r--r--contrib/ipfilter/test/expected/p220
-rw-r--r--contrib/ipfilter/test/expected/p333
-rw-r--r--contrib/ipfilter/test/hextest2
-rw-r--r--contrib/ipfilter/test/input/f112
-rw-r--r--contrib/ipfilter/test/input/f1241
-rw-r--r--contrib/ipfilter/test/input/f1348
-rw-r--r--contrib/ipfilter/test/input/f1735
-rw-r--r--contrib/ipfilter/test/input/ipv6.12
-rw-r--r--contrib/ipfilter/test/input/l158
-rw-r--r--contrib/ipfilter/test/input/n13
-rw-r--r--contrib/ipfilter/test/input/n106
-rw-r--r--contrib/ipfilter/test/input/n1116
-rw-r--r--contrib/ipfilter/test/input/n1218
-rw-r--r--contrib/ipfilter/test/input/n47
-rw-r--r--contrib/ipfilter/test/input/n830
-rw-r--r--contrib/ipfilter/test/input/n930
-rw-r--r--contrib/ipfilter/test/input/ni19
-rw-r--r--contrib/ipfilter/test/input/ni104
-rw-r--r--contrib/ipfilter/test/input/ni1224
-rw-r--r--contrib/ipfilter/test/input/ni13235
-rw-r--r--contrib/ipfilter/test/input/ni14235
-rw-r--r--contrib/ipfilter/test/input/ni15235
-rw-r--r--contrib/ipfilter/test/input/ni16235
-rw-r--r--contrib/ipfilter/test/input/ni654
-rw-r--r--contrib/ipfilter/test/input/ni74
-rw-r--r--contrib/ipfilter/test/input/ni924
-rw-r--r--contrib/ipfilter/test/input/p18
-rw-r--r--contrib/ipfilter/test/input/p28
-rw-r--r--contrib/ipfilter/test/input/p312
-rwxr-xr-xcontrib/ipfilter/test/intest3
-rw-r--r--contrib/ipfilter/test/iptest22
-rw-r--r--contrib/ipfilter/test/itest3
-rwxr-xr-xcontrib/ipfilter/test/logtest23
-rwxr-xr-xcontrib/ipfilter/test/mhtest2
-rwxr-xr-xcontrib/ipfilter/test/mtest4
-rwxr-xr-xcontrib/ipfilter/test/natipftest55
-rwxr-xr-xcontrib/ipfilter/test/nattest10
-rw-r--r--contrib/ipfilter/test/ptest31
-rw-r--r--contrib/ipfilter/test/regress/bpf-f14
-rw-r--r--contrib/ipfilter/test/regress/bpf14
-rw-r--r--contrib/ipfilter/test/regress/i15
-rw-r--r--contrib/ipfilter/test/regress/i117
-rw-r--r--contrib/ipfilter/test/regress/i1213
-rw-r--r--contrib/ipfilter/test/regress/i138
-rw-r--r--contrib/ipfilter/test/regress/i148
-rw-r--r--contrib/ipfilter/test/regress/i155
-rw-r--r--contrib/ipfilter/test/regress/i21
-rw-r--r--contrib/ipfilter/test/regress/i34
-rw-r--r--contrib/ipfilter/test/regress/i43
-rw-r--r--contrib/ipfilter/test/regress/i68
-rw-r--r--contrib/ipfilter/test/regress/i94
-rw-r--r--contrib/ipfilter/test/regress/in12
-rw-r--r--contrib/ipfilter/test/regress/in289
-rw-r--r--contrib/ipfilter/test/regress/in522
-rw-r--r--contrib/ipfilter/test/regress/in63
-rw-r--r--contrib/ipfilter/test/regress/ip178
-rw-r--r--contrib/ipfilter/test/regress/n103
-rw-r--r--contrib/ipfilter/test/regress/n113
-rw-r--r--contrib/ipfilter/test/regress/n121
-rw-r--r--contrib/ipfilter/test/regress/n41
-rw-r--r--contrib/ipfilter/test/regress/n71
-rw-r--r--contrib/ipfilter/test/regress/n81
-rw-r--r--contrib/ipfilter/test/regress/n91
-rw-r--r--contrib/ipfilter/test/regress/ni10.nat2
-rw-r--r--contrib/ipfilter/test/regress/ni11.nat2
-rw-r--r--contrib/ipfilter/test/regress/ni12.ipf4
-rw-r--r--contrib/ipfilter/test/regress/ni12.nat1
-rw-r--r--contrib/ipfilter/test/regress/ni13.ipf3
-rw-r--r--contrib/ipfilter/test/regress/ni13.nat1
-rw-r--r--contrib/ipfilter/test/regress/ni14.ipf3
-rw-r--r--contrib/ipfilter/test/regress/ni14.nat1
-rw-r--r--contrib/ipfilter/test/regress/ni15.ipf3
-rw-r--r--contrib/ipfilter/test/regress/ni15.nat1
-rw-r--r--contrib/ipfilter/test/regress/ni16.ipf3
-rw-r--r--contrib/ipfilter/test/regress/ni16.nat1
-rw-r--r--contrib/ipfilter/test/regress/ni6.ipf9
-rw-r--r--contrib/ipfilter/test/regress/ni6.nat3
-rw-r--r--contrib/ipfilter/test/regress/ni7.nat2
-rw-r--r--contrib/ipfilter/test/regress/ni8.nat2
-rw-r--r--contrib/ipfilter/test/regress/ni9.ipf1
-rw-r--r--contrib/ipfilter/test/regress/ni9.nat1
-rw-r--r--contrib/ipfilter/test/regress/p1.ipf1
-rw-r--r--contrib/ipfilter/test/regress/p1.pool2
-rw-r--r--contrib/ipfilter/test/regress/p2.ipf1
-rw-r--r--contrib/ipfilter/test/regress/p3.ipf6
-rw-r--r--contrib/ipfilter/test/regress/p3.pool4
-rw-r--r--contrib/ipfilter/test/test.format77
-rwxr-xr-xcontrib/ipfilter/test/vfycksum.pl41
-rw-r--r--contrib/ipfilter/todo46
-rw-r--r--contrib/ipfilter/tools/BNF.ipf80
-rw-r--r--contrib/ipfilter/tools/BNF.ipnat28
-rw-r--r--contrib/ipfilter/tools/Makefile103
-rw-r--r--contrib/ipfilter/tools/ipf.c562
-rw-r--r--contrib/ipfilter/tools/ipf_y.y2126
-rw-r--r--contrib/ipfilter/tools/ipfcomp.c1347
-rw-r--r--contrib/ipfilter/tools/ipfs.c855
-rw-r--r--contrib/ipfilter/tools/ipfstat.c1792
-rw-r--r--contrib/ipfilter/tools/ipftest.c776
-rw-r--r--contrib/ipfilter/tools/ipmon.c1663
-rw-r--r--contrib/ipfilter/tools/ipmon_y.y694
-rw-r--r--contrib/ipfilter/tools/ipnat.c400
-rw-r--r--contrib/ipfilter/tools/ipnat_y.y828
-rw-r--r--contrib/ipfilter/tools/ippool.c700
-rw-r--r--contrib/ipfilter/tools/ippool_y.y415
-rw-r--r--contrib/ipfilter/tools/ipscan_y.y565
-rw-r--r--contrib/ipfilter/tools/ipsyncm.c253
-rw-r--r--contrib/ipfilter/tools/ipsyncs.c272
-rw-r--r--contrib/ipfilter/tools/lex_var.h55
-rw-r--r--contrib/ipfilter/tools/lexer.c632
-rw-r--r--contrib/ipfilter/tools/lexer.h37
-rw-r--r--contrib/ipfilter/typescript121
458 files changed, 60111 insertions, 11191 deletions
diff --git a/contrib/ipfilter/.cvsignore b/contrib/ipfilter/.cvsignore
new file mode 100644
index 000000000000..616828f4144d
--- /dev/null
+++ b/contrib/ipfilter/.cvsignore
@@ -0,0 +1,28 @@
+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/BNF b/contrib/ipfilter/BNF
index cf30ab6f1064..404cc281fccf 100644
--- a/contrib/ipfilter/BNF
+++ b/contrib/ipfilter/BNF
@@ -1,25 +1,26 @@
filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
- [ proto ] [ ip ] [ group ].
+ [ proto ] [ ip ] [ group ] [ tag ] [ pps ] .
insert = "@" decnumber .
-action = block | "no-match" | "pass" | log | "count" | skip | auth | call .
+action = block | "pass" | log | "count" | auth | call .
in-out = "in" | "out" .
-options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ]
- [ via ] ] .
+options = [ log ] [ "quick" ] [ onif [ dup ] [ froute ] ] .
tos = "tos" decnumber | "tos" hexnumber .
ttl = "ttl" decnumber .
proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
group = [ "head" decnumber ] [ "group" decnumber ] .
+pps = "pps" decnumber .
+onif = "on" interface-name [ "out-via" interface-name ] .
block = "block" [ return-icmp[return-code] | "return-rst" ] .
auth = "auth" | "preauth" .
log = "log" [ "body" ] [ "first" ] [ "or-block" ] [ "level" loglevel ] .
-call = "call" [ "now" ] function-name .
-skip = "skip" decnumber .
+tag = "tag" tagid .
+call = "call" [ "now" ] function-name "/" decnumber.
dup = "dup-to" interface-name[":"ipaddr] .
-via = "in-via" interface-name | "out-via" interface-name .
-froute = "fastroute" | "to" interface-name [ ":" ipaddr ] .
+froute = "fastroute" | "to" interface-name .
+replyto = "reply-to" interface-name [ ":" ipaddr ] .
protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
@@ -34,8 +35,7 @@ flags = "flags" flag { flag } [ "/" flag { flag } ] .
with = "with" | "and" .
icmp = "icmp-type" icmp-type [ "code" decnumber ] .
return-code = "("icmp-code")" .
-keep = "keep" "state" | "keep" "frags" | "keep" "state-age" state-age .
-state-age = decnmber [ "/" decnumber ] .
+keep = "keep" "state" [ "limit" number ] | "keep" "frags" .
nummask = host-name [ "/" decnumber ] .
host-name = ipaddr | hostname | "any" .
@@ -43,8 +43,9 @@ ipaddr = host-num "." host-num "." host-num "." host-num .
host-num = digit [ digit [ digit ] ] .
port-num = service-name | decnumber .
-withopt = [ "not" | "no" ] opttype [ withopt ] .
-opttype = "ipopts" | "short" | "frag" | "opt" ipopts .
+withopt = [ "not" | "no" ] opttype [ [ "," ] withopt ] .
+opttype = "ipopts" | "short" | "nat" | "bad-src" | "lowttl" | "frag" |
+ "mbcast" | "opt" ipopts .
optname = ipopts [ "," optname ] .
ipopts = optlist | "sec-class" [ secname ] .
secname = seclvl [ "," secname ] .
@@ -77,4 +78,4 @@ compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" |
range = "<>" | "><" .
hexdigit = digit | "a" | "b" | "c" | "d" | "e" | "f" .
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
-flag = "F" | "S" | "R" | "P" | "A" | "U" .
+flag = "F" | "S" | "R" | "P" | "A" | "U" | "C" | "W" .
diff --git a/contrib/ipfilter/BSD/.cvsignore b/contrib/ipfilter/BSD/.cvsignore
new file mode 100644
index 000000000000..c149a0043f45
--- /dev/null
+++ b/contrib/ipfilter/BSD/.cvsignore
@@ -0,0 +1,22 @@
+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/BSD/Makefile b/contrib/ipfilter/BSD/Makefile
index 50a61e886a44..72086a016cdb 100644
--- a/contrib/ipfilter/BSD/Makefile
+++ b/contrib/ipfilter/BSD/Makefile
@@ -1,16 +1,14 @@
#
# 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.
+# See the IPFILTER.LICENCE file for details on licencing.
#
BINDEST=/usr/sbin
SBINDEST=/sbin
-SEARCHDIRS=$(BINDEST) $(SBINDEST) /bin /usr/bin /sbin /usr/sbin \
- /usr/local/bin /usr/local/sbin
MANDIR=/usr/share/man
-CC=cc -Wall -Wstrict-prototypes -Wuninitialized -O
+SEARCHDIRS!=echo $(BINDEST) $(SBINDEST) /bin /usr/bin /sbin /usr/sbin /usr/local/bin /usr/local/sbin | awk '{for(i=1;i<NF;i++){print $$i;}}' - | sort -u
+
+CC=cc -Wall -Wuninitialized -Wstrict-prototypes -O
CFLAGS=-g -I$(TOP)
#
# For NetBSD/FreeBSD
@@ -21,16 +19,19 @@ INC=-I/usr/include -I/sys -I/sys/sys -I/sys/arch
DEF=-D$(CPU) -D__$(CPU)__ -DINET -DKERNEL -D_KERNEL $(INC) $(DEVFS)
IPDEF=$(DEF) -DGATEWAY -DDIRECTED_BROADCAST
VNODESHDIR=/sys/kern
-MLD=$(ML) vnode_if.h
+MLD=$(ML)
ML=mln_ipl.c
-IPFILC=ip_fil.c
LKM=if_ipl.o
+LKMR=ipfrule.o
DLKM=
+OBJ=.
+DEST=$(OBJ)
MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
- "CPUDIR=$(CPUDIR)"
+ "CPUDIR=$(CPUDIR)" "LOOKUP=$(LOOKUP)" "SYNC=$(SYNC)"
+LIBS=-L. -lipf $(LIBBPF)
#
########## ########## ########## ########## ########## ########## ##########
#
@@ -39,205 +40,425 @@ RM=/bin/rm
CHMOD=/bin/chmod
INSTALL=install
#
-MODOBJS=ip_fil.o fil_k.o ml_ipl.o ip_nat.o ip_frag.o ip_state.o ip_proxy.o \
- ip_auth.o ip_log.o
-DFLAGS=$(IPFLKM) $(DEF) $(DLKM)
-IPF=ipf.o parse.o common.o opt.o facpri.o
-IPT=ipt.o parse.o common.o fil.o ipft_sn.o ipft_ef.o ipft_td.o ipft_pc.o \
- opt.o ipft_tx.o misc.o ip_frag_u.o ip_state_u.o ip_nat_u.o ip_proxy_u.o \
- ip_auth_u.o ipft_hx.o ip_fil_u.o ip_log_u.o natparse.o facpri.o \
- printnat.o printstate.o
-IPNAT=ipnat.o kmem.o natparse.o common.o printnat.o
-FILS=fils.o parse.o kmem.o opt.o facpri.o common.o printstate.o
-
-build all: ipf ipfs ipfstat ipftest ipmon ipnat $(LKM)
- /bin/rm -f $(TOP)/ipf
- ln -s `pwd`/ipf $(TOP)
- /bin/rm -f $(TOP)/ipftest
- ln -s `pwd`/ipftest $(TOP)
- /bin/rm -f $(TOP)/ipmon
- ln -s `pwd`/ipmon $(TOP)
- /bin/rm -f $(TOP)/ipnat
- ln -s `pwd`/ipnat $(TOP)
-
-ipfstat: $(FILS)
- $(CC) -static $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) \
- $(FILS) -o $@ $(LIBS) $(STATETOP_LIB) -lkvm
-
-ipf: $(IPF)
- $(CC) -static $(DEBUG) $(CFLAGS) $(IPF) -o $@ $(LIBS)
-
-ipftest: $(IPT)
- $(CC) $(DEBUG) $(CFLAGS) $(IPT) -o $@ $(LIBS)
-
-ipnat: $(IPNAT)
- $(CC) -static $(DEBUG) $(CFLAGS) $(IPNAT) -o $@ $(LIBS) -lkvm
+MODOBJS=ip_fil.o fil.o ml_ipl.o ip_nat.o ip_frag.o ip_state.o ip_proxy.o \
+ ip_auth.o ip_log.o ip_pool.o ip_htable.o ip_lookup.o ip_rules.o \
+ ip_scan.o ip_sync.o
+# ip_trafcon.o
+DFLAGS=$(IPFLKM) $(IPFLOG) $(LOOKUP) $(SYNC) $(DEF) $(DLKM) $(IPFBPF)
+IPF=ipf.o ipfcomp.o ipf_y.o ipf_l.o
+IPT=ipftest.o fil_u.o ip_frag_u.o ip_state_u.o ip_nat_u.o \
+ ip_proxy_u.o ip_auth_u.o ip_htable_u.o ip_lookup_u.o ip_pool_u.o \
+ ip_scan_u.o ip_sync_u.o ip_rules_u.o ip_fil_u.o ip_log_u.o \
+ ippool_y.o ippool_l.o ipf_y.o ipf_l.o ipnat_y.o ipnat_l.o \
+ md5_u.o radix_u.o bpf_filter_u.o
+# ip_syn_u.o
+#ip_trafcon_u.o
+TOOL=$(TOP)/tools
+IPNAT=ipnat.o ipnat_y.o ipnat_l.o
+IPMON=ipmon.o ipmon_y.o ipmon_l.o
+IPPOOL=ippool_y.o ippool_l.o kmem.o ippool.o
+IPTRAFCON=iptrafcon.o
+PROXYLIST=$(TOP)/ip_ftp_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_irc_pxy.c \
+ $(TOP)/ip_netbios_pxy.c $(TOP)/ip_raudio_pxy.c $(TOP)/ip_rcmd_pxy.c \
+ $(TOP)/ip_rpcb_pxy.c $(TOP)/ip_pptp_pxy.c
+FILS=ipfstat.o
+LIBSRC=$(TOP)/lib
+RANLIB=ranlib
+AROPTS=cq
+HERE!=pwd
+CCARGS=-I. $(DEBUG) $(CFLAGS)
+#
+# Extra is option kernel things we always want in user space.
+#
+EXTRA=$(ALLOPTS)
+
+include $(TOP)/lib/Makefile
+
+build all: machine $(OBJ)/libipf.a ipf ipfs ipfstat ipftest ipmon ipnat \
+ ippool ipscan ipsyncm ipsyncs $(LKM) $(LKMR)
+ -sh -c 'for i in ipf ipftest ipmon ippool ipnat ipscan ipsyncm ipsyncs; do /bin/rm -f $(TOP)/$$i; ln -s `pwd`/$$i $(TOP); done'
+
+machine: Makefile.kmod
+ if [ -f Makefile.kmod ] ; then \
+ make -f Makefile.kmod depend MKUPDATE=no; \
+ fi
+
+Makefile.kmod:
+ if [ -f /usr/share/mk/bsd.kmod.mk -a "`uname -s`" = "NetBSD" ] ; then \
+ rm -f Makefile.kmod; \
+ ln -s /usr/share/mk/bsd.kmod.mk Makefile.kmod; \
+ fi
+
+ipfstat: $(FILS) $(OBJ)/libipf.a
+ $(CC) $(CCARGS) $(STATETOP_CFLAGS) $(STATETOP_INC) $(FILS) \
+ -o $@ $(LIBS) $(STATETOP_LIB) -lkvm
+
+ipf: $(IPF) $(OBJ)/libipf.a
+ $(CC) $(CCARGS) $(IPF) -o $@ $(LIBS) -ll $(LIBBPF)
+
+ipftest: $(IPT) $(OBJ)/libipf.a
+ $(CC) $(CCARGS) $(IPT) -o $@ $(LIBS) -ll $(LIBBPF)
+
+ipnat: $(IPNAT) $(OBJ)/libipf.a
+ $(CC) $(CCARGS) $(IPNAT) -o $@ $(LIBS) -lkvm -ll
ipfs: ipfs.o
- $(CC) -static $(DEBUG) $(CFLAGS) ipfs.o -o $@ $(LIBS)
+ $(CC) $(CCARGS) ipfs.o -o $@
-tests:
- (cd test; make )
+ipsyncm: ipsyncm.o $(OBJ)/libipf.a
+ $(CC) $(CCARGS) ipsyncm.o -o $@ $(LIBS)
-fils.o: $(TOP)/fils.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_frag.h \
- $(TOP)/ip_compat.h $(TOP)/ip_state.h $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) $(STATETOP_CFLAGS) $(STATETOP_INC) \
- -c $(TOP)/fils.c -o $@
+ipsyncs: ipsyncs.o $(OBJ)/libipf.a
+ $(CC) $(CCARGS) ipsyncs.o -o $@ $(LIBS)
-ipfs.o: $(TOP)/ipfs.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_state.h \
- $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipfs.c -o $@
+ipsyncm.o: $(TOOL)/ipsyncm.c $(TOP)/ip_sync.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipsyncm.c -o $@
-fil.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/fil.c -o $@
+ipsyncs.o: $(TOOL)/ipsyncs.c $(TOP)/ip_sync.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipsyncs.c -o $@
-fil_k.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h \
- $(TOP)/ipl.h
- $(CC) $(DEBUG) $(CFLAGS) $(POLICY) $(DFLAGS) -c $(TOP)/fil.c -o $@
+tests:
+ (cd test; make )
-ipf.o: $(TOP)/ipf.c $(TOP)/ip_fil.h $(TOP)/ipf.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipf.c -o $@
+ipfstat.o: $(TOOL)/ipfstat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_frag.h \
+ $(TOP)/ip_compat.h $(TOP)/ip_state.h $(TOP)/ip_nat.h $(TOP)/opts.h
+ $(CC) $(CCARGS) $(STATETOP_CFLAGS) $(STATETOP_INC) \
+ -c $(TOOL)/ipfstat.c -o $@
-ipt.o: $(TOP)/ipt.c $(TOP)/ip_fil.h $(TOP)/ipt.h $(TOP)/ipf.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipt.c -o $@
+ipfs.o: $(TOOL)/ipfs.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_state.h \
+ $(TOP)/ip_nat.h $(TOP)/opts.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipfs.c -o $@
-misc.o: $(TOP)/misc.c $(TOP)/ip_fil.h $(TOP)/ipt.h $(TOP)/ipf.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/misc.c -o $@
+fil_u.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_compat.h \
+ $(TOP)/opts.h $(TOP)/ip_rules.h
+ $(CC) $(CCARGS) $(EXTRA) $(IPFBPF) -D_RADIX_H_ -c $(TOP)/fil.c -o $@
-opt.o: $(TOP)/opt.c $(TOP)/ip_fil.h $(TOP)/ipf.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/opt.c -o $@
+fil.o: $(TOP)/fil.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ipl.h \
+ $(TOP)/ip_rules.h
+ $(CC) $(CCARGS) $(POLICY) $(DFLAGS) $(IPFBPF) $(COMPIPF) \
+ -c $(TOP)/fil.c -o $@
-ipnat.o: $(TOP)/ipnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipnat.c -o $@
+ipf.o: $(TOOL)/ipf.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/opts.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipf.c -o $@
-natparse.o: $(TOP)/natparse.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
- $(TOP)/ip_compat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/natparse.c -o $@
+ipfcomp.o: $(TOOL)/ipfcomp.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/opts.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipfcomp.c -o $@
-printnat.o: $(TOP)/printnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
- $(TOP)/ip_compat.h $(TOP)/ip_proxy.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/printnat.c -o $@
+ipftest.o: $(TOOL)/ipftest.c $(TOP)/ip_fil.h $(TOP)/ipt.h $(TOP)/ipf.h \
+ $(TOP)/opts.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipftest.c -o $@
-printstate.o: $(TOP)/printstate.c $(TOP)/ip_fil.h $(TOP)/ipf.h \
- $(TOP)/ip_state.h $(TOP)/ip_compat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/printstate.c -o $@
+ipnat.o: $(TOOL)/ipnat.c $(TOP)/ip_fil.h $(TOP)/ipf.h $(TOP)/ip_nat.h \
+ $(TOP)/opts.h
+ $(CC) $(CCARGS) -c $(TOOL)/ipnat.c -o $@
-ipft_sn.o: $(TOP)/ipft_sn.c $(TOP)/ipt.h $(TOP)/ipf.h $(TOP)/ip_fil.h \
- $(TOP)/snoop.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_sn.c -o $@
+ipnat_y.o: ipnat_y.c ipnat_y.h ipnat_l.h
+ $(CC) $(CCARGS) -c ipnat_y.c -o $@
-ipft_ef.o: $(TOP)/ipft_ef.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_ef.c -o $@
+ipnat_l.o: ipnat_l.c ipnat_y.h
+ $(CC) $(CCARGS) -I. -c ipnat_l.c -o $@
-ipft_td.o: $(TOP)/ipft_td.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_td.c -o $@
+ipnat_y.c: $(TOOL)/ipnat_y.y
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
-ipft_pc.o: $(TOP)/ipft_pc.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_pc.c -o $@
+ipnat_y.h: ipnat_y.c
-ipft_tx.o: $(TOP)/ipft_tx.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_tx.c -o $@
+ipnat_l.c: $(TOOL)/lexer.c $(TOP)/ip_nat.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
-ipft_hx.o: $(TOP)/ipft_hx.c $(TOP)/ipf.h $(TOP)/ip_fil.h $(TOP)/ipt.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipft_hx.c -o $@
+ipnat_l.h: $(TOOL)/lexer.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
ip_nat_u.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_nat.c -o $@
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_nat.c -o $@
ip_proxy_u.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
- $(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_rcmd_pxy.c \
- $(TOP)/ip_raudio_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_proxy.c -o $@
+ $(TOP)/ip_fil.h $(PROXYLIST) $(TOP)/ip_nat.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_proxy.c -o $@
ip_frag_u.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_frag.c -o $@
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_frag.c -o $@
ip_state_u.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_state.c -o $@
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_state.c -o $@
ip_auth_u.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_auth.c -o $@
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_auth.c -o $@
+
+ip_fil_u.o: $(TOP)/ip_fil.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_fil.c -o $@
+
+ip_rules_u.o: ip_rules.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_rules.h
+ $(CC) $(CCARGS) $(EXTRA) -c ip_rules.c -o $@
+
+ip_scan_u.o: $(TOP)/ip_scan.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_scan.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_scan.c -o $@
-ip_fil_u.o: $(TOP)/$(IPFILC) $(TOP)/ip_fil.h $(TOP)/ip_compat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/$(IPFILC) -o $@
+ip_sync_u.o: $(TOP)/ip_sync.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_sync.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_sync.c -o $@
+
+ip_pool_u.o: $(TOP)/ip_pool.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_pool.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_pool.c -o $@
+
+ip_htable_u.o: $(TOP)/ip_htable.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_htable.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_htable.c -o $@
+
+ip_lookup_u.o: $(TOP)/ip_lookup.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_lookup.h $(TOP)/ip_pool.h $(TOP)/ip_htable.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_lookup.c -o $@
+
+ip_trafcon_u.o: $(TOP)/ip_trafcon.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_trafcon.h
+ $(CC) $(CCARGS) -c $(TOP)/ip_trafcon.c -o $@
ip_log_u.o: $(TOP)/ip_log.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ip_log.c -o $@
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/ip_log.c -o $@
+
+md5_u.o: $(TOP)/md5.c $(TOP)/md5.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/md5.c -o $@
+
+radix_u.o: $(TOP)/md5.c $(TOP)/radix_ipf.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/radix.c -o $@
+
+bpf_filter_u.o: $(TOP)/bpf_filter.c $(TOP)/pcap-ipf.h
+ $(CC) $(CCARGS) $(EXTRA) -c $(TOP)/bpf_filter.c -o $@
if_ipl.o: $(MODOBJS)
ld -r $(MODOBJS) -o $(LKM)
${RM} -f if_ipl
+ipfrule.ko.5: ip_rulesx.o $(MLR)
+ ld -warn-common -r -d -o $(.TARGET:S/.ko/.kld/) ip_rulesx.o $(MLR)
+ ld -Bshareable -d -warn-common -o $(LKMR:S/.5$//) $(.TARGET:S/.ko/.kld/)
+ipfrule.ko: ip_rulesx.o $(MLR)
+ gensetdefs ip_rulesx.o $(MLR)
+ $(CC) $(CCARGS) -c setdef0.c
+ $(CC) $(CCARGS) -c setdef1.c
+ ld -Bshareable -o $@ setdef0.o ip_rulesx.o $(MLR) setdef1.o
+
+ipf.ko.5 ipl.ko.5: $(MODOBJS)
+ ld -warn-common -r -d -o $(.TARGET:S/.ko/.kld/) $(MODOBJS)
+ ld -Bshareable -d -warn-common -o $(LKM:S/.5$//) $(.TARGET:S/.ko/.kld/)
+
ipf.ko ipl.ko: $(MODOBJS)
gensetdefs $(MODOBJS)
- $(CC) $(DEBUG) $(CFLAGS) -c setdef0.c
- $(CC) $(DEBUG) $(CFLAGS) -c setdef1.c
- ld -Bshareable -o $(LKM) setdef0.o $(MODOBJS) setdef1.o
+ $(CC) $(CCARGS) -c setdef0.c
+ $(CC) $(CCARGS) -c setdef1.c
+ ld -Bshareable -o $@ setdef0.o $(MODOBJS) setdef1.o
ip_nat.o: $(TOP)/ip_nat.c $(TOP)/ip_nat.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_nat.c -o $@
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_nat.c -o $@
ip_frag.o: $(TOP)/ip_frag.c $(TOP)/ip_frag.h $(TOP)/ip_compat.h $(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_frag.c -o $@
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_frag.c -o $@
ip_state.o: $(TOP)/ip_state.c $(TOP)/ip_state.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_state.c -o $@
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_state.c -o $@
ip_proxy.o: $(TOP)/ip_proxy.c $(TOP)/ip_proxy.h $(TOP)/ip_compat.h \
- $(TOP)/ip_fil.h $(TOP)/ip_ftp_pxy.c $(TOP)/ip_raudio_pxy.c \
- $(TOP)/ip_rcmd_pxy.c $(TOP)/ip_ipsec_pxy.c $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_proxy.c -o $@
+ $(TOP)/ip_fil.h $(PROXYLIST) $(TOP)/ip_nat.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_proxy.c -o $@
ip_auth.o: $(TOP)/ip_auth.c $(TOP)/ip_auth.h $(TOP)/ip_compat.h \
$(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_auth.c -o $@
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_auth.c -o $@
+
+ip_fil.c:
+ /bin/rm -f ip_fil.c
+ ln -s $(TOP)/ip_fil_`uname -s|tr A-Z a-z`.c ip_fil.c
-ip_fil.o: $(TOP)/$(IPFILC) $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ip_nat.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/$(IPFILC) -o $@
+ip_fil.o: ip_fil.c $(TOP)/ip_fil.h $(TOP)/ip_compat.h $(TOP)/ip_nat.h
+ $(CC) $(CCARGS) $(DFLAGS) $(COMPIPF) -c ip_fil.c -o $@
ip_log.o: $(TOP)/ip_log.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) $(DFLAGS) -c $(TOP)/ip_log.c -o $@
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_log.c -o $@
-vnode_if.h: $(VNODESHDIR)/vnode_if.sh $(VNODESHDIR)/vnode_if.src
+ip_scan.o: $(TOP)/ip_scan.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(TOP)/ip_scan.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_scan.c -o $@
+
+ip_sync.o: $(TOP)/ip_sync.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h $(TOP)/ip_sync.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_sync.c -o $@
+
+ip_pool.o: $(TOP)/ip_pool.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_lookup.h $(TOP)/ip_pool.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_pool.c -o $@
+
+ip_htable.o: $(TOP)/ip_htable.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_lookup.h $(TOP)/ip_htable.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_htable.c -o $@
+
+ip_lookup.o: $(TOP)/ip_lookup.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_pool.h $(TOP)/ip_htable.h $(TOP)/ip_lookup.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_lookup.c -o $@
+
+ip_trafcon.o: $(TOP)/ip_trafcon.c $(TOP)/ip_compat.h $(TOP)/ip_fil.h \
+ $(TOP)/ip_trafcon.h
+ $(CC) $(CCARGS) $(DFLAGS) -c $(TOP)/ip_trafcon.c -o $@
+
+vnode_if.h: $(VNODESHDIR)/vnode_if.src
mkdir -p ../sys
- sh $(VNODESHDIR)/vnode_if.sh $(VNODESHDIR)/vnode_if.src
+ if [ -f $(VNODESHDIR)/vnode_if.sh ] ; then \
+ sh $(VNODESHDIR)/vnode_if.sh $(VNODESHDIR)/vnode_if.src; \
+ fi
+ if [ -f $(VNODESHDIR)/vnode_if.pl ] ; then \
+ perl $(VNODESHDIR)/vnode_if.pl $(VNODESHDIR)/vnode_if.src; \
+ fi
if [ -f ../sys/vnode_if.h ] ; then mv ../sys/vnode_if.h .; fi
rmdir ../sys
-ml_ipl.o: $(TOP)/$(MLD) $(TOP)/ipl.h
+ml_ipl.o: vnode_if.h $(TOP)/$(MLD) $(TOP)/ipl.h
-/bin/rm -f vnode_if.c
$(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/$(ML) -o $@
-kmem.o: $(TOP)/kmem.c
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/kmem.c -o $@
+ip_rules.o: ip_rules.c $(TOP)/ip_rules.h
+ $(CC) -I. $(CFLAGS) $(DFLAGS) $(COMPIPF) -c ip_rules.c -o $@
+
+ip_rules.c: $(TOP)/rules/ip_rules $(TOP)/tools/ipfcomp.c ipf
+ ./ipf -cc -nf $(TOP)/rules/ip_rules
+
+$(TOP)/ip_rules.h: ip_rules.c
+ if [ ! -f $(TOP)/ip_rules.h ] ; then \
+ /bin/mv -f ip_rules.h $(TOP); \
+ else \
+ touch $(TOP)/ip_rules.h; \
+ fi
+
+ip_rulesx.o: ip_rules.c $(TOP)/ip_rules.h
+ $(CC) -I. $(CFLAGS) $(DFLAGS) -DIPFILTER_COMPILED -c ip_rules.c -o $@
+
+mlf_rule.o: $(TOP)/mlf_rule.c $(TOP)/ip_rules.h
+ $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mlf_rule.c -o $@
+
+mln_rule.o: $(TOP)/mln_rule.c $(TOP)/ip_rules.h
+ $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mln_rule.c -o $@
+
+mlo_rule.o: $(TOP)/mlo_rule.c $(TOP)/ip_rules.h
+ $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mlo_rule.c -o $@
+
+mlfk_rule.o: $(TOP)/mlfk_rule.c $(TOP)/ip_rules.h
+ $(CC) -I. $(CFLAGS) $(DFLAGS) -c $(TOP)/mlfk_rule.c -o $@
+
+ipf_y.o: ipf_y.c ipf_y.h $(TOP)/ipf.h ipf_l.h $(TOP)/opts.h
+ $(CC) $(CCARGS) $(IPFBPF) -c ipf_y.c -o $@
+
+ipf_l.o: ipf_l.c ipf_y.h $(TOP)/ipf.h ipf_l.h $(TOP)/opts.h
+ $(CC) $(CCARGS) -I. -c ipf_l.c -o $@
+
+ipf_y.c: $(TOOL)/ipf_y.y $(TOP)/ipf.h $(TOP)/opts.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ipf_y.h: ipf_y.c
+
+ipf_l.c: $(TOOL)/lexer.c $(TOP)/ipf.h $(TOP)/opts.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ipf_l.h: $(TOOL)/lexer.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ipmon: $(IPMON) $(OBJ)/libipf.a
+ $(CC) $(CCARGS) $(IPMON) -o $@ $(LIBS) -ll
+
+ipmon.o: $(TOOL)/ipmon.c $(TOP)/ipmon.h
+ $(CC) $(CCARGS) $(LOGFAC) -c $(TOOL)/ipmon.c -o $@
+
+ipmon_y.o: ipmon_y.c ipmon_y.h $(TOP)/ipmon.h ipmon_l.h
+ $(CC) $(CCARGS) -c ipmon_y.c -o $@
+
+ipmon_l.o: ipmon_l.c ipmon_y.h $(TOP)/ipmon.h
+ $(CC) $(CCARGS) -I. -c ipmon_l.c -o $@
+
+ipmon_y.c: $(TOOL)/ipmon_y.y $(TOP)/ipmon.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ipmon_y.h: ipmon_y.c
+
+ipmon_l.c: $(TOOL)/lexer.c $(TOP)/ipmon.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ipmon_l.h: $(TOOL)/lexer.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
-parse.o: $(TOP)/parse.c $(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/parse.c -o $@
+ipscan: ipscan_y.o ipscan_l.o
+ $(CC) $(DEBUG) ipscan_y.o ipscan_l.o -o $@ -ll $(LIBS) -lkvm
-common.o: $(TOP)/common.c $(TOP)/ip_fil.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/common.c -o $@
+ipscan_y.o: ipscan_y.c ipscan_y.h $(TOP)/ip_scan.h ipscan_l.h
+ $(CC) $(CCARGS) -c ipscan_y.c -o $@
-facpri.o: $(TOP)/facpri.c $(TOP)/facpri.h
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/facpri.c -o $@
+ipscan_l.o: ipscan_l.c ipscan_y.h $(TOP)/ip_scan.h
+ $(CC) $(CCARGS) -I. -c ipscan_l.c -o $@
-ipmon: $(TOP)/ipmon.c
- $(CC) $(DEBUG) $(CFLAGS) $(LOGFAC) $(TOP)/ipmon.c -o $@ $(LIBS)
+ipscan_y.c: $(TOOL)/ipscan_y.y $(TOP)/ip_scan.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ipscan_y.h: ipscan_y.c
+
+ipscan_l.c ipscan_l.h: $(TOOL)/lexer.c $(TOP)/ip_scan.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ippool: $(IPPOOL) $(OBJ)/libipf.a
+ $(CC) $(DEBUG) -I. $(CFLAGS) $(IPPOOL) -o $@ -ll -lkvm -L. -lipf
+
+ippool.o: $(TOOL)/ippool.c $(TOP)/ip_pool.h
+ $(CC) $(CCARGS) -c $(TOOL)/ippool.c -o $@
+
+ippool_y.o: ippool_y.c ippool_y.h $(TOP)/ip_pool.h ippool_l.h
+ $(CC) $(CCARGS) -c ippool_y.c -o $@
+
+ippool_l.o: ippool_l.c ippool_y.h $(TOP)/ip_pool.h
+ $(CC) $(CCARGS) -I. -c ippool_l.c -o $@
+
+ippool_y.c: $(TOOL)/ippool_y.y $(TOP)/ip_pool.h ippool_l.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ippool_y.h: ippool_y.c
+
+ippool_l.c: $(TOOL)/lexer.c $(TOP)/ip_pool.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+ippool_l.h: $(TOOL)/lexer.h
+ (cd $(TOOL); make "DEST=$(HERE)" $(HERE)/$@)
+
+iptrafcon.o: $(TOP)/iptrafcon.c
+ $(CC) $(CCARGS) -c $< -o $@
+
+iptrafcon: $(IPTRAFCON) $(OBJ)/libipf.a
+ $(CC) $(CCARGS) $(IPTRAFCON) -o $@ $(LIBS)
+
+.y.c:
+
+.l.c:
clean:
- ${RM} -f *.core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl ipnat \
- vnode_if.h $(LKM) ioconf.h *.ko setdef1.c setdef0.c setdefs.h \
- y.tab.? lex.yy.c ipfs
- ${RM} -f ../opt_inet6.h ../ipftest ../ipmon ../ipf ../ipnat
+ ${RM} -f ../ipf ../ipnat ../ipmon ../ippool ../ipftest
+ ${RM} -f ../ipscan ../ipsyncm ../ipsyncs
+ ${RM} -f *.core *.o *.a ipt ipfstat ipf ipfstat ipftest ipmon
+ ${RM} -f if_ipl ipnat ipfrule.ko* ipf.kld*
+ ${RM} -f vnode_if.h $(LKM) ioconf.h *.ko setdef1.c setdef0.c setdefs.h
+ ${RM} -f ip_fil.c ipf_l.c ipf_y.c ipf_y.h ipf_l.h
+ ${RM} -f ipscan ipscan_y.c ipscan_y.h ipscan_l.c ipscan_l.h
+ ${RM} -f ippool ippool_y.c ippool_y.h ippool_l.c ippool_l.h
+ ${RM} -f ipnat_y.c ipnat_y.h ipnat_l.c ipnat_l.h
+ ${RM} -f ipmon_y.c ipmon_y.h ipmon_l.c ipmon_l.h
+ ${RM} -f ipsyncm ipsyncs ipfs ip_rules.c ip_rules.h
${MAKE} -f Makefile.ipsend ${MFLAGS} clean
+ if [ -f Makefile.kmod ] ; then \
+ ${MAKE} -f Makefile.kmod ${MFLAGS} clean; \
+ fi
-(for i in *; do \
if [ -d $${i} -a -f $${i}/Makefile ] ; then \
- cd $${i}; (make clean); cd ..; \
- rm $${i}/Makefile $${i}/Makefile.ipsend; \
+ cd $${i}; (make TOP=../.. clean); cd ..; \
+ /bin/rm -f $${i}/Makefile $${i}/Makefile.ipsend; \
+ /bin/rm -f $${i}/Makefile.kmod; \
rmdir $${i}; \
fi \
done)
@@ -254,15 +475,31 @@ install:
-if [ -d /modules -a -f ipf.ko ] ; then \
cp ipf.ko /modules; \
fi
+ -if [ -d /modules -a -f ipfrule.ko ] ; then \
+ cp ipfrule.ko /modules; \
+ fi
+ -if [ -d /boot/kernel -a -f ipf.ko ] ; then \
+ cp ipf.ko /boot/kernel; \
+ fi
+ -if [ -d /boot/kernel -a -f ipfrule.ko ] ; then \
+ cp ipfrule.ko /boot/kernel; \
+ fi
+ -if [ -d /usr/lkm -a -f if_ipl.o ] ; then \
+ cp if_ipl.o /usr/lkm; \
+ fi
+ -$(INSTALL) -cs -g wheel -m 755 -o root ipscan $(SBINDEST)
+ (cd $(TOP)/man; make INSTALL=$(INSTALL) MANDIR=$(MANDIR) install; cd $(TOP))
@for i in ipf:$(SBINDEST) ipfs:$(SBINDEST) ipnat:$(SBINDEST) \
+ ippool:$(BINDEST) ipsyncm:$(BINDEST) ipsyncs:$(BINDEST) \
ipfstat:$(SBINDEST) ipftest:$(SBINDEST) ipmon:$(BINDEST); do \
def="`expr $$i : '[^:]*:\(.*\)'`"; \
p="`expr $$i : '\([^:]*\):.*'`"; \
+ dd=; \
for d in $(SEARCHDIRS); do \
if [ -f $$d/$$p ] ; then \
echo "$(INSTALL) -cs -g wheel -m 755 -o root $$p $$d"; \
$(INSTALL) -cs -g wheel -m 755 -o root $$p $$d; \
- dd=$$d; \
+ dd=XXX; \
fi; \
done; \
if [ -z "$$dd" ] ; then \
diff --git a/contrib/ipfilter/BSD/Makefile.ipsend b/contrib/ipfilter/BSD/Makefile.ipsend
index 94a3c7ad1069..410ea67c14fa 100644
--- a/contrib/ipfilter/BSD/Makefile.ipsend
+++ b/contrib/ipfilter/BSD/Makefile.ipsend
@@ -1,16 +1,18 @@
#
-# $Id: Makefile.ipsend,v 2.2 2000/02/28 08:27:51 darrenr Exp $
+# Id: Makefile.ipsend,v 2.8 2002/05/22 16:15:36 darrenr Exp
#
BINDEST=/usr/sbin
SBINDEST=/sbin
MANDIR=/usr/share/man
-OBJS=ipsend.o ip.o ipsopt.o y.tab.o lex.yy.o
+OBJS=ipsend.o ip.o ipsopt.o iplang_y.o iplang_l.o
IPFTO=ipft_ef.o ipft_hx.o ipft_pc.o ipft_sn.o ipft_td.o ipft_tx.o
-ROBJS=ipresend.o ip.o resend.o $(IPFTO) opt.o
+ROBJS=ipresend.o ip.o resend.o
TOBJS=iptest.o iptests.o ip.o
UNIXOBJS=sbpf.o sock.o 44arp.o
+OBJ=.
+LIBS=-L$(OBJ) -lipf
CC=gcc -Wuninitialized -Wstrict-prototypes -O
CFLAGS=-g -I$(TOP)
@@ -19,14 +21,14 @@ MFLAGS="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)" \
'CFLAGS=$(CFLAGS) $(SOLARIS2)' "IPFLKM=$(IPFLKM)" \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
- "CPUDIR=$(CPUDIR)"
+ "CPUDIR=$(CPUDIR)" "LOOKUP=$(LOOKUP)"
#
all build bsd-bpf : ipsend ipresend iptest
-y.tab.o: $(TOP)/iplang/iplang_y.y
+iplang_y.o: $(TOP)/iplang/iplang_y.y
(cd $(TOP)/iplang; $(MAKE) ../BSD/$(CPUDIR)/$@ $(MFLAGS) 'DESTDIR=../BSD/$(CPUDIR)' )
-lex.yy.o: $(TOP)/iplang/iplang_l.l
+iplang_l.o: $(TOP)/iplang/iplang_l.l
(cd $(TOP)/iplang; $(MAKE) ../BSD/$(CPUDIR)/$@ $(MFLAGS) 'DESTDIR=../BSD/$(CPUDIR)' )
.c.o:
@@ -42,7 +44,7 @@ iptest: $(TOBJS) $(UNIXOBJS)
$(CC) $(DEBUG) $(TOBJS) $(UNIXOBJS) -o $@ $(LIBS)
clean:
- rm -rf *.o core a.out ipsend ipresend iptest
+ rm -rf *.o core a.out ipsend ipresend iptest iplang_y.* iplang_l.*
ipsend.o: $(TOP)/ipsend/ipsend.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/ipsend.c -o $@
@@ -101,9 +103,6 @@ dlcommon.o: $(TOP)/ipsend/dlcommon.c
sdlpi.o: $(TOP)/ipsend/sdlpi.c
$(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/sdlpi.c -o $@
-arp.o: $(TOP)/ipsend/arp.c
- $(CC) $(DEBUG) $(CFLAGS) -c $(TOP)/ipsend/arp.c -o $@
-
install:
-$(INSTALL) -cs -g wheel -m 755 -o root ipsend ipresend iptest $(BINDEST)
diff --git a/contrib/ipfilter/BSD/kupgrade b/contrib/ipfilter/BSD/kupgrade
index ae0b71f4e6e1..91f32daab43b 100644
--- a/contrib/ipfilter/BSD/kupgrade
+++ b/contrib/ipfilter/BSD/kupgrade
@@ -1,41 +1,89 @@
#!/bin/sh
#
PATH=/sbin:/usr/sbin:/bin:/usr/bin; export PATH
+argv0=`basename $0`
+os=`uname -s`
+rev=`uname -r`
+maj=`expr $rev : '\([0-9]*\)\.'`
+min=`expr $rev : '[0-9]*\.\([0-9]*\)'`
+sub=`expr $rev : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
+
# try to bomb out fast if anything fails....
set -e
-
-argv0=`basename $0`
+
+fullrev=`printf '%02d%02d%02d' $maj $min $sub`
dir=`pwd`
karch=`uname -m`
-os=`uname -s`
-if [ $os = FreeBSD ] ; then
- rev=`uname -r`
- rev=`expr $rev : '\([0-9]*\)\..*'`
- if [ $rev = 2 ] ; then
- echo "Copying /usr/include/osreldate.h to /sys/sys"
- cp /usr/include/osreldate.h /sys/sys
- fi
- if [ -f /sys/contrib/ipfilter/netinet/mlfk_ipl.c ] ; then
- /bin/cp mlfk_ipl.c /sys/contrib/ipfilter/netinet/
- fi
-fi
archdir="/sys/arch/$karch"
ipfdir=/sys/netinet
if [ -d /sys/contrib/ipfilter ] ; then
ipfdir=/sys/contrib/ipfilter/netinet
fi
+if [ -d /sys/dist/ipf ] ; then
+ ipfdir=/sys/dist/ipf/netinet
+fi
confdir="$archdir/conf"
+if [ -f /dev/ipnat ] ; then
+ major=`ls -l /dev/ipnat | sed -e 's/.* \([0-9]*\),.*/\1/'`
+ echo "Major number for IP Filter is $major"
+else
+ major=x
+fi
echo -n "Installing "
-for i in ip_fil.[ch] fil.c ip_nat.[ch] ip_frag.[ch] ip_state.[ch] ip_proxy.[ch] ip_auth.[ch] ip_log.c ip_compat.h ipl.h ip_*_pxy.c ; do
- echo -n "$i "
+for j in auth frag nat proxy scan state sync pool htable lookup rules; do
+ for i in ip_$j.[ch]; do
+ if [ -f "$i" ] ; then
+ echo -n " $i"
+ cp $i $ipfdir
+ chmod 644 $ipfdir/$i
+ fi
+ done
+done
+
+case $os in
+SunOS)
+ case `uname -r` in
+ 5.*)
+ filc=ip_fil_solaris.c
+ ;;
+ 4.*)
+ filc=ip_fil_sunos.c
+ ;;
+ esac
+ ;;
+*BSD)
+ filc=ip_fil_`echo $os | tr A-Z a-z`.c
+ case $os in
+ FreeBSD)
+ cp mlfk_ipl.c $ipfdir/
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+esac
+
+if [ -f $ipfdir/$filc ] ; then
+ echo -n "$filc -> $ipfdir/$filc "
+ cp $filc $ipfdir/$filc
+ chmod 644 $ipfdir/$filc
+fi
+if [ -f $ipfdir/ip_fil.c ] ; then
+ echo -n "$filc -> $ipfdir/ip_fil.c "
+ cp $filc $ipfdir/ip_fil.c
+ chmod 644 $ipfdir/ip_fil.c
+fi
+
+for i in ip_fil.h fil.c ip_log.c ip_compat.h ipl.h ip_*_pxy.c; do
+ echo -n " $i"
cp $i $ipfdir
chmod 644 $ipfdir/$i
done
echo ""
echo -n "Installing into /usr/include/netinet"
-for j in auth compat fil frag nat proxy state ; do
+for j in auth compat fil frag nat proxy scan state sync pool htable lookup; do
i=ip_$j.h
if [ -f "$i" ] ; then
echo -n " $i"
@@ -57,4 +105,148 @@ if [ -f /sys/netinet/ip_fil_compat.h ] ; then
rm /sys/netinet/ip_fil_compat.h
ln -s /sys/netinet/ip_compat.h /sys/netinet/ip_fil_compat.h
fi
+
+if [ $major != x ] ; then
+ if [ ! -e /dev/ipsync ] ; then
+ echo "Creating /dev/ipsync"
+ mknod /dev/ipsync c $major 4
+ fi
+
+ if [ ! -e /dev/ipsync ] ; then
+ echo "Creating /dev/ipscan"
+ mknod /dev/ipsync c $major 5
+ fi
+
+ if [ ! -e /dev/iplookup ] ; then
+ echo "Creating /dev/iplookup"
+ mknod /dev/iplookup c $major 6
+ fi
+fi
+
+set +e
+os=`uname -s`
+if [ $os = FreeBSD -a -f /sys/conf/files ] ; then
+ cd /sys/conf
+ if [ -f options ] ; then
+ if [ ! -f options.preipf4 ] ; then
+ mv options options.preipf4
+ cp -p options.preipf4 options
+ fi
+ for i in SCAN SYNC LOOKUP COMPILED; do
+ grep IPFILTER_$i options >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo >> options
+ echo "# extra option for IP Filter" >> options
+ echo "IPFILTER_$i opt_ipfilter.h" >> options
+ fi
+ done
+ fi
+ if [ ! -f files.preipf4 ] ; then
+ mv files files.preipf4
+ cp -p files.preipf4 files
+ fi
+ for i in htable pool lookup; do
+ grep ip_$i.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo "contrib/ipfilter/netinet/ip_$i.c optional ipfilter inet ipfilter_lookup" >> files
+ fi
+ done
+ grep ip_sync.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'contrib/ipfilter/netinet/ip_sync.c optional ipfilter inet ipfilter_sync' >> files
+ fi
+ grep ip_scan.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'contrib/ipfilter/netinet/ip_scan.c optional ipfilter inet ipfilter_scan' >> files
+ fi
+ grep ip_rules.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'contrib/ipfilter/netinet/ip_rules.c optional ipfilter inet ipfilter_compiled' >> files
+ fi
+fi
+if [ $os = NetBSD -a -f /sys/conf/files ] ; then
+ cd /sys/conf
+ if [ ! -f files.preipf4 ] ; then
+ mv files files.preipf4
+ cp -p files.preipf4 files
+ fi
+ if [ $fullrev -ge 010600 -a $fullrev -lt 020000 ] ; then
+ for i in htable pool lookup; do
+ grep ip_$i.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo "file netinet/ip_$i.c ipfilter & ipfilter_lookup" >> files
+ fi
+ done
+ grep ip_sync.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'file netinet/ip_sync.c ipfilter & ipfilter_sync' >> files
+ fi
+ grep ip_scan.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'file netinet/ip_scan.c ipfilter & ipfilter_scan' >> files
+ fi
+ grep ip_rules.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'file netinet/ip_rules.c ipfilter & ipfilter_compiled' >> files
+ fi
+ fi
+fi
+if [ $os = OpenBSD -a -f /sys/conf/files ] ; then
+ cd /sys/conf
+ if [ ! -f files.preipf4 ] ; then
+ mv files files.preipf4
+ cp -p files.preipf4 files
+ fi
+ if [ $fullrev -ge 030400 ] ; then
+ for i in htable pool lookup; do
+ grep ip_$i.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo "file netinet/ip_$i.c ipfilter & ipfilter_lookup" >> files
+ fi
+ done
+ grep ip_sync.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'file netinet/ip_sync.c ipfilter & ipfilter_sync' >> files
+ fi
+ grep ip_scan.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'file netinet/ip_scan.c ipfilter & ipfilter_scan' >> files
+ fi
+ grep ip_rules.c files >/dev/null 2>&1
+ if [ $? -ne 0 ] ; then
+ echo 'file netinet/ip_rules.c ipfilter & ipfilter_compiled' >> files
+ fi
+ fi
+fi
+
+if [ -f /usr/src/sys/modules/ipfilter/Makefile -a \
+ ! -f /usr/src/sys/modules/ipfilter/Makefile.orig ] ; then
+cat | (cd /usr/src/sys/modules/ipfilter; patch) <<__EOF__
+*** Makefile.orig Mon Mar 28 09:10:11 2005
+--- Makefile Mon Mar 28 09:12:51 2005
+***************
+*** 5,13 ****
+ KMOD= ipl
+ SRCS= mlfk_ipl.c ip_nat.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \\
+! ip_log.c ip_fil.c fil.c
+
+ .if !defined(NOINET6)
+ CFLAGS+= -DUSE_INET6
+ .endif
+ CFLAGS+= -I$${.CURDIR}/../../contrib/ipfilter
+! CFLAGS+= -DIPFILTER=1 -DIPFILTER_LKM -DIPFILTER_LOG -DPFIL_HOOKS
+--- 5,15 ----
+ KMOD= ipl
+ SRCS= mlfk_ipl.c ip_nat.c ip_frag.c ip_state.c ip_proxy.c ip_auth.c \\
+! ip_log.c ip_fil.c fil.c ip_lookup.c ip_pool.c ip_htable.c \\
+! ip_sync.c ip_scan.c ip_rules.c
+
+ .if !defined(NOINET6)
+ CFLAGS+= -DUSE_INET6
+ .endif
+ CFLAGS+= -I$${.CURDIR}/../../contrib/ipfilter
+! CFLAGS+= -DIPFILTER=1 -DIPFILTER_LKM -DIPFILTER_LOG -DPFIL_HOOKS \\
+! -DIPFILTER_LOOKUP -DIPFILTER_COMPILED
+__EOF__
+fi
exit 0
diff --git a/contrib/ipfilter/BSD/make-devices b/contrib/ipfilter/BSD/make-devices
index 320bd8075d44..d512e1c76b23 100755
--- a/contrib/ipfilter/BSD/make-devices
+++ b/contrib/ipfilter/BSD/make-devices
@@ -26,3 +26,5 @@ mknod /dev/ipl c $major 0
mknod /dev/ipnat c $major 1
mknod /dev/ipstate c $major 2
mknod /dev/ipauth c $major 3
+mknod /dev/ipsync c $major 4
+mknod /dev/ipscan c $major 5
diff --git a/contrib/ipfilter/FWTK/fwtk_transparent.diff b/contrib/ipfilter/FWTK/fwtk_transparent.diff
index 69962b6fe93e..a6c21fa1f1d1 100644
--- a/contrib/ipfilter/FWTK/fwtk_transparent.diff
+++ b/contrib/ipfilter/FWTK/fwtk_transparent.diff
@@ -124,7 +124,7 @@ diff -cr ../TIS.orig/fwtk/Makefile.config.solaris fwtk/Makefile.config.solaris
***************
*** 11,30 ****
#
- # RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.1 1999/08/04 17:40:48 darrenr Exp $"
+ # RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.2 2001/02/28 09:36:06 darrenr Exp $"
# Your C compiler (eg, "cc" or "gcc")
@@ -145,7 +145,7 @@ diff -cr ../TIS.orig/fwtk/Makefile.config.solaris fwtk/Makefile.config.solaris
-Dgethostbyaddr=res_gethostbyaddr -Dgetnetbyname=res_getnetbyname \
--- 11,34 ----
#
- # RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.1 1999/08/04 17:40:48 darrenr Exp $"
+ # RcsId: "$Header: /devel/CVS/IP-Filter/FWTK/fwtk_transparent.diff,v 2.2 2001/02/28 09:36:06 darrenr Exp $"
+ #
+ # Path to sources of ip_filter (ip_nat.h required in lib/hnam.c)
@@ -649,15 +649,15 @@ diff -cr ../TIS.orig/fwtk/lib/hnam.c fwtk/lib/hnam.c
+ 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) {
++ if((natfd=open("/dev/ipnat",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));
++ if(ptr) *ptr=ntohs(natlookup.nl_realport);
++ sprintf(buf,"%s",inet_ntoa(natlookup.nl_realip));
+ #endif
+
+ #if defined(SOLARIS) /* for Solaris */
@@ -679,15 +679,15 @@ diff -cr ../TIS.orig/fwtk/lib/hnam.c fwtk/lib/hnam.c
+ 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) {
++ if( (natfd=open(IPL_NAT,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));
++ if(ptr) *ptr=ntohs(natlookup.nl_realport);
++ sprintf(buf,"%s",inet_ntoa(natlookup.nl_realip));
+ #endif
+
+ /* No transparent proxy support */
diff --git a/contrib/ipfilter/FWTK/fwtkp b/contrib/ipfilter/FWTK/fwtkp
index 8f4819a16f81..aba869db0e7b 100644
--- a/contrib/ipfilter/FWTK/fwtkp
+++ b/contrib/ipfilter/FWTK/fwtkp
@@ -482,15 +482,15 @@ diff -c -r ./lib/hnam.c ../../NEW/fwtk/lib/hnam.c
+ 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) {
++ if((natfd=open(IPL_NAT,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));
++ if(ptr) *ptr=ntohs(natlookup.nl_realport);
++ sprintf(buf,"%s",inet_ntoa(natlookup.nl_realip));
+ #endif
+
+ /* No transparent proxy support */
diff --git a/contrib/ipfilter/FreeBSD-2.2/files.diffs b/contrib/ipfilter/FreeBSD-2.2/files.diffs
index 10bce4b28e9b..2ada3fa4b300 100644
--- a/contrib/ipfilter/FreeBSD-2.2/files.diffs
+++ b/contrib/ipfilter/FreeBSD-2.2/files.diffs
@@ -2,7 +2,7 @@
--- files Sat Apr 4 10:52:58 1998
***************
*** 222,227 ****
---- 222,236 ----
+--- 222,240 ----
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
@@ -15,6 +15,10 @@
+ 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
index 67894d0f8798..82599f199056 100644
--- a/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs
+++ b/contrib/ipfilter/FreeBSD-2.2/files.newconf.diffs
@@ -2,7 +2,7 @@
--- files.newconf Sun Jun 25 02:19:10 1995
***************
*** 161,166 ****
---- 161,175 ----
+--- 161,179 ----
file netinet/ip_input.c inet
file netinet/ip_mroute.c inet
file netinet/ip_output.c inet
@@ -15,6 +15,10 @@
+ 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/kinstall b/contrib/ipfilter/FreeBSD-2.2/kinstall
index 9ecadc4ce2c2..5a4368eba122 100755
--- a/contrib/ipfilter/FreeBSD-2.2/kinstall
+++ b/contrib/ipfilter/FreeBSD-2.2/kinstall
@@ -8,18 +8,17 @@ 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_*_pxy.c mlf_ipl.c ipl.h ip_compat.h \
- ip_auth.[ch] ip_log.c)
+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 )
+ switch ($i)
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
- breaksw
- endsw
+ breaksw
+ endsw
end
echo ""
echo "Copying /usr/include/osreldate.h to /sys/sys"
diff --git a/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3 b/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3
index 6c68dbbda93f..5c30b57821f2 100644
--- a/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3
+++ b/contrib/ipfilter/FreeBSD-3/INST.FreeBSD-3
@@ -16,6 +16,8 @@ To build a kernel with the IP filter, follow these seven steps:
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
diff --git a/contrib/ipfilter/FreeBSD-3/kinstall b/contrib/ipfilter/FreeBSD-3/kinstall
index 8282de731d21..20f0369d6eaf 100755
--- a/contrib/ipfilter/FreeBSD-3/kinstall
+++ b/contrib/ipfilter/FreeBSD-3/kinstall
@@ -9,17 +9,17 @@ 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_*_pxy.c mlf_ipl.c ipl.h \
+ 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 )
+ switch ($i)
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
- breaksw
- endsw
+ breaksw
+ endsw
end
echo ""
echo "Linking /usr/include/osreldate.h to /sys/sys/osreldate.h"
diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0 b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0
index c232b2c15972..8a827cf899e3 100755
--- a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0
+++ b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.0
@@ -1,3 +1,5 @@
+.\" $NetBSD$
+.\"
*** ip6_input.c.orig Sun Feb 13 14:32:01 2000
--- ip6_input.c Wed Apr 26 22:31:34 2000
***************
diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1 b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1
index 90dac19eb044..a6a461299036 100644
--- a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1
+++ b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.1
@@ -1,3 +1,5 @@
+.\" $NetBSD$
+.\"
*** ip6_input.c.orig Sat Jul 15 07:14:34 2000
--- ip6_input.c Thu Oct 19 17:14:37 2000
***************
diff --git a/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2 b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2
new file mode 100644
index 000000000000..a6a461299036
--- /dev/null
+++ b/contrib/ipfilter/FreeBSD-4.0/ipv6-patch-4.2
@@ -0,0 +1,65 @@
+.\" $NetBSD$
+.\"
+*** 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 <netinet6/ip6_fw.h>
+ #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
index 99ec6790bb00..ebd6e2e8a075 100755
--- a/contrib/ipfilter/FreeBSD-4.0/kinstall
+++ b/contrib/ipfilter/FreeBSD-4.0/kinstall
@@ -11,31 +11,25 @@ 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_*_pxy.c mlf_ipl.c mlfk_ipl.c \
- ipl.h ip_compat.h ip_auth.[ch] ip_log.c)
+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 $ipfdir
- chmod 644 $ipfdir/$i
- switch ( $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
+ 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 patchfile=FreeBSD-4.0/ipv6-patch-$krev
-if ( -f $patchfile ) then
- echo ""
- echo "Patching ip6_input.c and ip6_output.c"
- cat $patchfile | (cd /sys/netinet6; patch)
-else
- echo "IPv6 patching not required for your OS version"
-endif
+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] "
diff --git a/contrib/ipfilter/FreeBSD-4.0/unkinstall b/contrib/ipfilter/FreeBSD-4.0/unkinstall
index b9c5f0294de8..4e9caaa9e541 100755
--- a/contrib/ipfilter/FreeBSD-4.0/unkinstall
+++ b/contrib/ipfilter/FreeBSD-4.0/unkinstall
@@ -12,7 +12,7 @@ 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 mlfk_ipl.c ipl.h)
+ ip_log.c mlf_ipl.c ipl.h)
echo -n "$i ";
/bin/rm -f /sys/netinet/$i
end
diff --git a/contrib/ipfilter/FreeBSD/files.diffs b/contrib/ipfilter/FreeBSD/files.diffs
index 84893d47f037..2f028e337eb0 100644
--- a/contrib/ipfilter/FreeBSD/files.diffs
+++ b/contrib/ipfilter/FreeBSD/files.diffs
@@ -2,7 +2,7 @@
--- files Sun Jan 14 14:32:25 1996
***************
*** 208,213 ****
---- 208,221 ----
+--- 208,225 ----
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
@@ -14,6 +14,10 @@
+ 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
index cc7cf41492b0..29aea54dc2fa 100644
--- a/contrib/ipfilter/FreeBSD/files.newconf.diffs
+++ b/contrib/ipfilter/FreeBSD/files.newconf.diffs
@@ -2,7 +2,7 @@
--- files.newconf Sun Jun 25 02:19:10 1995
***************
*** 161,166 ****
---- 161,174 ----
+--- 161,178 ----
file netinet/ip_input.c inet
file netinet/ip_mroute.c inet
file netinet/ip_output.c inet
@@ -14,6 +14,10 @@
+ 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
index 55b526fff770..ed8aff94b39f 100644
--- a/contrib/ipfilter/FreeBSD/files.oldconf.diffs
+++ b/contrib/ipfilter/FreeBSD/files.oldconf.diffs
@@ -2,7 +2,7 @@
--- files.oldconf Sun Apr 23 17:54:18 1995
***************
*** 180,185 ****
---- 180,193 ----
+--- 180,197 ----
netinet/tcp_timer.c optional inet
netinet/tcp_usrreq.c optional inet
netinet/udp_usrreq.c optional inet
@@ -14,6 +14,10 @@
+ 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
index 52492e8a2271..96560063dcd7 100644
--- a/contrib/ipfilter/FreeBSD/filez.diffs
+++ b/contrib/ipfilter/FreeBSD/filez.diffs
@@ -9,11 +9,15 @@
+ 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_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/kinstall b/contrib/ipfilter/FreeBSD/kinstall
index ef2db54b27cb..2b67b9ad995c 100755
--- a/contrib/ipfilter/FreeBSD/kinstall
+++ b/contrib/ipfilter/FreeBSD/kinstall
@@ -8,17 +8,17 @@ 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_auth.[ch] ip_*_pxy.c ip_compat.h ip_log.c)
+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 )
+ switch ($i)
case *.h:
/bin/cp $i /usr/include/netinet/$i
chmod 644 /usr/include/netinet/$i
- breaksw
- endsw
+ breaksw
+ endsw
end
echo ""
grep iplopen $archdir/$karch/conf.c >& /dev/null
diff --git a/contrib/ipfilter/HISTORY b/contrib/ipfilter/HISTORY
index 85a8b5fff068..9b93e8309cab 100644
--- a/contrib/ipfilter/HISTORY
+++ b/contrib/ipfilter/HISTORY
@@ -6,757 +6,394 @@
# in providing a very available location for the IP Filter home page and
# distribution center.
#
-# Thanks to Hewlett Packard for making it possible to port IP Filter to
-# HP-UX 11.00.
-#
-# Thanks to Tel.Net Media for supplying me with equipment to ensure that
-# IP Filter continues to work on Solaris/sparc64.
-#
-# Thanks to BSDI for providing object files for BSD/OS 3.1 and the means
-# to further support development of IP Filter under BSDI.
-#
-# Thanks to Craig Bishop of connect.com.au and Sun Microsystems for the
-# loan of a machine to work on a Solaris 2.x port of this software.
-#
# Thanks also to all those who have contributed patches and other code,
# and especially those who have found the time to port IP Filter to new
# platforms.
#
-3.4.35 21/6/2004 - Released
-
-some cases of ICMP checksum alteration were wrong
-
-block packets that fail to create state table entries
-
-correctly handle all return values from ip_natout() when fastrouting
-
-ipmon was not correctly calculating the length of the IPv6 packet (excluded
-ipv6 header length)
-
-3.4.34 20/4/2004 - Released
-
-correct the ICMP packet checksum fixing up when processing ICMP errors for NAT
-
-various changes to ipsend for sending packets with ipv4 options
-
-look for ipmon's pidfile in /var/run and /etc/opt/ipf in Solaris' init script
-
-only allow non-fragmented packets to influence whether or not a logged
-packet is the same as the one logged before.
-
-make "ipfstat -f" output more informative
-
-compatibility for openbsd byte order changes to ip_off/ip_len
-
-disallow "freebsd" as a make target (encourages people to do the wrong thing)
-
-3.4.33 15/12/2003 - Released
-
-pass on messages moving through ipfilter when it is unloading itself on Solaris
-
-add disabling of auto-detach when the module attaches on Solaris
-
-compatibility patches for 'struct ifnet' changes on FreeBSD
-
-implement a maximum for the number of entries in the NAT table (NAT_TABLE_MAX
-and ipf_nattable_max)
-
-fix ipfstat -A
-
-frsynclist() wasn't paying attention to all the places where interface
-names are, like it should.
-
-fix where packet header pointers are pointing to after doing an ipf_pullup
-
-fix comparing ICMP packets with established TCP state where only 8 bytes
-of header are returned in the ICMP error.
-
-3.4.32 18/6/2003 - Released
-
-fix up the behaviour of ipfs
-
-make parsing errors in ipf/ipnat return an error rather than return
-indicating success.
-
-window scaling patch
-
-make ipfstat work as a set{g,u}id thing - gave up privs before opening
-/dev/ipl
-
-checksum adjustment corrections for ICMP & NAT
-
-attempt to always get an mbuf full of data through pullup if possible
-
-Fix bug with NAT and fragments causing system to crash
-
-Add patches for OpenBSD 3.3
-
-stop LKM locking up the machine on modern NetBSD(?)
-
-allow timeouts in NAT rules to over-ride fr_defnatage if LARGE_NAT is defined
-
-Locking patches for IRIX 6.5 from SGI.
-
-fix bug in synchronising state sessions where all interfaces were invalidated
-
-fix bug in openbsd 3.2 bridge diffs
-
-fix bug parsing port comparisons in proxy rules
-
-3.4.31 7/12/2002 - Released
-
-Solaris 10 compatibility
-
-fix linking into pfil in NetBSD
-
-fix IRIX 6.2 compatibility
-
-add code to check consistency of fr_checkp/fr_check on non-Solaris
-
-OpenBSD: missing patches for ip6_output.c on OpenBSD 3.2,
- make LKM work for 3.2 (OpenBSD LKMs now match NetBSD)
-
-3.4.30 26/11/2002 - Released
-
-attempt to detect using GNU make and abort if so
-
-OpenBSD 3.2 patches from Stefan Hermes von GMX
-
-add MSS clamping code from NetBSD
-
-correctly display ipv6 output with ipfstat for (accounting) rules
-
-fix problems with ioctl handling for /dev/ipauth
-
-set SYN bit in rcmd fake packet to create back channel
-
-make libpcap reader capable of determining in/out (not in libpcap file)
-and add more DLT types
-
-do not allow redirects to localhost for Solaris in NAT parser
-
-allow return-rst with auth rules
-
-man page corrections
-
-fix for handling ipv6 icmp errors
-
-fix up ipfs command line option processing
-
-only allow processing a ftp 227 response following a PASV command
-
-NetBSD: use poll() and adapt to new cdevsw mechanism
-
-make flushing for just ipv6 things work
-
-3.4.29 28/8/2002 - Released
-
-Make substantial changes to the FTP proxy to improve reliability, security
-and functionality.
-
-don't send ICMP errors/TCP RST's in response to blocked proxy packets
-
-fix potential memory leaks when unloading ipfilter from kernel
-
-fix bug in SIOCGNATL handler that did not preserve the expected
-byte order from earlier versions in the port number
-
-set do not fragment flag in generated packets according to system flags,
-where available.
-
-preserve filter rule number and group number in state structure
-
-fix bug in ipmon printing of p/P/b/B
-
-make some changes to the kmem.c code for IRIX compatibility
-
-add code to specifically handle ip.tun* interfaces on Solaris
-
-3.4.28 6/6/2002 - Released
-
-Fix for H.323 proxy to work on little endian boxes
-
-IRIX: Update installation documentation
- add route lock patch
-
-allow use of groups > 65535
-
-create a new packet info summary for packets going through ipfr_fastroute()
-so that where details are different (RST/ICMP errors), the packet now gets
-correctly NAT'd, etc.
-
-fix the FTP proxy so that checks for TCP sequence numbers outside the
-normal offset due to data changes use absolute numbers
-
-make it possible to remove rules in ipftest
-
-Update installing onto OpenBSD and split into two directories:
-OpenBSD-2 and OpenBSD-3
-
-fix error in printout out the protocol in NAT rules
-
-always unlock ipfilter if locking fails half way through in ipfs
-
-fix problems with TCP window scaling
-
-update of man pages for ipnat(4) and ipftest(1)
-
-3.4.27 28/04/2002 - Released
-
-fix calculation of 2's complmenent 16 bit checksum for user space
-
-add mbuflen() to usespace compiles.
-
-add more #ifdef complexity for platform portability
-
-add OpenBSD 3.1 diffs
-
-3.4.26 25/04/2002 - Released
-
-fix parsing and printing of NAT rules with regression tests.
-
-add code to adjust TCP checksums inside ICMP errors where present and as
-required for NAT.
-
-fix documentation problems in instal documents
-
-fix locking problem with auth code on Solaris
-
-fix use of version macros for FreeBSD and make the use of __FreeBSD_version
-override previous hacks except when not present
-
-fix the macros defined for SIOCAUTHR and SIOCAUTHW
-
-fix the H.323 proxy so it no longer panics (multiple issues: re-entry into
-nat_ioctl with lock held on Solaris, trying to copy data from kernel space
-with copyin, unaligned access to get 32bit & 16bit numbers)
-
-use the ip_ttl ndd parameter on Solaris to fill in ip_ttl for packets
-generated by IPFilter
-
-fix comparing state information to delete state table entries
-
-flag packets as being "bad state" if they're outside the window and prevent
-them from being able to cause new state to be created - except for SYN packets
-
-be stricter about what packets match a TCP state table entry if its creation
-was triggered by a SYN packet.
-
-add patches to handle TCP window scaling
-
-don't update TCP state table entries if the packet is not considered to be
-part of the connection
-
-ipfs wasn't allowing -i command line option in getopt
-
-IRIX: fix kvm interface, fix compile warnings, compile the kernel with -O2
- regardless of user compile, fix the getkflags script to prune down the
- output more so it is acceptable
-
-change building in Makefiles to create links to the application in $(TOP)
-at the end of "build" rather than when each is created.
-
-update BSD/kupgrade for FreeBSD
-
-l4check wasn't properly closing things when a connection fails
-
-man page updates for ipmon(8) and ipnat(5)
-
-more regression tests added.
-
-3.4.25 13/03/2002 - Released
-
-retain rule # in state information
-
-log the direction of a packet so ipmon gets it right rather than incorrectly
-deriving it from the rule flags
-
-add #ifdef for IPFILTER_LOGSIZE (put options IPFILTER_LOGSIZE=16384 in BSD
-kernel config files to increase that buffer size)
-
-recognise return-* rules differently to block in ipftest
-
-fix bug in ipmon output for solaris
-
-add regression testing for skip rules, logging and using head/group
-
-fix output of ipmon: was displaying large unsigned ints rather than -1
-when no rules matched.
-
-make logging code compile into ipftest and add -l command line option to
-dump binary log file (read with ipmon -f) when it finishes.
-
-protect rule # and group # from interference when checking accounting rules
-
-add regression testing for log output (text) from ipmon.
-
-document -b command line option for ipmon
-
-fix double-quick in Solaris startup script
-
-3.4.24 01/03/2002 - Released
-
-fix how files are installed on SunOS5
-
-fix some minor problems in SunOS5 ipfboot script
-
-by default, compile all OpenBSD tools in 3.0 for IPv6
-
-fix NULL-pointer dereference in NAT code
-
-make a better attempt at replacing the appropriate binaries on BSD systems
-
-always print IPv6 icmp-types as a number
-
-impose some rules about what "skip" can be used with
-
-fix parsing problems with "keep state" and "keep state-age"
-
-Try to read as much data as is in the log device in ipmon
-
-remove some redundant checks when searching for rdr/nat rules
-
-fix bug in handling of ACCT with FTP proxy
-
-increase array size for interface names, using LIFNAMSIZ
-
-include H.323 proxy from QNX
-
-3.4.23 16/01/2002 - Released
-
-Include patches to install IPFilter into OpenBSD 3.0, both for just kernel
-compiles and complete system builds.
-
-Fix bug in automatic flushing of state table which would cause it to hang
-in an infinite loop bug introduced in 3.4.20.
-
-Modify the sample proxy (samples/proxy.c) so that it ads a NAT mapping for
-the outgoing connection to make it look like it comes from the real source.
-
-Only support ICMPv6 with IPv6.
-
-Move ipnat.1 to ipnat.8
-
-Enhance ipmon to print textual ICMP[v6] types and subtypes where possible.
-
-Make it possible to do IPv6 regression testing with ipftest.
-
-Use kvm library for kmem access, rather than trying to do it manually with
-open/lseek/read.
-
-Fix diffs for ip_input.c on BSDOS so it doesn't crash with fastroute.
-
-Remove Berkeley advertising licence clause. Reference:
-ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
-
-Add more regression tests: ICMPv6 neighbour discovery, ICMP time exceeded
-and fragmentation required.
-
-Fix ipfboot script on Solaris to deal with no nameservers or no route to
-them in a clean manner.
-
-Support per-rule set timeouts for non-TCP NAT and state
-
-Add netbios proxy
-
-Add ICMPv6 stateful checking, including handling multicast destination
-addresses for neighbour discovery.
-
-Fix problems with internals of ICMP messages for MTU discovery and
-unreachables not being correctly adjust on little endian boxes.
-
-Add "in-via" and "out-via" to filtering rules grammar. It is now possible
-to bind a rule to both incoming and outgoing interfaces, in both forward
-and reverse directions (4 directions in total). allows for asymetric flows
-through a firewall.
-
-Fix ipfstat and ipnat for working on crash dumps.
-
-Don't let USE_INET6 stay defined for SunOS4
-
-Count things we see for each interface on solaris.
-
-Include <netinet/icmp6.h> when compiling with USE_INET6 defined and
-also include a whole bunch of #define's to make sure the symbols expected
-can be used.
-
-Fix up fastroute on BSD systems.
-
-Make fastrouting work for IPv6 just a bit better. doesn't split up big
-packets into fragments like the IPv4 one does. You can now do a
-"to <if>:<ipv6_addr>"
-
-Remove some of the differences between user-space and kernel-space code
-that is internal to ipfilter.
-
-Call ipfr_slowtimer() after each packet is processed in ipftest to artificially
-create the illusion of passing time and include the expire functions in the
-code compiled for user-space.
-
-Fix issues with the IPSec proxy not working or leading to a system crash.
-
-Junk all processing of SPIs and special handling for ESP.
-
-Add "no-match" as a filter rule action (resets _LAST_ match)
-
-Add hack to workaround problems with Cassini interface cards on
-Solaris and VLANs
-
-Add some protocols to etc/protocols
-
-3.4.22 03/12/2001 - Released
-
-various openbsd changes
-
-sorting based on IP numbers for ipfstat top output
-
-fix various IPv6 code & compile problems
-
-modify ip_fil.c to be more netbsd friendly
-
-fix fastroute bug where it modified a packet post-sending
-
-fix get_unit() - don't understand why it was broken.
+4.1.8 - Released 29 March 2005
-add FI_IGNOREPKT and don't count so marked packets when doing stats or
-state/nat.
+include path from Phil Dibowitz for sorting ipfstat -t output by source or
+destination port.
-extend the interface name saved to log output
+fix a bug in printing rules where interface names could not be printed,
+even if they're in the rule structure.
-make proxies capable of extending the matching done on a packet with a
-particular nat session
+fix BSD/kupgrade to correctly change ipfilter lkm Makefile for FreeBSD
-change interfaces inside NAT & state code to accomodate redesign to allow
-IPsec proxy to work.
+add 2 new features to SIOCGNATL:
+- if IPN_FINDFORWARD is set, check if the respective MAP is already
+ present in the outbound table
+- if IPN_IN is set, search for a matching MAP entry instead of RDR
+ (Peter Potsma)
-fix bug when free'ing loaded rules that results in a memory leak
-(only an issue with "ipf -rf -", not flush)
+turn off function inlining for freebsd 5.3+
-make ipftest capable of loading > 1 file or rules, making it now possible
-to load both NAT & filter rules
+UDP doesn't pullup enough data which can sometimes cause a panic.
+Fix other protocols, as required, where a similar problem may exist.
-fix hex input for ipftest to allow interface name & direction to work
+overhaul the timeout queue management, especially that for user defined queues
+which are now only freed in an orderly manner.
-show ipsec proxy details in ipnat output
+4.1.7 - Released 13 March 2005
-if OPT_HEX is set in opts, print a packet out as hex
+Using the GRE call field is almost impossible because it is unbalanced and
+both call fields are not present in each v1 header.
-don't modify b_next or preseve it or preserve b_prev for solaris
+Fix a problem where it was possible to load duplicate rules into ipf
-fix up kinstall scripts to install all the files everywhere they need to
+patch from John Wehle to address problems with fastroute on solaris
-fix overflowing of bits in ip_off inside iptest
+Copying data out for ipf -z failed because it tried to copy out to an address
+that is a kernel pointer in user space.
-make userauth and proxy in samples directory compile
+add "ip" timeout for both NAT & state that's for non-TCP/UDP/ICMP
-fix minimum size when doing a pullup for ESP & ICMPv6
+synch up with NetBSD's changes
-3.4.21 24/10/2001 - Released
+fix problems parsing long lines of text in the ftp proxy where they would not
+be parsed properly and stop the session from working
-include ipsec proxy
+enhance the PPTP proxy so that it tries to decode messages in the TCP stream
+so it knows when to create and destroy the state/nat sessions for GRE. There
+are also 4 new regression tests for it, testing map/rdr rules.
-make state work for non-tcp/udp/icmp in a very simple way
+impose some limits on the size of data that can be moved with SIOCSTPUT in
+the NAT code and also prevent a duplicate session entry from being created
+using this method.
-include diffs for ipv6 firewall on openbsd-2.9
+add a new flag (IPN_FINDFORWARD) to NAT code that can be used with SIOCGNATL
+to check if it is possible to create an outgoing transparent NAT mapping to
+compliment the redirect being investigated.
-add compatibility filter wrapper for NetBSD-current
+Linux requires that the checksums in the IP header get adjusted
-fix command line option problems with ipfs
+only resolve unknown interfaces in fr_stinsert, and nuke all interface pointers
+in SIOCSTPUT to prevent bad data being loaded from userspace.
-if we fill the state table and a automated flush doesn't purge any
-expiring entries, remove all entries idle for more than half a day
+make the byte counting for state correct (was counting data from ICMP packet
+twice)
-fix bug with sending resets/icmp errors where the pointer to the data
-section of the packet was not being set (BSD only)
+print out the keyword "frag-body" if the flag is set.
-split out validating ftp commands and responses into different halves,
-one for each of server & client.
+fix ipfs loading/restoring NAT sessions
-do not compile in STATETOP support for specific architectures
+patch from Frank to correctly format IP addresses in ipfstat -t output
-fix INSTALL.FreeBSD to no longer provide directions and properly direct
-people to the right file for the right version of FreeBSD.
+parsing port numbers in ipf/ipnat was confusing as the port number was returned
+in an int that was also overloaded to be the suceess/failure. instead, change
+the port using pass by reference and only use the return value for indicating
+success or failure.
-3.4.20 24/07/2001 - Released
+4.1.6 - Released 19 February 2005
-adjust NAT hashing to give a better spread across the table
+add a new timeout number to NAT (fr_defnatipage) that is used for all
+non-TCP/UDP/ICMP protocols - default 60 seconds.
-show icmp code/type names in output, where known
+buffer leak with bad nat - David Gueluy
-fix bug in altering cached interface names in state when resync'ing
+fix memory leak with state entries created by proxies
-fix bug in real audio proxy that caused crashs
-
-fix compiling using sunos4 cc
+eliminate copying too much data into a scan buffer
-patch from casper to address weird exit problem for ipstat in top mode
+allow a trailing protocol name for map rules as well as rdr ones
-patch from Greg Woods to produce names for icmp types/unreach codes,
-where they are known
+fix bug in parsing of <= and > for NAT rules (two were crossed over)
-fix bug where ipfr_fastroute() would use a mblk and it would also get
-freed later.
+FreeBSD's iplwrite hasn't kept pace with iplread's prototype
-don't match fragments which would cause 64k length to be exceeded
+expand documention on the karma of using "auto" in ipnat map rules
-ftp proxy fix for port numbers being setup for pasv ftp with state/nat
+add matching on IP protocol to ipnat map rules
-change hashing for NAT to include both IP#'s and ports.
+allow ippool definitions to contain no addresses to start with
-Solaris fixes for IPv6
+Linux NAT needs to modify the IP header checksum as it gets called after it
+has been computed by IP.
-fix compiling iplang bits, under Solaris, for ipsend
+UDP was missing a pullup for packet header information before examining
+the header
-3.4.19 29/06/2001 - Released
+4.1.5 - Released 9 January 2005
-fix to support suspend/resume on solaris8 as well as ipv6
+all rules were being converted into "dup-to" rules in the kernel
-include group/group-head in match of filter rules
+fix two ftp proxy problems: 1st, buffer needs to be bigger for fitting in
+complete RETR/CWD commands, 2nd is () use in 227 messages isn't copied
+over correctly.
-fix endian problem reading snoop files
+response to CWDs
+revert ip_off back to network byte order in the ICMP error packet that
+gets generated.
-make all licence comments point to the one place
+4.1.4 - Released 9 January 2005
-fix ftp proxy to only advance state if a reply is received in response to
-a recognised command
+force NAT rules to only match ipv4 NAT rules (which all are, currently,
+by default)
-3.4.18 05/06/2001 - Released
+include state synchronisation fixes from Frank Volf
-fix up parsing of "from ! host" where '!' is separate
+make the maximum log size for internally buffered log entries accessible
+via "ipf -T"
-disable hardware checksums for NetBSD
+redesign start of fr_check() to avoid putting duplicate information in
+ipfilter about how much data needs to be pulled up for a protocol to be
+properly filtered.
-put ipftest temporary files in . rather than /tmp
+tidy up sending ICMP error messages - some bad inputs could result in
+data not being freed and/or no error returned.
-modify ftp proxy to be more intelligent about moving between states
-and recognise new authentication commands
+make the maximum size of the log buffer run-time tunable
-allow state/nat table sizes to be externally influenced
+fix bug in parsing TCP header when looking for MSS option that could make
+the system hang
-print out host mapping table for NAT with ipnat -l
+change pool lookups that fail to find a match to return "no match"
+rather than fail.
-fix handling of hardware checksum'ing on Solaris
+add run-time tunable debugging for proxy support code and FTP proxy.
-fixup makefiles for Solaris
+fix state table updates for entries where the first packet as an ICMPv6
+multicast message
-update regression tests
+fix hang when flushing state for v4/v6 and other (v6/v4) entries are present
+too
-fix surrender of SPL's for failure cases
+attaching filtering to ipv6 pfil hook wasn't present for solaris
-include patches for OpenBSD's new timeout mechanism
+don't allow rules with "keep state" and "with oow"
-default ipl_unreach to ICMP_UNREACH_FILTER_PROHIB if defined, else make it
-ICMP_UNREACH_FILTER
+move a bunch of userland only code from fil.c to ip_fil.c
-fix up handling of packets matching auth rules and interaction with state
+make fr_coalesce() more resiliant to bad input, just returning an error
+instead of crashing, making calling it easier in many places
-add -q command line option to ipfstat on Solaris to list bound interfaces
+When m_pulldown doesn't return NULL, it doesn't necessarily return a pointer
+to the same mbuf passed in as the first arg.
-add command line option to ipfstat/ipnat to select different core image
+remove fr_unreach and use ENETUNREACH by default.
-don't use ncurses on Solaris for STATETOP
+printing out of tag data in ipf rules doesn't match input syntax
-fix includes to get FreeBSD version
+ipftest(1) man page update
-do not byte swap ip_id
+ipfs command line option parsing still rejects some valid syntaxes
-fix handling success for packets matching the auth rule
+SIGHUP handling by ipmon was not as safe as it could be
-don't double-count short packets
+fix various parsing regressions, including "<thishost>", "tcpudp", ordering
+of "keep" options
-add ICMP router discovery message size recognition
+patches from Frank Volk: add udp_acktimeout to sysctl list for FreeBSD,
+ICMP packet length not calculated correctly in send_icmp_err, reply-to
+not printed by ipfstat, keep state with icmp passing (mtrr)
-fix packet length calculation for IPv6
+patches for return-rst and return-icmp from Attila Fueloep
+(lichtscheu@gesindel.org)
-set CPUDIR when for install-sunos5 make target
+4.1.3 - Released 18 July 2004
-SUNWspro -xF causes Solaris 2.5.1 kernel to crash
+do some more fine tuning on NAT checksum adjustments
-3.4.17 06/04/2001 - Released
+correct IP address byte order in proxy setup for ipsec/pptp
-fix fragment#0 handling bug where they could get in via cache information
-created by state table entries
+man page updates
-use ire_walk to look for ire cache entries with link layer headers cached
+fix numerous problems with ipfs operation
-deal with bad SPL assumptions for log reading on BSD
+complete new syntax for ipmon.conf in its parser and update the sample file
-fix ftp proxy to allow logins with passwords
+assign error value consistantly in fastroute code
-some auth rule patches, fixing byte endian problems and returning as an error
+rewrite allocation of mbufs in send_reset/send_icmp_err to better use
+mbuf clusters and size calculations
-support LOG_SECURITY, where available, in ipmon
+resolve problem with linux panic'ing because the wrong flag was being
+passed to skb_clone/skb_alloc
-don't return an error for packets which match auth rules
+enable use of shared/exclusive locks on freebsd5 and above
-introduce fr_icmpacktimeout to timeout entries once an ICMP reply has
-been seen separately to when created
+do not rely on m_pkthdr.len to be valid all the time for mbufs on modern BSD
+and so use mbufchainlen to get the mbuf length instead
-3.4.16 15/01/2001 - Released
+replace lots of COPYIN/COPYOUT with BCOPYIN/BCOPYOUT where the data is
+going to be on the stack and not in userland
-fix race condition in flushing of state entries that are timing out
+packet buffer pointers were not refreshed & used properly in fr_check()
-Add TCP ECN patches
+include extra bits for OpenBSD 3.4 & 3.5.
-log all NAT entries created, not just those via rules
+fix ipf/ipnat parsing regression problems with v3.4
-3.4.15 17/12/2000 - Released
+4.1.2 - RELEASED - 27 May 2004
-add minimum ttl filtering (to be replaced later by return-icmp-as-dest
-for all ICMP packets matching state entries).
+add state top for ipv6
-fix NAT'ing of fragments
+fix numerous parsing regressions
-fix sanity checks for ICMPV6
+change sample proxies to use SIOCGNATL with the new API
-fix up compiling on IRIX 6.2 with IDF/IDL installed
+allow macro names to contain underscores (_)
-3.4.14 02/11/2000 - Released
+split the parser into a collection of dictionaries so that keywords do
+not interfere with resolving hostnames and portnames
-cause flushing NAT table to generate log records the same as state flush
-does.
+fix ipfrule LKM loading on freebsd
-fix ftp proxy port/pasv
+support mapping a fixed range of ports to a single port
-fix problem where nat_{in,out}lookup() would release a write lock when it
-didn't need to.
+fix timeout queue use by proxies with private queues
-add check for ipf6.conf in Solaris ipfboot
+handle space-led ftp server replies properly
-3.4.13 28/10/2000 - Released
+fix timeout queue management
-fix introduced bug with ICMP packets being rejected when valid
+fix fastroute, generation of RST & ICMP packets and operation with to/fastroute
-fix bug with proxy's that don't set fin_dlen correctly when calling
-fr_addstate()
+resolve further linux compatibility problems
-3.4.12 26/10/2000 - Released
+replace the use of COPYIN with BCOPYIN for platforms that provide ioctl
+args on the stack
-fix installing into FreeBSD-4.1
+allow flushing of ipv6 rules independant of ipv4 rules
-fix FTP proxy bug where it'd hang and make NAT slightly more efficient
+correct internal ipv6 checksum calculations
-fix general compiling errors/warnings on various platforms
+if a 'keep state' rule fails to create state, block the packet rather
+than let it through
-don't access ICMP data fields that aren't there
+correct all checksums in regression tests and correct NAT code to adjust
+checksums correctly.
-3.4.11 09/10/2000 - Released
+fix ipfs -R/-W
-return NULL for IPv6 access control lists if it is disabled rather than
-random garbage.
+4.1.1 - RELEASED - 24 March 2004
-fix for getting protocol & packet length for IPv6 packets for pullup.
+allow new connections with the same port numbers as an existing one
+in the state table if the creating packet is a SYN
-update plog script from version 0.8 to version 0.10
+timeout values have drifted, incorrectly, from what they were in 3.4
-patch from Frank Volf adding fix_datacksum() to NAT code, enhancing the
-capabilities for "fixing" checksums.
+FreeBSD - compatibility changes for 5.2
-3.4.10 03/09/2000 - Released
+don't match on sequence number (as well) for ICMO ECHO/REPLY, just the
+ICMP Id. field as otherwise thre is a state/NAT entry per packet pair
+rather than per "flow"
-merge patch from Frank Volf for ICMP nat handling of TCP/UDP data `errors'
+fr_cksum() returned the wrong answer for ICMP
-getline() adjusts linenum now
+Linux:
+- get return-rst and return-icmp working
+- treat the interface name the same as if_xname on BSD
-add tcphalfclosed timeout
+adjust expectations for TCP urgent bits based on observed traffic in the
+wild
-fill in icmp_nextmtu field if it is defined on the platform
+openbsd3.4 has ip_len/ip_off in network byte order when ipfilter is called
-RST generation fix from guido
+fix flushing of hash pool gorups (ippool -F) as well as displaying them
+(ippool -l)
-force 32bit compile for gcc on solaris if it can't generate 64bit code
+passing of pointers to interface structures wrong for HP-UX/Solaris with
+return-* rules.
-encase logging when fr_chksrc == 2 in #ifdef IPFILTER_LOG
+Make the solaris boot script able to run on 2.5.1
-fix up line wrap problems in plog script
+ippool related files missing from Solaris packages
-fix ICMP packet handling to not drop valid ICMP errors
+The name /dev/ippool should be /dev/iplookup
-freebsd 5.0 compat changes
+add regression testing for parsing long interface names in nat rules,
+along with mssclamp and tags. Also add test for mssclamp operation.
-3.4.9 08/08/2000 - Released
+ttl displayed for "ipfstat -t" is wrong because ttl is not computed.
-implement new aging mechanism in fr_tcp_age()
+parse logical interface names (Sun)
-fix icmp state checking bug
+unloading LKMs was only working if they were enabled.
-revamp buildsunos script and build both sparcv7/sparcv9 for Solaris
-if on an Ultra with a 64bit system & compiler (Caseper Dik)
+sync'ing up NAT sessions when NICs change should cause NAT rules to
+re-lookup name->pointer mappings
-open ipfilter device read only if we know we can
+not all of the ippool ioctl's are IOWR and they should be because they
+use the ipfobj_t for passing information in/out of the kernel. leave the
+old values defined and handle them, for compatibility.
-print out better information for ICMP packets in ipmon
+pool stats wrong: ippoolstate used where ipoolstat should be, hash table
+ statistics not reported at all
-move checking for source spoofed packets to a point where we can generate
-logs of them
+fr_running not set correctly for OpenBSD when compiled into the kernel
-return EFAULT from ircopyptr/iwcopyptr
+Allow SIOCGETFF while disabled
-don't do ioctl(SIOCGETFS) for auth stats
+Fix mssclamp with NAT (pasing and printing of the word, plus wrong bytes
+altered. How do you say "untested" ?)
-fix up freeing mbufs for post-4.3BSD
+4.1 - RELEASED - 12 February 2004
-fix returning of inc from ftp proxy
+4.0-BETA1 20 August 2003
-fix bugs with ipfs -R/-W (Caseper Dik)
+support 0/32 and 0/0 on the RHS in redirect rules
-3.4.8 19/07/2000 - Released
+where LHS and RHS netmasks are the same size for redirect, do 1:1 mapping
+for bimap rules.
-create fake opt_inet6.h for FreeBSD-4 compile as LKM
+allow NAT rule to match 'all' interfaces with * as interface name
-add #ifdef's for KLD_MODULE sanity
+do mapping of ICMP sequence id#'s in pings
-NAT fastroute'd packets which come out of return-*
+allow default age for NAT entries to be set per NAT rule
-fix upper/lower case crap in ftp proxy and get seq# checking fixed up.
+provide round robin selection of destination addresses for redirect
-3.4.7 08/07/2000 - Released
+ipmon can load a configuration file with instructions on actions
+to take when a matching log entry is received
-make "ipf -y" lookup NAT if's which are unknown
+now requires pfil to work on Solaris & HP-UX
-prepend line numbers to ioctl error messages in ipf/ipnat
+supports mapping outbound connections to a specific address/port
-don't apply patches to FreeBSD twice
+support toggling of logging per ipfilter 'device'
-allow for ip_len to be on an unaligned boundary early on in fr_precheck
+use queues to expire data rather than lists
-fix printing of icmp code when it is 0
+add MSN RPC proxy
-correct printing of port numbers in map rules with from/to
+add IRC proxy
-don't allow fr_func to be called at securelevel > 0 or rules to be added
-if securelevel > 0 if they have a non-zero fr_func.
+support rules with dynamic ip addresses
-3.4.6 11/06/2000 - Released
+add ability to define a pool of addresses & networks which can then
+be placed in a single rule
-add extra regression tests for new nat functionality
+support passing entire packet back to user program for authentication
-place restrictions on using '!' in map/rdr rules
+support master/slave for state information sharing
-fix up solaris compile problems
+reorganise generic code into a lib directory and make libipf.a
-3.4.5 10/06/2000 - Released
+user programs enforce version matching with the kernel
-mention -sl in ipfstat.8
+supports window scaling if seen at TCP session setup
-fix/support '!' in from/to rules (rdr) for NAT
+generates C code from filter rules to compile in or load as native
+machine code.
-add from/to support to rdr NAT rules
+supports loading rules comprised of BPF bytecode statements
-don't send ICMP errors in response to ICMP errors
+HP-UX 11 port completed
-fix sunos5 compilation for "ipfstat-top" and cleanup ipfboot
+and packets-per-second filtering
-input accounting list used for both outbound and inbound packets
+add numerical tags to rules for filtering and display in ipmon output
-3.4.4 23/05/2000 - Released
+3.4.4 23/05/2000 - Released
don't add TCP state if it is an RST packet and (attempt) to send out
RST/ICMP packets in a manner that bypasses IP Filter.
add patch to work with 4.0_STABLE delayed checksums
-3.4.3 20/05/2000 - Released
+3.4.3 20/05/2000 - Released
fix ipmon -F
diff --git a/contrib/ipfilter/INST.FreeBSD-2.2 b/contrib/ipfilter/INST.FreeBSD-2.2
index 78f7295e0894..0e0ea06786f9 100644
--- a/contrib/ipfilter/INST.FreeBSD-2.2
+++ b/contrib/ipfilter/INST.FreeBSD-2.2
@@ -1,3 +1,5 @@
+.\" $NetBSD$
+.\"
To build a kernel for use with the loadable kernel module, follow these
steps:
diff --git a/contrib/ipfilter/INSTALL.FreeBSD b/contrib/ipfilter/INSTALL.FreeBSD
index c732bacfaa29..a4a787ac42be 100644
--- a/contrib/ipfilter/INSTALL.FreeBSD
+++ b/contrib/ipfilter/INSTALL.FreeBSD
@@ -1,7 +1,56 @@
-*** IF you are using FreeBSD 2.2.x, see the file "INST.FreeBSD-2.2" ***
-*** IF you are using FreeBSD 3.x, see the file "FreeBSD-3/INST.FreeBSD-3" ***
-*** IF you are using FreeBSD 4.x, see the file "FreeBSD-4.0/INST.FreeBSD-4" ***
+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/IPFILTER.LICENCE b/contrib/ipfilter/IPFILTER.LICENCE
index 2b4b67e86fd9..41c151ccdedb 100644
--- a/contrib/ipfilter/IPFILTER.LICENCE
+++ b/contrib/ipfilter/IPFILTER.LICENCE
@@ -1,28 +1,29 @@
-Copyright (C) 1993-2002 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 ?
-
+/*
+ * 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/Makefile b/contrib/ipfilter/Makefile
index 44bd1069b036..c54e1db1b866 100644
--- a/contrib/ipfilter/Makefile
+++ b/contrib/ipfilter/Makefile
@@ -1,23 +1,27 @@
#
# Copyright (C) 1993-2001 by Darren Reed.
#
-# See the IPFILTER.LICENCE file for details on licencing.
+# 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.
#
-# $Id: Makefile,v 2.11.2.17 2004/04/16 23:26:09 darrenr Exp $
+# Id: Makefile,v 2.76.2.13 2004/11/08 18:42:40 darrenr Exp
#
+SHELL=/bin/sh
BINDEST=/usr/local/bin
SBINDEST=/sbin
MANDIR=/usr/local/man
#To test prototyping
-CC=gcc -Wstrict-prototypes -Wmissing-prototypes
+#CC=gcc -Wstrict-prototypes -Wmissing-prototypes
+# -Wunused -Wuninitialized
#CC=gcc
#CC=cc -Dconst=
DEBUG=-g
-TOP=../..
-CFLAGS=-I$$(TOP)
+# -O
+CFLAGS=-I$$(TOP) -D_BSD_SOURCE
CPU=`uname -m`
CPUDIR=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m`
-IPFILKERN=`/bin/ls -1tr /usr/src/sys/compile | grep -v .bak | tail -1`
+OBJ=.
#
# To enable this to work as a Loadable Kernel Module...
#
@@ -27,14 +31,53 @@ IPFLKM=-DIPFILTER_LKM
#
IPFLOG=-DIPFILTER_LOG
#
+# To enable loading filter rules compiled to C code...
+#
+#COMPIPF=-DIPFILTER_COMPILED
+#
+# To enable synchronisation between IPFilter hosts
+#
+#SYNC=-DIPFILTER_SYNC
+#
+# To enable extended IPFilter functionality
+#
+LOOKUP=-DIPFILTER_LOOKUP -DIPFILTER_SCAN
+#
# The facility you wish to log messages from ipmon to syslogd with.
#
LOGFAC=-DLOGFAC=LOG_LOCAL0
+#
+# To enable rules to be written with BPF syntax, uncomment these two lines.
+#
+# WARNING: If you're building a commercial product based on IPFilter, using
+# this options *may* infringe at least one patent held by CheckPoint
+# (5,606,668.)
+#
+#IPFBPF=-DIPFILTER_BPF -I/usr/local/include
+#LIBBPF=-L/usr/local/lib -lpcap
+#
+# HP-UX and Solaris require this uncommented for BPF.
+#
+#BPFILTER=bpf_filter.o
+#
+# LINUXKERNEL is the path to the top of your Linux kernel source tree.
+# By default IPFilter looks for /usr/src/linux, but you may have to change
+# it to /usr/src/linux-2.4 or similar.
+#
+LINUXKERNEL=/usr/src/linux
+LINUX=`uname -r | awk -F. ' { printf"%d",$$1;for(i=1;i<NF&&i<3;i++){printf("%02d",$$(i+1));}}'`
+
+#
+# All of the compile-time options are here, used for compiling the userland
+# tools for regression testing. Well, all except for IPFILTER_LKM, of course.
+#
+ALLOPTS=-DIPFILTER_LOG -DIPFILTER_LOOKUP \
+ -DIPFILTER_SCAN -DIPFILTER_SYNC -DIPFILTER_CKSUM
#
# Uncomment the next 3 lines if you want to view the state table a la top(1)
# (requires that you have installed ncurses).
-STATETOP_CFLAGS=-DSTATETOP
+#STATETOP_CFLAGS=-DSTATETOP
#
# Where to find the ncurses include files (if not in default path),
#
@@ -43,7 +86,7 @@ STATETOP_CFLAGS=-DSTATETOP
#
# How to link the ncurses library
#
-STATETOP_LIB=-lcurses
+#STATETOP_LIB=-lncurses
#STATETOP_LIB=-L/usr/local/lib -lncurses
#
@@ -59,14 +102,16 @@ STATETOP_LIB=-lcurses
#
POLICY=-DIPF_DEFAULT_PASS=FR_PASS
#
-MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(INET6) $(IPFLOG)' \
+MFLAGS1='CFLAGS=$(CFLAGS) $(ARCHINC) $(SOLARIS2) $(SGIREV) $(INET6)' \
"IPFLOG=$(IPFLOG)" "LOGFAC=$(LOGFAC)" "POLICY=$(POLICY)" \
"SOLARIS2=$(SOLARIS2)" "DEBUG=$(DEBUG)" "DCPU=$(CPU)" \
- "CPUDIR=$(CPUDIR)" 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' \
+ "LIBBPF=$(LIBBPF)" "CPUDIR=$(CPUDIR)" "IPFBPF=$(IPFBPF)" \
+ 'STATETOP_CFLAGS=$(STATETOP_CFLAGS)' "BPFILTER=$(BPFILTER)" \
'STATETOP_INC=$(STATETOP_INC)' 'STATETOP_LIB=$(STATETOP_LIB)' \
- "BITS=$(BITS)" "OBJ=$(OBJ)"
-DEST="BINDEST=$(BINDEST)" "SBINDEST=$(SBINDEST)" "MANDIR=$(MANDIR)"
+ "BITS=$(BITS)" "OBJ=$(OBJ)" "LOOKUP=$(LOOKUP)" "COMPIPF=$(COMPIPF)" \
+ 'SYNC=$(SYNC)' 'ALLOPTS=$(ALLOPTS)' 'LIBBPF=$(LIBBPF)'
MFLAGS=$(MFLAGS1) "IPFLKM=$(IPFLKM)"
+MACHASSERT=`/bin/ls -1 /usr/sys/*/mach_assert.h | head -1`
#
SHELL=/bin/sh
#
@@ -88,227 +133,248 @@ all:
@echo "freebsd22 - compile for FreeBSD-2.2 or greater"
@echo "freebsd3 - compile for FreeBSD-3.x"
@echo "freebsd4 - compile for FreeBSD-4.x"
+ @echo "freebsd5 - compile for FreeBSD-5.x"
@echo "bsd - compile for generic 4.4BSD systems"
@echo "bsdi - compile for BSD/OS"
@echo "irix - compile for SGI IRIX"
+ @echo "hpux - compile for HP-UX 11.00"
+ @echo "osf - compile for OSF/Tru64 5.1"
@echo ""
tests:
@if [ -d test ]; then (cd test; make) \
else echo test directory not present, sorry; fi
+retest:
+ @if [ -d test ]; then (cd test; make clean && make) \
+ else echo test directory not present, sorry; fi
+
include:
if [ ! -f netinet/done ] ; then \
- (cd netinet; ln -s ../*.h .; ln -s ../ip_*_pxy.c .; ); \
+ (cd netinet; ln -s ../*.h .; ln -s ../ip_*_pxy.c .;); \
(cd netinet; ln -s ../ipsend/tcpip.h tcpip.h); \
touch netinet/done; \
fi
+ -(cd netinet; ln -s ../ip_rules.h ip_rules.h)
+ if [ ! -f net/done ] ; then \
+ (cd net; ln -s ../radix_ipf.h .; ); \
+ touch net/done; \
+ fi
sunos solaris: include
- CC="$(CC)" ./buildsunos
+ MAKE="$(MAKE)" MAKEFLAGS="$(MAKEFLAGS)" BPFILTER=$(BPFILTER) \
+ CC="$(CC)" DEBUG="$(DEBUG)" ./buildsunos
freebsd22: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
-rm -f BSD/$(CPUDIR)/ioconf.h
- @if [ -n $(IPFILKERN) ] ; then \
+ -if [ x$(IPFILKERN) != x ] ; then \
if [ -f /sys/compile/$(IPFILKERN)/ioconf.h ] ; then \
- ln -s /sys/compile/$(IPFILKERN)/ioconf.h BSD/$(CPUDIR); \
+ ln -s /sys/compile/$(IPFILKERN)/ioconf.h BSD/$$y; \
else \
- ln -s /sys/$(IPFILKERN)/ioconf.h BSD/$(CPUDIR); \
+ ln -s /sys/$(IPFILKERN)/ioconf.h BSD/$$y; \
fi \
- elif [ ! -f `uname -v|sed -e 's@^.*:\(/[^: ]*\).*@\1@'`/ioconf.h ] ; then \
- echo -n "Can't find ioconf.h in "; \
- echo `uname -v|sed -e 's@^.*:\(/[^: ]*\).*@\1@'`; \
- exit 1;\
else \
- ln -s `uname -v|sed -e 's@^.*:\(/[^: ]*\).*@\1@'`/ioconf.h BSD/$(CPU) ; \
+ x=`uname -v|sed -e 's@^.*:\(/[^: ]*\).*$$@\1/ioconf.h@'`; \
+ y=`uname -s|sed -e 's@/@@g'`-`uname -r`-`uname -m`; \
+ if [ ! -f $$x ] ; then \
+ echo -n "Can't find ioconf.h at $$x "; \
+ exit 1;\
+ else \
+ ln -s $$x BSD/$$y ; \
+ fi \
fi
make freebsd20
-freebsd4: include
- if [ x$INET6 = x ] ; then \
+freebsd5: include
+ if [ x$(INET6) = x ] ; then \
+ echo "#undef INET6" > opt_inet6.h; \
+ else \
+ echo "#define INET6" > opt_inet6.h; \
+ fi
+ if [ x$(ENABLE_PFIL) = x ] ; then \
+ echo "#undef PFIL_HOOKS" > opt_pfil.h; \
+ else \
+ echo "#define PFIL_HOOKS" > opt_pfil.h; \
+ fi
+
+ make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko.5" "LKMR=ipfrule.ko.5" "DLKM=-DKLD_MODULE" "MLR=mlfk_rule.o"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS1); cd ..)
+
+freebsd4 : include
+ if [ x$(INET6) = x ] ; then \
echo "#undef INET6" > opt_inet6.h; \
else \
echo "#define INET6" > opt_inet6.h; \
fi
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko" "DLKM=-DKLD_MODULE -I/sys"; cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS1); cd ..)
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlfk_ipl.c" "MLD=mlfk_ipl.c" "LKM=ipf.ko" "LKMR=ipfrule.ko" "DLKM=-DKLD_MODULE" "MLR=mlfk_rule.o"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS1); cd ..)
freebsd3 freebsd30: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS1) "ML=mlf_ipl.c" LKM= ; cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS1); cd ..)
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS1) "ML=mlf_ipl.c" "MLR=mlf_rule.o" LKM= LKMR=; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS1); cd ..)
netbsd: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c"; cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c" LKMR= "MLR=mln_rule.o"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS); cd ..)
-openbsd openbsd21: include
+openbsd: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c"; cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mlo_ipl.c" LKMR= "MLR=mlo_rule.o"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS); cd ..)
freebsd20 freebsd21: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlf_ipl.c"; cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) "ML=mlf_ipl.c" "MLR=mlf_rule.o"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS); cd ..)
+
+osf tru64: null include
+ make setup "TARGOS=OSF" "CPUDIR=`OSF/cpurev`"
+ (cd OSF/`OSF/cpurev`; make build TRU64=`uname -v` TOP=../.. "DEBUG=-g" $(MFLAGS) "MACHASSERT=$(MACHASSERT)" "OSREV=`../cpurev`"; cd ..)
+ (cd OSF/`OSF/cpurev`; make -f Makefile.ipsend build TRU64=`uname -v` TOP=../.. $(MFLAGS) "OSREV=`../cpurev`"; cd ..)
bsd: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS); cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make build TOP=../.. $(MFLAGS) 'DLKM=-D_LKM' "ML=mln_ipl.c" "MLR=mln_rule.o"; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. $(MFLAGS); cd ..)
bsdi bsdos: include
make setup "TARGOS=BSD" "CPUDIR=$(CPUDIR)"
- (cd BSD/$(CPUDIR); make build "CC=$(CC)" TOP=../.. $(MFLAGS) LKM= ; cd ..)
- (cd BSD/$(CPUDIR); make -f Makefile.ipsend "CC=$(CC)" TOP=../.. $(MFLAGS); cd ..)
+ (cd BSD/$(CPUDIR); make build "CC=$(CC)" TOP=../.. $(MFLAGS) LKM= LKMR= ; cd ..)
+ (cd BSD/$(CPUDIR); make -f Makefile.ipsend build "CC=$(CC)" TOP=../.. $(MFLAGS); cd ..)
irix IRIX: include
- make setup "TARGOS=IRIX" "CPUDIR=$(CPUDIR)"
- -(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.std build TOP=../.. $(DEST) SGI=`../getrev` $(MFLAGS); else smake build SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); fi;)
- -(cd IRIX/$(CPUDIR); if [ $(MAKE) = make ] ; then make -f Makefile.ipsend.std SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); else smake -f Makefile.ipsend SGI=`../getrev` TOP=../.. $(DEST) $(MFLAGS); fi)
-
-linux: include
- make setup "TARGOS=Linux" "CPUDIR=$(CPUDIR)"
- ./buildlinux
-
-linuxrev:
- (cd Linux/$(CPUDIR); make build TOP=../.. $(DEST) $(MFLAGS) LKM= ; cd ..)
- (cd Linux/$(CPUDIR); make -f Makefile.ipsend TOP=../.. $(DEST) $(MFLAGS); cd ..)
+ make setup TARGOS=IRIX CPUDIR=`IRIX/cpurev`
+ if [ "x${SGIREV}" = "x" ] ; then \
+ make irix "SGIREV=-D_KMEMUSER -DIRIX=`IRIX/getrev`"; \
+ else \
+ (cd IRIX/`IRIX/cpurev`; smake -l -J 1 build TOP=../.. $(DEST) $(MFLAGS) IRIX=`../getrev` SGI=$$(IRIX) CPUDIR=`../cpurev`; cd ..); \
+ (cd IRIX/`IRIX/cpurev`; make -f Makefile.ipsend build TOP=../.. $(DEST) $(MFLAGS) IRIX=`../getrev` SGI=$$(IRIX) CPUDIR=`../cpurev`; cd ..); \
+ fi
setup:
-if [ ! -d $(TARGOS)/$(CPUDIR) ] ; then mkdir $(TARGOS)/$(CPUDIR); fi
-rm -f $(TARGOS)/$(CPUDIR)/Makefile $(TARGOS)/$(CPUDIR)/Makefile.ipsend
-ln -s ../Makefile $(TARGOS)/$(CPUDIR)/Makefile
- -if [ ! -f $(TARGOS)/$(CPUDIR)/Makefile.std -a \
- -f $(TARGOS)/Makefile.std ] ; then \
- ln -s ../Makefile.std $(TARGOS)/$(CPUDIR)/Makefile.std; \
- fi
- -if [ ! -f $(TARGOS)/$(CPUDIR)/Makefile.ipsend.std -a \
- -f $(TARGOS)/Makefile.ipsend.std ] ; then \
- ln -s ../Makefile.ipsend.std $(TARGOS)/$(CPUDIR)/Makefile.ipsend.std; \
- fi
-ln -s ../Makefile.ipsend $(TARGOS)/$(CPUDIR)/Makefile.ipsend
+ -if [ -f $(TARGOS)/Makefile.common ] ; then \
+ rm -f $(TARGOS)/$(CPUDIR)/Makefile.common; \
+ ln -s ../Makefile.common $(TARGOS)/$(CPUDIR)/Makefile.common;\
+ fi
clean: clean-include
+ /bin/rm -rf h y.output
${RM} -f core *.o ipt fils ipf ipfstat ipftest ipmon if_ipl \
vnode_if.h $(LKM) *~
- ${RM} -rf sparcv7 sparcv9
- (cd SunOS4; make clean)
- (cd SunOS5; make clean)
- (cd BSD; make clean)
- (cd Linux; make clean)
- if [ "`uname -s`" = "IRIX" ]; then (cd IRIX; make clean); fi
- [ -d test ] && (cd test; make clean)
- (cd ipsend; make clean)
+ /bin/rm -rf sparcv7 sparcv9 mdbgen_build
+ (cd SunOS4; $(MAKE) TOP=.. clean)
+ -(cd SunOS5; $(MAKE) TOP=.. clean)
+ (cd BSD; $(MAKE) TOP=.. clean)
+ (cd HPUX; $(MAKE) BITS=32 TOP=.. clean)
+ (cd Linux; $(MAKE) TOP=.. clean)
+ (cd OSF; $(MAKE) TOP=.. clean)
+ if [ "`uname -s`" = "IRIX" ]; then (cd IRIX; $(MAKE) clean); fi
+ [ -d test ] && (cd test; $(MAKE) clean)
+ (cd ipsend; $(MAKE) clean)
clean-include:
- sh -c 'cd netinet; for i in *; do if [ -h $$i ] ; then /bin/rm -f $$i; fi; done'
- ${RM} -f netinet/done
+ sh -c 'if [ -d netinet ] ; then cd netinet; for i in *; do if [ -h $$i ] ; then /bin/rm -f $$i; fi; done fi'
+ sh -c 'if [ -d net ] ; then cd net; for i in *; do if [ -h $$i ] ; then /bin/rm -f $$i; fi; done fi'
+ ${RM} -f netinet/done net/done
clean-bsd: clean-include
- (cd BSD; make clean)
+ (cd BSD; make TOP=.. clean)
+
+clean-hpux: clean-include
+ (cd HPUX; $(MAKE) BITS=32 clean)
+
+clean-osf: clean-include
+ (cd OSF; make clean)
+
+clean-linux: clean-include
+ (cd Linux; make clean)
clean-sunos4: clean-include
(cd SunOS4; make clean)
clean-sunos5: clean-include
- (cd SunOS5; make clean)
+ (cd SunOS5; $(MAKE) clean)
+ /bin/rm -rf sparcv?
clean-irix: clean-include
- (cd IRIX; make clean)
+ (cd IRIX; $(MAKE) clean)
-clean-linux: clean-include
- (cd Linux; make clean)
+h/xti.h:
+ mkdir -p h
+ ln -s /usr/include/sys/xti.h h
-get:
- -@for i in ipf.c ipt.h solaris.c ipf.h kmem.c ipft_ef.c linux.h \
- ipft_pc.c fil.c ipft_sn.c mln_ipl.c fils.c ipft_td.c \
- mls_ipl.c ip_compat.h ipl.h opt.c ip_fil.c ipl_ldev.c \
- parse.c ip_fil.h ipmon.c pcap.h ip_sfil.c ipt.c snoop.h \
- ip_state.c ip_state.h ip_nat.c ip_nat.h ip_frag.c \
- ip_frag.h ip_sfil.c misc.c; do \
- if [ ! -f $$i ] ; then \
- echo "getting $$i"; \
- sccs get $$i; \
- fi \
- done
+hpux: include h/xti.h
+ make setup CPUDIR=`HPUX/cpurev` TARGOS=HPUX
+ (cd HPUX/`HPUX/cpurev`; $(MAKE) build TOP=../.. $(DEST) $(MFLAGS) "BITS=`getconf KERNEL_BITS`" `../makeargs`; cd ..)
+ (cd HPUX/`HPUX/cpurev`; $(MAKE) -f Makefile.ipsend build TOP=../.. $(DEST) $(MFLAGS) "BITS=`getconf KERNEL_BITS`" `../makeargs`; cd ..)
-sunos4 solaris1: null
+sunos4 solaris1:
(cd SunOS4; make build TOP=.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
- (cd SunOS4; make -f Makefile.ipsend "CC=$(CC)" TOP=.. $(DEST) $(MFLAGS); cd ..)
+ (cd SunOS4; make -f Makefile.ipsend build "CC=$(CC)" TOP=.. $(DEST) $(MFLAGS); cd ..)
sunos5 solaris2: null
- (cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
- (cd SunOS5/$(CPUDIR); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
+ (cd SunOS5/$(CPUDIR); $(MAKE) build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Dsparc -D__sparc__"; cd ..)
+ (cd SunOS5/$(CPUDIR); $(MAKE) -f Makefile.ipsend build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
sunos5x86 solaris2x86: null
(cd SunOS5/$(CPUDIR); make build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS) "SOLARIS2=$(SOLARIS2)" "CPU=-Di86pc -Di386 -D__i386__"; cd ..)
- (cd SunOS5/$(CPUDIR); make -f Makefile.ipsend TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
+ (cd SunOS5/$(CPUDIR); make -f Makefile.ipsend build TOP=../.. "CC=$(CC)" $(DEST) $(MFLAGS); cd ..)
+
+linux: include
+ (cd Linux; make build LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) LINUXKERNEL=$(LINUXKERNEL); cd ..)
+ (cd Linux; make ipflkm LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) LINUXKERNEL=$(LINUXKERNEL) WORKDIR=`pwd`; cd ..)
+# (cd Linux; make -f Makefile.ipsend build LINUX=$(LINUX) TOP=.. "CC=$(CC)" $(MFLAGS); cd ..)
-install-linux:
- (cd Linux/$(CPUDIR); make install "TOP=../.." $(DEST) $(MFLAGS); cd ..)
- (cd Linux/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(DEST) $(MFLAGS); cd ..)
+install-linux: linux
+ (cd Linux/; make LINUX=$(LINUX) TOP=.. "DEBUG=-g" "CC=$(CC)" $(MFLAGS) OBJ=$(CPUDIR) install ; cd ..)
install-bsd:
(cd BSD/$(CPUDIR); make install "TOP=../.." $(MFLAGS); cd ..)
(cd BSD/$(CPUDIR); make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
install-sunos4: solaris
- (cd SunOS4; $(MAKE) "CPU=$(CPU)" "TOP=.." install)
+ (cd SunOS4; $(MAKE) CPU=$(CPU) TOP=.. install)
-install-sunos5: solaris
- (cd SunOS5; $(MAKE) "CPUDIR=`uname -p`-`uname -r`" "CPU=$(CPU) TOP=.." install)
+install-sunos5: solaris null
+ (cd SunOS5; $(MAKE) CPU=$(CPU) TOP=.. install)
+
+install-hpux: hpux
+ (cd HPUX/`HPUX/cpurev`; $(MAKE) CPU=$(CPU) TOP=../.. "BITS=`getconf KERNEL_BITS`" install)
install-irix: irix
- (cd IRIX; smake install "CPU=$(CPU) TOP=.." $(DEST) $(MFLAGS))
-
-rcsget:
- -@for i in ipf.c ipt.h solaris.c ipf.h kmem.c ipft_ef.c linux.h \
- ipft_pc.c fil.c ipft_sn.c mln_ipl.c fils.c ipft_td.c \
- mls_ipl.c ip_compat.h ipl.h opt.c ip_fil.c ipl_ldev.c \
- parse.c ip_fil.h ipmon.c pcap.h ip_sfil.c ipt.c snoop.h \
- ip_state.c ip_state.h ip_nat.c ip_nat.h ip_frag.c \
- ip_frag.h ip_sfil.c misc.c; do \
- if [ ! -f $$i ] ; then \
- echo "getting $$i"; \
- co $$i; \
- fi \
- done
+ (cd IRIX; smake install CPU=$(CPU) TOP=.. $(DEST) $(MFLAGS) CPUDIR=`./cpurev`)
+
+install-osf install-tru64:
+ (cd OSF/`OSF/cpurev`; make install "TOP=../.." $(MFLAGS); cd ..)
+ (cd OSF/`OSF/cpurev`; make -f Makefile.ipsend INSTALL=$(INSTALL) install "TOP=../.." $(MFLAGS); cd ..)
do-cvs:
find . -type d -name CVS -print | xargs /bin/rm -rf
find . -type f -name .cvsignore -print | xargs /bin/rm -f
+ /bin/rm -f ip_msnrpc_pxy.c ip_sunrpc_pxy.c
+
+ip_rules.c ip_rules.h: rules/ip_rules tools/ipfcomp.c
+ -./ipf -n -cc -f rules/ip_rules 2>/dev/null 1>&2
null:
- -@if [ "`$(MAKE) -v 2>&1 | sed -ne 's/GNU.*/GNU/p'`" = "GNU" ] ; then \
+ @if [ "`$(MAKE) -v 2>&1 | sed -ne 's/GNU.*/GNU/p'`" = "GNU" ] ; then \
echo 'Do not use GNU make (gmake) to compile IPFilter'; \
exit 1; \
fi
-@echo make ok
-test-solaris test-sunos4 test-sunos5: solaris
- (cd test && make clean && make)
-
-test-freebsd: freebsd
- (cd test && make clean && make)
-
-test-freebsd22: freebsd22
- (cd test && make clean && make)
-
-test-freebsd3: freebsd3
- (cd test && make clean && make)
-
-test-freebsd4: freebsd4
- (cd test && make clean && make)
-
-test-netbsd: netbsd
- (cd test && make clean && make)
-
-test-openbsd: openbsd
- (cd test && make clean && make)
-
-test-irix: irix
- (cd test && make clean && make)
+mdb:
+ /bin/rm -rf mdbgen_build
+ mdbgen -D_KERNEL -DIPFILTER_LOG -DIPFILTER_LOOKUP -DSUNDDI \
+ -DIPFILTER_SCAN -DIPFILTER_LKM -DSOLARIS2=10 -n ipf_mdb -k \
+ -I/home/dr146992/pfil -I/home/dr146992/ipf -f \
+ /usr/include/netinet/in_systm.h,/usr/include/sys/ethernet.h,/usr/include/netinet/in.h,/usr/include/netinet/ip.h,/usr/include/netinet/ip_var.h,/usr/include/netinet/tcp.h,/usr/include/netinet/tcpip.h,/usr/include/netinet/ip_icmp.h,/usr/include/netinet/udp.h,ip_compat.h,ip_fil.h,ip_nat.h,ip_state.h,ip_proxy.h,ip_scan.h
diff --git a/contrib/ipfilter/README b/contrib/ipfilter/README
index 80ce748c5652..8464af4c64d2 100644
--- a/contrib/ipfilter/README
+++ b/contrib/ipfilter/README
@@ -1,5 +1,7 @@
IP Filter - What's this about ?
============================
+Web site: http://coombs.anu.edu.au/~avalon/ip-filter.html
+How-to: http://www.obfuscation.org/ipf/ipf-howto.txt
The idea behind this package is allow those who use Unix workstations as
routers (a common occurance in Universities it appears) to apply packet
@@ -96,3 +98,4 @@ BNF
Darren Reed
darrenr@pobox.com
+http://coombs.anu.edu.au/~avalon/ip-filter.html
diff --git a/contrib/ipfilter/STYLE.TXT b/contrib/ipfilter/STYLE.TXT
new file mode 100644
index 000000000000..384bcec3d909
--- /dev/null
+++ b/contrib/ipfilter/STYLE.TXT
@@ -0,0 +1,57 @@
+
+Over time, I am moving all of the IPFilter code to what I consider a better
+coding style than it had before. If you submit patches, I expect them to
+conform as appropriate.
+
+Function Comments
+=================
+Preceeding each and every function, a comment block like this should
+be present:
+
+/* ------------------------------------------------------------------------ */
+/* Function: function-name */
+/* Returns: return-type */
+/* Parameters: param1(I) - param1 is an input parameter */
+/* p2(O) - p2 is an output parameter passed as an arg */
+/* par3(IO) - par3 is a parameter which is both input and */
+/* output. Pointers to things which are used and */
+/* then get a result stored in them qualify here. */
+/* */
+/* Description about what the function does. This comment should explain */
+/* any gotchas or algorithms that are used which aren't obvious to the */
+/* casual reader. It should not be an excuse to not use comments inside */
+/* the function. */
+/* ------------------------------------------------------------------------ */
+
+
+Tab spacing
+===========
+Tabs are to be at 8 characters.
+
+
+Conditions
+==========
+All expressions which evaluate to a boolean for a test condition, such as
+in an if()/while() statement must involve a boolean operation. Since C
+has no native boolean type, this means that one of <,>,<=,>=,==,!= must
+be present. Implied boolean evaluations are out.
+
+In code, the following is banned:
+
+if (x)
+if (!x)
+while ((a = b))
+
+and should be replaced by:
+
+if (x != 0)
+if (x == 0)
+while ((a = b) != 0)
+
+If pointers are involved, always compare with NULL, ie.:
+
+if (x != NULL)
+if (x == NULL)
+while ((a = b) != NULL)
+
+
diff --git a/contrib/ipfilter/WhatsNew40.txt b/contrib/ipfilter/WhatsNew40.txt
new file mode 100644
index 000000000000..e5b8294d7be9
--- /dev/null
+++ b/contrib/ipfilter/WhatsNew40.txt
@@ -0,0 +1,90 @@
+What's new in IPFilter 4.1
+==========================
+(Well, compared to 3.*, anyway)
+In no particular order, except headline alphabetical:
+
+Administration:
+ - Run-time support for modifying ipf table size parameters.
+ - Run-time support for tuning other ipfilter parameters.
+
+Content Scanning:
+ - Simple matching of content for TCP session startup.
+
+Firewall Synchronising:
+ - Master/slave programs available.
+
+General:
+ - All input files allow simple 'marco' definitions and expansion,
+ including nesting.
+ - Code has been rototilled to make maintenance and enhancements
+ eaiser for me and you.
+ - More configuration files and binaries.
+ - Takes up more memory.
+ - Probably slower.
+ - Versioned API to support changes in the ABI without breaking
+ existing binaries (4.0 onward only.)
+ - IP-Filter framework in place for handling multiple different
+ types of packet matching for firewalling.
+ - IP Id number rewriting available.
+ - Verification of checksums for recognised packet types.
+ - Optionally enable/disable IP forwarding when enabled/disabled.
+
+IPF:
+ - BPF syntax available for matching packets in ipf rules (1).
+ - Can convert IPv4 ipf rules into C code and either:
+ * load them as an LKM o;
+ * compile them statically into the kernel (where possible.)
+ - Address pools allow for simpler rules covering large numbers of
+ addresses/networks (IPv4 only).
+ - Lookup functions available to map an IPv4 address to a group.
+ - Groups can be referenced by multiple heads for subroutine-like use.
+ - NAT/ipf rules can refer to each other via a tag, creating an implied
+ join that forms part of the packet matching.
+ - Extra packet attributes available for filter rules:
+ * source address/routing interface mismatch;
+ * multicast (3);
+ * broadcast (2,3);
+ * state lookup partially failed;
+ * out of the TCP window for a state connection;
+ * NAT lookup partially failed.
+ - PPS (packets per second) matching available for ipf rules.
+ - Rule collections (cf FreeBSD numbering) supported for ipf rules.
+ - Groups can now be names rather than just numbers
+
+IPV6:
+ - understands extension headers.
+ - can filter on extension headers.
+
+Logging:
+ - ipmon now comes with a configuration file for more advanced logging
+ behaviour.
+ - Can append arbitrary logging tags with ipf rules for easy matching.
+
+NAT:
+ - "sticky" mapping available to ensure an address translation on
+ a per-address basis is always the same (while known) for a set
+ IP address.
+
+Operating System Support:
+ - HP-UX 11 added.
+ - Tru64 5.1a added.
+ - Solaris/HP-UX now use pfil STREAMS module.
+ - Linux 2.4 on the way.
+
+Proxies:
+ - PPTP proxy added.
+ - IRC proxy added.
+ - RPCBIND proxy added.
+ - FTP proxy support for EPSV (IPv4 only.)
+
+Stateful Inspection:
+ - Can insist that all TCP data arrives in order.
+ - Can insist that all fragments pass through in order.
+ - The number of states created per-rule can be set where the total
+ across all rules may exceed the maximum allowed.
+ - Can elect not to automatically match ICMP error packets.
+ - TCP sequence number rewriting supported.
+
+(1) - Requires libpcap for rule parsing
+(2) - On Solaris/HP-UX, broadcast packets are seen as multicast packets.
+(3) - Not supported on SunOS4
diff --git a/contrib/ipfilter/bpf-ipf.h b/contrib/ipfilter/bpf-ipf.h
new file mode 100644
index 000000000000..c30315242a42
--- /dev/null
+++ b/contrib/ipfilter/bpf-ipf.h
@@ -0,0 +1,452 @@
+/* $NetBSD$ */
+
+/*-
+ * 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/bpf-ipf.h,v 2.1 2002/10/26 12:14:26 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 <net/bpf.h> 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 <donlee@cray.com>.
+ *
+ * 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 <net/if.h>) 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/bpf_filter.c b/contrib/ipfilter/bpf_filter.c
new file mode 100644
index 000000000000..9876ff3e2637
--- /dev/null
+++ b/contrib/ipfilter/bpf_filter.c
@@ -0,0 +1,517 @@
+/* $NetBSD$ */
+
+/*-
+ * 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.c 7.5 (Berkeley) 7/15/91
+ */
+
+#if !(defined(lint) || defined(KERNEL) || defined(_KERNEL))
+static const char rcsid[] =
+ "@(#) $Header: /devel/CVS/IP-Filter/bpf_filter.c,v 2.2 2003/08/19 16:49:58 darrenr Exp $ (LBL)";
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <net/if.h>
+
+#include "ip_compat.h"
+#include "bpf-ipf.h"
+
+
+#if (defined(__hpux) || SOLARIS) && (defined(_KERNEL) || defined(KERNEL))
+# include <sys/sysmacros.h>
+# include <sys/stream.h>
+#endif
+
+#include "pcap-ipf.h"
+
+#if !defined(KERNEL) && !defined(_KERNEL)
+#include <stdlib.h>
+#endif
+
+#define int32 bpf_int32
+#define u_int32 bpf_u_int32
+
+static int m_xword __P((mb_t *, int, int *));
+static int m_xhalf __P((mb_t *, int, int *));
+
+#ifndef LBL_ALIGN
+/*
+ * XXX - IA-64? If not, this probably won't work on Win64 IA-64
+ * systems, unless LBL_ALIGN is defined elsewhere for them.
+ * XXX - SuperH? If not, this probably won't work on WinCE SuperH
+ * systems, unless LBL_ALIGN is defined elsewhere for them.
+ */
+#if defined(sparc) || defined(__sparc__) || defined(mips) || \
+ defined(ibm032) || defined(__alpha) || defined(__hpux) || \
+ defined(__arm__)
+#define LBL_ALIGN
+#endif
+#endif
+
+#ifndef LBL_ALIGN
+
+#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
+#define EXTRACT_LONG(p) (ntohl(*(u_int32 *)p))
+#else
+#define EXTRACT_SHORT(p)\
+ ((u_short)\
+ ((u_short)*((u_char *)p+0)<<8|\
+ (u_short)*((u_char *)p+1)<<0))
+#define EXTRACT_LONG(p)\
+ ((u_int32)*((u_char *)p+0)<<24|\
+ (u_int32)*((u_char *)p+1)<<16|\
+ (u_int32)*((u_char *)p+2)<<8|\
+ (u_int32)*((u_char *)p+3)<<0)
+#endif
+
+#define MINDEX(len, _m, _k) \
+{ \
+ len = M_LEN(m); \
+ while ((_k) >= len) { \
+ (_k) -= len; \
+ (_m) = (_m)->m_next; \
+ if ((_m) == 0) \
+ return 0; \
+ len = M_LEN(m); \
+ } \
+}
+
+static int
+m_xword(m, k, err)
+ register mb_t *m;
+ register int k, *err;
+{
+ register int len;
+ register u_char *cp, *np;
+ register mb_t *m0;
+
+ MINDEX(len, m, k);
+ cp = MTOD(m, u_char *) + k;
+ if (len - k >= 4) {
+ *err = 0;
+ return EXTRACT_LONG(cp);
+ }
+ m0 = m->m_next;
+ if (m0 == 0 || M_LEN(m0) + len - k < 4)
+ goto bad;
+ *err = 0;
+ np = MTOD(m0, u_char *);
+ switch (len - k) {
+
+ case 1:
+ return (cp[0] << 24) | (np[0] << 16) | (np[1] << 8) | np[2];
+
+ case 2:
+ return (cp[0] << 24) | (cp[1] << 16) | (np[0] << 8) | np[1];
+
+ default:
+ return (cp[0] << 24) | (cp[1] << 16) | (cp[2] << 8) | np[0];
+ }
+ bad:
+ *err = 1;
+ return 0;
+}
+
+static int
+m_xhalf(m, k, err)
+ register mb_t *m;
+ register int k, *err;
+{
+ register int len;
+ register u_char *cp;
+ register mb_t *m0;
+
+ MINDEX(len, m, k);
+ cp = MTOD(m, u_char *) + k;
+ if (len - k >= 2) {
+ *err = 0;
+ return EXTRACT_SHORT(cp);
+ }
+ m0 = m->m_next;
+ if (m0 == 0)
+ goto bad;
+ *err = 0;
+ return (cp[0] << 8) | MTOD(m0, u_char *)[0];
+ bad:
+ *err = 1;
+ return 0;
+}
+
+/*
+ * Execute the filter program starting at pc on the packet p
+ * wirelen is the length of the original packet
+ * buflen is the amount of data present
+ * For the kernel, p is assumed to be a pointer to an mbuf if buflen is 0,
+ * in all other cases, p is a pointer to a buffer and buflen is its size.
+ */
+u_int
+bpf_filter(pc, p, wirelen, buflen)
+ register struct bpf_insn *pc;
+ register u_char *p;
+ u_int wirelen;
+ register u_int buflen;
+{
+ register u_int32 A, X;
+ register int k;
+ int32 mem[BPF_MEMWORDS];
+ mb_t *m, *n;
+ int merr, len;
+
+ if (buflen == 0) {
+ m = (mb_t *)p;
+ p = MTOD(m, u_char *);
+ buflen = M_LEN(m);
+ } else
+ m = NULL;
+
+ if (pc == 0)
+ /*
+ * No filter means accept all.
+ */
+ return (u_int)-1;
+ A = 0;
+ X = 0;
+ --pc;
+ while (1) {
+ ++pc;
+ switch (pc->code) {
+
+ default:
+ return 0;
+ case BPF_RET|BPF_K:
+ return (u_int)pc->k;
+
+ case BPF_RET|BPF_A:
+ return (u_int)A;
+
+ case BPF_LD|BPF_W|BPF_ABS:
+ k = pc->k;
+ if (k + sizeof(int32) > buflen) {
+ if (m == NULL)
+ return 0;
+ A = m_xword(m, k, &merr);
+ if (merr != 0)
+ return 0;
+ continue;
+ }
+ A = EXTRACT_LONG(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_H|BPF_ABS:
+ k = pc->k;
+ if (k + sizeof(short) > buflen) {
+ if (m == NULL)
+ return 0;
+ A = m_xhalf(m, k, &merr);
+ if (merr != 0)
+ return 0;
+ continue;
+ }
+ A = EXTRACT_SHORT(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_B|BPF_ABS:
+ k = pc->k;
+ if (k >= buflen) {
+ if (m == NULL)
+ return 0;
+ n = m;
+ MINDEX(len, n, k);
+ A = MTOD(n, u_char *)[k];
+ continue;
+ }
+ A = p[k];
+ continue;
+
+ case BPF_LD|BPF_W|BPF_LEN:
+ A = wirelen;
+ continue;
+
+ case BPF_LDX|BPF_W|BPF_LEN:
+ X = wirelen;
+ continue;
+
+ case BPF_LD|BPF_W|BPF_IND:
+ k = X + pc->k;
+ if (k + sizeof(int32) > buflen) {
+ if (m == NULL)
+ return 0;
+ A = m_xword(m, k, &merr);
+ if (merr != 0)
+ return 0;
+ continue;
+ }
+ A = EXTRACT_LONG(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_H|BPF_IND:
+ k = X + pc->k;
+ if (k + sizeof(short) > buflen) {
+ if (m == NULL)
+ return 0;
+ A = m_xhalf(m, k, &merr);
+ if (merr != 0)
+ return 0;
+ continue;
+ }
+ A = EXTRACT_SHORT(&p[k]);
+ continue;
+
+ case BPF_LD|BPF_B|BPF_IND:
+ k = X + pc->k;
+ if (k >= buflen) {
+ if (m == NULL)
+ return 0;
+ n = m;
+ MINDEX(len, n, k);
+ A = MTOD(n, u_char *)[k];
+ continue;
+ }
+ A = p[k];
+ continue;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+ k = pc->k;
+ if (k >= buflen) {
+ if (m == NULL)
+ return 0;
+ n = m;
+ MINDEX(len, n, k);
+ X = (MTOD(n, char *)[k] & 0xf) << 2;
+ continue;
+ }
+ X = (p[pc->k] & 0xf) << 2;
+ continue;
+
+ case BPF_LD|BPF_IMM:
+ A = pc->k;
+ continue;
+
+ case BPF_LDX|BPF_IMM:
+ X = pc->k;
+ continue;
+
+ case BPF_LD|BPF_MEM:
+ A = mem[pc->k];
+ continue;
+
+ case BPF_LDX|BPF_MEM:
+ X = mem[pc->k];
+ continue;
+
+ case BPF_ST:
+ mem[pc->k] = A;
+ continue;
+
+ case BPF_STX:
+ mem[pc->k] = X;
+ continue;
+
+ case BPF_JMP|BPF_JA:
+ pc += pc->k;
+ continue;
+
+ case BPF_JMP|BPF_JGT|BPF_K:
+ pc += (A > pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JGE|BPF_K:
+ pc += (A >= pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JEQ|BPF_K:
+ pc += (A == pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JSET|BPF_K:
+ pc += (A & pc->k) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JGT|BPF_X:
+ pc += (A > X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JGE|BPF_X:
+ pc += (A >= X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JEQ|BPF_X:
+ pc += (A == X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_JMP|BPF_JSET|BPF_X:
+ pc += (A & X) ? pc->jt : pc->jf;
+ continue;
+
+ case BPF_ALU|BPF_ADD|BPF_X:
+ A += X;
+ continue;
+
+ case BPF_ALU|BPF_SUB|BPF_X:
+ A -= X;
+ continue;
+
+ case BPF_ALU|BPF_MUL|BPF_X:
+ A *= X;
+ continue;
+
+ case BPF_ALU|BPF_DIV|BPF_X:
+ if (X == 0)
+ return 0;
+ A /= X;
+ continue;
+
+ case BPF_ALU|BPF_AND|BPF_X:
+ A &= X;
+ continue;
+
+ case BPF_ALU|BPF_OR|BPF_X:
+ A |= X;
+ continue;
+
+ case BPF_ALU|BPF_LSH|BPF_X:
+ A <<= X;
+ continue;
+
+ case BPF_ALU|BPF_RSH|BPF_X:
+ A >>= X;
+ continue;
+
+ case BPF_ALU|BPF_ADD|BPF_K:
+ A += pc->k;
+ continue;
+
+ case BPF_ALU|BPF_SUB|BPF_K:
+ A -= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_MUL|BPF_K:
+ A *= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_DIV|BPF_K:
+ A /= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_AND|BPF_K:
+ A &= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_OR|BPF_K:
+ A |= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_LSH|BPF_K:
+ A <<= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_RSH|BPF_K:
+ A >>= pc->k;
+ continue;
+
+ case BPF_ALU|BPF_NEG:
+ A = -A;
+ continue;
+
+ case BPF_MISC|BPF_TAX:
+ X = A;
+ continue;
+
+ case BPF_MISC|BPF_TXA:
+ A = X;
+ continue;
+ }
+ }
+}
+
+
+/*
+ * Return true if the 'fcode' is a valid filter program.
+ * The constraints are that each jump be forward and to a valid
+ * code. The code must terminate with either an accept or reject.
+ * 'valid' is an array for use by the routine (it must be at least
+ * 'len' bytes long).
+ *
+ * The kernel needs to be able to verify an application's filter code.
+ * Otherwise, a bogus program could easily crash the system.
+ */
+int
+bpf_validate(f, len)
+ struct bpf_insn *f;
+ int len;
+{
+ register int i;
+ register struct bpf_insn *p;
+
+ for (i = 0; i < len; ++i) {
+ /*
+ * Check that that jumps are forward, and within
+ * the code block.
+ */
+ p = &f[i];
+ if (BPF_CLASS(p->code) == BPF_JMP) {
+ register int from = i + 1;
+
+ if (BPF_OP(p->code) == BPF_JA) {
+ if (from + p->k >= (unsigned)len)
+ return 0;
+ }
+ else if (from + p->jt >= len || from + p->jf >= len)
+ return 0;
+ }
+ /*
+ * Check that memory operations use valid addresses.
+ */
+ if ((BPF_CLASS(p->code) == BPF_ST ||
+ (BPF_CLASS(p->code) == BPF_LD &&
+ (p->code & 0xe0) == BPF_MEM)) &&
+ (p->k >= BPF_MEMWORDS || p->k < 0))
+ return 0;
+ /*
+ * Check for constant division by 0.
+ */
+ if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
+ return 0;
+ }
+ return BPF_CLASS(f[len - 1].code) == BPF_RET;
+}
diff --git a/contrib/ipfilter/bsdinstall b/contrib/ipfilter/bsdinstall
index ce921b60fa47..7689a2105325 100755
--- a/contrib/ipfilter/bsdinstall
+++ b/contrib/ipfilter/bsdinstall
@@ -5,8 +5,13 @@
cmd=/bin/mv
strip=""
chmod="chmod 755"
-chown="chown -f root"
-chgrp="chgrp -f bin"
+if [ "`uname -s`" = "HP-UX" ] ; then
+ chown="chown root"
+ chgrp="chgrp bin"
+else
+ chown="chown -f root"
+ chgrp="chgrp -f bin"
+fi
while true ; do
case $1 in
-s ) strip="strip"
diff --git a/contrib/ipfilter/buildsunos b/contrib/ipfilter/buildsunos
index fa2474e8b356..5e857e77953c 100755
--- a/contrib/ipfilter/buildsunos
+++ b/contrib/ipfilter/buildsunos
@@ -3,13 +3,30 @@ if [ ! -f netinet/done ] ; then
echo "Do NOT run this script directly, do 'make solaris'!"
exit 1
fi
-# $Id: buildsunos,v 2.1.2.1 1999/08/08 13:55:20 darrenr Exp $
+# 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'`
@@ -20,30 +37,132 @@ if [ $rev = 5 ] ; then
/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
- ARCHINC=
- XARCH=
- if [ -d /opt/SUNWspro/bin ] ; then
- CC="/opt/SUNWspro/bin/cc ${CFL}"
- export CC
- /bin/optisa sparcv9 >/dev/null 2>&1
- if [ $? -eq 0 ] ; then
- ARCHINC="-I/usr/include/v9"
- XARCH="-xarch=v9 -xchip=ultra -dalign -xcode=abs32"
+
+ #
+ # 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
- else
+ 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 <stdio.h>
+ 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
- make ${1+"$@"} sunos5x86 SOLARIS2="-DSOLARIS2=$solrev" CPU= CPUDIR=${cpudir} CC="$CC $XARCH" XARCH="$XARCH" ARCHINC="$ARCHINC"
+ 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 "ARCH=`uname -m`"
+ make ${1+"$@"} sunos$rev "TOP=.." "ARCH=`uname -m`"
exit $?
fi
-make ${1+"$@"} sunos$rev SOLARIS2="-DSOLARIS2=$solrev" CPU= CPUDIR=${cpudir} CC="$CC $XARCH" XARCH="$XARCH" ARCHINC="$ARCHINC"
-exit $?
+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/etc/protocols b/contrib/ipfilter/etc/protocols
index fd7a1d246be1..30c5b7647f17 100644
--- a/contrib/ipfilter/etc/protocols
+++ b/contrib/ipfilter/etc/protocols
@@ -38,9 +38,12 @@ ddp 37 DDP # Datagram Delivery Protocol
idpr-cmtp 38 IDPR-CMTP # IDPR Control Message Transport Proto
tp++ 39 TP++ # TP++ Transport Protocol
il 40 IL # IL Transport Protocol
+ipv6 41 IPv6 # Internet Protocol, version 6
sip 41 SIP # Simple Internet Protocol
sdrp 42 SDRP # Source Demand Routing Protocol
+ipv6-route 43 IPv6-Route # Routing Header for IPv6
sip-sr 43 SIP-SR # SIP Source Route
+ipv6-frag 44 IPv6-Frag # Fragment Hedaer for IPv6
sip-frag 44 SIP-FRAG # SIP Fragment
idrp 45 IDRP # Inter-Domain Routing Protocol
rsvp 46 RSVP # Reservation Protocol
diff --git a/contrib/ipfilter/etc/services b/contrib/ipfilter/etc/services
index 01c4b782e29e..d8aa0d5ae223 100644
--- a/contrib/ipfilter/etc/services
+++ b/contrib/ipfilter/etc/services
@@ -2359,8 +2359,8 @@ dpserve 7020/tcp # DP Serve
dpserve 7020/udp # DP Serve
dpserveadmin 7021/tcp # DP Serve Admin
dpserveadmin 7021/udp # DP Serve Admin
+raudio 7070/tcp @ Real Audio
arcp 7070/tcp # ARCP
-raudio 7070/tcp # Real Audio
arcp 7070/udp # ARCP
clutild 7174/tcp # Clutild
clutild 7174/udp # Clutild
diff --git a/contrib/ipfilter/fil.c b/contrib/ipfilter/fil.c
index 1a1da36a740e..6f3a13d57889 100644
--- a/contrib/ipfilter/fil.c
+++ b/contrib/ipfilter/fil.c
@@ -1,24 +1,29 @@
+/* $NetBSD$ */
+
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * Copyright (C) 1993-2003 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#if defined(__sgi) && (IRIX > 602)
-# include <sys/ptimers.h>
+#if defined(KERNEL) || defined(_KERNEL)
+# undef KERNEL
+# undef _KERNEL
+# define KERNEL 1
+# define _KERNEL 1
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
-#include <sys/file.h>
-#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
- defined(_KERNEL)
-# include "opt_ipfilter_log.h"
+#if defined(__NetBSD__)
+# if (NetBSD >= 199905) && !defined(IPFILTER_LKM) && defined(_KERNEL)
+# include "opt_ipfilter_log.h"
+# endif
#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && defined(__FreeBSD_version) && \
+#if defined(_KERNEL) && defined(__FreeBSD_version) && \
(__FreeBSD_version >= 220000)
# if (__FreeBSD_version >= 400000)
-# ifndef KLD_MODULE
+# if !defined(IPFILTER_LKM)
# include "opt_inet6.h"
# endif
# if (__FreeBSD_version == 400019)
@@ -26,42 +31,56 @@
# endif
# endif
# include <sys/filio.h>
-# include <sys/fcntl.h>
#else
# include <sys/ioctl.h>
#endif
-#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
+#include <sys/fcntl.h>
+#if defined(_KERNEL)
# include <sys/systm.h>
+# include <sys/file.h>
#else
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
-# include <sys/mbuf.h>
+# include <stddef.h>
+# include <sys/file.h>
+# define _KERNEL
+# ifdef __OpenBSD__
+struct file;
# endif
+# include <sys/uio.h>
+# undef _KERNEL
+#endif
+#if !defined(__SVR4) && !defined(__svr4__) && !defined(__hpux) && \
+ !defined(linux)
+# include <sys/mbuf.h>
#else
-# include <sys/cmn_err.h>
-# include <sys/byteorder.h>
-# if SOLARIS2 < 5
+# if !defined(linux)
+# include <sys/byteorder.h>
+# endif
+# if (SOLARIS2 < 5) && defined(sun)
# include <sys/dditypes.h>
# endif
-# include <sys/stream.h>
#endif
-#ifndef linux
+#ifdef __hpux
+# define _NET_ROUTE_INCLUDED
+#endif
+#if !defined(linux)
# include <sys/protosw.h>
-# include <sys/socket.h>
#endif
+#include <sys/socket.h>
#include <net/if.h>
#ifdef sun
# include <net/af.h>
#endif
+#if !defined(_KERNEL) && defined(__FreeBSD__)
+# include "radix_ipf.h"
+#endif
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#ifndef linux
+#if !defined(linux)
# include <netinet/ip_var.h>
#endif
#if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
@@ -69,12 +88,17 @@
# include <netinet/in_var.h>
#endif
#include <netinet/tcp.h>
-#include <netinet/udp.h>
-#include <netinet/ip_icmp.h>
+#if !defined(__sgi) || defined(_KERNEL)
+# include <netinet/udp.h>
+# include <netinet/ip_icmp.h>
+#endif
+#ifdef __hpux
+# undef _NET_ROUTE_INCLUDED
+#endif
#include "netinet/ip_compat.h"
#ifdef USE_INET6
# include <netinet/icmp6.h>
-# if !SOLARIS && defined(_KERNEL)
+# if !SOLARIS && defined(_KERNEL) && !defined(__osf__) && !defined(__hpux)
# include <netinet6/in6_var.h>
# endif
#endif
@@ -85,76 +109,142 @@
#include "netinet/ip_state.h"
#include "netinet/ip_proxy.h"
#include "netinet/ip_auth.h"
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
-# include <sys/malloc.h>
-# if defined(_KERNEL) && !defined(IPFILTER_LKM)
-# include "opt_ipfilter.h"
-# endif
+#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 <net/bpf.h>
+#endif
+#if defined(__FreeBSD_version) && (__FreeBSD_version >= 300000)
+# include <sys/malloc.h>
+# if defined(_KERNEL) && !defined(IPFILTER_LKM)
+# include "opt_ipfilter.h"
# endif
-#ifndef MIN
-# define MIN(a,b) (((a)<(b))?(a):(b))
#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.35.2.82 2004/06/20 10:27:47 darrenr Exp $";
+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
-# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
#else /* #ifndef _KERNEL */
# define FR_VERBOSE(verb_pr)
# define FR_DEBUG(verb_pr)
-# define IPLLOG(a, c, d, e) ipflog(a, c, d, e)
-# if SOLARIS || defined(__sgi)
-extern KRWLOCK_T ipf_mutex, ipf_auth, ipf_nat;
-extern kmutex_t ipf_rw;
-# endif /* SOLARIS || __sgi */
#endif /* _KERNEL */
-struct filterstats frstats[2] = {{0,0,0,0,0},{0,0,0,0,0}};
+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 } },
-#ifdef USE_INET6
*ipfilter6[2][2] = { { NULL, NULL }, { NULL, NULL } },
*ipacct6[2][2] = { { NULL, NULL }, { NULL, NULL } },
-#endif
- *ipacct[2][2] = { { NULL, NULL }, { NULL, NULL } };
-struct frgroup *ipfgroups[3][2];
+ *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_chksrc = 0;
-int fr_minttl = 3;
-int fr_minttllog = 1;
+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_NOMATCH|FR_BLOCK;
+int fr_pass = FR_BLOCK|FR_NOMATCH;
#else
-int fr_pass = (IPF_DEFAULT_PASS|FR_NOMATCH);
+int fr_pass = (IPF_DEFAULT_PASS)|FR_NOMATCH;
#endif
-char ipfilter_version[] = IPL_VERSION;
-
-fr_info_t frcache[2];
+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 int frflushlist __P((int, minor_t, int *, frentry_t **));
-#ifdef _KERNEL
-static void frsynclist __P((frentry_t *));
-# ifndef __sgi
-static void *ipf_pullup __P((mb_t *, fr_info_t *, int, void *));
-# 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.
*/
-struct optlist ipopts[20] = {
+const struct optlist ipopts[20] = {
{ IPOPT_NOP, 0x000001 },
{ IPOPT_RR, 0x000002 },
{ IPOPT_ZSU, 0x000004 },
@@ -177,10 +267,34 @@ struct optlist ipopts[20] = {
{ 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
*/
-struct optlist secopt[8] = {
+const struct optlist secopt[8] = {
{ IPSO_CLASS_RES4, 0x01 },
{ IPSO_CLASS_TOPS, 0x02 },
{ IPSO_CLASS_SECR, 0x04 },
@@ -193,292 +307,1021 @@ struct optlist secopt[8] = {
/*
- * compact the IP header into a structure which contains just the info.
- * which is useful for comparing IP headers with.
+ * Table of functions available for use with call rules.
*/
-int fr_makefrip(hlen, ip, fin)
-int hlen;
-ip_t *ip;
+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;
{
- u_short optmsk = 0, secmsk = 0, auth = 0;
- int i, mv, ol, off, p, plen, v;
-#if defined(_KERNEL)
-# if SOLARIS
- mb_t *m = fin->fin_qfm;
-# else
- mb_t *m = fin->fin_mp ? *fin->fin_mp : NULL;
-# endif
-#endif
fr_ip_t *fi = &fin->fin_fi;
- struct optlist *op;
- u_char *s, opt;
- tcphdr_t *tcp;
+ int off;
- fin->fin_rev = 0;
- fin->fin_dp = NULL;
- fin->fin_fr = NULL;
- fin->fin_tcpf = 0;
- fin->fin_data[0] = 0;
- fin->fin_data[1] = 0;
- fin->fin_rule = -1;
- fin->fin_group = -1;
- fin->fin_icode = ipl_unreach;
- v = fin->fin_v;
- fi->fi_v = v;
- fin->fin_hlen = hlen;
- if (v == 4) {
- fin->fin_id = ip->ip_id;
- fi->fi_tos = ip->ip_tos;
-#if (OpenBSD >= 200311) && defined(_KERNEL)
- ip->ip_off = ntohs(ip->ip_off);
-#endif
- off = (ip->ip_off & IP_OFFMASK);
- (*(((u_short *)fi) + 1)) = (*(((u_short *)ip) + 4));
- 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;
- p = ip->ip_p;
- fi->fi_fl = (hlen > sizeof(ip_t)) ? FI_OPTIONS : 0;
- if (ip->ip_off & (IP_MF|IP_OFFMASK))
- fi->fi_fl |= FI_FRAG;
-#if (OpenBSD >= 200311) && defined(_KERNEL)
- ip->ip_len = ntohs(ip->ip_len);
-#endif
- plen = ip->ip_len;
- fin->fin_dlen = plen - hlen;
+ 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;
}
-#ifdef USE_INET6
- else if (v == 6) {
- ip6_t *ip6 = (ip6_t *)ip;
+}
- off = 0;
- p = ip6->ip6_nxt;
- fi->fi_p = p;
- 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);
- fi->fi_tos = 0;
- fi->fi_fl = 0;
- plen = ntohs(ip6->ip6_plen);
- fin->fin_dlen = plen;
- plen += sizeof(*ip6);
+
+/* ------------------------------------------------------------------------ */
+/* 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;
+ }
}
-#endif
- else
- return -1;
+ fi->fi_p = p;
+}
- fin->fin_off = off;
- fin->fin_plen = plen;
- tcp = (tcphdr_t *)((char *)ip + hlen);
- fin->fin_misc = 0;
- off <<= 3;
+/* ------------------------------------------------------------------------ */
+/* 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);
/*
- * For both ICMPV6 & ICMP, we attempt to pullup the entire packet into
- * a single buffer for recognised error return packets. Why? Because
- * the entire data section of the ICMP payload is considered to be of
- * significance and maybe required in NAT/state processing, so rather
- * than be careful later, attempt to get it all in one buffeer first.
- * For TCP we just make sure the _entire_ TCP header is in the first
- * buffer for convienience.
+ * Nasty extension header length?
*/
- switch (p)
- {
-#ifdef USE_INET6
- case IPPROTO_ICMPV6 :
- {
- int minicmpsz = sizeof(struct icmp6_hdr);
- struct icmp6_hdr *icmp6;
+ if ((shift > fin->fin_dlen) || (shift < sizeof(struct ip6_hdr)) ||
+ ((shift - sizeof(struct ip6_hdr)) & 15)) {
+ fin->fin_flx |= FI_BAD;
+ return IPPROTO_NONE;
+ }
- if (!(fin->fin_fl & FI_SHORT) && (fin->fin_dlen > 1)) {
- fin->fin_data[0] = *(u_short *)tcp;
+ for (i = 0; ip6exthdr[i].ol_bit != 0; i++)
+ if (ip6exthdr[i].ol_val == IPPROTO_ROUTING) {
+ fin->fin_optmsk |= ip6exthdr[i].ol_bit;
+ break;
+ }
- icmp6 = (struct icmp6_hdr *)tcp;
+ fin->fin_dp = (char *)fin->fin_dp + shift;
+ fin->fin_dlen -= shift;
- switch (icmp6->icmp6_type)
- {
- case ICMP6_ECHO_REPLY :
- case ICMP6_ECHO_REQUEST :
- minicmpsz = ICMP6_MINLEN;
- break;
- case ICMP6_DST_UNREACH :
- case ICMP6_PACKET_TOO_BIG :
- case ICMP6_TIME_EXCEEDED :
- case ICMP6_PARAM_PROB :
-# if defined(KERNEL) && !defined(__sgi)
- if ((m != NULL) && (M_BLEN(m) < plen)) {
- ip = ipf_pullup(m, fin, plen, ip);
- if (ip == NULL)
- return -1;
- tcp = (tcphdr_t *)((char *)ip + hlen);
- }
-# endif /* KERNEL && !__sgi */
- minicmpsz = ICMP6ERR_IPICMPHLEN;
- break;
- default :
- break;
+ 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;
}
+ }
- if (!(fin->fin_dlen >= minicmpsz))
- fi->fi_fl |= FI_SHORT;
+ frpr_short(fin, minicmpsz);
+}
- break;
+
+/* ------------------------------------------------------------------------ */
+/* 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 /* USE_INET6 */
+#endif
+ return 0;
+}
- case IPPROTO_ICMP :
- {
- int minicmpsz = sizeof(struct icmp);
- icmphdr_t *icmp;
- if (!off && (fin->fin_dlen > 1) && !(fin->fin_fl & FI_SHORT)) {
- fin->fin_data[0] = *(u_short *)tcp;
+/* ------------------------------------------------------------------------ */
+/* 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;
- icmp = (icmphdr_t *)tcp;
+ 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)) {
/*
- * Minimum ICMP packet is type(1) code(1) cksum(2)
- * plus 4 bytes following, totalling 8 bytes.
- */
- switch (icmp->icmp_type)
- {
- case ICMP_ECHOREPLY :
- case ICMP_ECHO :
- /* Router discovery messages - 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 = ICMP_MINLEN + 12;
- break;
- /*
- * type(1) + code(1) + cksum(2) + id(2) seq(2) +
- * mask(4)
+ * 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.
*/
- case ICMP_MASKREQ :
- case ICMP_MASKREPLY :
- minicmpsz = ICMP_MINLEN + 4;
+ /*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;
- /*
- * type(1) + code(1) + cksum(2) + arg(4) ip(20+)
- */
- case ICMP_UNREACH :
- case ICMP_SOURCEQUENCH :
- case ICMP_REDIRECT :
- case ICMP_TIMXCEED :
- case ICMP_PARAMPROB :
-#if defined(KERNEL) && !defined(__sgi)
- if ((m != NULL) && (M_BLEN(m) < plen)) {
- ip = ipf_pullup(m, fin, plen, ip);
- if (ip == NULL)
- return -1;
- tcp = (tcphdr_t *)((char *)ip + hlen);
- }
-#endif /* KERNEL && !__sgi */
- minicmpsz = ICMPERR_MINPKTLEN - sizeof(ip_t);
+ ol = (int)*(s + 1);
+ if (ol < 2 || ol > tlen)
break;
- default :
- minicmpsz = ICMP_MINLEN;
+ }
+
+ 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 */
+}
- if ((!(plen >= hlen + minicmpsz) && !off) ||
- (off && off < sizeof(struct icmp)))
- fi->fi_fl |= FI_SHORT;
- break;
+
+
+/* ------------------------------------------------------------------------ */
+/* 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);
}
+}
- case IPPROTO_TCP :
- fi->fi_fl |= FI_TCPUDP;
-#ifdef USE_INET6
- if (v == 6) {
- if (plen < sizeof(struct tcphdr))
- fi->fi_fl |= FI_SHORT;
- } else
+
+/* ------------------------------------------------------------------------ */
+/* 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
- if (v == 4) {
- if ((!IPMINLEN(ip, tcphdr) && !off) ||
- (off && off < sizeof(struct tcphdr)))
- fi->fi_fl |= FI_SHORT;
- }
+}
+
+
+/* ------------------------------------------------------------------------ */
+/* 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;
+}
-#if defined(KERNEL) && !defined(__sgi)
- if (!off && !(fi->fi_fl & FI_SHORT)) {
- int tlen = hlen + (tcp->th_off << 2);
- if ((m != NULL) && (M_BLEN(m) < tlen)) {
- ip = ipf_pullup(m, fin, tlen, ip);
- if (ip == NULL)
- return -1;
- tcp = (tcphdr_t *)((char *)ip + hlen);
+/* ------------------------------------------------------------------------ */
+/* 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;
}
}
-#endif /* _KERNEL && !_sgi */
+ }
+ fin->fin_off = off;
- if (!(fi->fi_fl & FI_SHORT) && !off)
- fin->fin_tcpf = tcp->th_flags;
- goto getports;
+ /*
+ * Call per-protocol setup and checking
+ */
+ switch (p)
+ {
case IPPROTO_UDP :
- fi->fi_fl |= FI_TCPUDP;
-#ifdef USE_INET6
- if (v == 6) {
- if (plen < sizeof(struct udphdr))
- fi->fi_fl |= FI_SHORT;
- } else
-#endif
- if (v == 4) {
- if ((!IPMINLEN(ip, udphdr) && !off) ||
- (off && off < sizeof(struct udphdr)))
- fi->fi_fl |= FI_SHORT;
- }
-getports:
- if (!off && (fin->fin_dlen > 3)) {
- fin->fin_data[0] = ntohs(tcp->th_sport);
- fin->fin_data[1] = ntohs(tcp->th_dport);
- }
+ frpr_udp(fin);
+ break;
+ case IPPROTO_TCP :
+ frpr_tcp(fin);
+ break;
+ case IPPROTO_ICMP :
+ frpr_icmp(fin);
break;
case IPPROTO_ESP :
-#ifdef USE_INET6
- if (v == 6) {
- if (plen < 8)
- fi->fi_fl |= FI_SHORT;
- } else
-#endif
- if (v == 4) {
- if (((ip->ip_len < hlen + 8) && !off) ||
- (off && off < 8))
- fi->fi_fl |= FI_SHORT;
- }
+ frpr_esp(fin);
break;
- default :
+ case IPPROTO_GRE :
+ frpr_gre(fin);
break;
}
- fin->fin_dp = (char *)tcp;
+ ip = fin->fin_ip;
+ if (ip == NULL)
+ return;
-#ifdef USE_INET6
- if (v == 6) {
+ /*
+ * 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 0;
+ return;
}
-#endif
+
+ /*
+ * 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;
@@ -495,10 +1338,10 @@ getports:
}
for (i = 9, mv = 4; mv >= 0; ) {
op = ipopts + i;
- if (opt == (u_char)op->ol_val) {
+ if ((opt == (u_char)op->ol_val) && (ol > 4)) {
optmsk |= op->ol_bit;
if (opt == IPOPT_SECURITY) {
- struct optlist *sp;
+ const struct optlist *sp;
u_char sec;
int j, m;
@@ -513,98 +1356,174 @@ getports:
break;
}
if (sec < sp->ol_val)
- j -= m--;
+ j -= m;
else
- j += m--;
+ j += m;
+ m--;
}
}
break;
}
if (opt < op->ol_val)
- i -= mv--;
+ i -= mv;
else
- i += mv--;
+ 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;
- return 0;
}
-/*
- * check an IP packet for TCP/UDP characteristics such as ports and flags.
- */
-int fr_tcpudpchk(ft, fin)
-frtuc_t *ft;
+/* ------------------------------------------------------------------------ */
+/* 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;
{
- register u_short po, tup;
- register char i;
- register int err = 1;
+ 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;
/*
- * Both ports should *always* be in the first fragment.
- * So far, I cannot find any cases where they can not be.
- *
- * compare destination ports
+ * Do opposite test to that required and continue if that succeeds.
*/
- if ((i = (int)ft->ftu_dcmp)) {
- po = ft->ftu_dport;
- tup = fin->fin_data[1];
- /*
- * Do opposite test to that required and
- * continue if that succeeds.
- */
- if (!--i && tup != po) /* EQUAL */
+ switch (frp->frp_cmp)
+ {
+ case FR_EQUAL :
+ if (tup != po) /* EQUAL */
err = 0;
- else if (!--i && tup == po) /* NOTEQUAL */
+ break;
+ case FR_NEQUAL :
+ if (tup == po) /* NOTEQUAL */
err = 0;
- else if (!--i && tup >= po) /* LESSTHAN */
+ break;
+ case FR_LESST :
+ if (tup >= po) /* LESSTHAN */
+ err = 0;
+ break;
+ case FR_GREATERT :
+ if (tup <= po) /* GREATERTHAN */
err = 0;
- else if (!--i && tup <= po) /* GREATERTHAN */
+ break;
+ case FR_LESSTE :
+ if (tup > po) /* LT or EQ */
err = 0;
- else if (!--i && tup > po) /* LT or EQ */
+ break;
+ case FR_GREATERTE :
+ if (tup < po) /* GT or EQ */
err = 0;
- else if (!--i && tup < po) /* GT or EQ */
+ break;
+ case FR_OUTRANGE :
+ if (tup >= po && tup <= frp->frp_top) /* Out of range */
err = 0;
- else if (!--i && /* Out of range */
- (tup >= po && tup <= ft->ftu_dtop))
+ break;
+ case FR_INRANGE :
+ if (tup <= po || tup >= frp->frp_top) /* In range */
err = 0;
- else if (!--i && /* In range */
- (tup <= po || tup >= ft->ftu_dtop))
+ 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 && (i = (int)ft->ftu_scmp)) {
- po = ft->ftu_sport;
- tup = fin->fin_data[0];
- if (!--i && tup != po)
- err = 0;
- else if (!--i && tup == po)
- err = 0;
- else if (!--i && tup >= po)
- err = 0;
- else if (!--i && tup <= po)
- err = 0;
- else if (!--i && tup > po)
- err = 0;
- else if (!--i && tup < po)
- err = 0;
- else if (!--i && /* Out of range */
- (tup >= po && tup <= ft->ftu_stop))
- err = 0;
- else if (!--i && /* In range */
- (tup <= po || tup >= ft->ftu_stop))
- err = 0;
- }
+ 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
@@ -612,8 +1531,8 @@ fr_info_t *fin;
* TCP flags, then NO match. If not, then match (which should
* satisfy the "short" class too).
*/
- if (err && (fin->fin_fi.fi_p == IPPROTO_TCP)) {
- if (fin->fin_fl & FI_SHORT)
+ 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.
@@ -628,38 +1547,246 @@ fr_info_t *fin;
return err;
}
-/*
- * Check the input/output list of rules for a match and result.
- * Could be per interface, but this gets real nasty when you don't have
- * kernel sauce.
- */
-int fr_scanlist(passin, ip, fin, m)
-u_32_t passin;
-ip_t *ip;
-register fr_info_t *fin;
-void *m;
+
+/* ------------------------------------------------------------------------ */
+/* 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;
{
- register struct frentry *fr;
- register fr_ip_t *fi = &fin->fin_fi;
- int rulen, portcmp = 0, off, skip = 0, logged = 0;
- u_32_t pass, passt, passl;
- frentry_t *frl;
+ 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;
- frl = NULL;
- pass = passin;
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 ((fi->fi_fl & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
+ if ((fin->fin_flx & FI_TCPUDP) && (fin->fin_dlen > 3) && !off)
portcmp = 1;
- for (rulen = 0; fr; fr = fr->fr_next, rulen++) {
- if (skip) {
+ 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.
@@ -667,198 +1794,376 @@ void *m;
* check that we are working for the right interface
*/
#ifdef _KERNEL
-# if (BSD >= 199306)
- if (fin->fin_out != 0) {
- if ((fr->fr_oifa &&
- (fr->fr_oifa != ((mb_t *)m)->m_pkthdr.rcvif)))
- continue;
- }
-# endif
+ if (fr->fr_ifa && fr->fr_ifa != fin->fin_ifp)
+ continue;
#else
if (opts & (OPT_VERBOSE|OPT_DEBUG))
printf("\n");
-#endif
-
- FR_VERBOSE(("%c", fr->fr_skip ? 's' :
- (pass & FR_PASS) ? 'p' :
- (pass & FR_AUTH) ? 'a' :
- (pass & FR_ACCOUNT) ? 'A' :
- (pass & FR_NOMATCH) ? 'n' : 'b'));
-
+ 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)
{
- register u_32_t *ld, *lm, *lip;
- register int i;
-
- lip = (u_32_t *)fi;
- lm = (u_32_t *)&fr->fr_mip;
- ld = (u_32_t *)&fr->fr_ip;
- i = ((*lip & *lm) != *ld);
- FR_DEBUG(("0. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- if (i)
+ case FR_T_IPF :
+ case FR_T_IPF|FR_T_BUILTIN :
+ if (fr_ipfcheck(fin, fr, portcmp))
continue;
- /*
- * We now know whether the packet version and the
- * rule version match, along with protocol, ttl and
- * tos.
- */
- lip++, lm++, ld++;
- /*
- * Unrolled loops (4 each, for 32 bits).
- */
- FR_DEBUG(("1a. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 5;
- if (fi->fi_v == 6) {
- FR_DEBUG(("1b. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 5;
- FR_DEBUG(("1c. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 5;
- FR_DEBUG(("1d. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 5;
- } else {
- lip += 3;
- lm += 3;
- ld += 3;
- }
- i ^= (fr->fr_flags & FR_NOTSRCIP);
- if (i)
+ 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;
- FR_DEBUG(("2a. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 6;
- if (fi->fi_v == 6) {
- FR_DEBUG(("2b. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 6;
- FR_DEBUG(("2c. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 6;
- FR_DEBUG(("2d. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++) << 6;
- } else {
- lip += 3;
- lm += 3;
- ld += 3;
- }
- i ^= (fr->fr_flags & FR_NOTDSTIP);
- if (i)
+ if (fin->fin_v != fr->fr_v)
continue;
- FR_DEBUG(("3. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip++ & *lm++) != *ld++);
- FR_DEBUG(("4. %#08x & %#08x != %#08x\n",
- *lip, *lm, *ld));
- i |= ((*lip & *lm) != *ld);
- if (i)
+ 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;
- /*
- * If a fragment, then only the first has what we're looking
- * for here...
- */
- if (!portcmp && (fr->fr_dcmp || fr->fr_scmp || fr->fr_tcpf ||
- fr->fr_tcpfm))
- continue;
- if (fi->fi_fl & FI_TCPUDP) {
- if (!fr_tcpudpchk(&fr->fr_tuc, fin))
+ f = (*fr->fr_func)(fin, &pass);
+ if (f != NULL)
+ fr = f;
+ else
continue;
- } else if (fr->fr_icmpm || fr->fr_icmp) {
- if (((fi->fi_p != IPPROTO_ICMP) &&
- (fi->fi_p != IPPROTO_ICMPV6)) || off ||
- (fin->fin_dlen < 2))
+ break;
+ }
+ default :
+ break;
+ }
+
+ if ((fin->fin_out == 0) && (fr->fr_nattag.ipt_num[0] != 0)) {
+ if (fin->fin_nattag == NULL)
continue;
- 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));
+ if (fr_matchtag(&fr->fr_nattag, fin->fin_nattag) == 0)
continue;
- }
}
- FR_VERBOSE(("*"));
+ FR_VERBOSE(("=%s.%d *", fr->fr_group, rulen));
- if (fr->fr_flags & FR_NOMATCH) {
- passt = passl;
- passl = passin;
- fin->fin_fr = frl;
- frl = NULL;
- if (fr->fr_flags & FR_QUICK)
- break;
+ 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;
}
- passl = passt;
- passt = fr->fr_flags;
- frl = fin->fin_fr;
- fin->fin_fr = fr;
-#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
- if (securelevel <= 0)
-#endif
- if ((passt & FR_CALLNOW) && fr->fr_func)
- passt = (*fr->fr_func)(passt, ip, fin);
#ifdef IPFILTER_LOG
/*
* Just log this packet...
*/
if ((passt & FR_LOGMASK) == FR_LOG) {
- if (!IPLLOG(passt, ip, fin, m)) {
- if (passt & FR_LOGORBLOCK)
+ 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 */
- ATOMIC_INCL(fr->fr_hits);
- if (passt & FR_ACCOUNT)
- fr->fr_bytes += (U_QUAD_T)fin->fin_plen;
- else
+ 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;
- fin->fin_group = fr->fr_group;
+ (void) strncpy(fin->fin_group, fr->fr_group, FR_GROUPLEN);
if (fr->fr_grp != NULL) {
- fin->fin_fr = fr->fr_grp;
- passt = fr_scanlist(passt, ip, fin, m);
+ fin->fin_fr = *fr->fr_grp;
+ pass = fr_scanlist(fin, pass);
if (fin->fin_fr == NULL) {
fin->fin_rule = rulen;
- fin->fin_group = fr->fr_group;
+ (void) strncpy(fin->fin_group, fr->fr_group,
+ FR_GROUPLEN);
fin->fin_fr = fr;
}
- if (passt & FR_DONTCACHE)
+ if (fin->fin_flx & FI_DONTCACHE)
logged = 1;
}
- if (!(skip = fr->fr_skip) && (passt & FR_LOGMASK) != FR_LOG)
- pass = passt;
- FR_DEBUG(("pass %#x\n", pass));
- if (passt & FR_QUICK)
+ if (pass & FR_QUICK)
break;
}
if (logged)
- pass |= FR_DONTCACHE;
- pass |= (fi->fi_fl << 24);
+ fin->fin_flx |= FI_DONTCACHE;
+ fin->fin_depth--;
return pass;
}
-/*
- * frcheck - filter check
- * check using source and destination addresses/ports in a packet whether
- * or not to pass it on or not.
- */
+/* ------------------------------------------------------------------------ */
+/* 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) && SOLARIS
+#if defined(_KERNEL) && defined(MENTAT)
, qif, mp)
-qif_t *qif;
+void *qif;
#else
, mp)
#endif
@@ -871,49 +2176,59 @@ int out;
/*
* The above really sucks, but short of writing a diff
*/
- fr_info_t frinfo, *fc;
- register fr_info_t *fin = &frinfo;
- int changed, error = EHOSTUNREACH, v = ip->ip_v;
- frentry_t *fr = NULL, *list;
- u_32_t pass, apass;
-#if !SOLARIS || !defined(_KERNEL)
- register mb_t *m = *mp;
+ 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
-#ifdef _KERNEL
- int p, len, drop = 0, logit = 0;
- mb_t *mc = NULL;
-# if !defined(__SVR4) && !defined(__svr4__)
/*
- * We don't do this section for Solaris because fr_precheck() does a
- * pullupmsg() instead, effectively achieving the same result as here
- * so no need to duplicate it.
+ * 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 __sgi
- char hbuf[128];
-# endif
- int up;
-
-# if !defined(NETBSD_PF) && \
- ((defined(__FreeBSD__) && (__FreeBSD_version < 500011)) || \
- defined(__OpenBSD__) || defined(_BSDI_VERSION))
- if (fr_checkp != fr_check && fr_running > 0) {
- static int counter = 0;
-
- if (counter == 0) {
- printf("WARNING: fr_checkp corrupt: value %lx\n",
- (u_long)fr_checkp);
- printf("WARNING: fr_checkp should be %lx\n",
- (u_long)fr_check);
- printf("WARNING: fixing fr_checkp\n");
- }
- fr_checkp = fr_check;
- counter++;
- if (counter == 10000)
- counter = 0;
+#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;
}
-# endif
+ 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
@@ -926,179 +2241,91 @@ int out;
/*
* disable delayed checksums.
*/
- if ((out != 0) && (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)) {
+ 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);
-# ifdef USE_INET6
- if (v == 6) {
- len = ntohs(((ip6_t*)ip)->ip6_plen);
- if (!len)
- return -1; /* potential jumbo gram */
- len += sizeof(ip6_t);
- p = ((ip6_t *)ip)->ip6_nxt;
- } else
-# endif
- {
- p = ip->ip_p;
- len = ip->ip_len;
- }
+ 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;
- if ((p == IPPROTO_TCP || p == IPPROTO_UDP ||
- (v == 4 && p == IPPROTO_ICMP)
-# ifdef USE_INET6
- || (v == 6 && p == IPPROTO_ICMPV6)
-# endif
- )) {
- int plen = 0;
-
- if ((v == 6) || (ip->ip_off & IP_OFFMASK) == 0)
- switch(p)
- {
- case IPPROTO_TCP:
- plen = sizeof(tcphdr_t);
- break;
- case IPPROTO_UDP:
- plen = sizeof(udphdr_t);
- break;
- /* 96 - enough for complete ICMP error IP header */
- case IPPROTO_ICMP:
- plen = ICMPERR_MAXPKTLEN - sizeof(ip_t);
- break;
- case IPPROTO_ESP:
- plen = 8;
- break;
-# ifdef USE_INET6
- case IPPROTO_ICMPV6 :
- /*
- * XXX does not take intermediate header
- * into account
- */
- plen = ICMP6ERR_MINPKTLEN + 8 - sizeof(ip6_t);
- break;
-# endif
- }
- if ((plen > 0) && (len < hlen + plen))
- fin->fin_fl |= FI_SHORT;
- up = MIN(hlen + plen, len);
-
- if (up > m->m_len) {
-# ifdef __sgi
- /* Under IRIX, avoid m_pullup as it makes ping <hostname> panic */
- if ((up > sizeof(hbuf)) || (m_length(m) < up)) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return -1;
- }
- m_copydata(m, 0, up, hbuf);
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- ip = (ip_t *)hbuf;
-# else /* __ sgi */
-# ifndef linux
- /*
- * Having determined that we need to pullup some data,
- * try to bring as much of the packet up into a single
- * buffer with the first pullup. This hopefully means
- * less need for doing futher pullups. Not needed for
- * Solaris because fr_precheck() does it anyway.
- *
- * The main potential for trouble here is if MLEN/MHLEN
- * become quite small, lets say < 64 bytes...but if
- * that did happen, BSD networking as a whole would be
- * slow/inefficient.
- */
-# 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 ((MHLEN > up) && (len > up))
- up = MIN(len, MHLEN);
-# else
- if ((MLEN > up) && (len > up))
- up = MIN(len, MLEN);
-# endif
- ip = ipf_pullup(m, fin, up, ip);
- if (ip == NULL)
- return -1;
- m = *mp;
-# endif /* !linux */
-# endif /* __sgi */
- } else
- up = 0;
+ 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
- up = 0;
-# endif /* !defined(__SVR4) && !defined(__svr4__) */
-# if SOLARIS
- mb_t *m = qif->qf_m;
+#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 ((u_int)ip & 0x3)
- return 2;
- fin->fin_mp = mp;
- fin->fin_out = out;
- fin->fin_qfm = m;
- fin->fin_qif = qif;
-# endif
-#else
- fin->fin_mp = mp;
- fin->fin_out = out;
-#endif /* _KERNEL */
-
- changed = 0;
- fin->fin_v = v;
- fin->fin_ifp = ifp;
if (fr_makefrip(hlen, ip, fin) == -1)
- return -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
-# ifdef USE_INET6
- if (v == 6) {
- ATOMIC_INCL(frstats[0].fr_ipv6[out]);
- if (((ip6_t *)ip)->ip6_hlim < fr_minttl) {
- ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog & 1)
- logit = -3;
- if (fr_minttllog & 2)
- drop = 1;
+ 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;
+ }
}
- } else
-# endif
- if (!out) {
- if (fr_chksrc && !fr_verifysrc(ip->ip_src, ifp)) {
- ATOMIC_INCL(frstats[0].fr_badsrc);
- if (fr_chksrc & 1)
- drop = 1;
- if (fr_chksrc & 2)
- logit = -2;
- } else if (ip->ip_ttl < fr_minttl) {
- ATOMIC_INCL(frstats[0].fr_badttl);
- if (fr_minttllog & 1)
- logit = -3;
- if (fr_minttllog & 2)
- drop = 1;
- }
- }
- if (drop) {
-# ifdef IPFILTER_LOG
- if (logit) {
- fin->fin_group = logit;
- pass = FR_INQUE|FR_NOMATCH|FR_LOGB;
- (void) IPLLOG(pass, ip, fin, m);
+#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 !SOLARIS
- m_freem(m);
-# endif
- return error;
- }
#endif
- pass = fr_pass;
- if (fin->fin_fl & FI_SHORT) {
+ }
+
+ if (fin->fin_flx & FI_SHORT) {
ATOMIC_INCL(frstats[out].fr_short);
}
@@ -1111,210 +2338,71 @@ int out;
* after it has no auth. table matchup. This also stops NAT from
* occuring until after the packet has been auth'd.
*/
- apass = fr_checkauth(ip, fin);
-
+ fr = fr_checkauth(fin, &pass);
if (!out) {
-#ifdef USE_INET6
- if (v == 6)
- list = ipacct6[0][fr_active];
- else
-#endif
- list = ipacct[0][fr_active];
- changed = ip_natin(ip, fin);
- if (!apass && (fin->fin_fr = list) &&
- (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT)) {
- ATOMIC_INCL(frstats[0].fr_acct);
+ if (fr_checknatin(fin, &pass) == -1) {
+ RWLOCK_EXIT(&ipf_mutex);
+ goto finished;
}
}
+ if (!out)
+ (void) fr_acctpkt(fin, NULL);
- if (!apass) {
- if ((fin->fin_fl & FI_FRAG) == FI_FRAG)
- fr = ipfr_knownfrag(ip, fin);
- if (!fr && !(fin->fin_fl & FI_SHORT))
- fr = fr_checkstate(ip, fin);
- if (fr != NULL)
- pass = fr->fr_flags;
- if (fr && (pass & FR_LOGFIRST))
- pass &= ~(FR_LOGFIRST|FR_LOG);
- }
-
- if (apass || !fr) {
- /*
- * 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.
- */
- if (!apass) {
- fc = frcache + out;
- 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)) {
- ATOMIC_INCL(fr->fr_hits);
- pass = fr->fr_flags;
- }
- } else {
-#ifdef USE_INET6
- if (v == 6)
- list = ipfilter6[out][fr_active];
- else
-#endif
- list = ipfilter[out][fr_active];
- if ((fin->fin_fr = list))
- pass = fr_scanlist(fr_pass, ip, fin, m);
- if (!(pass & (FR_KEEPSTATE|FR_DONTCACHE)))
- bcopy((char *)fin, (char *)fc,
- FI_COPYSIZE);
- if (pass & FR_NOMATCH) {
- ATOMIC_INCL(frstats[out].fr_nom);
- fin->fin_fr = NULL;
- }
- }
- } else
- pass = apass;
- fr = fin->fin_fr;
-
- /*
- * 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 ((pass & FR_AUTH)) {
- if (fr_newauth((mb_t *)m, fin, ip) != 0) {
- m = *mp = NULL;
- error = 0;
- } else
- error = ENOSPC;
- }
-
- if (pass & FR_PREAUTH) {
- READ_ENTER(&ipf_auth);
- if ((fin->fin_fr = ipauth) &&
- (pass = fr_scanlist(0, ip, fin, m))) {
- ATOMIC_INCL(fr_authstats.fas_hits);
- } else {
- ATOMIC_INCL(fr_authstats.fas_miss);
- }
- RWLOCK_EXIT(&ipf_auth);
- }
+ 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);
- fin->fin_fr = fr;
- if ((pass & (FR_KEEPFRAG|FR_KEEPSTATE)) == FR_KEEPFRAG) {
- if (fin->fin_fl & FI_FRAG) {
- if (ipfr_newfrag(ip, fin) == -1) {
- ATOMIC_INCL(frstats[out].fr_bnfr);
- } else {
- ATOMIC_INCL(frstats[out].fr_nfr);
- }
- } else {
- ATOMIC_INCL(frstats[out].fr_cfr);
- }
- }
- if (pass & FR_KEEPSTATE) {
- if (fr_addstate(ip, fin, NULL, 0) == NULL) {
- ATOMIC_INCL(frstats[out].fr_bads);
- if (pass & FR_PASS) {
- pass &= ~FR_PASS;
- pass |= FR_BLOCK;
- }
- } else {
- ATOMIC_INCL(frstats[out].fr_ads);
- }
- }
- } else if (fr != NULL) {
- pass = fr->fr_flags;
- if (pass & FR_LOGFIRST)
- pass &= ~(FR_LOGFIRST|FR_LOG);
- }
+ if ((pass & FR_NOMATCH) || (fr == NULL))
+ fr = fr_firewall(fin, &pass);
-#if (BSD >= 199306) && (defined(_KERNEL) || defined(KERNEL))
- if (securelevel <= 0)
-#endif
- if (fr && fr->fr_func && !(pass & FR_CALLNOW))
- pass = (*fr->fr_func)(pass, ip, fin);
+ fin->fin_fr = fr;
/*
* Only count/translate packets which will be passed on, out the
* interface.
*/
- if (out && (pass & FR_PASS)) {
-#ifdef USE_INET6
- if (v == 6)
- list = ipacct6[1][fr_active];
- else
-#endif
- list = ipacct[1][fr_active];
- if (list != NULL) {
- u_32_t sg, sr;
-
- fin->fin_fr = list;
- sg = fin->fin_group;
- sr = fin->fin_rule;
- if (fr_scanlist(FR_NOMATCH, ip, fin, m) & FR_ACCOUNT) {
- ATOMIC_INCL(frstats[1].fr_acct);
+ 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);
}
- fin->fin_group = sg;
- fin->fin_rule = sr;
- fin->fin_fr = fr;
}
- changed = ip_natout(ip, fin);
- } else
- fin->fin_fr = fr;
- RWLOCK_EXIT(&ipf_mutex);
+ }
#ifdef IPFILTER_LOG
if ((fr_flags & FF_LOGGING) || (pass & FR_LOGMASK)) {
- 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) ||
- ((pass & FR_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) ||
- ((pass & FR_BLOCK) && (fr_flags & FF_LOGBLOCK))) {
- if ((pass & FR_LOGMASK) != FR_LOGB)
- pass |= FF_LOGBLOCK;
- ATOMIC_INCL(frstats[out].fr_bpkl);
-logit:
- if (!IPLLOG(pass, ip, fin, m)) {
- ATOMIC_INCL(frstats[out].fr_skip);
- if ((pass & (FR_PASS|FR_LOGORBLOCK)) ==
- (FR_PASS|FR_LOGORBLOCK))
- pass ^= FR_PASS|FR_BLOCK;
- }
- }
+ (void) fr_dolog(fin, &pass);
}
-#endif /* IPFILTER_LOG */
+#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);
-#ifdef _KERNEL
/*
* 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.
+ * to send the packet. Use fin_m here because it may have changed
+ * (without an update of 'm') in prior processing.
*/
- if (fr && (pass & FR_DUP))
-# if SOLARIS
- mc = dupmsg(m);
-# else
-# if defined(__OpenBSD__) && (OpenBSD >= 199905)
- mc = m_copym2(m, 0, M_COPYALL, M_DONTWAIT);
-# else
- mc = m_copy(m, 0, M_COPYALL);
-# endif
-# endif
-#endif
- if (pass & FR_PASS) {
- ATOMIC_INCL(frstats[out].fr_pass);
- } else if (pass & FR_BLOCK) {
- ATOMIC_INCL(frstats[out].fr_block);
+ 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 ?
@@ -1324,33 +2412,24 @@ logit:
* some operating systems.
*/
if (!out) {
- if (changed == -1)
- /*
- * If a packet results in a NAT error, do not
- * send a reset or ICMP error as it may disrupt
- * an existing flow. This is the proxy saying
- * the content is bad so just drop the packet
- * silently.
- */
- ;
- else if (pass & FR_RETICMP) {
+ if (pass & FR_RETICMP) {
int dst;
if ((pass & FR_RETMASK) == FR_FAKEICMP)
dst = 1;
else
dst = 0;
- send_icmp_err(ip, ICMP_UNREACH, fin, dst);
+ (void) fr_send_icmp_err(ICMP_UNREACH, fin, dst);
ATOMIC_INCL(frstats[0].fr_ret);
} else if (((pass & FR_RETMASK) == FR_RETRST) &&
- !(fin->fin_fl & FI_SHORT)) {
- if (send_reset(ip, fin) == 0) {
+ !(fin->fin_flx & FI_SHORT)) {
+ if (fr_send_reset(fin) == 0) {
ATOMIC_INCL(frstats[1].fr_ret);
}
}
} else {
if (pass & FR_RETRST)
- error = ECONNRESET;
+ fin->fin_error = ECONNRESET;
}
}
@@ -1360,83 +2439,177 @@ logit:
* 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 ((changed == -1) && (pass & FR_PASS)) {
- pass &= ~FR_PASS;
- pass |= FR_BLOCK;
- }
-#if defined(_KERNEL)
-# if !SOLARIS
-# if !defined(linux)
- if (fr) {
- frdest_t *fdp = &fr->fr_tif;
+#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 (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1)) {
- (void) ipfr_fastroute(m, mp, fin, fdp);
- m = *mp;
+ 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) ipfr_fastroute(mc, &mc, fin, &fr->fr_dif);
- }
-
- if (!(pass & FR_PASS) && m) {
- m_freem(m);
- m = *mp = NULL;
+ (void) fr_fastroute(mc, &mc, fin, &fr->fr_dif);
}
-# ifdef __sgi
- else if (changed && up && m)
- m_copyback(m, 0, up, hbuf);
-# endif
-# endif /* !linux */
-# else /* !SOLARIS */
- if (fr) {
- frdest_t *fdp = &fr->fr_tif;
- if (((pass & FR_FASTROUTE) && !out) ||
- (fdp->fd_ifp && fdp->fd_ifp != (struct ifnet *)-1))
- (void) ipfr_fastroute(ip, m, mp, fin, fdp);
+ /*
+ * This late because the likes of fr_fastroute() use fin_fr.
+ */
+ RWLOCK_EXIT(&ipf_mutex);
- if (mc != NULL)
- (void) ipfr_fastroute(ip, mc, &mc, fin, &fr->fr_dif);
+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
}
-# endif /* !SOLARIS */
-#if (OpenBSD >= 200311) && defined(_KERNEL)
- if (pass & FR_PASS) {
- ip->ip_len = htons(ip->ip_len);
- ip->ip_off = htons(ip->ip_off);
+
+ 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 (pass & FR_PASS) ? 0 : error;
+# endif
+ return (FR_ISPASS(pass)) ? 0 : fin->fin_error;
#else /* _KERNEL */
- if (pass & FR_NOMATCH)
+ FR_VERBOSE(("fin_flx %#x pass %#x ", fin->fin_flx, pass));
+ if ((pass & FR_NOMATCH) != 0)
return 1;
- if (pass & FR_PASS)
+
+ 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;
- if (pass & FR_AUTH)
+ case FR_BLOCK :
+ return -1;
+ case FR_AUTH :
return -2;
- if ((pass & FR_RETMASK) == FR_RETRST)
+ case FR_ACCOUNT :
return -3;
- if ((pass & FR_RETMASK) == FR_RETICMP)
+ case FR_PREAUTH :
return -4;
- if ((pass & FR_RETMASK) == FR_FAKEICMP)
- return -5;
- return -1;
+ }
+ return 2;
#endif /* _KERNEL */
}
-/*
- * ipf_cksum
- * addr should be 16bit aligned and len is in bytes.
- * length is in bytes
- */
+#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)
-register u_short *addr;
-register int len;
+u_short *addr;
+int len;
{
- register u_32_t sum = 0;
+ u_32_t sum = 0;
for (sum = 0; len > 1; len -= 2)
sum += *addr++;
@@ -1454,42 +2627,127 @@ register int len;
}
-/*
- * 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.
- */
-u_short fr_tcpsum(m, ip, tcp)
+/* ------------------------------------------------------------------------ */
+/* 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;
-tcphdr_t *tcp;
+int l4proto;
+void *l4hdr;
{
- u_short *sp, slen, ts;
+ 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
*/
- hlen = ip->ip_hl << 2;
- slen = ip->ip_len - hlen;
- sum = htons((u_short)ip->ip_p);
- sum += htons(slen);
- sp = (u_short *)&ip->ip_src;
- sum += *sp++; /* ip_src */
- sum += *sp++;
- sum += *sp++; /* ip_dst */
- sum += *sp++;
- ts = tcp->th_sum;
- tcp->th_sum = 0;
-#ifdef KERNEL
-# if SOLARIS
+#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 */
- sum2 = (sum2 & 0xffff) + (sum2 >> 16);
- sum2 = ~sum2 & 0xffff;
-# else /* SOLARIS */
+ m->b_rptr = rp;
+ sum2 = (u_short)(~sum2 & 0xffff);
+ }
+# else /* MENTAT */
# if defined(BSD) || defined(sun)
-# if BSD >= 199306
+# if BSD >= 199103
m->m_data += hlen;
# else
m->m_off += hlen;
@@ -1497,7 +2755,7 @@ tcphdr_t *tcp;
m->m_len -= hlen;
sum2 = in_cksum(m, slen);
m->m_len += hlen;
-# if BSD >= 199306
+# if BSD >= 199103
m->m_data -= hlen;
# else
m->m_off -= hlen;
@@ -1516,35 +2774,44 @@ tcphdr_t *tcp;
u_short s;
} bytes;
u_short len = ip->ip_len;
-# if defined(__sgi)
+# if defined(__sgi)
int add;
-# endif
+# endif
/*
* Add up IP Header portion
*/
- sp = (u_short *)&ip->ip_src;
- len -= (ip->ip_hl << 2);
- sum = ntohs(IPPROTO_TCP);
- sum += htons(len);
- sum += *sp++; /* ip_src */
- sum += *sp++;
- sum += *sp++; /* ip_dst */
- sum += *sp++;
- if (sp != (u_short *)tcp)
- sp = (u_short *)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++; /* Skip over checksum */
- sum += *sp++; /* urp */
-
-# ifdef __sgi
+ 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
@@ -1562,24 +2829,26 @@ tcphdr_t *tcp;
break;
sp = mtod(m, u_short *);
}
- PANIC((!m),("fr_tcpsum(1): not enough data"));
+ PANIC((!m),("fr_cksum(1): not enough data"));
}
}
}
-# endif
+# endif
- if (!(len -= sizeof(*tcp)))
+ 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_tcpsum(2): not enough data"));
+ 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_tcpsum(3): not enough data"));
+ PANIC((!m),("fr_cksum(3): not enough data"));
sp = mtod(m, u_short *);
bytes.c[1] = *(u_char *)sp;
sum += bytes.s;
@@ -1592,7 +2861,8 @@ tcphdr_t *tcp;
sum += *sp++;
len -= 2;
}
- if (len)
+
+ if (len != 0)
sum += ntohs(*(u_char *)sp << 8);
nodata:
while (sum > 0xffff)
@@ -1600,22 +2870,24 @@ nodata:
sum2 = (u_short)(~sum & 0xffff);
}
# endif /* defined(BSD) || defined(sun) */
-# endif /* SOLARIS */
-#else /* KERNEL */
+# endif /* MENTAT */
+#else /* _KERNEL */
for (; slen > 1; slen -= 2)
- sum += *sp++;
+ 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 */
- tcp->th_sum = ts;
+#endif /* _KERNEL */
+ if (csump != NULL)
+ *csump = sumsave;
return sum2;
}
-#if defined(_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || defined(__sgi) )
+#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.
@@ -1628,11 +2900,7 @@ nodata:
* 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
+ * 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.
*
@@ -1649,7 +2917,7 @@ nodata:
* SUCH DAMAGE.
*
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
- * $Id: fil.c,v 2.35.2.82 2004/06/20 10:27:47 darrenr Exp $
+ * 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,
@@ -1657,12 +2925,12 @@ nodata:
*/
void
m_copydata(m, off, len, cp)
- register mb_t *m;
- register int off;
- register int len;
+ mb_t *m;
+ int off;
+ int len;
caddr_t cp;
{
- register unsigned count;
+ unsigned count;
if (off < 0 || len < 0)
panic("m_copydata");
@@ -1687,7 +2955,6 @@ m_copydata(m, off, len, cp)
}
-# ifndef linux
/*
* Copy data from a buffer back into the indicated mbuf chain,
* starting "off" bytes from the beginning, extending the mbuf
@@ -1696,12 +2963,12 @@ m_copydata(m, off, len, cp)
void
m_copyback(m0, off, len, cp)
struct mbuf *m0;
- register int off;
- register int len;
+ int off;
+ int len;
caddr_t cp;
{
- register int mlen;
- register struct mbuf *m = m0, *n;
+ int mlen;
+ struct mbuf *m = m0, *n;
int totlen = 0;
if (m0 == 0)
@@ -1744,169 +3011,322 @@ out:
#endif
return;
}
-# endif /* linux */
-#endif /* (_KERNEL) && ( ((BSD < 199306) && !SOLARIS) || __sgi) */
-
-
-frgroup_t *fr_findgroup(num, flags, which, set, fgpp)
-u_32_t num, flags;
-minor_t which;
+#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;
- if (which == IPL_LOGAUTH)
- fgp = &ipfgroups[2][set];
- else if (flags & FR_ACCOUNT)
- fgp = &ipfgroups[1][set];
- else if (flags & (FR_OUTQUE|FR_INQUE))
- fgp = &ipfgroups[0][set];
- else
- return NULL;
+ /*
+ * 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))
- if (fg->fg_num == num)
+ while ((fg = *fgp) != NULL) {
+ if (strncmp(group, fg->fg_name, FR_GROUPLEN) == 0)
break;
else
fgp = &fg->fg_next;
- if (fgpp)
+ }
+ if (fgpp != NULL)
*fgpp = fgp;
return fg;
}
-frgroup_t *fr_addgroup(num, fp, which, set)
-u_32_t num;
-frentry_t *fp;
-minor_t which;
+/* ------------------------------------------------------------------------ */
+/* 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 ((fg = fr_findgroup(num, fp->fr_flags, which, set, &fgp)))
- return fg;
+ 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) {
- fg->fg_num = num;
+ if (fg != NULL) {
+ fg->fg_head = head;
+ fg->fg_start = NULL;
fg->fg_next = *fgp;
- fg->fg_head = fp;
- fg->fg_start = &fp->fr_grp;
+ bcopy(group, fg->fg_name, FR_GROUPLEN);
+ fg->fg_flags = gflags;
+ fg->fg_ref = 1;
*fgp = fg;
}
return fg;
}
-void fr_delgroup(num, flags, which, set)
-u_32_t num, flags;
-minor_t which;
+/* ------------------------------------------------------------------------ */
+/* 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;
-
- if (!(fg = fr_findgroup(num, flags, which, set, &fgp)))
+
+ fg = fr_findgroup(group, unit, set, &fgp);
+ if (fg == NULL)
return;
-
- *fgp = fg->fg_next;
- KFREE(fg);
+
+ 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;
-/*
- * 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.
- */
+ 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;
{
- register int freed = 0, i;
- register frentry_t *fp;
+ int freed = 0, i;
+ frentry_t *fp;
- while ((fp = *listp)) {
+ 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) {
- i = frflushlist(set, unit, nfreedp, &fp->fr_grp);
- MUTEX_ENTER(&ipf_rw);
+ if (fp->fr_grp != NULL) {
+ i = frflushlist(set, unit, nfreedp, fp->fr_grp);
fp->fr_ref -= i;
- MUTEX_EXIT(&ipf_rw);
}
- ATOMIC_DEC32(fp->fr_ref);
- if (fp->fr_grhead) {
- fr_delgroup(fp->fr_grhead, fp->fr_flags,
- unit, set);
- fp->fr_grhead = 0;
+ if (fp->fr_grhead != NULL) {
+ fr_delgroup(fp->fr_grhead, unit, set);
+ *fp->fr_grhead = '\0';
}
- if (fp->fr_ref == 0) {
- KFREE(fp);
+
+ ASSERT(fp->fr_ref > 0);
+ fp->fr_next = NULL;
+ if (fr_derefrule(&fp) == 0)
freed++;
- } else
- fp->fr_next = NULL;
}
*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;
- if (unit != IPL_LOGIPF)
- return 0;
WRITE_ENTER(&ipf_mutex);
- bzero((char *)frcache, sizeof(frcache[0]) * 2);
+ bzero((char *)frcache, sizeof(frcache));
set = fr_active;
- if (flags & FR_INACTIVE)
+ if ((flags & FR_INACTIVE) == FR_INACTIVE)
set = 1 - set;
if (flags & FR_OUTQUE) {
-#ifdef USE_INET6
if (proto == 0 || proto == 6) {
(void) frflushlist(set, unit,
- &flushed, &ipfilter6[1][set]);
+ &flushed, &ipfilter6[1][set]);
(void) frflushlist(set, unit,
- &flushed, &ipacct6[1][set]);
+ &flushed, &ipacct6[1][set]);
}
-#endif
if (proto == 0 || proto == 4) {
(void) frflushlist(set, unit,
- &flushed, &ipfilter[1][set]);
+ &flushed, &ipfilter[1][set]);
(void) frflushlist(set, unit,
- &flushed, &ipacct[1][set]);
+ &flushed, &ipacct[1][set]);
}
}
if (flags & FR_INQUE) {
-#ifdef USE_INET6
if (proto == 0 || proto == 6) {
(void) frflushlist(set, unit,
- &flushed, &ipfilter6[0][set]);
+ &flushed, &ipfilter6[0][set]);
(void) frflushlist(set, unit,
- &flushed, &ipacct6[0][set]);
+ &flushed, &ipacct6[0][set]);
}
-#endif
if (proto == 0 || proto == 4) {
(void) frflushlist(set, unit,
- &flushed, &ipfilter[0][set]);
+ &flushed, &ipfilter[0][set]);
(void) frflushlist(set, unit,
- &flushed, &ipacct[0][set]);
+ &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;
@@ -1923,34 +3343,50 @@ int slen, dlen;
}
return s;
}
-
-
-void fixskip(listp, rp, addremove)
+/* ------------------------------------------------------------------------ */
+/* 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;
- int rules = 0, rn = 0;
- for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rules++)
- ;
+ rules = 0;
+ for (fp = *listp; (fp != NULL) && (fp != rp); fp = fp->fr_next)
+ rules++;
if (!fp)
return;
- for (fp = *listp; fp && (fp != rp); fp = fp->fr_next, rn++)
- if (fp->fr_skip && (rn + fp->fr_skip >= rules))
- fp->fr_skip += addremove;
+ 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
-/*
- * 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)
+/* ------------------------------------------------------------------------ */
+/* 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;
@@ -1974,192 +3410,156 @@ u_32_t ip;
}
-/*
- * return the first IP Address associated with an interface
- */
-int fr_ifpaddr(v, ifptr, inp)
-int v;
-void *ifptr;
-struct in_addr *inp;
+# 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;
{
-# ifdef USE_INET6
- struct in6_addr *inp6 = NULL;
-# endif
-# if SOLARIS
- ill_t *ill = ifptr;
-# else
- struct ifnet *ifp = ifptr;
-# endif
- struct in_addr in;
-
-# if SOLARIS
-# ifdef USE_INET6
- if (v == 6) {
- struct in6_addr in6;
+ int i = 0, k;
+ u_32_t j;
- /*
- * First is always link local.
- */
- if (ill->ill_ipif->ipif_next)
- in6 = ill->ill_ipif->ipif_next->ipif_v6lcl_addr;
- else
- bzero((char *)&in6, sizeof(in6));
- bcopy((char *)&in6, (char *)inp, sizeof(in6));
- } else
-# endif
- {
- in.s_addr = ill->ill_ipif->ipif_local_addr;
- *inp = in;
- }
-# else /* SOLARIS */
-# if linux
- ;
-# else /* linux */
- struct sockaddr_in *sin;
- struct ifaddr *ifa;
-
-# if (__FreeBSD_version >= 300000)
- ifa = TAILQ_FIRST(&ifp->if_addrhead);
-# else
-# if defined(__NetBSD__) || defined(__OpenBSD__)
- ifa = ifp->if_addrlist.tqh_first;
-# else
-# if defined(__sgi) && defined(IFF_DRVRLOCK) /* IRIX 6 */
- ifa = &((struct in_ifaddr *)ifp->in_ifaddr)->ia_ifa;
-# else
- ifa = ifp->if_addrlist;
-# endif
-# endif /* __NetBSD__ || __OpenBSD__ */
-# endif /* __FreeBSD_version >= 300000 */
-# if (BSD < 199306) && !(/*IRIX6*/defined(__sgi) && defined(IFF_DRVRLOCK))
- sin = (struct sockaddr_in *)&ifa->ifa_addr;
-# else
- sin = (struct sockaddr_in *)ifa->ifa_addr;
- while (sin && ifa) {
- 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;
+ for (k = 3; k >= 0; k--)
+ if (msk[k] == 0xffffffff)
+ i += 32;
+ else {
+ for (j = msk[k]; j; j <<= 1)
+ if (j & 0x80000000)
+ i++;
}
-# endif
-# if (__FreeBSD_version >= 300000)
- ifa = TAILQ_NEXT(ifa, ifa_link);
-# else
-# if defined(__NetBSD__) || defined(__OpenBSD__)
- ifa = ifa->ifa_list.tqe_next;
-# else
- ifa = ifa->ifa_next;
-# endif
-# endif /* __FreeBSD_version >= 300000 */
- if (ifa)
- sin = (struct sockaddr_in *)ifa->ifa_addr;
- }
- if (ifa == NULL)
- sin = NULL;
- if (sin == NULL)
- return -1;
-# endif /* (BSD < 199306) && (!__sgi && IFF_DRVLOCK) */
-# ifdef USE_INET6
- if (v == 6)
- bcopy((char *)inp6, (char *)inp, sizeof(*inp6));
- else
-# endif
- {
- in = sin->sin_addr;
- *inp = in;
- }
-# endif /* linux */
-# endif /* SOLARIS */
- return 0;
+ return i;
}
+# endif
+#endif /* _KERNEL */
-static void frsynclist(fr)
-register frentry_t *fr;
+/* ------------------------------------------------------------------------ */
+/* 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 i;
+ 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 ((fr->fr_ifnames[i][1] == '\0') &&
- ((fr->fr_ifnames[i][0] == '-') ||
- (fr->fr_ifnames[i][0] == '*'))) {
- fr->fr_ifas[i] = NULL;
- } else if (*fr->fr_ifnames[i]) {
- fr->fr_ifas[i] = GETUNIT(fr->fr_ifnames[i],
- fr->fr_v);
- if (!fr->fr_ifas[i])
- fr->fr_ifas[i] = (void *)-1;
+ 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;
- fr->fr_flags &= ~FR_DUP;
- if (*fdp->fd_ifname) {
- fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
- if (!fdp->fd_ifp)
- fdp->fd_ifp = (struct ifnet *)-1;
- else
+ 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;
}
- fdp = &fr->fr_tif;
- if (*fdp->fd_ifname) {
- fdp->fd_ifp = GETUNIT(fdp->fd_ifname, fr->fr_v);
- if (!fdp->fd_ifp)
- fdp->fd_ifp = (struct ifnet *)-1;
+#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_grp)
- frsynclist(fr->fr_grp);
+ 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
}
}
-void frsync()
+#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
- register struct ifnet *ifp;
-
-# if defined(__OpenBSD__) || ((NetBSD >= 199511) && (NetBSD < 1991011)) || \
- (defined(__FreeBSD_version) && (__FreeBSD_version >= 300000))
-# if (NetBSD >= 199905) || defined(__OpenBSD__)
- for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_list.tqe_next)
-# elif defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
- IFNET_RLOCK();
- TAILQ_FOREACH(ifp, &ifnet, if_link);
-# else
- for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next)
-# endif
-# else
- for (ifp = ifnet; ifp; ifp = ifp->if_next)
-# endif
- {
- ip_natsync(ifp);
- ip_statesync(ifp);
- }
- ip_natsync((struct ifnet *)-1);
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 500043)
- IFNET_RUNLOCK();
-# endif
-# endif /* !SOLARIS */
+ fr_natsync(ifp);
+ fr_statesync(ifp);
+# endif
WRITE_ENTER(&ipf_mutex);
- frsynclist(ipacct[0][fr_active]);
- frsynclist(ipacct[1][fr_active]);
- frsynclist(ipfilter[0][fr_active]);
- frsynclist(ipfilter[1][fr_active]);
-#ifdef USE_INET6
- frsynclist(ipacct6[0][fr_active]);
- frsynclist(ipacct6[1][fr_active]);
- frsynclist(ipfilter6[0][fr_active]);
- frsynclist(ipfilter6[1][fr_active]);
-#endif
+ 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);
}
@@ -2169,156 +3569,134 @@ void frsync()
* 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.
*/
-int ircopyptr(a, b, c)
-void *a, *b;
-size_t c;
+/* ------------------------------------------------------------------------ */
+/* 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
- if (copyin(a, (char *)&ca, sizeof(ca)))
- return EFAULT;
-#else
- bcopy(a, &ca, sizeof(ca));
-#endif
- err = copyin(ca, b, c);
- if (err)
- err = EFAULT;
+# 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;
}
-int iwcopyptr(a, b, c)
-void *a, *b;
-size_t c;
+/* ------------------------------------------------------------------------ */
+/* 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
- if (copyin(b, (char *)&ca, sizeof(ca)))
- return EFAULT;
-#else
- bcopy(b, &ca, sizeof(ca));
-#endif
- err = copyout(a, ca, c);
- if (err)
- err = EFAULT;
+# 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;
}
-
-#else /* _KERNEL */
-
-
-/*
- * return the first IP Address associated with an interface
- */
-int fr_ifpaddr(v, ifptr, inp)
-int v;
-void *ifptr;
-struct in_addr *inp;
-{
- return 0;
-}
-
-
-int ircopyptr(a, b, c)
-void *a, *b;
-size_t c;
-{
- caddr_t ca;
-
- bcopy(a, &ca, sizeof(ca));
- bcopy(ca, b, c);
- return 0;
-}
-
-
-int iwcopyptr(a, b, c)
-void *a, *b;
-size_t c;
-{
- caddr_t ca;
-
- bcopy(b, &ca, sizeof(ca));
- bcopy(a, ca, c);
- return 0;
-}
-
-
#endif
-int fr_lock(data, lockp)
+/* ------------------------------------------------------------------------ */
+/* 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, error;
+ int arg;
- error = IRCOPY(data, (caddr_t)&arg, sizeof(arg));
- if (!error) {
- error = IWCOPY((caddr_t)lockp, data, sizeof(*lockp));
- if (!error)
- *lockp = arg;
- }
- return error;
+ 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[0] = fr_state_lock;
- fiop->f_locks[1] = fr_nat_lock;
- fiop->f_locks[2] = fr_frag_lock;
- fiop->f_locks[3] = fr_auth_lock;
- fiop->f_fin[0] = ipfilter[0][0];
- fiop->f_fin[1] = ipfilter[0][1];
- fiop->f_fout[0] = ipfilter[1][0];
- fiop->f_fout[1] = ipfilter[1][1];
- fiop->f_acctin[0] = ipacct[0][0];
- fiop->f_acctin[1] = ipacct[0][1];
- fiop->f_acctout[0] = ipacct[1][0];
- fiop->f_acctout[1] = ipacct[1][1];
-#ifdef USE_INET6
- fiop->f_fin6[0] = ipfilter6[0][0];
- fiop->f_fin6[1] = ipfilter6[0][1];
- fiop->f_fout6[0] = ipfilter6[1][0];
- fiop->f_fout6[1] = ipfilter6[1][1];
- fiop->f_acctin6[0] = ipacct6[0][0];
- fiop->f_acctin6[1] = ipacct6[0][1];
- fiop->f_acctout6[0] = ipacct6[1][0];
- fiop->f_acctout6[1] = ipacct6[1][1];
-#else
- fiop->f_fin6[0] = NULL;
- fiop->f_fin6[1] = NULL;
- fiop->f_fout6[0] = NULL;
- fiop->f_fout6[1] = NULL;
- fiop->f_acctin6[0] = NULL;
- fiop->f_acctin6[1] = NULL;
- fiop->f_acctout6[0] = NULL;
- fiop->f_acctout6[1] = NULL;
-#endif
+ 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] = ipl_frouteok[0];
- fiop->f_froute[1] = ipl_frouteok[1];
+ fiop->f_froute[0] = fr_frouteok[0];
+ fiop->f_froute[1] = fr_frouteok[1];
fiop->f_running = fr_running;
- fiop->f_groups[0][0] = ipfgroups[0][0];
- fiop->f_groups[0][1] = ipfgroups[0][1];
- fiop->f_groups[1][0] = ipfgroups[1][0];
- fiop->f_groups[1][1] = ipfgroups[1][1];
- fiop->f_groups[2][0] = ipfgroups[2][0];
- fiop->f_groups[2][1] = ipfgroups[2][1];
+ 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;
- strncpy(fiop->f_version, ipfilter_version, sizeof(fiop->f_version));
+ fiop->f_features = fr_features;
+ (void) strncpy(fiop->f_version, ipfilter_version,
+ sizeof(fiop->f_version));
}
@@ -2362,77 +3740,2470 @@ int icmptoicmp6unreach[ICMP_MAX_UNREACH] = {
-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;
-#ifndef _KERNEL
-int mbuflen(buf)
-mb_t *buf;
+ 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;
{
- ip_t *ip;
+ 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);
- ip = (ip_t *)buf;
- return ip->ip_len;
+ 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
-#if defined(_KERNEL) && !defined(__sgi)
-void *ipf_pullup(m, fin, len, ipin)
-mb_t *m;
+/* ------------------------------------------------------------------------ */
+/* 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;
-int len;
-void *ipin;
+u_32_t *passp;
{
-# if SOLARIS
- qif_t *qf = fin->fin_qif;
-# endif
- int out = fin->fin_out, dpoff, ipoff;
- char *ip;
+ frgroup_t *fg;
+ void *rval;
- if (m == NULL)
+ rval = fr_iphmfindgroup(fin->fin_fr->fr_ptr, &fin->fin_src);
+ if (rval == NULL)
return NULL;
- ipoff = (char *)ipin - MTOD(m, char *);
- if (fin->fin_dp != NULL)
- dpoff = (char *)fin->fin_dp - (char *)ipin;
+ 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
- dpoff = 0;
+ oifq->ifq_tail = tqe->tqe_pnext;
+ tqe->tqe_next = NULL;
- if (M_BLEN(m) < len) {
-# if SOLARIS
- qif_t *qf = fin->fin_qif;
- int inc = 0;
-
- if (ipoff > 0) {
- if ((ipoff & 3) != 0) {
- inc = 4 - (ipoff & 3);
- if (m->b_rptr - inc >= m->b_datap->db_base)
- m->b_rptr -= inc;
+ /*
+ * 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
- inc = 0;
+ *next = &ipf_tunelist;
}
+ return ta;
}
- if (!pullupmsg(m, len + ipoff + inc)) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return NULL;
+
+ for (tap = &ipf_tunelist; (ta = *tap) != NULL; tap = &ta->ipft_next)
+ if (tap == cookie) {
+ if (next != NULL)
+ *next = &ta->ipft_next;
+ return ta;
}
- m->b_rptr += inc;
- ATOMIC_INCL(frstats[out].fr_pull[0]);
- qf->qf_data = MTOD(m, char *) + ipoff;
-# else
- m = m_pullup(m, len);
- *fin->fin_mp = m;
- if (m == NULL) {
- ATOMIC_INCL(frstats[out].fr_pull[1]);
- return NULL;
+
+ 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;
}
- ATOMIC_INCL(frstats[out].fr_pull[0]);
-# endif /* SOLARIS */
+
+ 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;
}
- ip = MTOD(m, char *) + ipoff;
- if (fin->fin_dp != NULL)
- fin->fin_dp = (char *)ip + dpoff;
- return ip;
+
+ 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;
}
-#endif /* _KERNEL */
diff --git a/contrib/ipfilter/ip_auth.c b/contrib/ipfilter/ip_auth.c
index 566f2039df97..b91c2e6245c0 100644
--- a/contrib/ipfilter/ip_auth.c
+++ b/contrib/ipfilter/ip_auth.c
@@ -1,39 +1,49 @@
+/* $NetBSD$ */
+
/*
- * Copyright (C) 1998-2001 by Darren Reed & Guido van Rooij.
+ * Copyright (C) 1998-2003 by Darren Reed & Guido van Rooij.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
-#if defined(__sgi) && (IRIX > 602)
-# include <sys/ptimers.h>
+#if defined(KERNEL) || defined(_KERNEL)
+# undef KERNEL
+# undef _KERNEL
+# define KERNEL 1
+# define _KERNEL 1
#endif
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/file.h>
-#if !defined(_KERNEL) && !defined(KERNEL)
+#if !defined(_KERNEL)
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
+# define _KERNEL
+# ifdef __OpenBSD__
+struct file;
+# endif
+# include <sys/uio.h>
+# undef _KERNEL
#endif
-#if (defined(KERNEL) || defined(_KERNEL)) && (__FreeBSD_version >= 220000)
+#if defined(_KERNEL) && (__FreeBSD_version >= 220000)
# include <sys/filio.h>
# include <sys/fcntl.h>
#else
# include <sys/ioctl.h>
#endif
-#ifndef linux
+#if !defined(linux)
# include <sys/protosw.h>
#endif
#include <sys/socket.h>
-#if (defined(_KERNEL) || defined(KERNEL)) && !defined(linux)
+#if defined(_KERNEL)
# include <sys/systm.h>
-#endif
-#if !defined(__SVR4) && !defined(__svr4__)
-# ifndef linux
+# if !defined(__SVR4) && !defined(__svr4__) && !defined(linux)
# include <sys/mbuf.h>
# endif
-#else
+#endif
+#if defined(__SVR4) || defined(__svr4__)
# include <sys/filio.h>
# include <sys/byteorder.h>
# ifdef _KERNEL
@@ -48,6 +58,9 @@
#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(bsdi)
# include <machine/cpu.h>
#endif
+#if defined(_KERNEL) && defined(__NetBSD__) && (__NetBSD_Version__ >= 104000000)
+# include <sys/proc.h>
+#endif
#include <net/if.h>
#ifdef sun
# include <net/af.h>
@@ -56,28 +69,29 @@
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
-#ifndef KERNEL
+#if !defined(_KERNEL) && !defined(__osf__) && !defined(__sgi)
# define KERNEL
+# define _KERNEL
# define NOT_KERNEL
#endif
-#ifndef linux
+#if !defined(linux)
# include <netinet/ip_var.h>
#endif
#ifdef NOT_KERNEL
+# undef _KERNEL
# undef KERNEL
#endif
-#ifdef __sgi
-# ifdef IFF_DRVRLOCK /* IRIX6 */
-# include <sys/hashing.h>
-# endif
-#endif
#include <netinet/tcp.h>
-#if defined(__sgi) && !defined(IFF_DRVRLOCK) /* IRIX < 6 */
+#if defined(IRIX) && (IRIX < 60516) /* IRIX < 6 */
extern struct ifqueue ipintrq; /* ip packet input queue */
#else
-# ifndef linux
+# if !defined(__hpux) && !defined(linux)
# if __FreeBSD_version >= 300000
# include <net/if_var.h>
+# if __FreeBSD_version >= 500042
+# define IF_QFULL _IF_QFULL
+# define IF_DROP _IF_DROP
+# endif /* __FreeBSD_version >= 500042 */
# endif
# include <netinet/in_var.h>
# include <netinet/tcp_fsm.h>
@@ -89,7 +103,7 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#include <netinet/tcpip.h>
#include "netinet/ip_fil.h"
#include "netinet/ip_auth.h"
-#if !SOLARIS && !defined(linux)
+#if !defined(MENTAT) && !defined(linux)
# include <net/netisr.h>
# ifdef __FreeBSD__
# include <machine/cpufunc.h>
@@ -97,58 +111,89 @@ extern struct ifqueue ipintrq; /* ip packet input queue */
#endif
#if (__FreeBSD_version >= 300000)
# include <sys/malloc.h>
-# if (defined(_KERNEL) || defined(KERNEL)) && !defined(IPFILTER_LKM)
+# if defined(_KERNEL) && !defined(IPFILTER_LKM)
# include <sys/libkern.h>
# include <sys/systm.h>
# endif
#endif
+/* END OF INCLUDES */
#if !defined(lint)
-static const char rcsid[] = "@(#)$Id: ip_auth.c,v 2.11.2.26 2003/09/22 12:37:04 darrenr Exp $";
+static const char rcsid[] = "@(#)Id: ip_auth.c,v 2.73.2.3 2004/08/26 11:25:21 darrenr Exp";
#endif
-#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
-extern KRWLOCK_T ipf_auth, ipf_mutex;
-extern kmutex_t ipf_authmx;
-# if SOLARIS
+#if SOLARIS
extern kcondvar_t ipfauthwait;
-# endif
-#endif
-#ifdef linux
-static struct wait_queue *ipfauthwait = NULL;
+#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[FR_NUMAUTH];
-mb_t *fr_authpkts[FR_NUMAUTH];
-static int fr_authstart = 0, fr_authend = 0, fr_authnext = 0;
-static frauthent_t *fae_list = NULL;
+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.
*/
-u_32_t fr_checkauth(ip, fin)
-ip_t *ip;
+frentry_t *fr_checkauth(fin, passp)
fr_info_t *fin;
+u_32_t *passp;
{
- u_short id = ip->ip_id;
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 0;
+ return NULL;
+
+ ip = fin->fin_ip;
+ id = ip->ip_id;
READ_ENTER(&ipf_auth);
for (i = fr_authstart; i != fr_authend; ) {
@@ -163,7 +208,7 @@ fr_info_t *fin;
/*
* Avoid feedback loop.
*/
- if (!(pass = fra->fra_pass) || (pass & FR_AUTH))
+ if (!(pass = fra->fra_pass) || (FR_ISAUTH(pass)))
pass = FR_BLOCK;
/*
* Create a dummy rule for the stateful checking to
@@ -171,26 +216,26 @@ fr_info_t *fin;
* trust from userland!
*/
if ((pass & FR_KEEPSTATE) || ((pass & FR_KEEPFRAG) &&
- (fin->fin_fi.fi_fl & FI_FRAG))) {
+ (fin->fin_flx & FI_FRAG))) {
KMALLOC(fr, frentry_t *);
if (fr) {
bcopy((char *)fra->fra_info.fin_fr,
- fr, sizeof(*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;
-#if BSD >= 199306
- fr->fr_oifa = NULL;
-#endif
+ 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 && fr != fra->fra_info.fin_fr) {
+ if ((fr != NULL) && (fr != fra->fra_info.fin_fr)) {
fr->fr_next = fr_authlist;
fr_authlist = fr;
}
@@ -201,7 +246,7 @@ fr_info_t *fin;
while (fra->fra_index == -1) {
i++;
fra++;
- if (i == FR_NUMAUTH) {
+ if (i == fr_authsize) {
i = 0;
fra = fr_auth;
}
@@ -215,15 +260,19 @@ fr_info_t *fin;
}
}
RWLOCK_EXIT(&ipf_auth);
- return pass;
+ if (passp != NULL)
+ *passp = pass;
+ ATOMIC_INC64(fr_authstats.fas_hits);
+ return fr;
}
i++;
- if (i == FR_NUMAUTH)
+ if (i == fr_authsize)
i = 0;
}
fr_authstats.fas_miss++;
RWLOCK_EXIT(&ipf_auth);
- return 0;
+ ATOMIC_INC64(fr_authstats.fas_miss);
+ return NULL;
}
@@ -232,15 +281,17 @@ fr_info_t *fin;
* If we do, store it and wake up any user programs which are waiting to
* hear about these events.
*/
-int fr_newauth(m, fin, ip)
+int fr_newauth(m, fin)
mb_t *m;
fr_info_t *fin;
-ip_t *ip;
{
-#if defined(_KERNEL) && SOLARIS
- qif_t *qif = fin->fin_qif;
+#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)
@@ -252,7 +303,7 @@ ip_t *ip;
RWLOCK_EXIT(&ipf_auth);
return 0;
} else {
- if (fr_authused == FR_NUMAUTH) {
+ if (fr_authused == fr_authsize) {
fr_authstats.fas_nospace++;
RWLOCK_EXIT(&ipf_auth);
return 0;
@@ -262,21 +313,24 @@ ip_t *ip;
fr_authstats.fas_added++;
fr_authused++;
i = fr_authend++;
- if (fr_authend == FR_NUMAUTH)
+ 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 SOLARIS && defined(_KERNEL)
-# if !defined(sparc)
+#if !defined(sparc) && !defined(m68k)
/*
* No need to copyback here as we want to undo the changes, not keep
* them.
*/
- if ((ip == (ip_t *)m->b_rptr) && (ip->ip_v == 4))
+ 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;
@@ -285,42 +339,42 @@ ip_t *ip;
bo = ip->ip_off;
ip->ip_off = htons(bo);
}
-# endif
- m->b_rptr -= qif->qf_off;
+#endif
+#if SOLARIS && defined(_KERNEL)
+ m->b_rptr -= qpi->qpi_off;
fr_authpkts[i] = *(mblk_t **)fin->fin_mp;
- fra->fra_q = qif->qf_q;
+ 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 == 0) {
+ 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);
+ WAKEUP(&fr_authnext,0);
#endif
return 1;
}
-int fr_auth_ioctl(data, mode, cmd)
+int fr_auth_ioctl(data, cmd, mode)
caddr_t data;
+ioctlcmd_t cmd;
int mode;
-#if defined(__NetBSD__) || defined(__OpenBSD__) || (__FreeBSD_version >= 300003)
-u_long cmd;
-#else
-int cmd;
-#endif
{
mb_t *m;
-#if defined(_KERNEL) && !SOLARIS && \
+#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;
+ int i, error = 0, len;
+ char *t;
switch (cmd)
{
@@ -329,81 +383,119 @@ int cmd;
error = EPERM;
break;
}
- error = fr_lock(data, &fr_auth_lock);
- break;
- case SIOCINIFR :
- case SIOCRMIFR :
- case SIOCADIFR :
- error = EINVAL;
- break;
- case SIOCINAFR :
- error = EINVAL;
- break;
- case SIOCRMAFR :
- case SIOCADAFR :
- /* These commands go via request to fr_preauthcmd */
- error = EINVAL;
+ fr_lock(data, &fr_auth_lock);
break;
+
case SIOCATHST:
fr_authstats.fas_faelist = fae_list;
- error = IWCOPYPTR((char *)&fr_authstats, data,
- sizeof(fr_authstats));
+ 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:
- if (!(mode & FWRITE)) {
- error = EPERM;
- break;
- }
fr_authioctlloop:
+ error = fr_inobj(data, au, IPFOBJ_FRAUTH);
READ_ENTER(&ipf_auth);
if ((fr_authnext != fr_authend) && fr_authpkts[fr_authnext]) {
- error = IWCOPYPTR((char *)&fr_auth[fr_authnext], data,
- sizeof(frauth_t));
+ 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)
+ if (error != 0)
break;
- WRITE_ENTER(&ipf_auth);
SPL_NET(s);
+ WRITE_ENTER(&ipf_auth);
fr_authnext++;
- if (fr_authnext == FR_NUMAUTH)
+ if (fr_authnext == fr_authsize)
fr_authnext = 0;
- SPL_X(s);
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
- mutex_enter(&ipf_authmx);
- if (!cv_wait_sig(&ipfauthwait, &ipf_authmx)) {
- mutex_exit(&ipf_authmx);
- return EINTR;
+ 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);
}
- mutex_exit(&ipf_authmx);
-# else
+# 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
+# endif /* __osf__ */
+# endif /* __hpux */
+# endif /* SOLARIS */
#endif
- if (!error)
+ MUTEX_EXIT(&ipf_authmx);
+ READ_ENTER(&ipf_global);
+ if (error == 0) {
+ READ_ENTER(&ipf_auth);
goto fr_authioctlloop;
+ }
break;
+
case SIOCAUTHR:
- if (!(mode & FWRITE)) {
- error = EPERM;
- break;
- }
- error = IRCOPYPTR(data, (caddr_t)&auth, sizeof(auth));
- if (error)
+ error = fr_inobj(data, &auth, IPFOBJ_FRAUTH);
+ if (error != 0)
return error;
- WRITE_ENTER(&ipf_auth);
SPL_NET(s);
+ WRITE_ENTER(&ipf_auth);
i = au->fra_index;
fra = fr_auth + i;
- if ((i < 0) || (i > FR_NUMAUTH) ||
+ if ((i < 0) || (i >= fr_authsize) ||
(fra->fra_info.fin_id != au->fra_info.fin_id)) {
- SPL_X(s);
RWLOCK_EXIT(&ipf_auth);
- return EINVAL;
+ SPL_X(s);
+ return ESRCH;
}
m = fr_authpkts[i];
fra->fra_index = -2;
@@ -411,63 +503,67 @@ fr_authioctlloop:
fr_authpkts[i] = NULL;
RWLOCK_EXIT(&ipf_auth);
#ifdef _KERNEL
- if (m && au->fra_info.fin_out) {
-# if SOLARIS
- error = (fr_qout(fra->fra_q, m) == 0) ? EINVAL : 0;
-# else /* SOLARIS */
- struct route ro;
-
- bzero((char *)&ro, sizeof(ro));
-# if ((_BSDI_VERSION >= 199802) && (_BSDI_VERSION < 200005)) || \
- defined(__OpenBSD__) || (defined(IRIX) && (IRIX >= 605)) || \
- (__FreeBSD_version >= 470102)
- error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL,
- NULL);
+ if ((m != NULL) && (au->fra_info.fin_out != 0)) {
+# ifdef MENTAT
+ error = !putq(fra->fra_q, m);
+# else /* MENTAT */
+# ifdef linux
# else
- error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL);
-# endif
- if (ro.ro_rt) {
- RTFREE(ro.ro_rt);
- }
-# endif /* SOLARIS */
- if (error)
+# 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) {
-# if SOLARIS
- error = (fr_qin(fra->fra_q, m) == 0) ? EINVAL : 0;
-# else /* SOLARIS */
-# if __FreeBSD_version >= 501104
- netisr_dispatch(NETISR_IP, 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);
- m_freem(m);
+ FREE_MB_T(m);
error = ENOBUFS;
} else {
IF_ENQUEUE(ifq, m);
-# if IRIX < 605
+# if IRIX < 60500
schednetisr(NETISR_IP);
-# endif
+# endif
}
-# endif
-# endif /* SOLARIS */
- if (error)
+# endif
+# endif /* Linux */
+# endif /* MENTAT */
+ if (error != 0)
fr_authstats.fas_quefail++;
else
fr_authstats.fas_queok++;
} else
error = EINVAL;
-# if SOLARIS
- if (error)
+# ifdef MENTAT
+ if (error != 0)
error = EINVAL;
-# else
+# 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;
@@ -475,7 +571,7 @@ fr_authioctlloop:
if (i == fr_authstart) {
while (fra->fra_index == -1) {
i++;
- if (i == FR_NUMAUTH)
+ if (i == fr_authsize)
i = 0;
fr_authstart = i;
if (i == fr_authend)
@@ -487,10 +583,11 @@ fr_authioctlloop:
}
}
}
-# endif
+# endif /* MENTAT */
#endif /* _KERNEL */
SPL_X(s);
break;
+
default :
error = EINVAL;
break;
@@ -509,41 +606,48 @@ void fr_authunload()
frentry_t *fr, **frp;
mb_t *m;
- WRITE_ENTER(&ipf_auth);
- for (i = 0; i < FR_NUMAUTH; i++) {
- if ((m = fr_authpkts[i])) {
- FREE_MB_T(m);
- fr_authpkts[i] = NULL;
- fr_auth[i].fra_index = -1;
- }
+ 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;
+ }
- for (faep = &fae_list; (fae = *faep); ) {
+ faep = &fae_list;
+ while ((fae = *faep) != NULL) {
*faep = fae->fae_next;
KFREE(fae);
}
ipauth = NULL;
- RWLOCK_EXIT(&ipf_auth);
- if (fr_authlist) {
- /*
- * We *MuST* reget ipf_auth because otherwise we won't get the
- * locks in the right order and risk deadlock.
- * We need ipf_mutex here to prevent a rule from using it
- * inside fr_check().
- */
- WRITE_ENTER(&ipf_mutex);
- WRITE_ENTER(&ipf_auth);
- for (frp = &fr_authlist; (fr = *frp); ) {
+ 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;
}
- RWLOCK_EXIT(&ipf_auth);
- RWLOCK_EXIT(&ipf_mutex);
+ }
+
+ 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;
}
}
@@ -559,17 +663,18 @@ void fr_authexpire()
register frauthent_t *fae, **faep;
register frentry_t *fr, **frp;
mb_t *m;
-#if !SOLARIS && defined(_KERNEL)
+# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
int s;
-#endif
+# endif
if (fr_auth_lock)
return;
SPL_NET(s);
WRITE_ENTER(&ipf_auth);
- for (i = 0, fra = fr_auth; i < FR_NUMAUTH; i++, fra++) {
- if ((!--fra->fra_age) && (m = fr_authpkts[i])) {
+ 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;
@@ -578,8 +683,9 @@ void fr_authexpire()
}
}
- for (faep = &fae_list; (fae = *faep); ) {
- if (!--fae->fae_age) {
+ 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++;
@@ -591,7 +697,7 @@ void fr_authexpire()
else
ipauth = NULL;
- for (frp = &fr_authlist; (fr = *frp); ) {
+ for (frp = &fr_authlist; ((fr = *frp) != NULL); ) {
if (fr->fr_ref == 1) {
*frp = fr->fr_next;
KFREE(fr);
@@ -603,52 +709,48 @@ void fr_authexpire()
}
int fr_preauthcmd(cmd, fr, frptr)
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (_BSDI_VERSION >= 199701) || (__FreeBSD_version >= 300000)
-u_long cmd;
-#else
-int cmd;
-#endif
+ioctlcmd_t cmd;
frentry_t *fr, **frptr;
{
frauthent_t *fae, **faep;
int error = 0;
-#if defined(KERNEL) && !SOLARIS
+# if !defined(MENAT) && defined(_KERNEL) && defined(USE_SPL)
int s;
#endif
- if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR)) {
- /* Should not happen */
- printf("fr_preauthcmd called with bad cmd 0x%lx", (u_long)cmd);
+ if ((cmd != SIOCADAFR) && (cmd != SIOCRMAFR))
return EIO;
- }
- for (faep = &fae_list; (fae = *faep); )
+ for (faep = &fae_list; ((fae = *faep) != NULL); ) {
if (&fae->fae_fr == fr)
break;
else
faep = &fae->fae_next;
- if (cmd == SIOCRMAFR) {
- if (!fr || !frptr)
+ }
+
+ if (cmd == (ioctlcmd_t)SIOCRMAFR) {
+ if (fr == NULL || frptr == NULL)
error = EINVAL;
- else if (!fae)
+ else if (fae == NULL)
error = ESRCH;
else {
- WRITE_ENTER(&ipf_auth);
SPL_NET(s);
+ WRITE_ENTER(&ipf_auth);
*faep = fae->fae_next;
- *frptr = fr->fr_next;
- SPL_X(s);
+ 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 && frptr) {
+ } else if (fr != NULL && frptr != NULL) {
KMALLOC(fae, frauthent_t *);
if (fae != NULL) {
bcopy((char *)fr, (char *)&fae->fae_fr,
sizeof(*fr));
- WRITE_ENTER(&ipf_auth);
SPL_NET(s);
+ WRITE_ENTER(&ipf_auth);
fae->fae_age = fr_defaultauthage;
fae->fae_fr.fr_hits = 0;
fae->fae_fr.fr_next = *frptr;
@@ -656,11 +758,47 @@ frentry_t *fr, **frptr;
fae->fae_next = *faep;
*faep = fae;
ipauth = &fae_list->fae_fr;
- SPL_X(s);
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
index e0cbf048f0a5..a39e7fd823f1 100644
--- a/contrib/ipfilter/ip_auth.h
+++ b/contrib/ipfilter/ip_auth.h
@@ -1,9 +1,11 @@
+/* $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.3.2.6 2002/10/26 07:03:00 darrenr Exp $
+ * Id: ip_auth.h,v 2.16 2003/07/25 12:29:56 darrenr Exp
*
*/
#ifndef __IP_AUTH_H__
@@ -13,10 +15,12 @@
typedef struct frauth {
int fra_age;
+ int fra_len;
int fra_index;
u_32_t fra_pass;
fr_info_t fra_info;
-#if SOLARIS
+ char *fra_buf;
+#ifdef MENTAT
queue_t *fra_q;
#endif
} frauth_t;
@@ -44,20 +48,19 @@ typedef struct fr_authstat {
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 u_32_t fr_checkauth __P((ip_t *, fr_info_t *));
+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 mb_t *fr_authpkts[];
-extern int fr_newauth __P((mb_t *, fr_info_t *, ip_t *));
-#if defined(__NetBSD__) || defined(__OpenBSD__) || \
- (__FreeBSD_version >= 300003)
-extern int fr_preauthcmd __P((u_long, frentry_t *, frentry_t **));
-extern int fr_auth_ioctl __P((caddr_t, int, u_long));
-#else
-extern int fr_preauthcmd __P((int, frentry_t *, frentry_t **));
-extern int fr_auth_ioctl __P((caddr_t, int, int));
-#endif
+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
index 76744247dda9..6ea3f709a558 100644
--- a/contrib/ipfilter/ip_compat.h
+++ b/contrib/ipfilter/ip_compat.h
@@ -1,10 +1,12 @@
+/* $NetBSD$ */
+
/*
- * Copyright (C) 1993-2001 by Darren Reed.
+ * 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.26.2.52 2004/06/09 00:01:14 darrenr Exp $
+ * Id: ip_compat.h,v 2.142.2.25 2005/03/28 09:33:36 darrenr Exp
*/
#ifndef __IP_COMPAT_H__
@@ -22,25 +24,6 @@
# define const
#endif
-#ifndef SOLARIS
-#define SOLARIS (defined(sun) && (defined(__svr4__) || defined(__SVR4)))
-#endif
-#if SOLARIS
-# if !defined(SOLARIS2)
-# define SOLARIS2 3 /* Pick an old version */
-# endif
-# if SOLARIS2 >= 8
-# ifndef USE_INET6
-# define USE_INET6
-# endif
-# else
-# undef USE_INET6
-# endif
-#endif
-#if defined(sun) && !(defined(__svr4__) || defined(__SVR4))
-# undef USE_INET6
-#endif
-
#if defined(_KERNEL) || defined(KERNEL) || defined(__KERNEL__)
# undef KERNEL
# undef _KERNEL
@@ -50,27 +33,53 @@
# define __KERNEL__
#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)
+#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
-#ifndef offsetof
-#define offsetof(t,m) (int)((&((t *)0L)->m))
+#if defined(BSD) && (BSD < 199103) && defined(__osf__)
+# undef BSD
+# define BSD 199103
#endif
-#if defined(__sgi) || defined(bsdi)
-struct ether_addr {
- u_char ether_addr_octet[6];
-};
+#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
+#ifndef LIFNAMSIZ
+# ifdef IF_NAMESIZE
# define LIFNAMSIZ IF_NAMESIZE
# else
# ifdef IFNAMSIZ
@@ -81,6 +90,12 @@ struct ether_addr {
# 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
@@ -95,233 +110,1543 @@ struct ether_addr {
# endif
#endif
-#ifdef __sgi
-# include <sys/debug.h>
-#endif
-
-#ifdef linux
-# include <sys/sysmacros.h>
-#endif
-
/*
* This is a workaround for <sys/uio.h> troubles on FreeBSD and OpenBSD.
*/
-#ifndef _KERNEL
-# define ADD_KERNEL
-# define _KERNEL
-# define KERNEL
-#endif
-#ifdef __OpenBSD__
+#ifndef linux
+# ifndef _KERNEL
+# define ADD_KERNEL
+# define _KERNEL
+# define KERNEL
+# endif
+# ifdef __OpenBSD__
struct file;
-#endif
-#include <sys/uio.h>
-#ifdef ADD_KERNEL
-# undef _KERNEL
-# undef KERNEL
+# endif
+# include <sys/uio.h>
+# ifdef ADD_KERNEL
+# undef _KERNEL
+# undef KERNEL
+# endif
#endif
-#if SOLARIS
-# define MTYPE(m) ((m)->b_datap->db_type)
-# if SOLARIS2 >= 4
-# include <sys/isa_defs.h>
-# endif
+
+/* ----------------------------------------------------------------------- */
+/* S O L A R I S */
+/* ----------------------------------------------------------------------- */
+#if SOLARIS
+# define MENTAT 1
+# include <sys/cmn_err.h>
+# include <sys/isa_defs.h>
+# include <sys/stream.h>
# include <sys/ioccom.h>
# include <sys/sysmacros.h>
# include <sys/kmem.h>
+# if SOLARIS2 >= 10
+# include <sys/procset.h>
+# include <sys/proc.h>
+# include <sys/devops.h>
+# include <sys/ddi_impldefs.h>
+# endif
/*
* because Solaris 2 defines these in two places :-/
*/
+# ifndef KERNEL
+# define _KERNEL
+# undef RES_INIT
+# endif /* _KERNEL */
+
+# if SOLARIS2 >= 8
+# include <netinet/ip6.h>
+# include <netinet/icmp6.h>
+# endif
+
+# include <inet/common.h>
+/* These 5 are defined in <inet/ip.h> and <netinet/ip.h> */
# undef IPOPT_EOL
# undef IPOPT_NOP
# undef IPOPT_LSRR
# undef IPOPT_RR
# undef IPOPT_SSRR
+# ifdef i386
+# define _SYS_PROMIF_H
+# endif
+# include <inet/ip.h>
+# undef COPYOUT
+# include <inet/ip_ire.h>
# ifndef KERNEL
-# define _KERNEL
-# undef RES_INIT
-# if SOLARIS2 >= 8
-# include <netinet/ip6.h>
-# endif
-# include <inet/common.h>
-# include <inet/ip.h>
-# include <inet/ip_ire.h>
# undef _KERNEL
-# else /* _KERNEL */
-# if SOLARIS2 >= 8
-# include <netinet/ip6.h>
-# endif
-# include <inet/common.h>
-# include <inet/ip.h>
-# include <inet/ip_ire.h>
-# endif /* _KERNEL */
+# endif
# if SOLARIS2 >= 8
+# define SNPRINTF snprintf
+
# include <inet/ip_if.h>
-# include <netinet/ip6.h>
# 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 <sys/atomic.h>
+typedef uint32_t u_32_t;
+# else
+typedef unsigned int u_32_t;
# endif
-# define M_BLEN(m) ((m)->b_wptr - (m)->b_rptr)
-
-typedef struct qif {
- struct qif *qf_next;
- ill_t *qf_ill;
- kmutex_t qf_lock;
- void *qf_iptr;
- void *qf_optr;
- queue_t *qf_in;
- queue_t *qf_out;
- void *qf_data; /* layer 3 header pointer */
- struct qinit *qf_wqinfo;
- struct qinit *qf_rqinfo;
- struct qinit qf_wqinit;
- struct qinit qf_rqinit;
- mblk_t *qf_m; /* These three fields are for passing data up from */
- queue_t *qf_q; /* fr_qin and fr_qout to the packet processing. */
- size_t qf_off;
- size_t qf_len; /* this field is used for in ipfr_fastroute */
- char qf_name[LIFNAMSIZ];
- /*
- * in case the ILL has disappeared...
- */
- size_t qf_hl; /* header length */
- int qf_sap;
-# if SOLARIS2 >= 8
- int qf_tunoff; /* tunnel offset */
-#endif
- size_t qf_incnt;
- size_t qf_outcnt;
-} qif_t;
-#else /* SOLARIS */
-# if !defined(__sgi)
-typedef int minor_t;
+# 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 */
-#define IPMINLEN(i, h) ((i)->ip_len >= ((i)->ip_hl * 4 + sizeof(struct h)))
-#ifndef IP_OFFMASK
-#define IP_OFFMASK 0x1fff
-#endif
+/* ----------------------------------------------------------------------- */
+/* H P U X */
+/* ----------------------------------------------------------------------- */
+#ifdef __hpux
+# define MENTAT 1
+# include <sys/sysmacros.h>
+# include <sys/spinlock.h>
+# include <sys/lock.h>
+# include <sys/stream.h>
+# ifdef USE_INET6
+# include <netinet/if_ether.h>
+# include <netinet/ip6.h>
+# include <netinet/icmp6.h>
+typedef struct ip6_hdr ip6_t;
+# endif
-#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 _KERNEL
+# define SNPRINTF sprintf
+# if (HPUXREV >= 1111)
+# define IPL_SELECT
+# ifdef IPL_SELECT
+# include <machine/sys/user.h>
+# include <sys/kthread_iface.h>
+# 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 defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
-# include <sys/param.h>
-# ifndef __FreeBSD_version
-# ifdef IPFILTER_LKM
-# include <osreldate.h>
+# if HPUXREV == 1111
+# include "kern_svcs.h"
+# else
+# include <sys/kern_svcs.h>
+# endif
+# undef ti_flags
+# undef TCP_NODELAY
+# undef TCP_MAXSEG
+# include <sys/reg.h>
+# 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
-# include <sys/osreldate.h>
+# 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 <netinet/ip_info.h>
+
+# 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
-# ifdef IPFILTER_LKM
-# define ACTUALLY_LKM_NOT_KERNEL
+
+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
-# if defined(__FreeBSD_version) && (__FreeBSD_version < 300000)
-# include <machine/spl.h>
+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 <sys/ksynch.h>
+# define IPF_LOCK_PL plhi
+# include <sys/sema.h>
+# undef kmutex_t
+typedef struct {
+ lock_t *l;
+ int pl;
+} kmutex_t;
+
+# ifdef MUTEX_INIT
+# define KMUTEX_T mutex_t
# else
-# if (__FreeBSD_version >= 300000) && (__FreeBSD_version < 400000)
-# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
-# define ACTUALLY_LKM_NOT_KERNEL
-# endif
+# 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 <sys/atomic_ops.h>
+# 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 <sys/kmem.h>
+# include <sys/ddi.h>
+# 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 <kern/lock.h>
+# include <sys/sysmacros.h>
+
+# ifdef _KERNEL
+# define KMUTEX_T simple_lock_data_t
+# define KRWLOCK_T lock_data_t
+# include <net/net_globals.h>
+# 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
-#endif /* __FreeBSD__ && KERNEL */
-#if defined(__FreeBSD_version) && (__FreeBSD_version >= 500000) && \
- defined(_KERNEL)
-# include <machine/in_cksum.h>
-#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;
/*
- * These operating systems already take care of the problem for us.
+ * Really, any arch where sizeof(long) != sizeof(int).
*/
-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || \
- defined(__sgi)
-typedef u_int32_t u_32_t;
+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
-# if defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \
- !defined(KLD_MODULE)
-# include "opt_inet6.h"
-# endif
# ifdef INET6
-# define USE_INET6
-# endif
+# 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
-# if !defined(_KERNEL) && !defined(IPFILTER_LKM) && !defined(USE_INET6)
-# if (defined(__FreeBSD_version) && (__FreeBSD_version >= 400000) && \
- !defined(NOINET6)) || \
- (defined(OpenBSD) && (OpenBSD >= 200111)) || \
- (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105000000))
+
+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
-#else
+
+# if defined(_KERNEL)
+# if (__FreeBSD_version >= 400000)
/*
- * Really, any arch where sizeof(long) != sizeof(int).
+ * 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.
*/
-# if defined(__alpha__) || defined(__alpha) || defined(_LP64)
-typedef unsigned int u_32_t;
-# else
-# if SOLARIS2 >= 6
-typedef uint32_t u_32_t;
+# 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 <sys/mutex.h>
+# include <sys/sx.h>
+/*
+ * 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
-typedef unsigned int u_32_t;
+# define KRWLOCK_T struct sx
# endif
# endif
-#endif /* __NetBSD__ || __OpenBSD__ || __FreeBSD__ || __sgi */
-#ifdef USE_INET6
-# if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
-# include <netinet/ip6.h>
-# ifdef _KERNEL
-# include <netinet6/ip6_var.h>
+# if (__FreeBSD_version >= 501113)
+# include <net/if_var.h>
+# 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 <netinet/in_systm.h>
+# include <netinet/ip.h>
+# include <machine/in_cksum.h>
+# 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 <machine/atomic.h>
+# 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 <machine/spl.h>
+# else
+# if __FreeBSD__ == 3
+# if defined(IPFILTER_LKM) && !defined(ACTUALLY_LKM_NOT_KERNEL)
+# define ACTUALLY_LKM_NOT_KERNEL
+# endif
# endif
-typedef struct ip6_hdr ip6_t;
# endif
-# include <netinet/icmp6.h>
-union i6addr {
- u_32_t i6[4];
- struct in_addr in4;
- struct in6_addr in6;
+
+# 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 <sys/kmem_alloc.h>
+# 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 <linux/config.h>
+#include <linux/version.h>
+# 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;
};
-#else
-union i6addr {
- u_32_t i6[4];
- struct in_addr in4;
+# 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 <net/ethernet.h>
+
+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 <linux/fs.h>
+# 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
-#define IP6CMP(a,b) bcmp((char *)&(a), (char *)&(b), sizeof(a))
-#define IP6EQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) == 0)
-#define IP6NEQ(a,b) (bcmp((char *)&(a), (char *)&(b), sizeof(a)) != 0)
-#define IP6_ISZERO(a) ((((union i6addr *)(a))->i6[0] | \
- ((union i6addr *)(a))->i6[1] | \
- ((union i6addr *)(a))->i6[2] | \
- ((union i6addr *)(a))->i6[3]) == 0)
-#define IP6_NOTZERO(a) ((((union i6addr *)(a))->i6[0] | \
- ((union i6addr *)(a))->i6[1] | \
- ((union i6addr *)(a))->i6[2] | \
- ((union i6addr *)(a))->i6[3]) != 0)
+
+/* ----------------------------------------------------------------------- */
+/* 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 <netinet/ip6.h>
+# include <netinet/icmp6.h>
+# if !defined(linux)
+# if defined(_KERNEL) && !defined(__osf__)
+# include <netinet6/ip6_var.h>
+# endif
+# endif
+typedef struct ip6_hdr ip6_t;
+# endif
+#endif
#ifndef MAX
-#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+# 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 <vm/vm.h>
+# endif
+# if !defined(__FreeBSD__) || (defined (__FreeBSD_version) && \
+ (__FreeBSD_version >= 300000))
+# if (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 105180000)) || \
+ (defined(OpenBSD) && (OpenBSD >= 200111))
+# include <uvm/uvm_extern.h>
+# else
+# include <vm/vm_extern.h>
+extern vm_map_t kmem_map;
+# endif
+# include <sys/proc.h>
+# else /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD_version >= 300000) */
+# include <vm/vm_kern.h>
+# endif /* !__FreeBSD__ || (__FreeBSD__ && __FreeBSD_version >= 300000) */
+
+# ifdef IPFILTER_M_IPFILTER
+# include <sys/malloc.h>
+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
@@ -355,320 +1680,87 @@ union i6addr {
/*
* IP option #defines
*/
-/*#define IPOPT_RR 7 */
+#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 */
-/*#define IPOPT_TS 68 */
+#undef IPOPT_TS
+#define IPOPT_TS 68
+#undef IPOPT_TR
#define IPOPT_TR 82 /* TR */
-/*#define IPOPT_SECURITY 130 */
-/*#define IPOPT_LSRR 131 */
+#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 */
-/*#define IPOPT_SATID 136 */
+#undef IPOPT_SATID
+#define IPOPT_SATID 136
#ifndef IPOPT_SID
# define IPOPT_SID IPOPT_SATID
#endif
-/*#define IPOPT_SSRR 137 */
+#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_WSCALE
-# define TCPOPT_WSCALE 3
+#ifndef TCPOPT_EOL
+# define TCPOPT_EOL 0
#endif
-
-/*
- * Build some macros and #defines to enable the same code to compile anywhere
- * Well, that's the idea, anyway :-)
- */
-#if SOLARIS
-typedef mblk_t mb_t;
-# 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
-#else
-typedef struct mbuf mb_t;
-#endif /* SOLARIS */
-
-#if !SOLARIS || (SOLARIS2 < 6) || !defined(KERNEL)
-# 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
+#ifndef TCPOPT_NOP
+# define TCPOPT_NOP 1
#endif
-#ifdef __sgi
-# define hz HZ
-# include <sys/ksynch.h>
-# define IPF_LOCK_PL plhi
-# include <sys/sema.h>
-#undef kmutex_t
-typedef struct {
- lock_t *l;
- int pl;
-} kmutex_t;
-# undef MUTEX_INIT
-# undef MUTEX_DESTROY
+#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
-#ifdef KERNEL
-# if SOLARIS
-# if SOLARIS2 >= 6
-# include <sys/atomic.h>
-# 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
-# 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 IRE_CACHE IRE_ROUTE
-# 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 MUTEX_ENTER(x) mutex_enter(x)
-# if 1
-# define KRWLOCK_T krwlock_t
-# define READ_ENTER(x) rw_enter(x, RW_READER)
-# define WRITE_ENTER(x) rw_enter(x, RW_WRITER)
-# define RW_UPGRADE(x) { if (rw_tryupgrade(x) == 0) { \
- rw_exit(x); \
- rw_enter(x, RW_WRITER); } \
- }
-# define MUTEX_DOWNGRADE(x) rw_downgrade(x)
-# define RWLOCK_INIT(x, y, z) rw_init((x), (y), RW_DRIVER, (z))
-# define RWLOCK_EXIT(x) rw_exit(x)
-# define RW_DESTROY(x) rw_destroy(x)
-# else
-# define KRWLOCK_T kmutex_t
-# define READ_ENTER(x) mutex_enter(x)
-# define WRITE_ENTER(x) mutex_enter(x)
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
-# define RWLOCK_EXIT(x) mutex_exit(x)
-# define RW_DESTROY(x) mutex_destroy(x)
-# endif
-# define MUTEX_INIT(x, y, z) mutex_init((x), (y), MUTEX_DRIVER, (z))
-# define MUTEX_DESTROY(x) mutex_destroy(x)
-# define MUTEX_EXIT(x) mutex_exit(x)
-# define MTOD(m,t) (t)((m)->b_rptr)
-# define IRCOPY(a,b,c) copyin((caddr_t)(a), (caddr_t)(b), (c))
-# define IWCOPY(a,b,c) copyout((caddr_t)(a), (caddr_t)(b), (c))
-# define IRCOPYPTR ircopyptr
-# define IWCOPYPTR iwcopyptr
-# define FREE_MB_T(m) freemsg(m)
-# 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 ill_t *get_unit __P((char *, int));
-# define GETUNIT(n, v) get_unit(n, v)
-# define IFNAME(x) ((ill_t *)x)->ill_name
-# else /* SOLARIS */
-# if defined(__sgi)
-# 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 MUTEX_ENTER(x) (x)->pl = LOCK((x)->l, IPF_LOCK_PL);
-# define KRWLOCK_T kmutex_t
-# define READ_ENTER(x) MUTEX_ENTER(x)
-# define WRITE_ENTER(x) MUTEX_ENTER(x)
-# define RW_UPGRADE(x) ;
-# define MUTEX_DOWNGRADE(x) ;
-# define RWLOCK_EXIT(x) MUTEX_EXIT(x)
-# define MUTEX_EXIT(x) UNLOCK((x)->l, (x)->pl);
-# define MUTEX_INIT(x,y,z) (x)->l = LOCK_ALLOC((uchar_t)-1, IPF_LOC